20 #include <GeoModelRead/ReadGeoModel.h> 
   21 #include <GeoModelKernel/GeoFullPhysVol.h> 
   25 constexpr 
int PixelHitIndex{0};
 
   54     m_detectorManager(detectorManager),
 
   55     m_commonItems(commonItems),
 
   56     m_moduleTree(moduleTree)
 
   67   if (not pixelIdHelper){
 
   68     ATH_MSG_ERROR(
"Failed dynamic_cast to PixelID in PixelGmxInterface::sensorId");
 
   78                     << 
index[
"eta_module"] << 
" " << 
index[
"phi_module"] << 
" " << 
index[
"side"]);
 
   84                                                              index[
"barrel_endcap"],
 
   91                                << 
index[
"eta_module"] << 
" " << 
index[
"phi_module"] << 
" " << 
index[
"side"]);
 
   92   ATH_MSG_DEBUG(
"hitIdOfModule = " << std::hex << hitIdOfModule << std::dec);
 
  105                                       const std::map<std::string, std::string>& 
parameters)
 
  109   if (clas == 
"SingleChip_RD53" || clas == 
"QuadChip_RD53") {
 
  120     if (   
typeName.find(
"Quad")!= std::string::npos
 
  121         && (   
typeName.find(
"endcap")!= std::string::npos
 
  122             || 
typeName.find(
"inclined")!= std::string::npos)) {
 
  126     ATH_MSG_ERROR(
"addSensorType: unrecognised module class: " << clas);
 
  133                                         const std::map<std::string, std::string> &
parameters)
 
  135   int circuitsPerEta{2}; 
 
  136   int circuitsPerPhi{2}; 
 
  137   double thickness{0.150};
 
  140   double pitchEtaLong{};
 
  141   double pitchPhiLong{};
 
  142   double pitchEtaEnd{};
 
  143   double pitchPhiEnd{};
 
  144   int nEtaLongPerSide{};
 
  145   int nPhiLongPerSide{};
 
  146   int nEtaEndPerSide{};
 
  147   int nPhiEndPerSide{};
 
  148   int rowsPerCircuit{};
 
  149   int columnsPerCircuit{};
 
  156   bool phiSymmetric{
true};
 
  157   bool etaSymmetric{
true};
 
  158   bool depthSymmetric{
true};
 
  185   ATH_MSG_DEBUG(
"readout geo - design thickness " << thickness << 
" " 
  186                 << 
" circuits " << circuitsPerPhi << 
" " << circuitsPerEta << 
" " 
  187                 << 
" rows/columns " << rowsPerCircuit << 
" " << columnsPerCircuit << 
" " 
  188                 << 
" pitch regular/long/end " << pitchPhi << 
" " << pitchEta
 
  189                 << 
" " << pitchPhiLong << 
" " << pitchEtaLong
 
  190                 << 
" " << pitchPhiEnd << 
" "  << pitchEtaEnd
 
  191                 << 
" n-long " << nPhiLongPerSide << 
" " << nEtaLongPerSide
 
  192                 << 
" n-end "  << nPhiEndPerSide  << 
" " << nEtaEndPerSide
 
  193                 << carrier << 
" " << readoutSide);
 
  198   int detectorTypeEnum = 0;
 
  209      std::stringstream amsg;
 
  210      amsg << 
"Index overflows index type of PixelDiodeTree. Parameters " 
  211           << 
"( " <<  circuitsPerPhi << 
" * " << rowsPerCircuit << 
" ), ( " 
  212           << 
"( " <<  circuitsPerEta << 
" * " << columnsPerCircuit << 
" ) !<" 
  214      throw std::runtime_error(amsg.str());
 
  219   bool flipFE=(
typeName.find(
"_even") !=std::string::npos);
 
  223   auto computeAttribute = [readoutTechnology,
 
  231                            ](
const std::array<PixelDiodeTree::IndexType,2> &split_idx,
 
  233                              [[maybe_unused]] 
const std::array<bool,4> &ganged,
 
  234                              [[maybe_unused]] 
unsigned int split_i,
 
  237      -> std::tuple<PixelDiodeTree::AttributeType,PixelDiodeTree::AttributeType>
 
  257         assert(split_idx[0]>=0 && split_idx[1]>=0);
 
  258         std::array<int,2> chip_idx{split_idx[0]/rowsPerCircuit, split_idx[1]/columnsPerCircuit};
 
  260         unsigned int n_large_dimensions = (  (std::abs(diode_width[0]-pitchPhi)>pitchPhi*.25)
 
  261                                             +(std::abs(diode_width[1]-pitchEta)>pitchEta*.25));
 
  262         switch (n_large_dimensions) {
 
  306                                                                           ? circuitsPerEta - chip_idx[1] - 1
 
  307                                                                           : (circuitsPerPhi-1) * circuitsPerEta + chip_idx[1]);
 
  309         return std::make_tuple(current_matrix_attribute, current_diode_attribute);
 
  313         = 
createPixelDiodeTree(std::array<unsigned int,2>{
static_cast<unsigned int>(circuitsPerPhi),
static_cast<unsigned int>(circuitsPerEta)},
 
  314                                std::array<unsigned int,2>{
static_cast<unsigned int>(rowsPerCircuit),
static_cast<unsigned int>(columnsPerCircuit)},
 
  316                                std::array<std::array<unsigned int,2>, 2>{ std::array<unsigned int,2>{
static_cast<unsigned int>(nPhiEndPerSide),
 
  317                                                                                                      static_cast<unsigned int>(nEtaEndPerSide)},   
 
  318                                                                           std::array<unsigned int,2>{
static_cast<unsigned int>(nPhiLongPerSide),
 
  319                                                                                                      static_cast<unsigned int>(nEtaLongPerSide)}}, 
 
  323                                std::array<std::array<unsigned int,2>, 2>{ std::array<unsigned int,2>{0
u,0
u},   
 
  324                                                                           std::array<unsigned int,2>{0
u,0
u}    
 
  329   auto design = std::make_unique<PixelModuleDesign>(thickness,
 
  330                                                     phiSymmetric, etaSymmetric, depthSymmetric,
 
  331                                                     circuitsPerPhi, circuitsPerEta,
 
  332                                                     columnsPerCircuit, rowsPerCircuit,
 
  333                                                     columnsPerCircuit, rowsPerCircuit,
 
  334                                                     std::move(diode_tree), carrier,
 
  335                                                     readoutSide, is3D, detectorType, readoutTechnology);
 
  338                 << 
" " << design->width() << 
"x" << design->length() << 
"x" << design->thickness()
 
  339                 << 
" " << design->rows() << 
"x" << design->columns()
 
  340                 << 
", " << circuitsPerPhi << 
"x" << circuitsPerEta << 
" " 
  341                 << rowsPerCircuit << 
" " << columnsPerCircuit << 
":\n" 
  352                                   std::map<std::string, int> &
index,
 
  354                                   GeoVFullPhysVol *fpv)
 
  360   if (not pixelIdHelper){
 
  361     ATH_MSG_ERROR(
"Failed dynamic_cast to PixelID in PixelGmxInterface::addSensor");
 
  365                                           index[
"layer_wheel"],
 
  367                                           index[
"eta_module"]);
 
  378       msg() << MSG::ERROR << 
key << 
" = " << 
value << 
"; ";
 
  381     ATH_MSG_ERROR(
"Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
 
  394   bool flipFE=
index[
"barrel_endcap"]!=0 && 
index[
"phi_module"]%2==0 && 
typeName.find(
"Quad") != std::string::npos;
 
  401     throw std::runtime_error(
"readout sensor type " + 
typeName + 
" not found.");
 
  405   if (design == 
nullptr) {
 
  407     throw std::runtime_error(
"readout sensor type " + 
typeName + 
" not found.");
 
  416   std::string errorMessage(
"");
 
  418                          index[
"layer_wheel"],
 
  431     const std::array<std::string,2> sensorTypes{
"QuadChip_RD53",
"SingleChip_RD53"};
 
  432     const std::array<std::string,17> rd53_ParamNames{
"circuitsPerEta",
"circuitsPerPhi",
"columns",
"detectorType",
"is3D",
"nEtaEndPerSide",
"nEtaLongPerSide",
"nPhiEndPerSide",
"nPhiLongPerSide",
"pitchEta",
"pitchEtaEnd",
"pitchEtaLong",
"pitchPhi",
"pitchPhiEnd",
"pitchPhiLong",
"rows",
"thickness"};
 
  434     for(
const std::string & sType:sensorTypes){
 
  436        if(rd53->size() !=0){
 
  437           for (
unsigned int iR =0;iR<rd53->size();iR++){
 
  438             std::map<std::string,std::string> rd53_Map;
 
  439             for(
const std::string & paramName:rd53_ParamNames){
 
  440             std::string paramValue = (*rd53)[iR]->getString(paramName);
 
  441             rd53_Map[paramName] = std::move(paramValue);
 
  443            std::string rd35_Name = (*rd53)[iR]->getString(
"SensorType");
 
  447            if (   rd35_Name.find(
"Quad")!= std::string::npos
 
  448                && (   rd35_Name.find(
"endcap")!= std::string::npos
 
  449                    || rd35_Name.find(
"inclined")!= std::string::npos)) {
 
  459     const std::array<std::string,5> 
fields{
"barrel_endcap",
"layer_wheel",
"phi_module",
"eta_module",
"side"}; 
 
  462     const std::array<std::string,3> publishers({
"ITk",
"ITkPixel",
"GeoModelXML"});
 
  465     std::map<std::string, GeoFullPhysVol*> mapFPV;
 
  466     for (
auto & iPub : publishers){
 
  468          mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,
true);
 
  469          if (!mapFPV.empty()) {
 
  474     if (mapFPV.empty()) 
ATH_MSG_ERROR(
"Could not find any FPV tables under the expected names: "<<publishers);
 
  476     for (
const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
 
  478         size_t startRG = fullPhysVolInfoString.find(
"RD53_");
 
  479         if(startRG==std::string::npos){
 
  480             ATH_MSG_DEBUG(
"GeoFullPhysVol "<<fullPhysVolInfoString<<
" does not have the expected format. Skipping");
 
  483         std::string 
typeName = fullPhysVolInfoString.substr(startRG);
 
  484         std::map<std::string, int> 
index;
 
  486         size_t first = fullPhysVolInfoString.find(
field+
"_");
 
  487         size_t last = fullPhysVolInfoString.find(
'_',
first+
field.size()+1);
 
  488         if(
first==std::string::npos || last==std::string::npos){
 
  489             ATH_MSG_DEBUG(
"Could not extract "<<
field<<
" from "<<fullPhysVolInfoString<<
". Skipping");
 
  492         std::string strNew = fullPhysVolInfoString.substr(
first+
field.size()+1,last-(
first+
field.size()+1));
 
  502                                      std::map<std::string, int> &
index,
 
  503                                      GeoVFullPhysVol *fpv,
 
  508   if (not pixelIdHelper){
 
  509     ATH_MSG_ERROR(
"Dynamic cast to PixelID failed in PixelGmxInterface::addAlignable");
 
  515       id = pixelIdHelper->wafer_id(
index[
"barrel_endcap"],
 
  516                                  index[
"layer_wheel"],
 
  522       id = pixelIdHelper->wafer_id(
index[
"barrel_endcap"],
 
  523                                  index[
"layer_wheel"],
 
  529       id = pixelIdHelper->wafer_id(
index[
"barrel_endcap"],
 
  530                                  index[
"layer_wheel"],
 
  536       id = pixelIdHelper->wafer_id(
index[
"barrel_endcap"],
 
  543       throw GaudiException(
"Unknown level " + 
std::to_string(
level) + 
" for alignment in addAlignable",
 
  544                            "PixelGmxInterface::addAlignable", StatusCode::FAILURE);