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