CMS 3D CMS Logo

DDCmsMTDConstruction.cc
Go to the documentation of this file.
2 
3 #include <utility>
4 #include <sstream>
5 
14 
17 
18 //#define EDM_ML_DEBUG
19 
20 class DDNameFilter : public DDFilter {
21 public:
22  void add(const std::string& add) { allowed_.emplace_back(add); }
23  void veto(const std::string& veto) { veto_.emplace_back(veto); }
24 
25  bool accept(const DDExpandedView& ev) const final {
26  for (const auto& test : veto_) {
27  if (ev.logicalPart().name().fullname().find(test) != std::string::npos)
28  return false;
29  }
30  for (const auto& test : allowed_) {
31  if (ev.logicalPart().name().fullname().find(test) != std::string::npos)
32  return true;
33  }
34  return false;
35  }
36 
37 private:
38  std::vector<std::string> allowed_;
39  std::vector<std::string> veto_;
40 };
41 
42 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const DDCompactView& cpv) {
43  std::string attribute{"CMSCutsRegion"};
45  filter.add("mtd:");
46  filter.add("btl:");
47  filter.add("etl:");
48  filter.veto("service");
49  filter.veto("support");
50  filter.veto("FSide");
51  filter.veto("BSide");
52  filter.veto("LSide");
53  filter.veto("RSide");
54  filter.veto("Between");
55  filter.veto("SupportPlate");
56  filter.veto("Shield");
57  filter.veto("ThermalScreen");
58  filter.veto("Aluminium_Disc");
59  filter.veto("MIC6_Aluminium_Disc");
60  filter.veto("ThermalPad");
61  filter.veto("AlN");
62  filter.veto("LairdFilm");
63  filter.veto("ETROC");
64  filter.veto("SensorModule");
65  filter.veto("DiscSector");
66  filter.veto("LGAD_Substrate");
67 
68  DDFilteredView fv(cpv, filter);
69 
70  CmsMTDStringToEnum theCmsMTDStringToEnum;
71 
72  auto check_root = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
73  if (check_root != GeometricTimingDet::MTD) {
74  fv.firstChild();
75  auto check_child = theCmsMTDStringToEnum.type(ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv));
76  if (check_child != GeometricTimingDet::MTD) {
77  throw cms::Exception("Configuration") << " The first child of the DDFilteredView is not what is expected \n"
78  << ExtractStringFromDD<DDFilteredView>::getString(attribute, &fv) << "\n";
79  }
80  fv.parent();
81  }
82 
83 #ifdef EDM_ML_DEBUG
84  edm::LogInfo("MTDNumbering") << "Top level node = " << fv.name();
85 #endif
86 
87  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
88  size_t limit = 0;
89  CmsMTDConstruction<DDFilteredView> theCmsMTDConstruction;
90 
91  std::vector<GeometricTimingDet*> subdet;
92  std::vector<GeometricTimingDet*> layer;
93 
94  do {
95  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(fv.name());
97  theCmsMTDStringToEnum.type(fv.name().substr(0, CmsMTDStringToEnum::kModStrLen));
98  size_t num = fv.geoHistory().size();
99 
100 #ifdef EDM_ML_DEBUG
101  edm::LogVerbatim("MTDNumbering") << "Module = " << fv.name() << " fullNode = " << fullNode
102  << " thisNode = " << thisNode;
103 #endif
104 
105  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
106  limit = 0;
107 
108  // define subdetectors as GeometricTimingDet components
109 
110  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
111  }
112  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
113  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
114 #ifdef EDM_ML_DEBUG
115  edm::LogVerbatim("MTDNumbering") << "Number of layers: " << layer.size();
116 #endif
117  }
118  //
119  // the level chosen corresponds to wafers for D50 and previous scenarios
120  //
121  if ((thisNode == GeometricTimingDet::BTLModule) && limit == 0) {
122  limit = num + 1;
123  }
124  //
125  // workaround to make old and TDR structure to cohexist until needed
126  //
127  else if ((thisNode == GeometricTimingDet::ETLModule) && limit == 0) {
128  if (theCmsMTDConstruction.isETLtdr(fv)) {
129  limit = num;
130  } else {
131  limit = num + 1;
132  }
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 == GeometricTimingDet::ETLModule) {
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  for (size_t index = 0; index < layer.size(); index++) {
165  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderZ);
166  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderRR);
167  if (index > 0) {
168  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<DDFilteredView>::mtdOrderPhi);
169  }
170  }
171 
172  // Add layers to subdetectors:
173  // first BTL (one layer only)
174 
175  subdet[0]->addComponent(layer[0]);
176 
177  // then ETL (number of layers depend on preTDR design or not)
178 
179  if (layer.size() == kNLayerPreTDR) {
180  subdet[1]->addComponent(layer[1]);
181  subdet[2]->addComponent(layer[2]);
182  } else if (layer.size() == kNLayerTDR) {
183  subdet[1]->addComponent(layer[1]);
184  subdet[1]->addComponent(layer[2]);
185  subdet[2]->addComponent(layer[3]);
186  subdet[2]->addComponent(layer[4]);
187  } else {
188  throw cms::Exception("MTDNumbering") << "Wrong number of layers: " << layer.size();
189  }
190 
191  // Add subdetectors to MTD
192 
193  mtd.get()->addComponents(subdet);
194 
195 #ifdef EDM_ML_DEBUG
196  comp.clear();
197  comp = mtd->deepComponents();
198  std::stringstream after(std::stringstream::in | std::stringstream::out);
199  for (const auto& it : comp) {
200  after << "ORDER2 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
201  }
202  edm::LogVerbatim("MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
203 #endif
204 
205  return mtd;
206 }
207 
208 std::unique_ptr<GeometricTimingDet> DDCmsMTDConstruction::construct(const cms::DDCompactView& cpv) {
209  cms::DDFilteredView fv(cpv.detector(), cpv.detector()->worldVolume());
210 
211  fv.next(0);
212  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
213  auto mtd = std::make_unique<GeometricTimingDet>(&fv, GeometricTimingDet::MTD);
214 
215  cms::DDSpecParRefs ref;
216  const cms::DDSpecParRegistry& mypar = cpv.specpars();
217  std::string attribute("MtdDDStructure");
218  mypar.filter(ref, attribute, "BarrelTimingLayer");
219  mypar.filter(ref, attribute, "EndcapTimingLayer");
220  fv.mergedSpecifics(ref);
221 
222 #ifdef EDM_ML_DEBUG
223  edm::LogVerbatim("DD4hep_MTDNumbering") << "Active filters using " << attribute << ":";
224  fv.printFilter();
225  edm::LogVerbatim("Geometry").log([&ref](auto& log) {
226  log << "Filtered DD SpecPar Registry size: " << ref.size() << "\n";
227  for (const auto& t : ref) {
228  log << "\nSpecPar " << t.first << ":\nRegExps { ";
229  for (const auto& ki : t.second->paths)
230  log << ki << " ";
231  log << "};\n ";
232  for (const auto& kl : t.second->spars) {
233  log << kl.first << " = ";
234  for (const auto& kil : kl.second) {
235  log << kil << " ";
236  }
237  log << "\n ";
238  }
239  }
240  });
241 #endif
242 
243  bool doSubdet = fv.firstChild();
244  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
245 
246  CmsMTDStringToEnum theCmsMTDStringToEnum;
247 
248  CmsMTDConstruction<cms::DDFilteredView> theCmsMTDConstruction;
249 
250  std::vector<GeometricTimingDet*> subdet;
251  std::vector<GeometricTimingDet*> layer;
252 
253  while (doSubdet) {
254  std::string nodeName(fv.name());
255  GeometricTimingDet::GeometricTimingEnumType fullNode = theCmsMTDStringToEnum.type(nodeName);
257  theCmsMTDStringToEnum.type(nodeName.substr(0, CmsMTDStringToEnum::kModStrLen));
258 
259 #ifdef EDM_ML_DEBUG
260  edm::LogVerbatim("DD4hep_MTDNumbering") << fv.path();
261  edm::LogVerbatim("DD4hep_MTDNumbering")
262  << "Module = " << fv.name() << " fullNode = " << fullNode << " thisNode = " << thisNode;
263 #endif
264 
265  if (fullNode == GeometricTimingDet::BTL || fullNode == GeometricTimingDet::ETL) {
266  // define subdetectors as GeometricTimingDet components
267 
268  subdet.emplace_back(theCmsMTDConstruction.buildSubdet(fv));
269  }
270  if (fullNode == GeometricTimingDet::BTLLayer || fullNode == GeometricTimingDet::ETLDisc) {
271  layer.emplace_back(theCmsMTDConstruction.buildLayer(fv));
272 #ifdef EDM_ML_DEBUG
273  edm::LogVerbatim("DD4hep_MTDNumbering") << "Number of layers: " << layer.size();
274 #endif
275  }
276  if (thisNode == GeometricTimingDet::BTLModule) {
277 #ifdef EDM_ML_DEBUG
278  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
279 #endif
280  theCmsMTDConstruction.buildBTLModule(fv, layer.back());
281  } else if (thisNode == GeometricTimingDet::ETLModule) {
282 #ifdef EDM_ML_DEBUG
283  edm::LogVerbatim("DD4hep_MTDNumbering") << "Registered in GeometricTimingDet as type " << thisNode;
284 #endif
285  theCmsMTDConstruction.buildETLModule(fv, layer.back());
286  }
287 
288  doSubdet = fv.firstChild();
289  }
290 
291  // sort GeometricTimingDet
292 
293 #ifdef EDM_ML_DEBUG
294  auto comp = mtd->deepComponents();
295  std::stringstream before(std::stringstream::in | std::stringstream::out);
296  for (const auto& it : comp) {
297  before << "ORDER1 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
298  }
299  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order before sorting \n" << before.str();
300 #endif
301 
302  for (size_t index = 0; index < layer.size(); index++) {
304  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<cms::DDFilteredView>::mtdOrderZ);
305  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<cms::DDFilteredView>::mtdOrderRR);
306  if (index > 0) {
307  std::stable_sort(icomp.begin(), icomp.end(), CmsMTDConstruction<cms::DDFilteredView>::mtdOrderPhi);
308  }
309  }
310 
311  // Add layers to subdetectors:
312  // first BTL (one layer only)
313 
314  subdet[0]->addComponent(layer[0]);
315 
316  // then ETL (number of layers depend on preTDR design or not)
317 
318  if (layer.size() == kNLayerPreTDR) {
319  subdet[1]->addComponent(layer[1]);
320  subdet[2]->addComponent(layer[2]);
321  } else if (layer.size() == kNLayerTDR) {
322  subdet[1]->addComponent(layer[1]);
323  subdet[1]->addComponent(layer[2]);
324  subdet[2]->addComponent(layer[3]);
325  subdet[2]->addComponent(layer[4]);
326  } else {
327  throw cms::Exception("DD4hep_MTDNumbering") << "Wrong number of layers: " << layer.size();
328  }
329 
330  // Add subdetectors to MTD
331 
332  mtd.get()->addComponents(subdet);
333 
334 #ifdef EDM_ML_DEBUG
335  comp.clear();
336  comp = mtd->deepComponents();
337  std::stringstream after(std::stringstream::in | std::stringstream::out);
338  for (const auto& it : comp) {
339  after << "ORDER2 " << it->geographicalId().rawId() << " " << it->type() << " " << it->translation().z() << "\n";
340  }
341  edm::LogVerbatim("DD4hep_MTDNumbering") << "GeometricTimingDet order after sorting \n" << after.str();
342 #endif
343 
344  return mtd;
345 }
Log< level::Info, true > LogVerbatim
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
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
constexpr std::array< uint8_t, layerIndexSize > layer
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
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)