Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-10-25 03:22:16

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