8 #include <GaudiKernel/GaudiException.h>
20 #include <GeoModelRead/ReadGeoModel.h>
21 #include <GeoModelKernel/GeoFullPhysVol.h>
27 constexpr
int SCT_HitIndex{1};
41 m_detectorManager(detectorManager),
42 m_commonItems(commonItems),
43 m_waferTree(waferTree)
53 index[
"barrel_endcap"],
60 <<
index[
"eta_module"] <<
" " <<
index[
"phi_module"] <<
" " <<
index[
"side"]);
61 ATH_MSG_DEBUG(
"hitIdOfWafer = " << std::hex << hitIdOfWafer << std::dec);
71 std::pair<std::string, int> &extraIndex,
72 std::map<std::string, int> &updatedIndex )
const
77 if (extraIndex.first !=
"eta_module") {
79 <<
index[
"eta_module"] <<
" " <<
index[
"phi_module"] <<
" " <<
index[
"side"]);
81 ATH_MSG_FATAL(
"Only splitting of eta_module supported for ITk strips!!!");
87 updatedIndex[extraIndex.first] += extraIndex.second;
90 index[
"barrel_endcap"],
92 index[
"eta_module"] + extraIndex.second,
97 <<
index[
"eta_module"] + extraIndex.second <<
" " <<
index[
"phi_module"] <<
" " <<
index[
"side"]);
98 ATH_MSG_DEBUG(
"hitIdOfWafer = " << std::hex << hitIdOfWafer << std::dec);
110 const std::map<std::string, std::string>&
parameters)
114 if (clas ==
"SiStripBox") {
116 }
else if (clas ==
"StereoAnnulus") {
119 ATH_MSG_ERROR(
"addSensorType: unrecognised sensor class: " << clas);
126 const std::map<std::string, std::string> &
parameters)
133 double thickness{0.320};
141 std::string carrierString;
143 if (carrierString ==
"electrons") {
145 }
else if (carrierString ==
"holes") {
148 throw GaudiException(
"Parameter carrierType should be electrons or holes for " +
typeName,
149 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
152 std::string readoutSideString;
154 if (readoutSideString ==
"+") {
156 }
else if (readoutSideString ==
"-") {
159 throw GaudiException(
"Parameter readoutSide should be + or - for " +
typeName,
160 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
163 std::string fieldDirectionString;
165 if (fieldDirectionString ==
"x") {
167 }
else if (fieldDirectionString ==
"y") {
169 }
else if (fieldDirectionString ==
"z") {
172 throw GaudiException(
"Parameter fieldDirection should be x, y, or z for " +
typeName,
173 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
176 std::string stripDirectionString;
178 if (stripDirectionString ==
"x") {
180 }
else if (stripDirectionString ==
"y") {
182 }
else if (stripDirectionString ==
"z") {
185 throw GaudiException(
"Parameter stripDirection should be x, y, or z for " +
typeName,
186 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
198 int detectorTypeEnum = 0;
201 else ATH_MSG_WARNING(
"Non-strip barrel type set for strip box DetectorElement - is this intended?");
212 double initZShift =
length * (-
static_cast<double>(splitLevel) * 0.5 + 0.5);
217 auto motherDesign = std::make_unique<StripBoxDesign>(stripDirection,
228 for (
int i = 0;
i< splitLevel;
i++) {
229 for (
int side : {0,1}) {
231 double zShift =
sign * (initZShift + (
i *
length));
233 auto design = std::make_unique<StripBoxDesign>(stripDirection,
245 design->setMother(motherDesign.get());
246 motherDesign->addChildDesign(
i,design.get());
257 auto design = std::make_unique<StripBoxDesign>(stripDirection,
276 const std::map<std::string, std::string> &
parameters)
285 double thickness{0.320};
286 double stereoAngle{0.020};
287 double centreR{500.};
290 std::vector<double> phiPitch;
291 std::vector<double> startR;
292 std::vector<double> endR;
295 std::string carrierString;
297 if (carrierString ==
"electrons") {
299 }
else if (carrierString ==
"holes") {
302 throw GaudiException(
"Parameter carrierType should be electrons or holes for " +
typeName,
303 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
306 std::string readoutSideString;
308 if (readoutSideString ==
"+") {
310 }
else if (readoutSideString ==
"-") {
313 throw GaudiException(
"Parameter readoutSide should be + or - for " +
typeName,
314 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
317 std::string fieldDirectionString;
319 if (fieldDirectionString ==
"x") {
321 }
else if (fieldDirectionString ==
"y") {
323 }
else if (fieldDirectionString ==
"z") {
326 throw GaudiException(
"Parameter fieldDirection should be x, y, or z for " +
typeName,
327 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
330 std::string stripDirectionString;
332 if (stripDirectionString ==
"x") {
334 }
else if (stripDirectionString ==
"y") {
336 }
else if (stripDirectionString ==
"z") {
339 throw GaudiException(
"Parameter stripDirection should be x, y, or z for " +
typeName,
340 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
351 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
355 if (phiPitch.size() !=
static_cast<size_t>(
nRows)) {
357 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
361 if (startR.size() !=
static_cast<size_t>(
nRows)) {
363 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
367 if (endR.size() !=
static_cast<size_t>(
nRows)) {
369 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
378 int detectorTypeEnum = 0;
381 else ATH_MSG_WARNING(
"Non-strip endcap type set for strip annulus DetectorElement - is this intended?");
387 std::vector<int> singleRowStrips;
388 std::vector<double> singleRowPitch;
389 std::vector<double> singleRowMinR;
390 std::vector<double> singleRowMaxR;
395 auto motherDesign = std::make_unique<StripStereoAnnulusDesign>(stripDirection,
410 for (
int i = 0;
i < splitLevel;
i++) {
411 singleRowStrips.clear();
412 singleRowPitch.clear();
413 singleRowMinR.clear();
414 singleRowMaxR.clear();
416 singleRowStrips.push_back(
nStrips[
i]);
417 singleRowPitch.push_back(phiPitch[
i]);
418 singleRowMinR.push_back(startR[
i]);
419 singleRowMaxR.push_back(endR[
i]);
423 double thisCentreR = (singleRowMinR[0] + singleRowMaxR[0] ) *0.5;
425 auto design = std::make_unique<StripStereoAnnulusDesign>(stripDirection,
443 design->setMother(motherDesign.get());
444 motherDesign->addChildDesign(
i,design.get());
456 auto design = std::make_unique<StripStereoAnnulusDesign>(stripDirection,
477 std::map<std::string, int> &
index,
478 std::pair<std::string, int> &extraIndex,
480 GeoVFullPhysVol *fpv,
483 std::map<std::string, int> updatedIndex;
485 int splitIndex = extraIndex.second;
490 if (not sctIdHelper){
491 ATH_MSG_ERROR(
"Failed dynamic cast to SCT_ID in StripGmxInterface::addSplitSensor");
494 Identifier id = sctIdHelper->wafer_id(updatedIndex[
"barrel_endcap"],
495 updatedIndex[
"layer_wheel"],
496 updatedIndex[
"phi_module"],
497 updatedIndex[
"eta_module"],
498 updatedIndex[
"side"]);
509 msg() << MSG::ERROR <<
key <<
" = " <<
value <<
"; ";
512 ATH_MSG_ERROR(
"Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
520 if (updatedIndex[
"barrel_endcap"] == 0) {
527 throw std::runtime_error(
"readout sensor type " +
typeName +
" not found.");
536 Wafer wafer((
unsigned int) hashId);
537 std::string errorMessage(
"");
539 updatedIndex[
"layer_wheel"],
540 updatedIndex[
"eta_module"],
541 updatedIndex[
"phi_module"],
542 updatedIndex[
"side"],
553 std::map<std::string, int> &
index,
555 GeoVFullPhysVol *fpv)
561 if (not sctIdHelper){
562 ATH_MSG_ERROR(
"StripGmxInterface::addSensor: ID helper pointer could not be cast to SCT_ID *");
566 index[
"layer_wheel"],
580 msg() << MSG::ERROR <<
key <<
" = " <<
value <<
"; ";
583 ATH_MSG_ERROR(
"Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
593 throw std::runtime_error(
"readout sensor type " +
typeName +
" not found.");
602 Wafer wafer((
unsigned int) hashId);
603 std::string errorMessage(
"");
605 index[
"layer_wheel"],
619 std::map<std::string, int> &
index,
620 GeoVFullPhysVol *fpv,
628 if (not sctIdHelper){
629 ATH_MSG_ERROR(
"Failed dynamic_cast to SCT_ID in StripGmxInterface::addAlignable");
635 id = sctIdHelper->wafer_id(
index[
"barrel_endcap"],
636 index[
"layer_wheel"],
642 id = sctIdHelper->wafer_id(
index[
"barrel_endcap"],
643 index[
"layer_wheel"],
649 id = sctIdHelper->wafer_id(
index[
"barrel_endcap"],
650 index[
"layer_wheel"],
656 id = sctIdHelper->wafer_id(
index[
"barrel_endcap"],
663 throw GaudiException(
"Unknown level " +
std::to_string(
level) +
" for alignment in addAlignable",
664 "StripGmxInterface::addAlignable", StatusCode::FAILURE);
671 std::map<std::string, int> &
index,
672 std::pair<std::string, int> &extraIndex,
673 GeoVFullPhysVol *fpv,
680 std::map<std::string, int> updatedIndex;
684 if (not sctIdHelper){
685 ATH_MSG_ERROR(
"Failed dynamic_cast to SCT_ID in StripGmxInterface::addSplitAlignable");
691 id = sctIdHelper->wafer_id(updatedIndex[
"barrel_endcap"],
692 updatedIndex[
"layer_wheel"],
693 updatedIndex[
"phi_module"],
694 updatedIndex[
"eta_module"],
695 updatedIndex[
"side"]);
698 id = sctIdHelper->wafer_id(updatedIndex[
"barrel_endcap"],
699 updatedIndex[
"layer_wheel"],
700 updatedIndex[
"phi_module"],
701 updatedIndex[
"eta_module"],
705 id = sctIdHelper->wafer_id(updatedIndex[
"barrel_endcap"],
706 updatedIndex[
"layer_wheel"],
712 id = sctIdHelper->wafer_id(updatedIndex[
"barrel_endcap"],
719 throw GaudiException(
"Unknown level " +
std::to_string(
level) +
" for alignment in addSplitAlignable",
720 "StripGmxInterface::addSplitAlignable", StatusCode::FAILURE);
729 const std::array<std::string,13> stereoAnnulusParamNames{
"thickness",
"carrierType",
"readoutSide",
"fieldDirection",
"stripDirection",
"stereoAngle",
"centreR",
"nRows",
"splitLevel",
"nStrips",
"phiPitch",
"startR",
"endR"};
731 if(stereoAnnulus->size() !=0){
732 for (
unsigned int iR =0;iR<stereoAnnulus->size();iR++){
733 std::map<std::string,std::string> stereoAnnulusMap;
734 for(
const std::string& paramName:stereoAnnulusParamNames){
735 std::string paramValue = (*stereoAnnulus)[iR]->getString(paramName);
736 stereoAnnulusMap[paramName] = paramValue;
738 std::string stereoAnnulusName = (*stereoAnnulus)[iR]->getString(
"SensorType");
745 const std::array<std::string,10> stripBoxParamNames{
"thickness",
"carrierType",
"readoutSide",
"fieldDirection",
"stripDirection",
"nRows",
"stripLength",
"splitLevel",
"nStrips",
"pitch"};
747 if(stripBox->size() !=0){
748 for (
unsigned int iR =0;iR<stripBox->size();iR++){
749 std::map<std::string,std::string> stripBoxMap;
750 for(
const std::string& paramName:stripBoxParamNames){
751 std::string paramValue = (*stripBox)[iR]->getString(paramName);
752 stripBoxMap[paramName] = paramValue;
754 std::string stripBoxName = (*stripBox)[iR]->getString(
"SensorType");
762 const std::array<std::string,5>
fields{
"barrel_endcap",
"layer_wheel",
"phi_module",
"eta_module",
"side"};
765 const std::array<std::string,3> publishers{
"ITk",
"ITkStrip",
"GeoModelXML"};
768 std::map<std::string, GeoFullPhysVol*> mapFPV;
769 for (
auto & iPub : publishers){
771 mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,
true);
772 if (!mapFPV.empty()) {
777 if (mapFPV.empty())
ATH_MSG_ERROR(
"Could not find any FPV tables under the expected names: "<<publishers);
778 for (
const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
780 size_t startRG = fullPhysVolInfoString.find(
"RG_");
781 if(startRG==std::string::npos){
782 ATH_MSG_DEBUG(
"GeoFullPhysVol "<<fullPhysVolInfoString<<
" does not have the expected format. Skipping");
785 std::string
typeName = fullPhysVolInfoString.substr(startRG);
786 std::map<std::string, int>
index;
788 size_t first = fullPhysVolInfoString.find(
field+
"_");
789 size_t last = fullPhysVolInfoString.find(
'_',
first+
field.size()+1);
790 if(
first==std::string::npos || last==std::string::npos){
791 ATH_MSG_DEBUG(
"Could not extract "<<
field<<
" from "<<fullPhysVolInfoString<<
". Skipping");
794 std::string strNew = fullPhysVolInfoString.substr(
first+
field.size()+1,last-(
first+
field.size()+1));
798 size_t splitPos = fullPhysVolInfoString.find(
"split_");
799 if(splitPos!=std::string::npos){
800 size_t last = fullPhysVolInfoString.find(
'_',splitPos+6);
801 std::string strNew = fullPhysVolInfoString.substr(splitPos+6,last-(splitPos+6));
802 int splitLevel = std::stoi(strNew);
803 for(
int i=0;
i<splitLevel;
i++){
804 std::string
field =
"eta_module";
805 std::pair<std::string,int> extraIndex(
field,
i);