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
0062 auto isBTLV2 = false;
0063
0064 const bool prev8(fv.name().find("EModule") != std::string::npos);
0065
0066
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
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
0122
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
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
0187
0188
0189 subdet[0]->addComponent(layer[0]);
0190
0191
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
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
0266 auto isBTLV2 = false;
0267
0268 const bool prev8(fv.name().find("EModule") != std::string::npos);
0269
0270
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
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
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
0359
0360
0361 subdet[0]->addComponent(layer[0]);
0362
0363
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
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 }