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                 stereoAnnulusMap[paramName] = (*stereoAnnulus)[iR]->getString(paramName);
 
  737         std::string stereoAnnulusName = (*stereoAnnulus)[iR]->getString(
"SensorType");
 
  744     const std::array<std::string,10> stripBoxParamNames{
"thickness",
"carrierType",
"readoutSide",
"fieldDirection",
"stripDirection",
"nRows",
"stripLength",
"splitLevel",
"nStrips",
"pitch"};
 
  746     if(stripBox->size() !=0){
 
  747        for (
unsigned int iR =0;iR<stripBox->size();iR++){
 
  748             std::map<std::string,std::string> stripBoxMap;
 
  749             for(
const std::string& paramName:stripBoxParamNames){
 
  750                 std::string paramValue = (*stripBox)[iR]->getString(paramName);
 
  751                 stripBoxMap[paramName] = std::move(paramValue);
 
  753         std::string stripBoxName = (*stripBox)[iR]->getString(
"SensorType");
 
  761     const std::array<std::string,5> 
fields{
"barrel_endcap",
"layer_wheel",
"phi_module",
"eta_module",
"side"}; 
 
  764     const std::array<std::string,3> publishers{
"ITk",
"ITkStrip",
"GeoModelXML"};
 
  767     std::map<std::string, GeoFullPhysVol*> mapFPV;
 
  768     for (
auto & iPub : publishers){
 
  770          mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,
true);
 
  771          if (!mapFPV.empty()) {
 
  776     if (mapFPV.empty()) 
ATH_MSG_ERROR(
"Could not find any FPV tables under the expected names: "<<publishers);
 
  777     for (
const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
 
  779         size_t startRG = fullPhysVolInfoString.find(
"RG_");
 
  780         if(startRG==std::string::npos){
 
  781             ATH_MSG_DEBUG(
"GeoFullPhysVol "<<fullPhysVolInfoString<<
" does not have the expected format. Skipping");
 
  784         std::string 
typeName = fullPhysVolInfoString.substr(startRG);
 
  785         std::map<std::string, int> 
index;
 
  787           size_t first = fullPhysVolInfoString.find(
field+
"_");
 
  788           size_t last = fullPhysVolInfoString.find(
'_',
first+
field.size()+1);
 
  789           if(
first==std::string::npos || last==std::string::npos){
 
  790              ATH_MSG_DEBUG(
"Could not extract "<<
field<<
" from "<<fullPhysVolInfoString<<
". Skipping");
 
  793           std::string strNew = fullPhysVolInfoString.substr(
first+
field.size()+1,last-(
first+
field.size()+1));
 
  797         size_t splitPos = fullPhysVolInfoString.find(
"split_");
 
  798         if(splitPos!=std::string::npos){
 
  799             size_t last = fullPhysVolInfoString.find(
'_',splitPos+6);
 
  800             std::string strNew = fullPhysVolInfoString.substr(splitPos+6,last-(splitPos+6));
 
  801             int splitLevel = std::stoi(strNew);
 
  802             for(
int i=0;
i<splitLevel;
i++){
 
  803               std::string 
field = 
"eta_module";
 
  804               std::pair<std::string,int> extraIndex(
field,
i);