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  limit = num;
169  }
170  if (num != limit && limit > 0) {
171  continue;
172  }
173  if (thisNode == GeometricTimingDet::BTLModule) {
174 #ifdef EDM_ML_DEBUG
175  edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
176 #endif
177  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
178  limit = num;
179  } else if (thisNode == GeometricTimingDet::ETLModule) {
180 #ifdef EDM_ML_DEBUG
181  edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
182 #endif
183  theCmsMTDConstruction.buildETLModule(fv, layer.back());
184  limit = num;
185  }
186  } while (fv.next());
187 
188  // sort GeometricTimingDet
189 
190 #ifdef EDM_ML_DEBUG
191  auto comp = mtd->deepComponents();
192  std::stringstream before(std::stringstream::in | std::stringstream::out);
193  for (const auto& it : comp) {
194  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
195  }
196  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
197 #endif
198 
199  if (!isBTLV2) {
200  for (size_t index = 0; index < layer.size(); index++) {
202  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
203  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
204  if (index > 0) {
205  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
206  }
207  }
208  } else {
209  for (size_t index = 0; index < layer.size(); index++) {
211  if (index > 0) {
212  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
213  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
214  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
215  } else {
216  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
217  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
218  }
219  }
220  }
221 
222  // Add layers to subdetectors:
223  // first BTL (one layer only)
224 
225  subdet[0]->addComponent(layer[0]);
226 
227  // then ETL (number of layers depend on preTDR design or not)
228 
229  if (layer.size() == kNLayerPreTDR) {
230  subdet[1]->addComponent(layer[1]);
231  subdet[2]->addComponent(layer[2]);
232  } else if (layer.size() == kNLayerTDR) {
233  subdet[1]->addComponent(layer[1]);
234  subdet[1]->addComponent(layer[2]);
235  subdet[2]->addComponent(layer[3]);
236  subdet[2]->addComponent(layer[4]);
237  } else {
238  throw cms::Exception("MTDNumbering") << "Wrong number of layers: " << layer.size();
239  }
240 
241  // Add subdetectors to MTD
242 
243  mtd.get()->addComponents(subdet);
244 
245 #ifdef EDM_ML_DEBUG
246  comp.clear();
247  comp = mtd->deepComponents();
248  std::stringstream after(std::stringstream::in | std::stringstream::out);
249  for (const auto& it : comp) {
250  after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
251  << " " << it->type() << " " << it->translation().z() << " "
252  << convertRadToDeg(angle0to2pi::make0To2pi(it->phi())) << "\n";
253  }
254  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
255 #endif
256 
257  return mtd;
258 }
259 
260 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const cms::DDCompactView& cpv) {
261  cms::DDFilteredView fv(cpv.detector(), cpv.detector()->worldVolume());
262 
263  fv.next(0);
264  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
265  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
266 
267  cms::DDSpecParRefs ref;
268  const cms::DDSpecParRegistry& mypar = cpv.specpars();
269  std::string attribute("MtdDDStructure");
270  mypar.filter(ref, attribute, "BarrelTimingLayer");
271  mypar.filter(ref, attribute, "EndcapTimingLayer");
272  fv.mergedSpecifics(ref);
273 
274 #ifdef EDM_ML_DEBUG
275  edm::LogVerbatim("DD4hep_MTDNumbering") << "Active filters using " << attribute << ":";
276  fv.printFilter();
277  edm::LogVerbatim("Geometry").log([&ref](auto& log) {
278  log << "Filtered DD SpecPar Registry size: " << ref.size() << "\n";
279  for (const auto& t : ref) {
280  log << "\nSpecPar " << t.first << ":\nRegExps { ";
281  for (const auto& ki : t.second->paths)
282  log << ki << " ";
283  log << "};\n ";
284  for (const auto& kl : t.second->spars) {
285  log << kl.first << " = ";
286  for (const auto& kil : kl.second) {
287  log << kil << " ";
288  }
289  log << "\n ";
290  }
291  }
292  });
293 #endif
294 
295  bool doSubdet = fv.firstChild();
296  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
297 
298  CmsMTDStringToEnum theCmsMTDStringToEnum;
299 
300  CmsMTDConstruction<cms::DDFilteredView> theCmsMTDConstruction;
301  // temporary workaround to distinguish BTL scenarios ordering without introducing a dependency on MTDTopologyMode
302  auto isBTLV2 = false;
303 
304  std::vector<GeometricTimingDet*> subdet;
305  std::vector<GeometricTimingDet*> layer;
306 
307  while (doSubdet) {
308  std::string nodeName(fv.name());
309  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(nodeName);
311  theCmsMTDStringToEnum.type(nodeName.substr(0, CmsMTDStringToEnum::kModStrLen));
312 
313 #ifdef EDM_ML_DEBUG
314  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
315  edm::LogVerbatim("DD4hep_MTDNumbering")
316  << "Module = " << fv.name() << " fullNode = " << fullNode << " thisNode = " << thisNode;
317 #endif
318 
319  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
320  // define subdetectors as GeometricTimingDet components
321 
322  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
323  }
324  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
325  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
326 #ifdef EDM_ML_DEBUG
327  edm::LogVerbatim("DD4hep_MTDNumbering") << "Number of layers: " << layer.size();
328 #endif
329  }
330  if (thisNode == GeometricTimingDet::BTLModule) {
331 #ifdef EDM_ML_DEBUG
332  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
333 #endif
334  if (isBTLV2 == false) {
335  if (theCmsMTDConstruction.isBTLV2(fv)) {
336  isBTLV2 = true;
337  }
338  }
339  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
340  } else if (thisNode == GeometricTimingDet::ETLModule) {
341 #ifdef EDM_ML_DEBUG
342  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
343 #endif
344  theCmsMTDConstruction.buildETLModule(fv, layer.back());
345  }
346 
347  doSubdet = fv.firstChild();
348  }
349 
350  // sort GeometricTimingDet
351 
352 #ifdef EDM_ML_DEBUG
353  auto comp = mtd->deepComponents();
354  std::stringstream before(std::stringstream::in | std::stringstream::out);
355  for (const auto& it : comp) {
356  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
357  }
358  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
359 #endif
360 
361  if (!isBTLV2) {
362  for (size_t index = 0; index < layer.size(); index++) {
364  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
365  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
366  if (index > 0) {
367  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
368  }
369  }
370  } else {
371  for (size_t index = 0; index < layer.size(); index++) {
373  if (index > 0) {
374  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
375  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
376  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
377  } else {
378  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
379  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
380  }
381  }
382  }
383 
384  // Add layers to subdetectors:
385  // first BTL (one layer only)
386 
387  subdet[0]->addComponent(layer[0]);
388 
389  // then ETL (number of layers depend on preTDR design or not)
390 
391  if (layer.size() == kNLayerPreTDR) {
392  subdet[1]->addComponent(layer[1]);
393  subdet[2]->addComponent(layer[2]);
394  } else if (layer.size() == kNLayerTDR) {
395  subdet[1]->addComponent(layer[1]);
396  subdet[1]->addComponent(layer[2]);
397  subdet[2]->addComponent(layer[3]);
398  subdet[2]->addComponent(layer[4]);
399  } else {
400  throw cms::Exception("DD4hep_MTDNumbering") << "Wrong number of layers: " << layer.size();
401  }
402 
403  // Add subdetectors to MTD
404 
405  mtd.get()->addComponents(subdet);
406 
407 #ifdef EDM_ML_DEBUG
408  comp.clear();
409  comp = mtd->deepComponents();
410  std::stringstream after(std::stringstream::in | std::stringstream::out);
411  for (const auto& it : comp) {
412  after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
413  << " " << it->type() << " " << it->translation().z() << " "
414  << convertRadToDeg(angle0to2pi::make0To2pi(it->phi())) << "\n";
415  }
416  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
417 #endif
418 
419  return mtd;
420 }
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 *)
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)