CMS 3D CMS Logo

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