CMS 3D CMS Logo

DDCmsMTDConstruction.cc
Go to the documentation of this file.
2 
3 #include <utility>
4 #include <sstream>
5 
14 
17 
18 #ifdef EDM_ML_DEBUG
21 #endif
22 
23 class DDNameFilter : public DDFilter {
24 public:
25  void add(const std::string& add) { allowed_.emplace_back(add); }
26  void veto(const std::string& veto) { veto_.emplace_back(veto); }
27 
28  bool accept(const DDExpandedView& ev) const final {
29  std::string currentName(ev.logicalPart().name().fullname());
30  for (const auto& test : veto_) {
31  if (currentName.find(test) != std::string::npos)
32  return false;
33  }
34  for (const auto& test : allowed_) {
35  if (currentName.find(test) != std::string::npos)
36  return true;
37  }
38  return false;
39  }
40 
41 private:
42  std::vector<std::string> allowed_;
43  std::vector<std::string> veto_;
44 };
45 
46 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const DDCompactView& cpv) {
47  std::string attribute{"CMSCutsRegion"};
49  filter.add("mtd:");
50  filter.add("btl:");
51  filter.add("etl:");
52 
53  std::vector<std::string> volnames = {"FSide", "SupportPlate"};
54  for (auto const& theVol : volnames) {
55  filter.veto(theVol);
56  }
57 
58  DDFilteredView fv(cpv, filter);
59 
60  CmsMTDStringToEnum theCmsMTDStringToEnum;
61  // temporary workaround to distinguish BTL scenarios ordering without introducing a dependency on MTDTopologyMode
62  auto isBTLV2 = false;
63  // temporary workaround to distinguish ETL scenarios ordering without introducing a dependency on MTDTopologyMode
64  const bool prev8(fv.name().find("EModule") != std::string::npos);
65 
66  // Specify ETL end component
68  if (prev8) {
69  ETLEndComponent = GeometricTimingDet::ETLSensor;
70  } else {
71  ETLEndComponent = GeometricTimingDet::ETLSensor;
72  }
73 
74  auto check_root = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
75  if (check_root != GeometricTimingDet::MTD) {
76  fv.firstChild();
77  auto check_child = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
78  if (check_child != GeometricTimingDet::MTD) {
79  throw cms::Exception("Configuration") << " The first child of the DDFilteredView is not what is expected \n"
80  << ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv) << "\n";
81  }
82  fv.parent();
83  }
84 
85 #ifdef EDM_ML_DEBUG
86  edm::LogInfo("MTDNumbering") << "Top level node = " << fv.name();
87 #endif
88 
89  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
90  size_t limit = 0;
91  CmsMTDConstruction<DDFilteredView> theCmsMTDConstruction;
92 
93  std::vector<GeometricTimingDet*> subdet;
94  std::vector<GeometricTimingDet*> layer;
95 
96  do {
97  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(fv.name());
99  theCmsMTDStringToEnum.type(fv.name().substr(0, CmsMTDStringToEnum::kModStrLen));
100  size_t num = fv.geoHistory().size();
101 
102 #ifdef EDM_ML_DEBUG
103  edm::LogVerbatim("MTDNumbering") << "Module = " << fv.name() << " fullNode = " << fullNode
104  << " thisNode = " << thisNode;
105 #endif
106 
107  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
108  limit = 0;
109 
110  // define subdetectors as GeometricTimingDet components
111 
112  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
113  }
114  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
115  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
116 #ifdef EDM_ML_DEBUG
117  edm::LogVerbatim("MTDNumbering") << "Number of layers: " << layer.size();
118 #endif
119  }
120  //
121  // workaround to make old and TDR structure to cohexist until needed
122  // the level chosen for old corresponds to wafers for D50 and previous scenarios
123  //
124  if ((thisNode == GeometricTimingDet::BTLModule) && limit == 0) {
125  if (theCmsMTDConstruction.isBTLV2(fv)) {
126  limit = num;
127  isBTLV2 = true;
128  } else {
129  limit = num + 1;
130  }
131  } else if ((thisNode == ETLEndComponent) && limit == 0) {
132  limit = num;
133  }
134  if (num != limit && limit > 0) {
135  continue;
136  }
137  if (thisNode == GeometricTimingDet::BTLModule) {
138 #ifdef EDM_ML_DEBUG
139  edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
140 #endif
141  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
142  limit = num;
143  } else if (thisNode == ETLEndComponent) {
144 #ifdef EDM_ML_DEBUG
145  edm::LogVerbatim("MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
146 #endif
147  theCmsMTDConstruction.buildETLModule(fv, layer.back());
148  limit = num;
149  }
150  } while (fv.next());
151 
152  // sort GeometricTimingDet
153 
154 #ifdef EDM_ML_DEBUG
155  auto comp = mtd->deepComponents();
156  std::stringstream before(std::stringstream::in | std::stringstream::out);
157  for (const auto& it : comp) {
158  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
159  }
160  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
161 #endif
162 
163  if (!isBTLV2) {
164  for (size_t index = 0; index < layer.size(); index++) {
166  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
167  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
168  if (index > 0) {
169  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
170  }
171  }
172  } else {
173  for (size_t index = 0; index < layer.size(); index++) {
175  if (index > 0) {
176  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
177  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
178  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
179  } else {
180  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
181  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
182  }
183  }
184  }
185 
186  // Add layers to subdetectors:
187  // first BTL (one layer only)
188 
189  subdet[0]->addComponent(layer[0]);
190 
191  // then ETL (number of layers depend on preTDR design or not)
192 
193  if (layer.size() == kNLayerPreTDR) {
194  subdet[1]->addComponent(layer[1]);
195  subdet[2]->addComponent(layer[2]);
196  } else if (layer.size() == kNLayerTDR) {
197  subdet[1]->addComponent(layer[1]);
198  subdet[1]->addComponent(layer[2]);
199  subdet[2]->addComponent(layer[3]);
200  subdet[2]->addComponent(layer[4]);
201  } else {
202  throw cms::Exception("MTDNumbering") << "Wrong number of layers: " << layer.size();
203  }
204 
205  // Add subdetectors to MTD
206 
207  mtd.get()->addComponents(subdet);
208 
209 #ifdef EDM_ML_DEBUG
210  comp.clear();
211  comp = mtd->deepComponents();
212  std::stringstream after(std::stringstream::in | std::stringstream::out);
213  for (const auto& it : comp) {
214  after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
215  << " " << it->type() << " " << it->translation().z() << " "
216  << convertRadToDeg(angle0to2pi::make0To2pi(it->phi())) << "\n";
217  }
218  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
219 #endif
220 
221  return mtd;
222 }
223 
224 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const cms::DDCompactView& cpv) {
225  cms::DDFilteredView fv(cpv.detector(), cpv.detector()->worldVolume());
226 
227  fv.next(0);
228  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
229  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
230 
231  cms::DDSpecParRefs ref;
232  const cms::DDSpecParRegistry& mypar = cpv.specpars();
233  std::string attribute("MtdDDStructure");
234  mypar.filter(ref, attribute, "BarrelTimingLayer");
235  mypar.filter(ref, attribute, "EndcapTimingLayer");
236  fv.mergedSpecifics(ref);
237 
238 #ifdef EDM_ML_DEBUG
239  edm::LogVerbatim("DD4hep_MTDNumbering") << "Active filters using " << attribute << ":";
240  fv.printFilter();
241  edm::LogVerbatim("Geometry").log([&ref](auto& log) {
242  log << "Filtered DD SpecPar Registry size: " << ref.size() << "\n";
243  for (const auto& t : ref) {
244  log << "\nSpecPar " << t.first << ":\nRegExps { ";
245  for (const auto& ki : t.second->paths)
246  log << ki << " ";
247  log << "};\n ";
248  for (const auto& kl : t.second->spars) {
249  log << kl.first << " = ";
250  for (const auto& kil : kl.second) {
251  log << kil << " ";
252  }
253  log << "\n ";
254  }
255  }
256  });
257 #endif
258 
259  bool doSubdet = fv.firstChild();
260  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
261 
262  CmsMTDStringToEnum theCmsMTDStringToEnum;
263 
264  CmsMTDConstruction<cms::DDFilteredView> theCmsMTDConstruction;
265  // temporary workaround to distinguish BTL scenarios ordering without introducing a dependency on MTDTopologyMode
266  auto isBTLV2 = false;
267  // temporary workaround to distinguish ETL scenarios ordering without introducing a dependency on MTDTopologyMode
268  const bool prev8(fv.name().find("EModule") != std::string::npos);
269 
270  // Specify ETL end component
272  if (prev8) {
273  ETLEndComponent = GeometricTimingDet::ETLSensor;
274  } else {
275  ETLEndComponent = GeometricTimingDet::ETLSensor;
276  }
277 
278  std::vector<GeometricTimingDet*> subdet;
279  std::vector<GeometricTimingDet*> layer;
280 
281  while (doSubdet) {
282  std::string nodeName(fv.name());
283  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(nodeName);
285  theCmsMTDStringToEnum.type(nodeName.substr(0, CmsMTDStringToEnum::kModStrLen));
286 
287 #ifdef EDM_ML_DEBUG
288  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
289  edm::LogVerbatim("DD4hep_MTDNumbering")
290  << "Module = " << fv.name() << " fullNode = " << fullNode << " thisNode = " << thisNode;
291 #endif
292 
293  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
294  // define subdetectors as GeometricTimingDet components
295 
296  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
297  }
298  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
299  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
300 #ifdef EDM_ML_DEBUG
301  edm::LogVerbatim("DD4hep_MTDNumbering") << "Number of layers: " << layer.size();
302 #endif
303  }
304  if (thisNode == GeometricTimingDet::BTLModule) {
305 #ifdef EDM_ML_DEBUG
306  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
307 #endif
308  if (isBTLV2 == false) {
309  if (theCmsMTDConstruction.isBTLV2(fv)) {
310  isBTLV2 = true;
311  }
312  }
313  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
314  } else if (thisNode == ETLEndComponent) {
315 #ifdef EDM_ML_DEBUG
316  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
317 #endif
318  theCmsMTDConstruction.buildETLModule(fv, layer.back());
319  }
320 
321  doSubdet = fv.firstChild();
322  }
323 
324  // sort GeometricTimingDet
325 
326 #ifdef EDM_ML_DEBUG
327  auto comp = mtd->deepComponents();
328  std::stringstream before(std::stringstream::in | std::stringstream::out);
329  for (const auto& it : comp) {
330  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
331  }
332  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
333 #endif
334 
335  if (!isBTLV2) {
336  for (size_t index = 0; index < layer.size(); index++) {
338  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
339  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
340  if (index > 0) {
341  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
342  }
343  }
344  } else {
345  for (size_t index = 0; index < layer.size(); index++) {
347  if (index > 0) {
348  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
349  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
350  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
351  } else {
352  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderPhi);
353  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::btlOrderZ);
354  }
355  }
356  }
357 
358  // Add layers to subdetectors:
359  // first BTL (one layer only)
360 
361  subdet[0]->addComponent(layer[0]);
362 
363  // then ETL (number of layers depend on preTDR design or not)
364 
365  if (layer.size() == kNLayerPreTDR) {
366  subdet[1]->addComponent(layer[1]);
367  subdet[2]->addComponent(layer[2]);
368  } else if (layer.size() == kNLayerTDR) {
369  subdet[1]->addComponent(layer[1]);
370  subdet[1]->addComponent(layer[2]);
371  subdet[2]->addComponent(layer[3]);
372  subdet[2]->addComponent(layer[4]);
373  } else {
374  throw cms::Exception("DD4hep_MTDNumbering") << "Wrong number of layers: " << layer.size();
375  }
376 
377  // Add subdetectors to MTD
378 
379  mtd.get()->addComponents(subdet);
380 
381 #ifdef EDM_ML_DEBUG
382  comp.clear();
383  comp = mtd->deepComponents();
384  std::stringstream after(std::stringstream::in | std::stringstream::out);
385  for (const auto& it : comp) {
386  after << "ORDER2 " << it->geographicalId().rawId() << " " << static_cast<MTDDetId>(it->geographicalId()).mtdRR()
387  << " " << it->type() << " " << it->translation().z() << " "
388  << convertRadToDeg(angle0to2pi::make0To2pi(it->phi())) << "\n";
389  }
390  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
391 #endif
392 
393  return mtd;
394 }
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)