CMS 3D CMS Logo

DDCmsMTDConstruction.cc
Go to the documentation of this file.
1 //#define EDM_ML_DEBUG
2 
4 
5 #include <utility>
6 #include <sstream>
7 
16 
19 
20 #ifdef EDM_ML_DEBUG
23 #endif
24 
25 class DDNameFilter : public DDFilter {
26 public:
27  void add(const std::string& add) { allowed_.emplace_back(add); }
28  void veto(const std::string& veto) { veto_.emplace_back(veto); }
29 
30  bool accept(const DDExpandedView& ev) const final {
31  for (const auto& test : veto_) {
32  if (ev.logicalPart().name().fullname().find(test) != std::string::npos)
33  return false;
34  }
35  for (const auto& test : allowed_) {
36  if (ev.logicalPart().name().fullname().find(test) != std::string::npos)
37  return true;
38  }
39  return false;
40  }
41 
42 private:
43  std::vector<std::string> allowed_;
44  std::vector<std::string> veto_;
45 };
46 
47 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const DDCompactView& cpv) {
48  std::string attribute{"CMSCutsRegion"};
50  filter.add("mtd:");
51  filter.add("btl:");
52  filter.add("etl:");
53 
54  std::vector<std::string> volnames = {"service",
55  "support",
56  "FSide",
57  "BSide",
58  "LSide",
59  "RSide",
60  "Between",
61  "SupportPlate",
62  "Shield",
63  "ThermalScreen",
64  "Aluminium_Disc",
65  "MIC6_Aluminium_Disc",
66  "ThermalPad",
67  "AlN",
68  "LairdFilm",
69  "ETROC",
70  "SensorModule",
71  "SensorModule_Front_Left",
72  "SensorModule_Front_Right",
73  "SensorModule_Back_Left",
74  "SensorModule_Back_Right",
75  "DiscSector",
76  "LGAD_Substrate",
77  "ConcentratorCard",
78  "PowerControlCard",
79  "CoolingPlate",
80  "FrontEndCard",
81  "FrontModerator",
82  "Cables",
83  "Cables1",
84  "Cables2",
85  "Cables3",
86  "Cables4",
87  "Cables5",
88  "Cables6",
89  "Cables7",
90  "PatchPanel",
91  "Notich_cables",
92  "ServicesExtVolume1",
93  "ServicesExtVolume2",
94  "glueLGAD",
95  "BumpBonds",
96  "ModulePCB",
97  "connectorsGap",
98  "ReadoutBoard",
99  "LGAD"};
100  for (auto const& theVol : volnames) {
101  filter.veto(theVol);
102  }
103 
104  DDFilteredView fv(cpv, filter);
105 
106  CmsMTDStringToEnum theCmsMTDStringToEnum;
107  // temporary workaround to distinguish BTL scenarios ordering without introducing a dependency on MTDTopologyMode
108  auto isBTLV2 = false;
109 
110  auto check_root = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
111  if (check_root != GeometricTimingDet::MTD) {
112  fv.firstChild();
113  auto check_child = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
114  if (check_child != GeometricTimingDet::MTD) {
115  throw cms::Exception("Configuration") << " The first child of the DDFilteredView is not what is expected \n"
116  << ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv) << "\n";
117  }
118  fv.parent();
119  }
120 
121 #ifdef EDM_ML_DEBUG
122  edm::LogInfo("MTDNumbering") << "Top level node = " << fv.name();
123 #endif
124 
125  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
126  size_t limit = 0;
127  CmsMTDConstruction<DDFilteredView> theCmsMTDConstruction;
128 
129  std::vector<GeometricTimingDet*> subdet;
130  std::vector<GeometricTimingDet*> layer;
131 
132  do {
133  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(fv.name());
135  theCmsMTDStringToEnum.type(fv.name().substr(0, CmsMTDStringToEnum::kModStrLen));
136  size_t num = fv.geoHistory().size();
137 
138 #ifdef EDM_ML_DEBUG
139  edm::LogVerbatim("MTDNumbering") << "Module = " << fv.name() << " fullNode = " << fullNode
140  << " thisNode = " << thisNode;
141 #endif
142 
143  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
144  limit = 0;
145 
146  // define subdetectors as GeometricTimingDet components
147 
148  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
149  }
150  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
151  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
152 #ifdef EDM_ML_DEBUG
153  edm::LogVerbatim("MTDNumbering") << "Number of layers: " << layer.size();
154 #endif
155  }
156  //
157  // workaround to make old and TDR structure to cohexist until needed
158  // the level chosen for old corresponds to wafers for D50 and previous scenarios
159  //
160  if ((thisNode == GeometricTimingDet::BTLModule) && limit == 0) {
161  if (theCmsMTDConstruction.isBTLV2(fv)) {
162  limit = num;
163  isBTLV2 = true;
164  } else {
165  limit = num + 1;
166  }
167  } else if ((thisNode == GeometricTimingDet::ETLModule) && limit == 0) {
168  if (theCmsMTDConstruction.isETLtdr(fv)) {
169  limit = num;
170  } else {
171  limit = num + 1;
172  }
173  }
174  if (num != limit && limit > 0) {
175  continue;
176  }
177  if (thisNode == GeometricTimingDet::BTLModule) {
178 #ifdef EDM_ML_DEBUG
179  edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
180 #endif
181  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
182  limit = num;
183  } else if (thisNode == GeometricTimingDet::ETLModule) {
184 #ifdef EDM_ML_DEBUG
185  edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
186 #endif
187  theCmsMTDConstruction.buildETLModule(fv, layer.back());
188  limit = num;
189  }
190  } while (fv.next());
191 
192  // sort GeometricTimingDet
193 
194 #ifdef EDM_ML_DEBUG
195  auto comp = mtd->deepComponents();
196  std::stringstream before(std::stringstream::in | std::stringstream::out);
197  for (const auto& it : comp) {
198  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
199  }
200  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
201 #endif
202 
203  if (!isBTLV2) {
204  for (size_t index = 0; index < layer.size(); index++) {
206  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
207  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
208  if (index > 0) {
209  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
210  }
211  }
212  } else {
213  for (size_t index = 0; index < layer.size(); index++) {
215  if (index > 0) {
216  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
217  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
218  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
219  } else {
220  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
221  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
222  }
223  }
224  }
225 
226  // Add layers to subdetectors:
227  // first BTL (one layer only)
228 
229  subdet[0]->addComponent(layer[0]);
230 
231  // then ETL (number of layers depend on preTDR design or not)
232 
233  if (layer.size() == kNLayerPreTDR) {
234  subdet[1]->addComponent(layer[1]);
235  subdet[2]->addComponent(layer[2]);
236  } else if (layer.size() == kNLayerTDR) {
237  subdet[1]->addComponent(layer[1]);
238  subdet[1]->addComponent(layer[2]);
239  subdet[2]->addComponent(layer[3]);
240  subdet[2]->addComponent(layer[4]);
241  } else {
242  throw cms::Exception("MTDNumbering") << "Wrong number of layers: " << layer.size();
243  }
244 
245  // Add subdetectors to MTD
246 
247  mtd.get()->addComponents(subdet);
248 
249 #ifdef EDM_ML_DEBUG
250  comp.clear();
251  comp = mtd->deepComponents();
252  std::stringstream after(std::stringstream::in | std::stringstream::out);
253  for (const auto& it : comp) {
254  after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
255  << " " << it->type() << " " << it->translation().z() << " "
256  << convertRadToDeg(angle0to2pi::make0To2pi(it->phi())) << "\n";
257  }
258  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
259 #endif
260 
261  return mtd;
262 }
263 
264 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const cms::DDCompactView& cpv) {
265  cms::DDFilteredView fv(cpv.detector(), cpv.detector()->worldVolume());
266 
267  fv.next(0);
268  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
269  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
270 
271  cms::DDSpecParRefs ref;
272  const cms::DDSpecParRegistry& mypar = cpv.specpars();
273  std::string attribute("MtdDDStructure");
274  mypar.filter(ref, attribute, "BarrelTimingLayer");
275  mypar.filter(ref, attribute, "EndcapTimingLayer");
276  fv.mergedSpecifics(ref);
277 
278 #ifdef EDM_ML_DEBUG
279  edm::LogVerbatim("DD4hep_MTDNumbering") << "Active filters using " << attribute << ":";
280  fv.printFilter();
281  edm::LogVerbatim("Geometry").log([&ref](auto& log) {
282  log << "Filtered DD SpecPar Registry size: " << ref.size() << "\n";
283  for (const auto& t : ref) {
284  log << "\nSpecPar " << t.first << ":\nRegExps { ";
285  for (const auto& ki : t.second->paths)
286  log << ki << " ";
287  log << "};\n ";
288  for (const auto& kl : t.second->spars) {
289  log << kl.first << " = ";
290  for (const auto& kil : kl.second) {
291  log << kil << " ";
292  }
293  log << "\n ";
294  }
295  }
296  });
297 #endif
298 
299  bool doSubdet = fv.firstChild();
300  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
301 
302  CmsMTDStringToEnum theCmsMTDStringToEnum;
303 
304  CmsMTDConstruction<cms::DDFilteredView> theCmsMTDConstruction;
305  // temporary workaround to distinguish BTL scenarios ordering without introducing a dependency on MTDTopologyMode
306  auto isBTLV2 = false;
307 
308  std::vector<GeometricTimingDet*> subdet;
309  std::vector<GeometricTimingDet*> layer;
310 
311  while (doSubdet) {
312  std::string nodeName(fv.name());
313  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(nodeName);
315  theCmsMTDStringToEnum.type(nodeName.substr(0, CmsMTDStringToEnum::kModStrLen));
316 
317 #ifdef EDM_ML_DEBUG
318  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
319  edm::LogVerbatim("DD4hep_MTDNumbering")
320  << "Module = " << fv.name() << " fullNode = " << fullNode << " thisNode = " << thisNode;
321 #endif
322 
323  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
324  // define subdetectors as GeometricTimingDet components
325 
326  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
327  }
328  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
329  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
330 #ifdef EDM_ML_DEBUG
331  edm::LogVerbatim("DD4hep_MTDNumbering") << "Number of layers: " << layer.size();
332 #endif
333  }
334  if (thisNode == GeometricTimingDet::BTLModule) {
335 #ifdef EDM_ML_DEBUG
336  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
337 #endif
338  if (isBTLV2 == false) {
339  if (theCmsMTDConstruction.isBTLV2(fv)) {
340  isBTLV2 = true;
341  }
342  }
343  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
344  } else if (thisNode == GeometricTimingDet::ETLModule) {
345 #ifdef EDM_ML_DEBUG
346  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
347 #endif
348  theCmsMTDConstruction.buildETLModule(fv, layer.back());
349  }
350 
351  doSubdet = fv.firstChild();
352  }
353 
354  // sort GeometricTimingDet
355 
356 #ifdef EDM_ML_DEBUG
357  auto comp = mtd->deepComponents();
358  std::stringstream before(std::stringstream::in | std::stringstream::out);
359  for (const auto& it : comp) {
360  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
361  }
362  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
363 #endif
364 
365  if (!isBTLV2) {
366  for (size_t index = 0; index < layer.size(); index++) {
368  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
369  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
370  if (index > 0) {
371  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
372  }
373  }
374  } else {
375  for (size_t index = 0; index < layer.size(); index++) {
377  if (index > 0) {
378  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
379  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
380  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
381  } else {
382  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
383  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
384  }
385  }
386  }
387 
388  // Add layers to subdetectors:
389  // first BTL (one layer only)
390 
391  subdet[0]->addComponent(layer[0]);
392 
393  // then ETL (number of layers depend on preTDR design or not)
394 
395  if (layer.size() == kNLayerPreTDR) {
396  subdet[1]->addComponent(layer[1]);
397  subdet[2]->addComponent(layer[2]);
398  } else if (layer.size() == kNLayerTDR) {
399  subdet[1]->addComponent(layer[1]);
400  subdet[1]->addComponent(layer[2]);
401  subdet[2]->addComponent(layer[3]);
402  subdet[2]->addComponent(layer[4]);
403  } else {
404  throw cms::Exception("DD4hep_MTDNumbering") << "Wrong number of layers: " << layer.size();
405  }
406 
407  // Add subdetectors to MTD
408 
409  mtd.get()->addComponents(subdet);
410 
411 #ifdef EDM_ML_DEBUG
412  comp.clear();
413  comp = mtd->deepComponents();
414  std::stringstream after(std::stringstream::in | std::stringstream::out);
415  for (const auto& it : comp) {
416  after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
417  << " " << it->type() << " " << it->translation().z() << " "
418  << convertRadToDeg(angle0to2pi::make0To2pi(it->phi())) << "\n";
419  }
420  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
421 #endif
422 
423  return mtd;
424 }
Log< level::Info, true > LogVerbatim
bool isBTLV2(FilteredView &)
bool parent()
set the current node to the parent node ...
void buildBTLModule(FilteredView &, GeometricTimingDet *)
GeometricTimingDet * buildSubdet(FilteredView &)
GeometricTimingDet::GeometricTimingEnumType type(std::string const &) const
dd4hep::SpecParRefs DDSpecParRefs
Definition: DDCompactView.h:29
constexpr NumType convertRadToDeg(NumType radians)
Definition: angle_units.h:21
const cms::DDDetector * detector() const
Definition: DDCompactView.h:34
const std::string & name() const
The name of a logical-part of the current node in the filtered-view.
DDSpecParRegistry const & specpars() const
Definition: DDCompactView.h:35
static constexpr size_t kNLayerTDR
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
static constexpr size_t kModStrLen
static constexpr size_t kNLayerPreTDR
Detector identifier base class for the MIP Timing Layer.
Definition: MTDDetId.h:21
std::vector< std::string > veto_
dd4hep::SpecParRegistry DDSpecParRegistry
Definition: DDCompactView.h:28
static std::unique_ptr< GeometricTimingDet > construct(const DDCompactView &cpv)
static std::string getString(const std::string &, FilteredView *)
bool isETLtdr(FilteredView &)
void add(const std::string &add)
GeometricTimingDet * buildLayer(FilteredView &)
bool next(int)
set current node to the next node in the filtered tree
std::vector< std::string > allowed_
Log< level::Info, false > LogInfo
void buildETLModule(FilteredView &, GeometricTimingDet *)
dd4hep::Volume worldVolume() const
Handle to the world volume containing everything.
Definition: DDDetector.cc:67
bool accept(const DDExpandedView &ev) const final
true, if the DDExpandedNode fulfills the filter criteria
constexpr valType make0To2pi(valType angle)
Definition: deltaPhi.h:67
enum GTDEnumType { unknown=100, MTD=0, BTL=1, BTLLayer=2, BTLTray=3, BTLModule=4, BTLSensor=5, BTLCrystal=6, ETL=7, ETLDisc=8, ETLRing=9, ETLModule=10, ETLSensor=11 } GeometricTimingEnumType
std::vector< GeometricTimingDet const * > ConstGeometricTimingDetContainer
bool firstChild()
set the current node to the first child ...
A Filter accepts or rejects a DDExpandedNode based on a user-coded decision rule. ...
Definition: DDFilter.h:15
void veto(const std::string &veto)
Provides an exploded view of the detector (tree-view)