Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-20 03:13:48

0001 //#define EDM_ML_DEBUG
0002 
0003 #include "Geometry/MTDNumberingBuilder/plugins/DDCmsMTDConstruction.h"
0004 
0005 #include <utility>
0006 #include <sstream>
0007 
0008 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0009 #include "DetectorDescription/Core/interface/DDCompactView.h"
0010 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0011 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0012 #include "DetectorDescription/DDCMS/interface/DDSpecParRegistry.h"
0013 #include "Geometry/MTDNumberingBuilder/interface/GeometricTimingDet.h"
0014 #include "Geometry/MTDNumberingBuilder/plugins/ExtractStringFromDD.h"
0015 #include "Geometry/MTDNumberingBuilder/plugins/CmsMTDConstruction.h"
0016 
0017 #include "DataFormats/ForwardDetId/interface/BTLDetId.h"
0018 #include "DataFormats/ForwardDetId/interface/ETLDetId.h"
0019 
0020 #ifdef EDM_ML_DEBUG
0021 #include "DataFormats/Math/interface/deltaPhi.h"
0022 using angle_units::operators::convertRadToDeg;
0023 #endif
0024 
0025 class DDNameFilter : public DDFilter {
0026 public:
0027   void addNS(const std::string& addNS) { allowedNS_.emplace_back(addNS); }
0028   void add(const std::string& add) { allowed_.emplace_back(add); }
0029   void veto(const std::string& veto) { veto_.emplace_back(veto); }
0030 
0031   bool accept(const DDExpandedView& ev) const final {
0032     if (allowedNS_.empty() && allowed_.empty() && veto_.empty()) {
0033       return true;
0034     }
0035     bool out(false);
0036     std::string_view currentNSName(ev.logicalPart().name().ns());
0037     for (const auto& test : allowedNS_) {
0038       if (currentNSName.find(test) != std::string::npos) {
0039         out = true;
0040         if (!allowed_.empty() || !veto_.empty()) {
0041           std::string_view currentName(ev.logicalPart().name().name());
0042           for (const auto& test : veto_) {
0043             if (currentName.find(test) != std::string::npos) {
0044               return false;
0045             }
0046           }
0047           for (const auto& test : allowed_) {
0048             if (currentName.find(test) != std::string::npos) {
0049               return true;
0050             }
0051           }
0052         }
0053         break;
0054       }
0055     }
0056     return out;
0057   }
0058 
0059 private:
0060   std::vector<std::string> allowedNS_;
0061   std::vector<std::string> allowed_;
0062   std::vector<std::string> veto_;
0063 };
0064 
0065 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const DDCompactView& cpv) {
0066   std::string attribute{"CMSCutsRegion"};
0067   DDNameFilter filter;
0068   filter.addNS("mtd");
0069   filter.addNS("btl");
0070   filter.addNS("etl");
0071 
0072   DDFilteredView fv(cpv, filter);
0073 
0074   CmsMTDStringToEnum theCmsMTDStringToEnum;
0075   // temporary workaround to distinguish ETL scenarios ordering without introducing a dependency on MTDTopologyMode
0076   const bool prev8(fv.name().find("EModule") != std::string::npos);
0077 
0078   // Specify ETL end component
0079   GeometricTimingDet::GeometricTimingEnumType ETLEndComponent;
0080   if (prev8) {
0081     ETLEndComponent = GeometricTimingDet::ETLSensor;
0082   } else {
0083     ETLEndComponent = GeometricTimingDet::ETLSensor;
0084   }
0085 
0086   auto check_root = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
0087   if (check_root != GeometricTimingDet::MTD) {
0088     fv.firstChild();
0089     auto check_child = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
0090     if (check_child != GeometricTimingDet::MTD) {
0091       throw cms::Exception("Configuration") << " The first child of the DDFilteredView is not what is expected \n"
0092                                             << ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv) << "\n";
0093     }
0094     fv.parent();
0095   }
0096 
0097 #ifdef EDM_ML_DEBUG
0098   edm::LogInfo("MTDNumbering") << "Top level node = " << fv.name();
0099 #endif
0100 
0101   auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
0102   size_t limit = 0;
0103   CmsMTDConstruction<DDFilteredView> theCmsMTDConstruction;
0104 
0105   std::vector<GeometricTimingDet*> subdet;
0106   std::vector<GeometricTimingDet*> layer;
0107 
0108   do {
0109     GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(fv.name());
0110     GeometricTimingDet::GeometricTimingEnumType thisNode =
0111         theCmsMTDStringToEnum.type(fv.name().substr(0, CmsMTDStringToEnum::kModStrLen));
0112     size_t num = fv.geoHistory().size();
0113 
0114 #ifdef EDM_ML_DEBUG
0115     edm::LogVerbatim("MTDNumbering") << "Module = " << fv.name() << " fullNode = " << fullNode
0116                                      << " thisNode = " << thisNode;
0117 #endif
0118 
0119     if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
0120       limit = 0;
0121 
0122       // define subdetectors as GeometricTimingDet components
0123 
0124       subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
0125     }
0126     if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
0127       layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
0128 #ifdef EDM_ML_DEBUG
0129       edm::LogVerbatim("MTDNumbering") << "Number of layers: " << layer.size();
0130 #endif
0131     }
0132     //
0133     // workaround to make old and TDR structure to cohexist until needed
0134     // the level chosen for old corresponds to wafers for D50 and previous scenarios
0135     //
0136     if ((thisNode == GeometricTimingDet::BTLModule) && limit == 0) {
0137       limit = num;
0138     } else if ((thisNode == ETLEndComponent) && limit == 0) {
0139       limit = num;
0140     }
0141     if (num != limit && limit > 0) {
0142       continue;
0143     }
0144     if (thisNode == GeometricTimingDet::BTLModule) {
0145 #ifdef EDM_ML_DEBUG
0146       edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
0147 #endif
0148       theCmsMTDConstruction.buildBTLModule(fv, layer.back());
0149       limit = num;
0150     } else if (thisNode == ETLEndComponent) {
0151 #ifdef EDM_ML_DEBUG
0152       edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
0153 #endif
0154       theCmsMTDConstruction.buildETLModule(fv, layer.back());
0155       limit = num;
0156     }
0157   } while (fv.next());
0158 
0159   // sort GeometricTimingDet
0160 
0161 #ifdef EDM_ML_DEBUG
0162   auto comp = mtd->deepComponents();
0163   std::stringstream before(std::stringstream::in | std::stringstream::out);
0164   for (const auto& it : comp) {
0165     before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
0166   }
0167   edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
0168 #endif
0169 
0170   for (size_t index = 0; index < layer.size(); index++) {
0171     GeometricTimingDet::ConstGeometricTimingDetContainer& icomp = layer[index]->components();
0172     if (index > 0) {
0173       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
0174       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
0175       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
0176     } else {
0177       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
0178       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
0179     }
0180   }
0181 
0182   // Add layers to subdetectors:
0183   // first BTL (one layer only)
0184 
0185   subdet[0]->addComponent(layer[0]);
0186 
0187   // then ETL (number of layers depend on preTDR design or not)
0188 
0189   if (layer.size() == kNLayerPreTDR) {
0190     subdet[1]->addComponent(layer[1]);
0191     subdet[2]->addComponent(layer[2]);
0192   } else if (layer.size() == kNLayerTDR) {
0193     subdet[1]->addComponent(layer[1]);
0194     subdet[1]->addComponent(layer[2]);
0195     subdet[2]->addComponent(layer[3]);
0196     subdet[2]->addComponent(layer[4]);
0197   } else {
0198     throw cms::Exception("MTDNumbering") << "Wrong number of layers: " << layer.size();
0199   }
0200 
0201   // Add subdetectors to MTD
0202 
0203   mtd.get()->addComponents(subdet);
0204 
0205 #ifdef EDM_ML_DEBUG
0206   comp.clear();
0207   comp = mtd->deepComponents();
0208   std::stringstream after(std::stringstream::in | std::stringstream::out);
0209   for (const auto& it : comp) {
0210     after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
0211           << " " << it->type() << " " << it->translation().z() << " " << convertRadToDeg(makempiToppi(it->phi()))
0212           << "\n";
0213   }
0214   edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
0215 #endif
0216 
0217   return mtd;
0218 }
0219 
0220 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const cms::DDCompactView& cpv) {
0221   cms::DDFilteredView fv(cpv.detector(), cpv.detector()->worldVolume());
0222 
0223   fv.next(0);
0224   edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
0225   auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
0226 
0227   cms::DDSpecParRefs ref;
0228   const cms::DDSpecParRegistry& mypar = cpv.specpars();
0229   std::string attribute("MtdDDStructure");
0230   mypar.filter(ref, attribute, "BarrelTimingLayer");
0231   mypar.filter(ref, attribute, "EndcapTimingLayer");
0232   fv.mergedSpecifics(ref);
0233 
0234 #ifdef EDM_ML_DEBUG
0235   edm::LogVerbatim("DD4hep_MTDNumbering") << "Active filters using " << attribute << ":";
0236   fv.printFilter();
0237   edm::LogVerbatim("Geometry").log([&ref](auto& log) {
0238     log << "Filtered DD SpecPar Registry size: " << ref.size() << "\n";
0239     for (const auto& t : ref) {
0240       log << "\nSpecPar " << t.first << ":\nRegExps { ";
0241       for (const auto& ki : t.second->paths)
0242         log << ki << " ";
0243       log << "};\n ";
0244       for (const auto& kl : t.second->spars) {
0245         log << kl.first << " = ";
0246         for (const auto& kil : kl.second) {
0247           log << kil << " ";
0248         }
0249         log << "\n ";
0250       }
0251     }
0252   });
0253 #endif
0254 
0255   bool doSubdet = fv.firstChild();
0256   edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
0257 
0258   CmsMTDStringToEnum theCmsMTDStringToEnum;
0259 
0260   CmsMTDConstruction<cms::DDFilteredView> theCmsMTDConstruction;
0261   // temporary workaround to distinguish ETL scenarios ordering without introducing a dependency on MTDTopologyMode
0262   const bool prev8(fv.name().find("EModule") != std::string::npos);
0263 
0264   // Specify ETL end component
0265   GeometricTimingDet::GeometricTimingEnumType ETLEndComponent;
0266   if (prev8) {
0267     ETLEndComponent = GeometricTimingDet::ETLSensor;
0268   } else {
0269     ETLEndComponent = GeometricTimingDet::ETLSensor;
0270   }
0271 
0272   std::vector<GeometricTimingDet*> subdet;
0273   std::vector<GeometricTimingDet*> layer;
0274 
0275   while (doSubdet) {
0276     std::string nodeName(fv.name());
0277     GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(nodeName);
0278     GeometricTimingDet::GeometricTimingEnumType thisNode =
0279         theCmsMTDStringToEnum.type(nodeName.substr(0, CmsMTDStringToEnum::kModStrLen));
0280 
0281 #ifdef EDM_ML_DEBUG
0282     edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
0283     edm::LogVerbatim("DD4hep_MTDNumbering")
0284         << "Module = " << fv.name() << " fullNode = " << fullNode << " thisNode = " << thisNode;
0285 #endif
0286 
0287     if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
0288       // define subdetectors as GeometricTimingDet components
0289 
0290       subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
0291     }
0292     if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
0293       layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
0294 #ifdef EDM_ML_DEBUG
0295       edm::LogVerbatim("DD4hep_MTDNumbering") << "Number of layers: " << layer.size();
0296 #endif
0297     }
0298     if (thisNode == GeometricTimingDet::BTLModule) {
0299 #ifdef EDM_ML_DEBUG
0300       edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
0301 #endif
0302       theCmsMTDConstruction.buildBTLModule(fv, layer.back());
0303     } else if (thisNode == ETLEndComponent) {
0304 #ifdef EDM_ML_DEBUG
0305       edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
0306 #endif
0307       theCmsMTDConstruction.buildETLModule(fv, layer.back());
0308     }
0309 
0310     doSubdet = fv.firstChild();
0311   }
0312 
0313   // sort GeometricTimingDet
0314 
0315 #ifdef EDM_ML_DEBUG
0316   auto comp = mtd->deepComponents();
0317   std::stringstream before(std::stringstream::in | std::stringstream::out);
0318   for (const auto& it : comp) {
0319     before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
0320   }
0321   edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
0322 #endif
0323 
0324   for (size_t index = 0; index < layer.size(); index++) {
0325     GeometricTimingDet::ConstGeometricTimingDetContainer& icomp = layer[index]->components();
0326     if (index > 0) {
0327       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
0328       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
0329       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
0330     } else {
0331       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
0332       std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
0333     }
0334   }
0335 
0336   // Add layers to subdetectors:
0337   // first BTL (one layer only)
0338 
0339   subdet[0]->addComponent(layer[0]);
0340 
0341   // then ETL (number of layers depend on preTDR design or not)
0342 
0343   if (layer.size() == kNLayerPreTDR) {
0344     subdet[1]->addComponent(layer[1]);
0345     subdet[2]->addComponent(layer[2]);
0346   } else if (layer.size() == kNLayerTDR) {
0347     subdet[1]->addComponent(layer[1]);
0348     subdet[1]->addComponent(layer[2]);
0349     subdet[2]->addComponent(layer[3]);
0350     subdet[2]->addComponent(layer[4]);
0351   } else {
0352     throw cms::Exception("DD4hep_MTDNumbering") << "Wrong number of layers: " << layer.size();
0353   }
0354 
0355   // Add subdetectors to MTD
0356 
0357   mtd.get()->addComponents(subdet);
0358 
0359 #ifdef EDM_ML_DEBUG
0360   comp.clear();
0361   comp = mtd->deepComponents();
0362   std::stringstream after(std::stringstream::in | std::stringstream::out);
0363   for (const auto& it : comp) {
0364     after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
0365           << " " << it->type() << " " << it->translation().z() << " " << convertRadToDeg(makempiToppi(it->phi()))
0366           << "\n";
0367   }
0368   edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
0369 #endif
0370 
0371   return mtd;
0372 }