CMS 3D CMS Logo

DDHGCalTBModule.cc
Go to the documentation of this file.
2 #include "DD4hep/DetFactoryHelper.h"
8 
9 //#define EDM_ML_DEBUG
10 
11 #ifdef EDM_ML_DEBUG
12 #include <unordered_set>
13 #endif
14 using namespace cms_units::operators;
15 
16 static long algorithm(dd4hep::Detector& /* description */,
18  xml_h e,
19  dd4hep::SensitiveDetector& /* sens */) {
20  cms::DDNamespace ns(ctxt, e, true);
21  cms::DDAlgoArguments args(ctxt, e);
22 
23  const auto& wafers = args.value<std::vector<std::string> >("WaferName"); // Wafers
24  const auto& covers = args.value<std::vector<std::string> >("CoverName"); // Insensitive layers of hexagonal size
25 #ifdef EDM_ML_DEBUG
26  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: " << wafers.size() << " wafers";
27  unsigned int i(0);
28  for (auto wafer : wafers) {
29  edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafer;
30  ++i;
31  }
32  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: " << covers.size() << " covers";
33  i = 0;
34  for (auto cover : covers) {
35  edm::LogVerbatim("HGCalGeom") << "Cover[" << i << "] " << cover;
36  ++i;
37  }
38 #endif
39  const auto& materials = args.value<std::vector<std::string> >("MaterialNames"); // Materials
40  const auto& names = args.value<std::vector<std::string> >("VolumeNames"); // Names
41  const auto& thick = args.value<std::vector<double> >("Thickness"); // Thickness of the material
42  std::vector<int> copyNumber; // Initial copy numbers
43  for (unsigned int i = 0; i < materials.size(); ++i) {
44  copyNumber.emplace_back(1);
45  }
46 #ifdef EDM_ML_DEBUG
47  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: " << materials.size() << " types of volumes";
48  for (unsigned int i = 0; i < names.size(); ++i)
49  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names[i] << " of thickness " << thick[i]
50  << " filled with " << materials[i] << " first copy number " << copyNumber[i];
51 #endif
52  const auto& layers = args.value<std::vector<int> >("Layers"); // Number of layers in a section
53  const auto& layerThick = args.value<std::vector<double> >("LayerThick"); // Thickness of each section
54 #ifdef EDM_ML_DEBUG
55  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: " << layers.size() << " blocks";
56  for (unsigned int i = 0; i < layers.size(); ++i)
57  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << layerThick[i] << " with " << layers[i]
58  << " layers";
59 #endif
60  const auto& layerType = args.value<std::vector<int> >("LayerType"); // Type of the layer
61  const auto& layerSense = args.value<std::vector<int> >("LayerSense"); // Content of a layer (sensitive?)
62 #ifdef EDM_ML_DEBUG
63  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: " << layerType.size() << " layers";
64  for (unsigned int i = 0; i < layerType.size(); ++i)
65  edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType[i] << " sensitive class "
66  << layerSense[i];
67 #endif
68  const auto& zMinBlock = args.value<double>("zMinBlock"); // Starting z-value of the block
69  const auto& rMaxFine = args.value<double>("rMaxFine"); // Maximum r-value for fine wafer
70  const auto& waferW = args.value<double>("waferW"); // Width of the wafer
71  const auto& waferGap = args.value<double>("waferGap"); // Gap between 2 wafers
72  const auto& absorbW = args.value<double>("absorberW"); // Width of the absorber
73  const auto& absorbH = args.value<double>("absorberH"); // Height of the absorber
74 #ifdef EDM_ML_DEBUG
75  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: zStart " << zMinBlock << " rFineCoarse " << rMaxFine
76  << " wafer width " << waferW << " gap among wafers " << waferGap << " absorber width "
77  << absorbW << " absorber height " << absorbH;
78 #endif
79  const auto& slopeB = args.value<std::vector<double> >("SlopeBottom"); // Slope at the lower R
80  const auto& slopeT = args.value<std::vector<double> >("SlopeTop"); // Slopes at the larger R
81  const auto& zFront = args.value<std::vector<double> >("ZFront"); // Starting Z values for the slopes
82  const auto& rMaxFront = args.value<std::vector<double> >("RMaxFront"); // Corresponding rMax's
83 #ifdef EDM_ML_DEBUG
84  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: Bottom slopes " << slopeB[0] << ":" << slopeB[1] << " and "
85  << slopeT.size() << " slopes for top";
86  for (unsigned int i = 0; i < slopeT.size(); ++i)
87  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << zFront[i] << " Rmax " << rMaxFront[i] << " Slope "
88  << slopeT[i];
89 #endif
90  std::string idNameSpace = static_cast<std::string>(ns.name()); // Namespace of this and ALL sub-parts
91  const auto& idName = args.parentName(); // Name of the "parent" volume.
92 #ifdef EDM_ML_DEBUG
93  std::unordered_set<int> copies; // List of copy #'s
94  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: NameSpace " << idNameSpace << " Mother " << idName;
95 #endif
96 
97  // Mother module
98  dd4hep::Volume module = ns.volume(idName);
99 #ifdef EDM_ML_DEBUG
100  edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalTBModule...";
101 #endif
102 
103  double zi(zMinBlock);
104  double ww = (waferW + waferGap);
105  double dx = 0.5 * ww;
106  double dy = 3.0 * dx * tan(30._deg);
107  double rr = 2.0 * dx * tan(30._deg);
108  int laymin(0);
109  for (unsigned int i = 0; i < layers.size(); i++) {
110  double zo = zi + layerThick[i];
111  double routF = HGCalGeomTools::radius(zi, zFront, rMaxFront, slopeT);
112  int laymax = laymin + layers[i];
113  double zz = zi;
114  double thickTot(0);
115  for (int ly = laymin; ly < laymax; ++ly) {
116  int ii = layerType[ly];
117  int copy = copyNumber[ii];
118  double rinB = (layerSense[ly] == 0) ? (zo * slopeB[0]) : (zo * slopeB[1]);
119  zz += (0.5 * thick[ii]);
120  thickTot += thick[ii];
121 
122  std::string name = "HGCal" + names[ii] + std::to_string(copy);
123 #ifdef EDM_ML_DEBUG
124  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: Layer " << ly << ":" << ii << " Front " << zi << ", " << routF
125  << " Back " << zo << ", " << rinB << " superlayer thickness " << layerThick[i];
126 #endif
127 
128  dd4hep::Material matter = ns.material(materials[ii]);
129  dd4hep::Volume glog;
130  if (layerSense[ly] == 0) {
131  dd4hep::Solid solid = dd4hep::Box(absorbW, absorbH, 0.5 * thick[ii]);
132  ns.addSolidNS(ns.prepend(name), solid);
133  glog = dd4hep::Volume(solid.name(), solid, matter);
134 #ifdef EDM_ML_DEBUG
135  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule test: " << solid.name() << " box of dimension " << absorbW
136  << ":" << absorbH << ":" << 0.5 * thick[ii];
137 #endif
138  } else {
139  dd4hep::Solid solid = dd4hep::Tube(rinB, routF, 0.5 * thick[ii], 0.0, 2 * cms_units::piRadians);
140  ns.addSolidNS(ns.prepend(name), solid);
141  glog = dd4hep::Volume(solid.name(), solid, matter);
142 #ifdef EDM_ML_DEBUG
143  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule: " << solid.name() << " Tubs made of " << materials[ii]
144  << " of dimensions " << rinB << ", " << routF << ", " << 0.5 * thick[ii]
145  << ", 0.0, 360.0";
146 #endif
147  int ncol = static_cast<int>(2.0 * routF / ww) + 1;
148  int nrow = static_cast<int>(routF / (ww * tan(30._deg))) + 1;
149 #ifdef EDM_ML_DEBUG
150  int incm(0), inrm(0), kount(0), ntot(0), nin(0), nfine(0), ncoarse(0);
151  edm::LogVerbatim("HGCalGeom") << glog.name() << " rout " << routF << " Row " << nrow << " Column " << ncol;
152 #endif
153  double xc[6], yc[6];
154  for (int nr = -nrow; nr <= nrow; ++nr) {
155  int inr = (nr >= 0) ? nr : -nr;
156  for (int nc = -ncol; nc <= ncol; ++nc) {
157  int inc = (nc >= 0) ? nc : -nc;
158  if (inr % 2 == inc % 2) {
159  double xpos = nc * dx;
160  double ypos = nr * dy;
161  xc[0] = xpos + dx;
162  yc[0] = ypos - 0.5 * rr;
163  xc[1] = xpos + dx;
164  yc[1] = ypos + 0.5 * rr;
165  xc[2] = xpos;
166  yc[2] = ypos + rr;
167  xc[3] = xpos - dx;
168  yc[3] = ypos + 0.5 * rr;
169  xc[4] = xpos + dx;
170  yc[4] = ypos - 0.5 * rr;
171  xc[5] = xpos;
172  yc[5] = ypos - rr;
173  bool cornerAll(true);
174  for (int k = 0; k < 6; ++k) {
175  double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]);
176  if (rpos < rinB || rpos > routF)
177  cornerAll = false;
178  }
179 #ifdef EDM_ML_DEBUG
180  ++ntot;
181 #endif
182  if (cornerAll) {
183  dd4hep::Volume glog1;
184  if (layerSense[ly] == 1) {
185  double rpos = std::sqrt(xpos * xpos + ypos * ypos);
186  glog1 = (rpos < rMaxFine) ? ns.volume(wafers[0]) : ns.volume(wafers[1]);
187 #ifdef EDM_ML_DEBUG
188  ++nin;
189  if (rpos < rMaxFine)
190  ++nfine;
191  else
192  ++ncoarse;
193 #endif
194  } else {
195  glog1 = ns.volume(covers[layerSense[ly] - 2]);
196  }
197  int copyL = inr * 100 + inc;
198  if (nc < 0)
199  copyL += 10000;
200  if (nr < 0)
201  copyL += 100000;
202 #ifdef EDM_ML_DEBUG
203  if (inc > incm)
204  incm = inc;
205  if (inr > inrm)
206  inrm = inr;
207  kount++;
208  copies.insert(copy);
209 #endif
210  dd4hep::Position tran(xpos, ypos, 0.0);
211  glog.placeVolume(glog1, copyL, tran);
212 #ifdef EDM_ML_DEBUG
213  edm::LogVerbatim("HGCalGeom") << "DDHGCalModule: " << glog1.name() << " number " << copyL
214  << " positioned in " << glog.name() << " at " << tran;
215 #endif
216  }
217  }
218  }
219  }
220 #ifdef EDM_ML_DEBUG
221  edm::LogVerbatim("HGCalGeom") << "DDHGCalModule: # of columns " << incm << " # of rows " << inrm << " and "
222  << nin << ":" << kount << ":" << ntot << " wafers (" << nfine << ":" << ncoarse
223  << ") for " << glog.name() << " R " << rinB << ":" << routF;
224 #endif
225  }
226  dd4hep::Position r1(0, 0, zz);
227  module.placeVolume(glog, copy, r1);
228  ++copyNumber[ii];
229 #ifdef EDM_ML_DEBUG
230  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModule test: " << glog.name() << " number " << copy
231  << " positioned in " << module.name() << " at " << r1;
232 #endif
233  zz += (0.5 * thick[ii]);
234  } // End of loop over layers in a block
235  zi = zo;
236  laymin = laymax;
237  if (fabs(thickTot - layerThick[i]) < 0.00001) {
238  } else if (thickTot > layerThick[i]) {
239  edm::LogError("HGCalGeom") << "Thickness of the partition " << layerThick[i] << " is smaller than thickness "
240  << thickTot << " of all its components **** ERROR ****\n";
241  } else if (thickTot < layerThick[i]) {
242  edm::LogWarning("HGCalGeom") << "Thickness of the partition " << layerThick[i] << " does not match with "
243  << thickTot << " of the components\n";
244  }
245  } // End of loop over blocks
246 
247  return 1;
248 }
249 
250 // first argument is the type from the xml file
251 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalTBModule, 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
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)
T value(const std::string &name) const
const std::string names[nVars_]
static long algorithm(dd4hep::Detector &, cms::DDParsingContext &ctxt, xml_h e, dd4hep::SensitiveDetector &)
int nin
std::string_view name() const
Definition: DDNamespace.h:68
constexpr long double piRadians(M_PIl)
T sqrt(T t)
Definition: SSEVec.h:19
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:121
std::string prepend(const std::string &) const
Definition: DDNamespace.cc:66
dd4hep::Volume Volume
ii
Definition: cuy.py:590
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:30
Definition: vlib.h:198
std::string parentName() const
Access value of rParent child node.