Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-09 02:40:46

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