CMS 3D CMS Logo

DDHGCalMixRotatedCassette.cc
Go to the documentation of this file.
1 // File: DDHGCalMixRotatedCassette.cc
3 // Description: Geometry factory class for HGCal (Mix) adopted for DD4hep
5 
6 #include <cmath>
7 #include <memory>
8 #include <string>
9 #include <unordered_set>
10 #include <vector>
11 
21 #include "DD4hep/DetFactoryHelper.h"
26 
27 //#define EDM_ML_DEBUG
28 using namespace angle_units::operators;
29 
31  HGCalMixRotatedCassette() { throw cms::Exception("HGCalGeom") << "Wrong initialization to HGCalMixRotatedCassette"; }
33  cms::DDNamespace ns(ctxt, e, true);
35 
36 #ifdef EDM_ML_DEBUG
37  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Creating an instance";
38 #endif
39 
40  static constexpr double tol1 = 0.01 * dd4hep::mm;
41  dd4hep::Volume mother = ns.volume(args.parentName());
42 
43  waferTypes_ = args.value<int>("WaferTypes");
44  passiveTypes_ = args.value<int>("PassiveTypes");
45  facingTypes_ = args.value<int>("FacingTypes");
46  orientationTypes_ = args.value<int>("OrientationTypes");
47  partialTypes_ = args.value<int>("PartialTypes");
48  placeOffset_ = args.value<int>("PlaceOffset");
49  phiBinsScint_ = args.value<int>("NPhiBinScint");
50  forFireworks_ = args.value<int>("ForFireWorks");
51 #ifdef EDM_ML_DEBUG
52  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette::Number of types of wafers: " << waferTypes_
53  << " passives: " << passiveTypes_ << " facings: " << facingTypes_
54  << " Orientations: " << orientationTypes_ << " PartialTypes: " << partialTypes_
55  << " PlaceOffset: " << placeOffset_ << "; number of cells along phi " << phiBinsScint_
56  << " forFireworks_: " << forFireworks_;
57 #endif
58  firstLayer_ = args.value<int>("FirstLayer");
59  absorbMode_ = args.value<int>("AbsorberMode");
60  sensitiveMode_ = args.value<int>("SensitiveMode");
61 #ifdef EDM_ML_DEBUG
62  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette::First Layer " << firstLayer_ << " and "
63  << "Absober:Sensitive mode " << absorbMode_ << ":" << sensitiveMode_;
64 #endif
65  zMinBlock_ = args.value<double>("zMinBlock");
66  waferSize_ = args.value<double>("waferSize");
67  waferSepar_ = args.value<double>("SensorSeparation");
68  sectors_ = args.value<int>("Sectors");
69  cassettes_ = args.value<int>("Cassettes");
70  alpha_ = (1._pi) / sectors_;
71  cosAlpha_ = cos(alpha_);
72 #ifdef EDM_ML_DEBUG
73  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: zStart " << cms::convert2mm(zMinBlock_)
74  << " wafer width " << cms::convert2mm(waferSize_) << " separations "
75  << cms::convert2mm(waferSepar_) << " sectors " << sectors_ << ":"
76  << convertRadToDeg(alpha_) << ":" << cosAlpha_ << " with " << cassettes_
77  << " cassettes";
78 #endif
79  slopeB_ = args.value<std::vector<double>>("SlopeBottom");
80  zFrontB_ = args.value<std::vector<double>>("ZFrontBottom");
81  rMinFront_ = args.value<std::vector<double>>("RMinFront");
82  slopeT_ = args.value<std::vector<double>>("SlopeTop");
83  zFrontT_ = args.value<std::vector<double>>("ZFrontTop");
84  rMaxFront_ = args.value<std::vector<double>>("RMaxFront");
85 #ifdef EDM_ML_DEBUG
86  for (unsigned int i = 0; i < slopeB_.size(); ++i)
87  edm::LogVerbatim("HGCalGeom") << "Bottom Block [" << i << "] Zmin " << cms::convert2mm(zFrontB_[i]) << " Rmin "
88  << cms::convert2mm(rMinFront_[i]) << " Slope " << slopeB_[i];
89  for (unsigned int i = 0; i < slopeT_.size(); ++i)
90  edm::LogVerbatim("HGCalGeom") << "Top Block [" << i << "] Zmin " << cms::convert2mm(zFrontT_[i]) << " Rmax "
91  << cms::convert2mm(rMaxFront_[i]) << " Slope " << slopeT_[i];
92 #endif
93 
94  waferFull_ = args.value<std::vector<std::string>>("WaferNamesFull");
95  waferPart_ = args.value<std::vector<std::string>>("WaferNamesPartial");
96 #ifdef EDM_ML_DEBUG
97  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << waferFull_.size() << " full and "
98  << waferPart_.size() << " partial modules\nDDHGCalMixRotatedCassette:Full Modules:";
99  unsigned int i1max = static_cast<unsigned int>(waferFull_.size());
100  for (unsigned int i1 = 0; i1 < i1max; i1 += 2) {
101  std::ostringstream st1;
102  unsigned int i2 = std::min((i1 + 2), i1max);
103  for (unsigned int i = i1; i < i2; ++i)
104  st1 << " [" << i << "] " << waferFull_[i];
105  edm::LogVerbatim("HGCalGeom") << st1.str();
106  }
107  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Partial Modules:";
108  i1max = static_cast<unsigned int>(waferPart_.size());
109  for (unsigned int i1 = 0; i1 < i1max; i1 += 2) {
110  std::ostringstream st1;
111  unsigned int i2 = std::min((i1 + 2), i1max);
112  for (unsigned int i = i1; i < i2; ++i)
113  st1 << " [" << i << "] " << waferPart_[i];
114  edm::LogVerbatim("HGCalGeom") << st1.str();
115  }
116 #endif
117  passiveFull_ = args.value<std::vector<std::string>>("PassiveNamesFull");
118  passivePart_ = args.value<std::vector<std::string>>("PassiveNamesPartial");
119 #ifdef EDM_ML_DEBUG
120  edm::LogVerbatim("HGCalGeom") << "DDHGCalSiliconRotatedCassette: " << passiveFull_.size() << " full and "
121  << passivePart_.size() << " partial passive modules";
122  i1max = static_cast<unsigned int>(passiveFull_.size());
123  for (unsigned int i1 = 0; i1 < i1max; i1 += 2) {
124  std::ostringstream st1;
125  unsigned int i2 = std::min((i1 + 2), i1max);
126  for (unsigned int i = i1; i < i2; ++i)
127  st1 << " [" << i << "] " << passiveFull_[i];
128  edm::LogVerbatim("HGCalGeom") << st1.str();
129  }
130  edm::LogVerbatim("HGCalGeom") << "DDHGCalSiliconRotatedCassette: Partial Modules:";
131  i1max = static_cast<unsigned int>(passivePart_.size());
132  for (unsigned int i1 = 0; i1 < i1max; i1 += 2) {
133  std::ostringstream st1;
134  unsigned int i2 = std::min((i1 + 2), i1max);
135  for (unsigned int i = i1; i < i2; ++i)
136  st1 << " [" << i << "] " << passivePart_[i];
137  edm::LogVerbatim("HGCalGeom") << st1.str();
138  }
139 #endif
140 
141  materials_ = args.value<std::vector<std::string>>("MaterialNames");
142  names_ = args.value<std::vector<std::string>>("VolumeNames");
143  thick_ = args.value<std::vector<double>>("Thickness");
144  copyNumber_.resize(materials_.size(), 1);
145 #ifdef EDM_ML_DEBUG
146  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << materials_.size() << " types of volumes";
147  for (unsigned int i = 0; i < names_.size(); ++i)
148  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names_[i] << " of thickness "
149  << cms::convert2mm(thick_[i]) << " filled with " << materials_[i]
150  << " first copy number " << copyNumber_[i];
151 #endif
152  layers_ = args.value<std::vector<int>>("Layers");
153  layerThick_ = args.value<std::vector<double>>("LayerThick");
154 #ifdef EDM_ML_DEBUG
155  edm::LogVerbatim("HGCalGeom") << "There are " << layers_.size() << " blocks";
156  for (unsigned int i = 0; i < layers_.size(); ++i)
157  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << cms::convert2mm(layerThick_[i])
158  << " with " << layers_[i] << " layers";
159 #endif
160  layerType_ = args.value<std::vector<int>>("LayerType");
161  layerSense_ = args.value<std::vector<int>>("LayerSense");
162  layerOrient_ = args.value<std::vector<int>>("LayerTypes");
163  for (unsigned int k = 0; k < layerOrient_.size(); ++k)
164  layerOrient_[k] = HGCalTypes::layerType(layerOrient_[k]);
165 #ifdef EDM_ML_DEBUG
166  for (unsigned int i = 0; i < layerOrient_.size(); ++i)
167  edm::LogVerbatim("HGCalGeom") << "LayerOrient [" << i << "] " << layerOrient_[i];
168 #endif
169  if (firstLayer_ > 0) {
170  for (unsigned int i = 0; i < layerType_.size(); ++i) {
171  if (layerSense_[i] != 0) {
172  int ii = layerType_[i];
173  copyNumber_[ii] = firstLayer_;
174 #ifdef EDM_ML_DEBUG
175  edm::LogVerbatim("HGCalGeom") << "First copy number for layer type " << i << ":" << ii << " with "
176  << materials_[ii] << " changed to " << copyNumber_[ii];
177 #endif
178  }
179  }
180  } else {
181  firstLayer_ = 1;
182  }
183 #ifdef EDM_ML_DEBUG
184  edm::LogVerbatim("HGCalGeom") << "There are " << layerType_.size() << " layers";
185  for (unsigned int i = 0; i < layerType_.size(); ++i)
186  edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType_[i] << " sensitive class "
187  << layerSense_[i];
188 #endif
189  materialTop_ = args.value<std::vector<std::string>>("TopMaterialNames");
190  namesTop_ = args.value<std::vector<std::string>>("TopVolumeNames");
191  layerThickTop_ = args.value<std::vector<double>>("TopLayerThickness");
192  layerTypeTop_ = args.value<std::vector<int>>("TopLayerType");
193  copyNumberTop_.resize(materialTop_.size(), firstLayer_);
194  coverTypeTop_ = args.value<int>("TopCoverLayerType");
195  copyNumberCoverTop_ = firstLayer_;
196 #ifdef EDM_ML_DEBUG
197  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << materialTop_.size()
198  << " types of volumes in the top part; cover Type " << coverTypeTop_
199  << " with initial copy number " << copyNumberCoverTop_;
200  for (unsigned int i = 0; i < materialTop_.size(); ++i)
201  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << namesTop_[i] << " of thickness "
202  << cms::convert2mm(layerThickTop_[i]) << " filled with " << materialTop_[i]
203  << " first copy number " << copyNumberTop_[i];
204  edm::LogVerbatim("HGCalGeom") << "There are " << layerTypeTop_.size() << " layers in the top part";
205  for (unsigned int i = 0; i < layerTypeTop_.size(); ++i)
206  edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerTypeTop_[i];
207 #endif
208  waferIndex_ = args.value<std::vector<int>>("WaferIndex");
209  waferProperty_ = args.value<std::vector<int>>("WaferProperties");
210  waferLayerStart_ = args.value<std::vector<int>>("WaferLayerStart");
211  cassetteShift_ = args.value<std::vector<double>>("CassetteShift");
212 #ifdef EDM_ML_DEBUG
213  edm::LogVerbatim("HGCalGeom") << "waferProperties with " << waferIndex_.size() << " entries in "
214  << waferLayerStart_.size() << " layers";
215  for (unsigned int k = 0; k < waferLayerStart_.size(); ++k)
216  edm::LogVerbatim("HGCalGeom") << "LayerStart[" << k << "] " << waferLayerStart_[k];
217  for (unsigned int k = 0; k < waferIndex_.size(); ++k)
218  edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << waferIndex_[k] << " ("
219  << HGCalWaferIndex::waferLayer(waferIndex_[k]) << ", "
220  << HGCalWaferIndex::waferU(waferIndex_[k]) << ", "
221  << HGCalWaferIndex::waferV(waferIndex_[k]) << ") : ("
222  << HGCalProperty::waferThick(waferProperty_[k]) << ":"
223  << HGCalProperty::waferPartial(waferProperty_[k]) << ":"
224  << HGCalProperty::waferOrient(waferProperty_[k]) << ")";
225  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << cassetteShift_.size()
226  << " elements for cassette shifts";
227  unsigned int j1max = cassetteShift_.size();
228  for (unsigned int j1 = 0; j1 < j1max; j1 += 6) {
229  std::ostringstream st1;
230  unsigned int j2 = std::min((j1 + 6), j1max);
231  for (unsigned int j = j1; j < j2; ++j)
232  st1 << " [" << j << "] " << std::setw(9) << cassetteShift_[j];
233  edm::LogVerbatim("HGCalGeom") << st1.str();
234  }
235 #endif
236  tileRMin_ = args.value<std::vector<double>>("TileRMin");
237  tileRMax_ = args.value<std::vector<double>>("TileRMax");
238  tileIndex_ = args.value<std::vector<int>>("TileLayerRings");
239  tilePhis_ = args.value<std::vector<int>>("TilePhiRange");
240  tileLayerStart_ = args.value<std::vector<int>>("TileLayerStart");
241 #ifdef EDM_ML_DEBUG
242  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette:: with " << tileRMin_.size() << " rings";
243  for (unsigned int k = 0; k < tileRMin_.size(); ++k)
244  edm::LogVerbatim("HGCalGeom") << "Ring[" << k << "] " << cms::convert2mm(tileRMin_[k]) << " : "
245  << cms::convert2mm(tileRMax_[k]);
246  edm::LogVerbatim("HGCalGeom") << "TileProperties with " << tileIndex_.size() << " entries in "
247  << tileLayerStart_.size() << " layers";
248  for (unsigned int k = 0; k < tileLayerStart_.size(); ++k)
249  edm::LogVerbatim("HGCalGeom") << "LayerStart[" << k << "] " << tileLayerStart_[k];
250  for (unsigned int k = 0; k < tileIndex_.size(); ++k)
251  edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << tileIndex_[k] << " ("
252  << "Layer " << std::get<0>(HGCalTileIndex::tileUnpack(tileIndex_[k])) << " Ring "
253  << std::get<1>(HGCalTileIndex::tileUnpack(tileIndex_[k])) << ":"
254  << std::get<2>(HGCalTileIndex::tileUnpack(tileIndex_[k])) << ") Phi "
255  << std::get<1>(HGCalTileIndex::tileUnpack(tilePhis_[k])) << ":"
256  << std::get<2>(HGCalTileIndex::tileUnpack(tilePhis_[k]));
257 #endif
258  cassette_.setParameter(cassettes_, cassetteShift_);
259 
260 #ifdef EDM_ML_DEBUG
261  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: NameSpace " << ns.name();
262 
263  edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalMixRotatedCassette...";
264  copies_.clear();
265 #endif
266 
267  double zi(zMinBlock_);
268  int laymin(0);
269  for (unsigned int i = 0; i < layers_.size(); i++) {
270  double zo = zi + layerThick_[i];
271  double routF = HGCalGeomTools::radius(zi, zFrontT_, rMaxFront_, slopeT_);
272  int laymax = laymin + layers_[i];
273  double zz = zi;
274  double thickTot(0);
275  for (int ly = laymin; ly < laymax; ++ly) {
276  int ii = layerType_[ly];
277  int copy = copyNumber_[ii];
278  double hthick = 0.5 * thick_[ii];
279  double rinB = HGCalGeomTools::radius(zo, zFrontB_, rMinFront_, slopeB_);
280  zz += hthick;
281  thickTot += thick_[ii];
282 
283  std::string name = names_[ii] + std::to_string(copy);
284 #ifdef EDM_ML_DEBUG
285  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Layer " << ly << ":" << ii << " Front "
286  << cms::convert2mm(zi) << ", " << cms::convert2mm(routF) << " Back "
287  << cms::convert2mm(zo) << ", " << cms::convert2mm(rinB)
288  << " superlayer thickness " << cms::convert2mm(layerThick_[i]);
289 #endif
290 
291  dd4hep::Material matter = ns.material(materials_[ii]);
292  dd4hep::Volume glog;
293 
294  if (layerSense_[ly] == 0) {
295  std::vector<double> pgonZ, pgonRin, pgonRout;
296  double rmax =
297  (std::min(routF, HGCalGeomTools::radius(zz + hthick, zFrontT_, rMaxFront_, slopeT_)) * cosAlpha_) - tol1;
298  HGCalGeomTools::radius(zz - hthick,
299  zz + hthick,
300  zFrontB_,
301  rMinFront_,
302  slopeB_,
303  zFrontT_,
304  rMaxFront_,
305  slopeT_,
306  -layerSense_[ly],
307  pgonZ,
308  pgonRin,
309  pgonRout);
310  for (unsigned int isec = 0; isec < pgonZ.size(); ++isec) {
311  pgonZ[isec] -= zz;
312  if (layerSense_[ly] == 0 || absorbMode_ == 0)
313  pgonRout[isec] = rmax;
314  else
315  pgonRout[isec] = pgonRout[isec] * cosAlpha_ - tol1;
316  }
317 
318  dd4hep::Solid solid = dd4hep::Polyhedra(sectors_, -alpha_, 2._pi, pgonZ, pgonRin, pgonRout);
319  ns.addSolidNS(ns.prepend(name), solid);
320  glog = dd4hep::Volume(solid.name(), solid, matter);
321  ns.addVolumeNS(glog);
322 #ifdef EDM_ML_DEBUG
323  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << solid.name() << " polyhedra of " << sectors_
324  << " sectors covering " << convertRadToDeg(-alpha_) << ":"
325  << convertRadToDeg(-alpha_ + 2._pi) << " with " << pgonZ.size() << " sections";
326  for (unsigned int k = 0; k < pgonZ.size(); ++k)
327  edm::LogVerbatim("HGCalGeom") << "[" << k << "] z " << cms::convert2mm(pgonZ[k]) << " R "
328  << cms::convert2mm(pgonRin[k]) << ":" << cms::convert2mm(pgonRout[k]);
329 #endif
330  } else {
331  int mode = (layerSense_[ly] > 0) ? sensitiveMode_ : absorbMode_;
332  double rins = (mode < 1) ? rinB : HGCalGeomTools::radius(zz + hthick, zFrontB_, rMinFront_, slopeB_);
333  double routs = (mode < 1) ? routF : HGCalGeomTools::radius(zz - hthick, zFrontT_, rMaxFront_, slopeT_);
334  dd4hep::Solid solid = dd4hep::Tube(rins, routs, hthick, 0.0, 2._pi);
335  ns.addSolidNS(ns.prepend(name), solid);
336  glog = dd4hep::Volume(solid.name(), solid, matter);
337  ns.addVolumeNS(glog);
338 
339 #ifdef EDM_ML_DEBUG
340  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << solid.name() << " Tubs made of "
341  << matter.name() << " of dimensions " << cms::convert2mm(rinB) << ":"
342  << cms::convert2mm(rins) << ", " << cms::convert2mm(routF) << ":"
343  << cms::convert2mm(routs) << ", " << cms::convert2mm(hthick)
344  << ", 0.0, 360.0 and positioned in: " << glog.name() << " number " << copy;
345 #endif
346  positionMix(ctxt, e, glog, name, copy, thick_[ii], matter, -layerSense_[ly]);
347  }
348 
349  dd4hep::Position r1(0, 0, zz);
350  mother.placeVolume(glog, copy, r1);
351  ++copyNumber_[ii];
352 #ifdef EDM_ML_DEBUG
353  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << glog.name() << " number " << copy
354  << " positioned in " << mother.name() << " at (0,0," << cms::convert2mm(zz)
355  << ") with no rotation";
356 #endif
357  zz += hthick;
358  } // End of loop over layers in a block
359  zi = zo;
360  laymin = laymax;
361  if (std::abs(thickTot - layerThick_[i]) > tol2_) {
362  if (thickTot > layerThick_[i]) {
363  edm::LogError("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(layerThick_[i])
364  << " is smaller than " << cms::convert2mm(thickTot)
365  << ": thickness of all its components **** ERROR ****";
366  } else {
367  edm::LogWarning("HGCalGeom") << "Thickness of the partition " << cms::convert2mm(layerThick_[i])
368  << " does not match with " << cms::convert2mm(thickTot) << " of the components";
369  }
370  }
371  } // End of loop over blocks
372 
373 #ifdef EDM_ML_DEBUG
374  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << copies_.size() << " different wafer copy numbers";
375  int k(0);
376  for (std::unordered_set<int>::const_iterator itr = copies_.begin(); itr != copies_.end(); ++itr, ++k) {
377  edm::LogVerbatim("HGCalGeom") << "Copy [" << k << "] : " << (*itr);
378  }
379  copies_.clear();
380  edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalMixRotatedCassette construction...";
381 #endif
382  }
383 
385  xml_h e,
386  const dd4hep::Volume& glog,
387  const std::string& nameM,
388  int copyM,
389  double thick,
390  const dd4hep::Material& matter,
391  int absType) {
392  cms::DDNamespace ns(ctxt, e, true);
393 
394  // Make the top part first
395  for (unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) {
396  int ii = layerTypeTop_[ly];
397  copyNumberTop_[ii] = copyM;
398  }
399  double hthick = 0.5 * thick;
400  double dphi = (2._pi) / phiBinsScint_;
401  double thickTot(0), zpos(-hthick);
402  if (absType < 0) {
403  for (unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) {
404  int ii = layerTypeTop_[ly];
405  int copy = copyNumberTop_[ii];
406  int layer = copy - firstLayer_;
407  double hthickl = 0.5 * layerThickTop_[ii];
408  thickTot += layerThickTop_[ii];
409  zpos += hthickl;
410  dd4hep::Material matter1 = ns.material(materialTop_[ii]);
411  unsigned int k = 0;
412  int firstTile = tileLayerStart_[layer];
413  int lastTile = ((layer + 1 < static_cast<int>(tileLayerStart_.size())) ? tileLayerStart_[layer + 1]
414  : static_cast<int>(tileIndex_.size()));
415 #ifdef EDM_ML_DEBUG
416  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Layer " << ly << ":" << ii << " Copy " << copy
417  << " Tiles " << firstTile << ":" << lastTile;
418 #endif
419  for (int ti = firstTile; ti < lastTile; ++ti) {
420  double r1 = tileRMin_[std::get<1>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) - 1];
421  double r2 = tileRMax_[std::get<2>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) - 1];
422  int cassette = std::get<0>(HGCalTileIndex::tileUnpack(tilePhis_[ti]));
423  int fimin = std::get<1>(HGCalTileIndex::tileUnpack(tilePhis_[ti]));
424  int fimax = std::get<2>(HGCalTileIndex::tileUnpack(tilePhis_[ti]));
425  double phi1 = dphi * (fimin - 1);
426  double phi2 = (forFireworks_ == 1) ? (dphi * (fimax - fimin + 1)) : (dphi * fimax);
427  auto cshift = cassette_.getShift(layer + 1, 1, cassette);
428 #ifdef EDM_ML_DEBUG
429  int cassette0 = HGCalCassette::cassetteType(2, 1, cassette); //
430  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Layer " << copy << ":" << (layer + 1) << " iR "
431  << std::get<1>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) << ":"
432  << std::get<2>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) << " R "
433  << cms::convert2mm(r1) << ":" << cms::convert2mm(r2) << " Thick "
434  << cms::convert2mm((2.0 * hthickl)) << " phi " << fimin << ":" << fimax << ":"
435  << convertRadToDeg(phi1) << ":" << convertRadToDeg(phi2) << " cassette "
436  << cassette << ":" << cassette0 << " Shift " << cms::convert2mm(cshift.first)
437  << ":" << cms::convert2mm(cshift.second);
438 #endif
439  std::string name = namesTop_[ii] + "L" + std::to_string(copy) + "F" + std::to_string(k);
440  ++k;
441  dd4hep::Solid solid = dd4hep::Tube(r1, r2, hthickl, phi1, phi2);
442  ns.addSolidNS(ns.prepend(name), solid);
443  dd4hep::Volume glog1 = dd4hep::Volume(solid.name(), solid, matter1);
444  ns.addVolumeNS(glog1);
445 #ifdef EDM_ML_DEBUG
446  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << glog1.name() << " Tubs made of "
447  << materialTop_[ii] << " of dimensions " << cms::convert2mm(r1) << ", "
448  << cms::convert2mm(r2) << ", " << cms::convert2mm(hthickl) << ", "
449  << convertRadToDeg(phi1) << ", " << convertRadToDeg(phi2);
450 #endif
451  dd4hep::Position tran(-cshift.first, cshift.second, zpos);
452  glog.placeVolume(glog1, copy, tran);
453 #ifdef EDM_ML_DEBUG
454  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Position " << glog1.name() << " number " << copy
455  << " in " << glog.name() << " at (" << cms::convert2mm(cshift.first) << ", "
456  << cms::convert2mm(cshift.second) << ", " << cms::convert2mm(zpos)
457  << ") with no rotation";
458 #endif
459  }
460  ++copyNumberTop_[ii];
461  zpos += hthickl;
462  }
463  if (std::abs(thickTot - thick) > tol2_) {
464  if (thickTot > thick) {
465  edm::LogError("HGCalGeom") << "DDHGCalMixRotatedCassette: Thickness of the partition "
466  << cms::convert2mm(thick) << " is smaller than " << cms::convert2mm(thickTot)
467  << ": thickness of all its components in the top part **** ERROR ****";
468  } else {
469  edm::LogWarning("HGCalGeom") << "DDHGCalMixRotatedCassette: Thickness of the partition "
470  << cms::convert2mm(thick) << " does not match with " << cms::convert2mm(thickTot)
471  << " of the components in top part";
472  }
473  }
474  } else {
475  int ii = coverTypeTop_;
476  int copy = copyNumberCoverTop_;
477  int layer = copy - firstLayer_;
478  double hthickl = 0.5 * layerThickTop_[ii];
479  zpos += hthickl;
480  dd4hep::Material matter1 = ns.material(materialTop_[ii]);
481  unsigned int k = 0;
482  int firstTile = tileLayerStart_[layer];
483  int lastTile = ((layer + 1 < static_cast<int>(tileLayerStart_.size())) ? tileLayerStart_[layer + 1]
484  : static_cast<int>(tileIndex_.size()));
485 #ifdef EDM_ML_DEBUG
486  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Layer " << layer << ":" << ii << " Copy " << copy
487  << " Tiles " << firstTile << ":" << lastTile;
488 #endif
489  for (int ti = firstTile; ti < lastTile; ++ti) {
490  double r1 = tileRMin_[std::get<1>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) - 1];
491  double r2 = tileRMax_[std::get<2>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) - 1];
492  int cassette = std::get<0>(HGCalTileIndex::tileUnpack(tilePhis_[ti]));
493  int fimin = std::get<1>(HGCalTileIndex::tileUnpack(tilePhis_[ti]));
494  int fimax = std::get<2>(HGCalTileIndex::tileUnpack(tilePhis_[ti]));
495  double phi1 = dphi * (fimin - 1);
496  double phi2 = (forFireworks_ == 1) ? (dphi * (fimax - fimin + 1)) : (dphi * fimax);
497  auto cshift = cassette_.getShift(layer + 1, 1, cassette);
498 #ifdef EDM_ML_DEBUG
499  int cassette0 = HGCalCassette::cassetteType(2, 1, cassette); //
500  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Layer " << copy << ":" << (layer + 1) << " iR "
501  << std::get<1>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) << ":"
502  << std::get<2>(HGCalTileIndex::tileUnpack(tileIndex_[ti])) << " R "
503  << cms::convert2mm(r1) << ":" << cms::convert2mm(r2) << " Thick "
504  << cms::convert2mm(2.0 * hthickl) << " phi " << fimin << ":" << fimax << ":"
505  << convertRadToDeg(phi1) << ":" << convertRadToDeg(phi2) << " cassette "
506  << cassette << ":" << cassette0 << " Shift " << cms::convert2mm(cshift.first)
507  << ":" << cms::convert2mm(cshift.second);
508 #endif
509  std::string name = namesTop_[ii] + "L" + std::to_string(copy) + "F" + std::to_string(k);
510  ++k;
511  dd4hep::Solid solid = dd4hep::Tube(r1, r2, hthickl, phi1, phi2);
512  ns.addSolidNS(ns.prepend(name), solid);
513  dd4hep::Volume glog1 = dd4hep::Volume(solid.name(), solid, matter1);
514  ns.addVolumeNS(glog1);
515 #ifdef EDM_ML_DEBUG
516  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << glog1.name() << " Tubs made of "
517  << matter1.name() << " of dimensions " << cms::convert2mm(r1) << ", "
518  << cms::convert2mm(r2) << ", " << cms::convert2mm(hthickl) << ", "
519  << convertRadToDeg(phi1) << ", " << convertRadToDeg(phi2);
520 #endif
521  dd4hep::Position tran(-cshift.first, cshift.second, zpos);
522  glog.placeVolume(glog1, copy, tran);
523 #ifdef EDM_ML_DEBUG
524  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Position " << glog1.name() << " number " << copy
525  << " in " << glog.name() << " at (" << cms::convert2mm(cshift.first) << ", "
526  << cms::convert2mm(cshift.second) << ", " << cms::convert2mm(zpos)
527  << ") with no rotation";
528 #endif
529  }
530  ++copyNumberCoverTop_;
531  }
532 
533  // Make the bottom part next
534  int layer = (copyM - firstLayer_);
535  static const double sqrt3 = std::sqrt(3.0);
536  int layercenter = layerOrient_[layer];
537  int layertype = HGCalTypes::layerFrontBack(layerOrient_[layer]);
538  int firstWafer = waferLayerStart_[layer];
539  int lastWafer = ((layer + 1 < static_cast<int>(waferLayerStart_.size())) ? waferLayerStart_[layer + 1]
540  : static_cast<int>(waferIndex_.size()));
541  double delx = 0.5 * (waferSize_ + waferSepar_);
542  double dely = 2.0 * delx / sqrt3;
543  double dy = 0.75 * dely;
544  const auto& xyoff = geomTools_.shiftXY(layercenter, (waferSize_ + waferSepar_));
545 #ifdef EDM_ML_DEBUG
546  int ium(0), ivm(0), kount(0);
547  std::vector<int> ntype(3, 0);
548  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: " << glog.name() << " r " << cms::convert2mm(delx)
549  << " R " << cms::convert2mm(dely) << " dy " << cms::convert2mm(dy) << " Shift "
550  << cms::convert2mm(xyoff.first) << ":" << cms::convert2mm(xyoff.second)
551  << " WaferSize " << cms::convert2mm((waferSize_ + waferSepar_)) << " index "
552  << firstWafer << ":" << (lastWafer - 1) << " Copy " << copyM << ":" << layer;
553 #endif
554  for (int k = firstWafer; k < lastWafer; ++k) {
555  int u = HGCalWaferIndex::waferU(waferIndex_[k]);
556  int v = HGCalWaferIndex::waferV(waferIndex_[k]);
557 #ifdef EDM_ML_DEBUG
558  int iu = std::abs(u);
559  int iv = std::abs(v);
560 #endif
561  int nr = 2 * v;
562  int nc = -2 * u + v;
563  int type = HGCalProperty::waferThick(waferProperty_[k]);
564  int part = HGCalProperty::waferPartial(waferProperty_[k]);
565  int orien = HGCalProperty::waferOrient(waferProperty_[k]);
566  int cassette = HGCalProperty::waferCassette(waferProperty_[k]);
567  int place = HGCalCell::cellPlacementIndex(1, layertype, orien);
568 #ifdef EDM_ML_DEBUG
569  edm::LogVerbatim("HGCalGeom")
570  << "DDHGCalMixRotatedCassette::index:Property:layertype:type:part:orien:cassette:place:offsets:ind " << k
571  << ":" << waferProperty_[k] << ":" << layertype << ":" << type << ":" << part << ":" << orien << ":"
572  << cassette << ":" << place;
573 #endif
574  auto cshift = cassette_.getShift(layer + 1, -1, cassette);
575  double xpos = xyoff.first - cshift.first + nc * delx;
576  double ypos = xyoff.second + cshift.second + nr * dy;
577 #ifdef EDM_ML_DEBUG
578  double xorig = xyoff.first + nc * delx;
579  double yorig = xyoff.second + nr * dy;
580  double angle = std::atan2(yorig, xorig);
581  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette::Wafer: layer " << layer + 1 << " cassette "
582  << cassette << " Shift " << cms::convert2mm(cshift.first) << ":"
583  << cms::convert2mm(cshift.second) << " Original " << cms::convert2mm(xorig) << ":"
584  << cms::convert2mm(yorig) << ":" << convertRadToDeg(angle) << " Final "
585  << cms::convert2mm(xpos) << ":" << cms::convert2mm(ypos);
586 #endif
587  std::string wafer;
588  int i(999);
589  if (absType < 0) {
590  if (part == HGCalTypes::WaferFull) {
591  i = type * facingTypes_ * orientationTypes_ + place - placeOffset_;
592 #ifdef EDM_ML_DEBUG
593  edm::LogVerbatim("HGCalGeom") << " FullWafer type:place:ind " << type << ":" << place << ":" << i << ":"
594  << waferFull_.size();
595 #endif
596  wafer = waferFull_[i];
597  } else {
598  int partoffset =
600  i = (part - partoffset) * facingTypes_ * orientationTypes_ +
601  HGCalTypes::WaferTypeOffset[type] * facingTypes_ * orientationTypes_ + place - placeOffset_;
602 
603 #ifdef EDM_ML_DEBUG
604  edm::LogVerbatim("HGCalGeom") << " layertype:type:part:orien:cassette:place:offsets:ind " << layertype << ":"
605  << type << ":" << part << ":" << orien << ":" << cassette << ":" << place << ":"
606  << partoffset << ":" << HGCalTypes::WaferTypeOffset[type] << ":" << i << ":"
607  << waferPart_.size();
608 #endif
609  wafer = waferPart_[i];
610  }
611  } else {
612  type = absType;
613  if (part == HGCalTypes::WaferFull) {
614  i = absType - 1;
615  wafer = passiveFull_[i];
616 #ifdef EDM_ML_DEBUG
617  edm::LogVerbatim("HGCalGeom") << " layertype:abstype:part:orien:cassette:offsets:ind " << layertype << ":"
618  << absType << ":" << part << ":" << orien << ":" << cassette << ":"
619  << ":" << partialTypes_ << ":" << orientationTypes_ << " passive " << i << ":"
620  << wafer;
621 #endif
622  } else {
623  int partoffset = (part >= HGCalTypes::WaferHDTop)
626  i = (part - partoffset) * facingTypes_ * orientationTypes_ +
627  (absType - 1) * facingTypes_ * orientationTypes_ * partialTypes_ + place - placeOffset_;
628 #ifdef EDM_ML_DEBUG
629  edm::LogVerbatim("HGCalGeom") << " layertype:abstype:part:orien:cassette:3Types:offset:ind " << layertype
630  << ":" << absType << ":" << part << ":" << orien << ":" << cassette << ":"
631  << partialTypes_ << ":" << facingTypes_ << ":" << orientationTypes_ << ":"
632  << partoffset << ":" << i << ":" << passivePart_.size();
633 #endif
634  wafer = passivePart_[i];
635  }
636  }
637 
638  int copy = HGCalTypes::packTypeUV(type, u, v);
639 #ifdef EDM_ML_DEBUG
640  edm::LogVerbatim("HGCalGeom") << " DDHGCalMixRotatedCassette: Layer "
641  << HGCalWaferIndex::waferLayer(waferIndex_[k]) << " Wafer " << wafer << " number "
642  << copy << " type :part:orien:ind " << type << ":" << part << ":" << orien << ":"
643  << i << " layer:u:v " << (layer + firstLayer_) << ":" << u << ":" << v;
644  if (iu > ium)
645  ium = iu;
646  if (iv > ivm)
647  ivm = iv;
648  kount++;
649  if (copies_.count(copy) == 0)
650  copies_.insert(copy);
651 #endif
652  dd4hep::Position tran(xpos, ypos, 0.0);
653  glog.placeVolume(ns.volume(wafer), copy, tran);
654 #ifdef EDM_ML_DEBUG
655  ++ntype[type];
656  edm::LogVerbatim("HGCalGeom") << " DDHGCalMixRotatedCassette: " << wafer << " number " << copy << " type "
657  << layertype << ":" << type << " positioned in " << glog.name() << " at ("
658  << cms::convert2mm(xpos) << "," << cms::convert2mm(ypos) << ",0) with no rotation";
659 #endif
660  }
661 
662 #ifdef EDM_ML_DEBUG
663  edm::LogVerbatim("HGCalGeom") << "DDHGCalMixRotatedCassette: Maximum # of u " << ium << " # of v " << ivm << " and "
664  << kount << " wafers (" << ntype[0] << ":" << ntype[1] << ":" << ntype[2] << ") for "
665  << glog.name();
666 #endif
667  }
668 
669  //Required data members to cache the values from XML file
672 
673  static constexpr double tol2_ = 0.00001 * dd4hep::mm;
674 
675  int waferTypes_; // Number of wafer types
676  int passiveTypes_; // Number of passive types
677  int facingTypes_; // Types of facings of modules toward IP
678  int orientationTypes_; // Number of partial wafer orienations
679  int partialTypes_; // Number of partial types
680  int placeOffset_; // Offset for placement
681  int phiBinsScint_; // Maximum number of cells along phi
682  int forFireworks_; // Needed for Fireworks(1)/Geant4(0)
683  int firstLayer_; // Copy # of the first sensitive layer
684  int absorbMode_; // Absorber mode
685  int sensitiveMode_; // Sensitive mode
686  double zMinBlock_; // Starting z-value of the block
687  double waferSize_; // Width of the wafer
688  double waferSepar_; // Sensor separation
689  int sectors_; // Sectors
690  int cassettes_; // Cassettes
691  std::vector<double> slopeB_; // Slope at the lower R
692  std::vector<double> zFrontB_; // Starting Z values for the slopes
693  std::vector<double> rMinFront_; // Corresponding rMin's
694  std::vector<double> slopeT_; // Slopes at the larger R
695  std::vector<double> zFrontT_; // Starting Z values for the slopes
696  std::vector<double> rMaxFront_; // Corresponding rMax's
697  std::vector<std::string> waferFull_; // Names of full wafer modules
698  std::vector<std::string> waferPart_; // Names of partial wafer modules
699  std::vector<std::string> passiveFull_; // Names of full passive modules
700  std::vector<std::string> passivePart_; // Names of partial passive modules
701  std::vector<std::string> materials_; // Materials
702  std::vector<std::string> names_; // Names
703  std::vector<double> thick_; // Thickness of the material
704  std::vector<int> copyNumber_; // Initial copy numbers
705  std::vector<int> layers_; // Number of layers in a section
706  std::vector<double> layerThick_; // Thickness of each section
707  std::vector<int> layerType_; // Type of the layer
708  std::vector<int> layerSense_; // Content of a layer (sensitive?)
709  std::vector<std::string> materialTop_; // Materials of top layers
710  std::vector<std::string> namesTop_; // Names of top layers
711  std::vector<double> layerThickTop_; // Thickness of the top sections
712  std::vector<int> layerTypeTop_; // Type of the Top layer
713  std::vector<int> copyNumberTop_; // Initial copy numbers (top section)
714  int coverTypeTop_; // Type of the Top layer cover
715  int copyNumberCoverTop_; // Initial copy number of top cover
716  std::vector<int> layerOrient_; // Layer orientation for the silicon component
717  std::vector<int> waferIndex_; // Wafer index for the types
718  std::vector<int> waferProperty_; // Wafer property
719  std::vector<int> waferLayerStart_; // Start index of wafers in each layer
720  std::vector<double> cassetteShift_; // Shifts of the cassetes
721  std::vector<double> tileRMin_; // Minimum radius of each ring
722  std::vector<double> tileRMax_; // Maximum radius of each ring
723  std::vector<int> tileIndex_; // Index of tile (layer/start|end ring)
724  std::vector<int> tilePhis_; // Tile phi range for each index
725  std::vector<int> tileLayerStart_; // Start index of tiles in each layer
726  std::unordered_set<int> copies_; // List of copy #'s
727  double alpha_, cosAlpha_;
728 };
729 
730 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
731  HGCalMixRotatedCassette mixRotatedCassetteAlgo(ctxt, e);
732  return cms::s_executed;
733 }
734 
735 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalMixRotatedCassette, algorithm)
Log< level::Info, true > LogVerbatim
static int32_t cellPlacementIndex(int32_t iz, int32_t frontBack, int32_t orient)
Definition: HGCalCell.cc:237
static long algorithm(dd4hep::Detector &, cms::DDParsingContext &ctxt, xml_h e)
static constexpr int32_t WaferPartLDOffset
Definition: HGCalTypes.h:57
std::unordered_set< int > copies_
void positionMix(cms::DDParsingContext &ctxt, xml_h e, const dd4hep::Volume &glog, const std::string &nameM, int copyM, double thick, const dd4hep::Material &matter, int absType)
static void radius(double zf, double zb, std::vector< double > const &zFront1, std::vector< double > const &rFront1, std::vector< double > const &slope1, std::vector< double > const &zFront2, std::vector< double > const &rFront2, std::vector< double > const &slope2, int flag, std::vector< double > &zz, std::vector< double > &rin, std::vector< double > &rout)
static constexpr int32_t WaferTypeOffset[3]
Definition: HGCalTypes.h:61
std::vector< std::string > namesTop_
int32_t waferU(const int32_t index)
int32_t waferLayer(const int32_t index)
constexpr NumType convertRadToDeg(NumType radians)
Definition: angle_units.h:21
constexpr NumType convert2mm(NumType length)
Definition: DDutils.h:7
std::vector< std::string > names_
std::vector< std::string > waferPart_
std::vector< double > layerThickTop_
Log< level::Error, false > LogError
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:166
int32_t waferOrient(const int32_t property)
static std::string to_string(const XMLCh *ch)
std::vector< std::string > materialTop_
int32_t waferCassette(const int32_t property)
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:25
static constexpr int32_t WaferFull
Definition: HGCalTypes.h:35
std::vector< double > cassetteShift_
static constexpr long s_executed
T sqrt(T t)
Definition: SSEVec.h:19
std::string_view name() const
Definition: DDNamespace.h:79
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< std::string > waferFull_
int32_t waferThick(const int32_t property)
dd4hep::Volume Volume
std::vector< std::string > passivePart_
ii
Definition: cuy.py:589
std::tuple< int32_t, int32_t, int32_t > tileUnpack(int32_t index)
static constexpr int32_t WaferPartHDOffset
Definition: HGCalTypes.h:58
part
Definition: HCALResponse.h:20
HGCalMixRotatedCassette(cms::DDParsingContext &ctxt, xml_h e)
int32_t waferPartial(const int32_t property)
int32_t waferV(const int32_t index)
static int32_t packTypeUV(int type, int u, int v)
Definition: HGCalTypes.cc:3
static constexpr int32_t WaferHDTop
Definition: HGCalTypes.h:51
Log< level::Warning, false > LogWarning
static int32_t layerType(int type)
Definition: HGCalTypes.cc:42
std::vector< std::string > materials_
dd4hep::Volume addVolumeNS(dd4hep::Volume vol) const
Definition: DDNamespace.cc:202
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:276
static int cassetteType(int det, int zside, int cassette)
dd4hep::Solid addSolidNS(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:292
std::vector< std::string > passiveFull_
std::string prepend(const std::string &) const
Definition: DDNamespace.cc:99
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
static constexpr int32_t layerFrontBack(int32_t layerOrient)
Definition: HGCalTypes.h:137