CMS 3D CMS Logo

DDHGCalTBModuleX.cc
Go to the documentation of this file.
1 /*
2  * DDHGCalTBModuleX.cc
3  *
4  * Created on: 27-Aug-2019
5  * Author: S. Banerjee
6  */
7 
8 #include <unordered_set>
9 
11 #include "DD4hep/DetFactoryHelper.h"
16 
17 //#define EDM_ML_DEBUG
18 using namespace geant_units::operators;
19 
20 namespace DDHGCalGeom {
22  const std::vector<std::string>& wafers,
23  const std::vector<std::string>& covers,
24  const std::vector<int>& layerType,
25  const std::vector<int>& layerSense,
26  const std::vector<int>& maxModule,
27  const std::vector<std::string>& names,
28  const std::vector<std::string>& materials,
29  std::vector<int>& copyNumber,
30  const std::vector<double>& layerThick,
31  const double& absorbW,
32  const double& absorbH,
33  const double& waferTot,
34  const double& rMax,
35  const double& rMaxFine,
36  std::unordered_set<int>& copies,
37  int firstLayer,
38  int lastLayer,
39  double zFront,
40  double totalWidth,
41  bool ignoreCenter,
43  static constexpr double tolerance = 0.00001;
44  static const double tan30deg = tan(30._deg);
45  double zi(zFront), thickTot(0);
46  for (int ly = firstLayer; ly <= lastLayer; ++ly) {
47  int ii = layerType[ly];
48  int copy = copyNumber[ii];
49  double zz = zi + (0.5 * layerThick[ii]);
50  double zo = zi + layerThick[ii];
51  thickTot += layerThick[ii];
52 
53  std::string name = "HGCal" + names[ii] + std::to_string(copy);
54 #ifdef EDM_ML_DEBUG
55  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " Layer " << ly << ":" << ii << " Z "
56  << convertCmToMm(zi) << ":" << convertCmToMm(zo) << " Thick "
57  << convertCmToMm(layerThick[ii]) << " Sense " << layerSense[ly];
58 #endif
59  dd4hep::Material matter = ns.material(materials[ii]);
60  dd4hep::Volume glog;
61  if (layerSense[ly] == 0) {
62  dd4hep::Solid solid = dd4hep::Box(absorbW, absorbH, 0.5 * layerThick[ii]);
63  ns.addSolidNS(ns.prepend(name), solid);
64  glog = dd4hep::Volume(solid.name(), solid, matter);
65 #ifdef EDM_ML_DEBUG
66  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << solid.name() << " box of dimension "
67  << convertCmToMm(absorbW) << ":" << convertCmToMm(absorbH) << ":"
68  << convertCmToMm(0.5 * layerThick[ii]);
69 #endif
70  dd4hep::Position r1(0, 0, zz);
71  module.placeVolume(glog, copy, r1);
72 #ifdef EDM_ML_DEBUG
73  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << copy << " positioned in "
74  << module.name() << " at " << r1 << " with no rotation";
75 #endif
76  } else if (layerSense[ly] > 0) {
77  double dx = 0.5 * waferTot;
78  double dy = 3.0 * dx * tan30deg;
79  double rr = 2.0 * dx * tan30deg;
80  int ncol = (int)(2.0 * rMax / waferTot) + 1;
81  int nrow = (int)(rMax / (waferTot * tan30deg)) + 1;
82 #ifdef EDM_ML_DEBUG
83  int incm(0), inrm(0);
84  edm::LogVerbatim("HGCalGeom") << module.name() << " Copy " << copy << " Type " << layerSense[ly] << " rout "
85  << convertCmToMm(rMax) << " Row " << nrow << " column " << ncol << " ncrMax "
86  << maxModule[ly] << " Z " << convertCmToMm(zz) << " Center " << ignoreCenter
87  << " name " << name << " matter " << matter.name();
88  int kount(0);
89 #endif
90  if (maxModule[ly] >= 0) {
91  nrow = std::min(nrow, maxModule[ly]);
92  ncol = std::min(ncol, maxModule[ly]);
93  }
94  for (int nr = -nrow; nr <= nrow; ++nr) {
95  int inr = std::abs(nr);
96  for (int nc = -ncol; nc <= ncol; ++nc) {
97  int inc = std::abs(nc);
98  if ((inr % 2 == inc % 2) && (!ignoreCenter || nc != 0 || nr != 0)) {
99  double xpos = nc * dx;
100  double ypos = nr * dy;
101  double xc[6], yc[6];
102  xc[0] = xpos + dx;
103  yc[0] = ypos - 0.5 * rr;
104  xc[1] = xpos + dx;
105  yc[1] = ypos + 0.5 * rr;
106  xc[2] = xpos;
107  yc[2] = ypos + rr;
108  xc[3] = xpos - dx;
109  yc[3] = ypos + 0.5 * rr;
110  xc[4] = xpos + dx;
111  yc[4] = ypos - 0.5 * rr;
112  xc[5] = xpos;
113  yc[5] = ypos - rr;
114  bool cornerAll(true);
115  for (int k = 0; k < 6; ++k) {
116  double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]);
117  if (rpos > rMax)
118  cornerAll = false;
119  }
120  if (cornerAll) {
121  double rpos = std::sqrt(xpos * xpos + ypos * ypos);
122  dd4hep::Position tran(xpos, ypos, zz);
123  int copyx = inr * 100 + inc;
124  if (nc < 0)
125  copyx += 10000;
126  if (nr < 0)
127  copyx += 100000;
128  if (layerSense[ly] == 1) {
129  dd4hep::Solid solid = ns.solid(covers[0]);
130  std::string name0 = name + "M" + std::to_string(copyx);
131  if (strchr(name0.c_str(), NAMESPACE_SEP) == nullptr)
132  name0 = ns.name() + name0;
133  dd4hep::Volume glog1 = dd4hep::Volume(name0, solid, matter);
134  module.placeVolume(glog1, copy, tran);
135 #ifdef EDM_ML_DEBUG
136  edm::LogVerbatim("HGCalGeom")
137  << "DDHGCalTBModuleX: " << glog1.name() << " number " << copy << " positioned in "
138  << module.name() << " at " << tran << " with no rotation";
139 #endif
140  dd4hep::Volume glog2 = (rpos < rMaxFine) ? ns.volume(wafers[0]) : ns.volume(wafers[1]);
141  glog1.placeVolume(glog2, copyx);
142 #ifdef EDM_ML_DEBUG
143  edm::LogVerbatim("HGCalGeom")
144  << "DDHGCalTBModuleX: " << glog2.name() << " number " << copyx << " positioned in "
145  << glog1.name() << " at (0, 0, 0) with no rotation";
146 #endif
147  if (layerSense[ly] == 1)
148  copies.insert(copy);
149  } else {
150  dd4hep::Volume glog2 = ns.volume(covers[layerSense[ly] - 1]);
151  copyx += (copy * 1000000);
152  module.placeVolume(glog2, copyx, tran);
153 #ifdef EDM_ML_DEBUG
154  edm::LogVerbatim("HGCalGeom")
155  << "DDHGCalTBModuleX: " << glog2.name() << " number " << copyx << " positioned in "
156  << module.name() << " at " << tran << " with no rotation";
157 #endif
158  }
159 #ifdef EDM_ML_DEBUG
160  if (inc > incm)
161  incm = inc;
162  if (inr > inrm)
163  inrm = inr;
164  kount++;
165 #endif
166  }
167  }
168  }
169  }
170 #ifdef EDM_ML_DEBUG
171  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: # of columns " << incm << " # of rows " << inrm << " and "
172  << kount << " wafers for " << module.name();
173 #endif
174  }
175  ++copyNumber[ii];
176  zi = zo;
177  } // End of loop over layers in a block
178 
179  if (fabs(thickTot - totalWidth) < tolerance) {
180  } else if (thickTot > totalWidth) {
181  edm::LogError("HGCalGeom") << "Thickness of the partition " << totalWidth << " is smaller than " << thickTot
182  << ": total thickness of all its components in " << module.name() << " Layers "
183  << firstLayer << ":" << lastLayer << ":" << ignoreCenter << "**** ERROR ****";
184  } else if (thickTot < totalWidth) {
185  edm::LogWarning("HGCalGeom") << "Thickness of the partition " << totalWidth << " does not match with " << thickTot
186  << " of the components in " << module.name() << " Layers " << firstLayer << ":"
187  << lastLayer << ":" << ignoreCenter;
188  }
189  }
190 } // namespace DDHGCalGeom
191 
192 static long algorithm(dd4hep::Detector& /* description */,
193  cms::DDParsingContext& ctxt,
194  xml_h e,
195  dd4hep::SensitiveDetector& /* sens */) {
196  cms::DDNamespace ns(ctxt, e, true);
197  cms::DDAlgoArguments args(ctxt, e);
198 
199  const auto& wafers = args.value<std::vector<std::string> >("WaferName"); // Wafers
200  const auto& covers = args.value<std::vector<std::string> >("CoverName"); // Insensitive layers of hexagonal size
201  const auto& genMat = args.value<std::string>("GeneralMaterial"); // General material used for blocks
202 #ifdef EDM_ML_DEBUG
203  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Material " << genMat << " with " << wafers.size() << " wafers";
204  unsigned int i(0);
205  for (auto wafer : wafers) {
206  edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafer;
207  ++i;
208  }
209  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << covers.size() << " covers";
210  i = 0;
211  for (auto cover : covers) {
212  edm::LogVerbatim("HGCalGeom") << "Cover[" << i << "] " << cover;
213  ++i;
214  }
215 #endif
216  const auto& materials = args.value<std::vector<std::string> >("MaterialNames"); // Material names in each layer
217  const auto& names = args.value<std::vector<std::string> >("VolumeNames"); // Names of each layer
218  const auto& layerThick = args.value<std::vector<double> >("Thickness"); // Thickness of the material
219  std::vector<int> copyNumber; // Copy numbers (initiated to 1)
220  for (unsigned int k = 0; k < layerThick.size(); ++k) {
221  copyNumber.emplace_back(1);
222  }
223 #ifdef EDM_ML_DEBUG
224  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << materials.size() << " types of volumes";
225  for (unsigned int i = 0; i < names.size(); ++i)
226  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names[i] << " of thickness "
227  << convertCmToMm(layerThick[i]) << " filled with " << materials[i]
228  << " first copy number " << copyNumber[i];
229 #endif
230  const auto& blockThick = args.value<std::vector<double> >("BlockThick"); // Thickness of each section
231  const auto& inOut = args.value<int>("InOut"); // Number of inner+outer parts
232  const auto& layerFrontIn = args.value<std::vector<int> >("LayerFrontIn"); // First layer index (inner) in block
233  const auto& layerBackIn = args.value<std::vector<int> >("LayerBackIn"); // Last layer index (inner) in block
234  std::vector<int> layerFrontOut; // First layer index (outner) in block
235  std::vector<int> layerBackOut; // Last layer index (outner) in block
236  if (inOut > 1) {
237  layerFrontOut = args.value<std::vector<int> >("LayerFrontOut");
238  layerBackOut = args.value<std::vector<int> >("LayerBackOut");
239  }
240 #ifdef EDM_ML_DEBUG
241  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << blockThick.size() << " blocks with in/out " << inOut;
242  for (unsigned int i = 0; i < blockThick.size(); ++i) {
243  if (inOut > 1)
244  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << convertCmToMm(blockThick[i])
245  << " with inner layers " << layerFrontIn[i] << ":" << layerBackIn[i]
246  << " and outer layers " << layerFrontOut[i] << ":" << layerBackOut[i];
247  else
248  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << convertCmToMm(blockThick[i])
249  << " with inner layers " << layerFrontIn[i] << ":" << layerBackIn[i];
250  }
251 #endif
252  const auto& layerType = args.value<std::vector<int> >("LayerType"); // Type of the layer
253  const auto& layerSense = args.value<std::vector<int> >("LayerSense"); // Content of a layer
254  const auto& maxModule = args.value<std::vector<int> >("MaxModule"); // Maximum # of row/column
255 #ifdef EDM_ML_DEBUG
256  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << layerType.size() << " layers";
257  for (unsigned int i = 0; i < layerType.size(); ++i)
258  edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType[i] << " sensitive class "
259  << layerSense[i] << " and " << maxModule[i] << " maximum row/columns";
260 #endif
261  const auto& zMinBlock = args.value<double>("zMinBlock"); // Starting z-value of the block
262  const auto& rMaxFine = args.value<double>("rMaxFine"); // Maximum r-value for fine wafer
263  const auto& waferW = args.value<double>("waferW"); // Width of the wafer
264  const auto& waferGap = args.value<double>("waferGap"); // Gap between 2 wafers
265  const auto& absorbW = args.value<double>("absorberW"); // Width of the absorber
266  const auto& absorbH = args.value<double>("absorberH"); // Height of the absorber
267  const auto& rMax = args.value<double>("rMax"); // Maximum radial extent
268  const auto& rMaxB = args.value<double>("rMaxB"); // Maximum radial extent of a block
269  double waferTot = waferW + waferGap;
271 #ifdef EDM_ML_DEBUG
272  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: zStart " << convertCmToMm(zMinBlock) << " rFineCoarse "
273  << convertCmToMm(rMaxFine) << " wafer width " << convertCmToMm(waferW)
274  << " gap among wafers " << convertCmToMm(waferGap) << " absorber width "
275  << convertCmToMm(absorbW) << " absorber height " << convertCmToMm(absorbH) << " rMax "
276  << convertCmToMm(rMax) << ":" << convertCmToMm(rMaxB);
277  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: NameSpace " << ns.name() << " Parent Name " << idName;
278 #endif
279  std::unordered_set<int> copies; // List of copy #'s
280  copies.clear();
281 
282  dd4hep::Volume parent = ns.volume(args.parentName());
283  double zi(zMinBlock);
284  for (unsigned int i = 0; i < blockThick.size(); i++) {
285  double zo = zi + blockThick[i];
286  std::string name = idName + "Block" + std::to_string(i);
287 #ifdef EDM_ML_DEBUG
288  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Block " << i << ":" << name << " z " << convertCmToMm(zi) << ":"
289  << convertCmToMm(zo) << " R " << convertCmToMm(rMaxB) << " T "
290  << convertCmToMm(blockThick[i]);
291 #endif
292  dd4hep::Material matter = ns.material(genMat);
293  dd4hep::Solid solid = dd4hep::Tube(0, rMaxB, 0.5 * blockThick[i], 0.0, 2._pi);
294  ns.addSolidNS(ns.prepend(name), solid);
295  dd4hep::Volume glog = dd4hep::Volume(solid.name(), solid, matter);
296  double zz = zi + 0.5 * blockThick[i];
297  dd4hep::Position r1(0, 0, zz);
298  parent.placeVolume(glog, i, r1);
299 #ifdef EDM_ML_DEBUG
300  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << i << " positioned in "
301  << args.parentName() << " at " << r1 << " with no rotation";
302  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: \t\tInside Block " << i << " Layers " << layerFrontIn[i] << ":"
303  << layerBackIn[i] << " zFront " << convertCmToMm(-0.5 * blockThick[i])
304  << " thickness " << convertCmToMm(blockThick[i]) << " ignore Center 0";
305 #endif
307  wafers,
308  covers,
309  layerType,
310  layerSense,
311  maxModule,
312  names,
313  materials,
314  copyNumber,
315  layerThick,
316  absorbW,
317  absorbH,
318  waferTot,
319  rMax,
320  rMaxFine,
321  copies,
322  layerFrontIn[i],
323  layerBackIn[i],
324  -0.5 * blockThick[i],
325  blockThick[i],
326  false,
327  glog);
328  if (inOut > 1) {
329 #ifdef EDM_ML_DEBUG
330  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: \t\tInside Block " << i << " Layers " << layerFrontOut[i]
331  << ":" << layerBackOut[i] << " zFront " << convertCmToMm(-0.5 * blockThick[i])
332  << " thickness " << convertCmToMm(blockThick[i]) << " ignore Center 1";
333 #endif
335  wafers,
336  covers,
337  layerType,
338  layerSense,
339  maxModule,
340  names,
341  materials,
342  copyNumber,
343  layerThick,
344  absorbW,
345  absorbH,
346  waferTot,
347  rMax,
348  rMaxFine,
349  copies,
350  layerFrontOut[i],
351  layerBackOut[i],
352  -0.5 * blockThick[i],
353  blockThick[i],
354  true,
355  glog);
356  }
357  zi = zo;
358  }
359 #ifdef EDM_ML_DEBUG
360  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: All blocks are placed in " << convertCmToMm(zMinBlock) << ":"
361  << convertCmToMm(zi) << " with " << copies.size() << " different wafer copy numbers";
362 #endif
363 
364  return 1;
365 }
366 
367 // first argument is the type from the xml file
368 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalTBModuleX, algorithm)
dd4hep::Solid addSolidNS(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:200
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:184
const double tolerance
T value(const std::string &name) const
dd4hep::Solid solid(const std::string &name) const
Definition: DDNamespace.cc:219
const std::string names[nVars_]
std::string_view name() const
Definition: DDNamespace.h:68
static long algorithm(dd4hep::Detector &, cms::DDParsingContext &ctxt, xml_h e, dd4hep::SensitiveDetector &)
T sqrt(T t)
Definition: SSEVec.h:19
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void constructLayers(const cms::DDNamespace &ns, const std::vector< std::string > &wafers, const std::vector< std::string > &covers, const std::vector< int > &layerType, const std::vector< int > &layerSense, const std::vector< int > &maxModule, const std::vector< std::string > &names, const std::vector< std::string > &materials, std::vector< int > &copyNumber, const std::vector< double > &layerThick, const double &absorbW, const double &absorbH, const double &waferTot, const double &rMax, const double &rMaxFine, std::unordered_set< int > &copies, int firstLayer, int lastLayer, double zFront, double totalWidth, bool ignoreCenter, dd4hep::Volume &module)
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:121
T min(T a, T b)
Definition: MathUtil.h:58
std::string prepend(const std::string &) const
Definition: DDNamespace.cc:66
constexpr NumType convertCmToMm(NumType centimeters)
Definition: GeantUnits.h:68
dd4hep::Volume Volume
ii
Definition: cuy.py:590
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:30
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
Definition: vlib.h:198
std::string parentName() const
Access value of rParent child node.
#define constexpr
#define NAMESPACE_SEP
Definition: DDNamespace.h:79