Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:16

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