CMS 3D CMS Logo

DDHGCalTBModuleX.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <cmath>
3 #include <string>
4 #include <unordered_set>
5 #include <vector>
6 
20 
21 //#define EDM_ML_DEBUG
22 using namespace angle_units::operators;
23 
24 class DDHGCalTBModuleX : public DDAlgorithm {
25 public:
26  // Constructor and Destructor
27  DDHGCalTBModuleX(); //
28  ~DDHGCalTBModuleX() override;
29 
30  void initialize(const DDNumericArguments& nArgs,
31  const DDVectorArguments& vArgs,
32  const DDMapArguments& mArgs,
33  const DDStringArguments& sArgs,
34  const DDStringVectorArguments& vsArgs) override;
35  void execute(DDCompactView& cpv) override;
36 
37 protected:
38  void constructBlocks(const DDLogicalPart&, DDCompactView& cpv);
39  void constructLayers(int block,
40  int layerFront,
41  int layerBack,
42  double zFront,
43  double thick,
44  bool ignore,
45  const DDLogicalPart&,
46  DDCompactView&);
47  void positionSensitive(double zpos,
48  int copyIn,
49  int type,
50  double rmax,
51  int ncrMax,
52  bool ignoreCenter,
53  const std::string&,
54  const DDMaterial&,
55  const DDLogicalPart&,
56  DDCompactView& cpv);
57 
58 private:
59  static constexpr double tolerance_ = 0.00001;
60  const double factor_, tan30deg_;
61 
62  std::vector<std::string> wafer_; // Wafers
63  std::vector<std::string> covers_; // Insensitive layers of hexagonal size
64  std::string genMat_; // General material used for blocks
65  std::vector<std::string> materials_; // Material names in each layer
66  std::vector<std::string> names_; // Names of each layer
67  std::vector<double> layerThick_; // Thickness of the material
68  std::vector<int> copyNumber_; // Copy numbers (initiated to 1)
69  std::vector<double> blockThick_; // Thickness of each section
70  int inOut_; // Number of inner+outer parts
71  std::vector<int> layerFrontIn_; // First layer index (inner) in block
72  std::vector<int> layerBackIn_; // Last layer index (inner) in block
73  std::vector<int> layerFrontOut_; // First layer index (outner) in block
74  std::vector<int> layerBackOut_; // Last layer index (outner) in block
75  std::vector<int> layerType_; // Type of the layer
76  std::vector<int> layerSense_; // Content of a layer
77  std::vector<int> maxModule_; // Maximum # of row/column
78  double zMinBlock_; // Starting z-value of the block
79  double rMaxFine_; // Maximum r-value for fine wafer
80  double waferW_; // Width of the wafer
81  double waferGap_; // Gap between 2 wafers
82  double absorbW_; // Width of the absorber
83  double absorbH_; // Height of the absorber
84  double rMax_; // Maximum radial extent
85  double rMaxB_; // Maximum radial extent of a block
86  std::string idName_; // Name of the "parent" volume.
87  std::string idNameSpace_; // Namespace of this and ALL sub-parts
88  std::unordered_set<int> copies_; // List of copy #'s
89 };
90 
91 DDHGCalTBModuleX::DDHGCalTBModuleX() : factor_(0.5 * sqrt(2.0)), tan30deg_(tan(30._deg)) {
92 #ifdef EDM_ML_DEBUG
93  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX info: Creating instance";
94 #endif
95 }
96 
98 
100  const DDVectorArguments& vArgs,
101  const DDMapArguments&,
102  const DDStringArguments& sArgs,
103  const DDStringVectorArguments& vsArgs) {
104  wafer_ = vsArgs["WaferName"];
105  covers_ = vsArgs["CoverName"];
106  genMat_ = sArgs["GeneralMaterial"];
107 #ifdef EDM_ML_DEBUG
108  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Material " << genMat_ << " with " << wafer_.size() << " wafers";
109  unsigned int i(0);
110  for (auto wafer : wafer_) {
111  edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafer;
112  ++i;
113  }
114  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << covers_.size() << " covers";
115  i = 0;
116  for (auto cover : covers_) {
117  edm::LogVerbatim("HGCalGeom") << "Cover[" << i << "] " << cover;
118  ++i;
119  }
120 #endif
121  materials_ = vsArgs["MaterialNames"];
122  names_ = vsArgs["VolumeNames"];
123  layerThick_ = vArgs["Thickness"];
124  for (unsigned int k = 0; k < layerThick_.size(); ++k)
125  copyNumber_.emplace_back(1);
126 #ifdef EDM_ML_DEBUG
127  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << materials_.size() << " types of volumes";
128  for (unsigned int i = 0; i < names_.size(); ++i)
129  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names_[i] << " of thickness " << layerThick_[i]
130  << " filled with " << materials_[i] << " first copy number " << copyNumber_[i];
131 #endif
132  inOut_ = nArgs["InOut"];
133  blockThick_ = vArgs["BlockThick"];
134  layerFrontIn_ = dbl_to_int(vArgs["LayerFrontIn"]);
135  layerBackIn_ = dbl_to_int(vArgs["LayerBackIn"]);
136  if (inOut_ > 1) {
137  layerFrontOut_ = dbl_to_int(vArgs["LayerFrontOut"]);
138  layerBackOut_ = dbl_to_int(vArgs["LayerBackOut"]);
139  }
140 #ifdef EDM_ML_DEBUG
141  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << blockThick_.size() << " blocks with in/out " << inOut_;
142  for (unsigned int i = 0; i < blockThick_.size(); ++i) {
143  if (inOut_ > 1)
144  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << blockThick_[i] << " with inner layers "
145  << layerFrontIn_[i] << ":" << layerBackIn_[i] << " and outer layers "
146  << layerFrontOut_[i] << ":" << layerBackOut_[i];
147  else
148  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness " << blockThick_[i] << " with inner layers "
149  << layerFrontIn_[i] << ":" << layerBackIn_[i];
150  }
151 #endif
152  layerType_ = dbl_to_int(vArgs["LayerType"]);
153  layerSense_ = dbl_to_int(vArgs["LayerSense"]);
154  maxModule_ = dbl_to_int(vArgs["MaxModule"]);
155 #ifdef EDM_ML_DEBUG
156  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << layerType_.size() << " layers";
157  for (unsigned int i = 0; i < layerType_.size(); ++i)
158  edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type " << layerType_[i] << " sensitive class "
159  << layerSense_[i] << " and " << maxModule_[i] << " maximum row/columns";
160 #endif
161  zMinBlock_ = nArgs["zMinBlock"];
162  rMaxFine_ = nArgs["rMaxFine"];
163  waferW_ = nArgs["waferW"];
164  waferGap_ = nArgs["waferGap"];
165  absorbW_ = nArgs["absorberW"];
166  absorbH_ = nArgs["absorberH"];
167  rMax_ = nArgs["rMax"];
168  rMaxB_ = nArgs["rMaxB"];
169 #ifdef EDM_ML_DEBUG
170  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: zStart " << zMinBlock_ << " rFineCoarse " << rMaxFine_
171  << " wafer width " << waferW_ << " gap among wafers " << waferGap_ << " absorber width "
172  << absorbW_ << " absorber height " << absorbH_ << " rMax " << rMax_ << ":" << rMaxB_;
173 #endif
175 #ifdef EDM_ML_DEBUG
176  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: NameSpace " << idNameSpace_ << " Parent Name "
177  << parent().name().name();
178 #endif
179 }
180 
182 // DDHGCalTBModuleX methods...
184 
186 #ifdef EDM_ML_DEBUG
187  edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalTBModuleX...";
188 #endif
189  copies_.clear();
190  constructBlocks(parent(), cpv);
191 #ifdef EDM_ML_DEBUG
192  edm::LogVerbatim("HGCalGeom") << copies_.size() << " different wafer copy numbers";
193 #endif
194  copies_.clear();
195 #ifdef EDM_ML_DEBUG
196  edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalTBModuleX construction";
197 #endif
198 }
199 
201 #ifdef EDM_ML_DEBUG
202  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Inside constructBlock";
203 #endif
204  double zi(zMinBlock_);
205  for (unsigned int i = 0; i < blockThick_.size(); i++) {
206  double zo = zi + blockThick_[i];
207  std::string name = parent.ddname().name() + "Block" + std::to_string(i);
208 #ifdef EDM_ML_DEBUG
209  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: Block " << i << ":" << name << " z " << zi << ":" << zo << " R "
210  << rMaxB_ << " T " << blockThick_[i];
211 #endif
213  DDMaterial matter(matName);
214  DDSolid solid = DDSolidFactory::tubs(DDName(name, idNameSpace_), 0.5 * blockThick_[i], 0, rMaxB_, 0.0, 2._pi);
215  DDLogicalPart glog = DDLogicalPart(solid.ddname(), matter, solid);
216  double zz = zi + 0.5 * blockThick_[i];
217  DDTranslation r1(0, 0, zz);
218  DDRotation rot;
219  cpv.position(glog, parent, i, r1, rot);
220 #ifdef EDM_ML_DEBUG
221  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << i << " positioned in "
222  << parent.name() << " at " << r1 << " with " << rot;
223 #endif
224  constructLayers(i, layerFrontIn_[i], layerBackIn_[i], -0.5 * blockThick_[i], blockThick_[i], false, glog, cpv);
225  if (inOut_ > 1)
226  constructLayers(i, layerFrontOut_[i], layerBackOut_[i], -0.5 * blockThick_[i], blockThick_[i], true, glog, cpv);
227  zi = zo;
228  }
229 #ifdef EDM_ML_DEBUG
230  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: All blocks are "
231  << "placed in " << zMinBlock_ << ":" << zi;
232 #endif
233 }
234 
236  int firstLayer,
237  int lastLayer,
238  double zFront,
239  double totalWidth,
240  bool ignoreCenter,
241  const DDLogicalPart& module,
242  DDCompactView& cpv) {
243 #ifdef EDM_ML_DEBUG
244  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: \t\tInside Block " << block << " Layers " << firstLayer << ":"
245  << lastLayer << " zFront " << zFront << " thickness " << totalWidth << " ignore Center "
246  << ignoreCenter;
247 #endif
248  double zi(zFront), thickTot(0);
249  for (int ly = firstLayer; ly <= lastLayer; ++ly) {
250  int ii = layerType_[ly];
251  int copy = copyNumber_[ii];
252  double zz = zi + (0.5 * layerThick_[ii]);
253  double zo = zi + layerThick_[ii];
254  thickTot += layerThick_[ii];
255 
256  std::string name = "HGCal" + names_[ii] + std::to_string(copy);
257 #ifdef EDM_ML_DEBUG
258  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " Layer " << ly << ":" << ii << " Z " << zi << ":"
259  << zo << " Thick " << layerThick_[ii] << " Sense " << layerSense_[ly];
260 #endif
262  DDMaterial matter(matName);
263  DDLogicalPart glog;
264  if (layerSense_[ly] == 0) {
266  glog = DDLogicalPart(solid.ddname(), matter, solid);
267 #ifdef EDM_ML_DEBUG
268  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << solid.name() << " box of dimension " << absorbW_ << ":"
269  << absorbH_ << ":" << 0.5 * layerThick_[ii];
270 #endif
271  DDTranslation r1(0, 0, zz);
272  DDRotation rot;
273  cpv.position(glog, module, copy, r1, rot);
274 #ifdef EDM_ML_DEBUG
275  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << glog.name() << " number " << copy << " positioned in "
276  << module.name() << " at " << r1 << " with " << rot;
277 #endif
278  } else if (layerSense_[ly] > 0) {
279  positionSensitive(zz, copy, layerSense_[ly], rMax_, maxModule_[ly], ignoreCenter, name, matter, module, cpv);
280  }
281  ++copyNumber_[ii];
282  zi = zo;
283  } // End of loop over layers in a block
284 
285  if (fabs(thickTot - totalWidth) < tolerance_) {
286  } else if (thickTot > totalWidth) {
287  edm::LogError("HGCalGeom") << "Thickness of the partition " << totalWidth << " is smaller than " << thickTot
288  << ": total thickness of all its components in " << module.name() << " Layers "
289  << firstLayer << ":" << lastLayer << ":" << ignoreCenter << "**** ERROR ****";
290  } else if (thickTot < totalWidth) {
291  edm::LogWarning("HGCalGeom") << "Thickness of the partition " << totalWidth << " does not match with " << thickTot
292  << " of the components in " << module.name() << " Layers " << firstLayer << ":"
293  << lastLayer << ":" << ignoreCenter;
294  }
295 }
296 
298  int copyIn,
299  int type,
300  double rout,
301  int ncrMax,
302  bool ignoreCenter,
303  const std::string& nameIn,
304  const DDMaterial& matter,
305  const DDLogicalPart& glog,
306  DDCompactView& cpv) {
307  double ww = (waferW_ + waferGap_);
308  double dx = 0.5 * ww;
309  double dy = 3.0 * dx * tan30deg_;
310  double rr = 2.0 * dx * tan30deg_;
311  int ncol = (int)(2.0 * rout / ww) + 1;
312  int nrow = (int)(rout / (ww * tan30deg_)) + 1;
313 #ifdef EDM_ML_DEBUG
314  int incm(0), inrm(0);
315  edm::LogVerbatim("HGCalGeom") << glog.ddname() << " Copy " << copyIn << " Type " << type << " rout " << rout
316  << " Row " << nrow << " column " << ncol << " ncrMax " << ncrMax << " Z " << zpos
317  << " Center " << ignoreCenter << " name " << nameIn << " matter " << matter.name();
318  int kount(0);
319 #endif
320  if (ncrMax >= 0) {
321  nrow = std::min(nrow, ncrMax);
322  ncol = std::min(ncol, ncrMax);
323  }
324  for (int nr = -nrow; nr <= nrow; ++nr) {
325  int inr = std::abs(nr);
326  for (int nc = -ncol; nc <= ncol; ++nc) {
327  int inc = std::abs(nc);
328  if ((inr % 2 == inc % 2) && (!ignoreCenter || nc != 0 || nr != 0)) {
329  double xpos = nc * dx;
330  double ypos = nr * dy;
331  double xc[6], yc[6];
332  xc[0] = xpos + dx;
333  yc[0] = ypos - 0.5 * rr;
334  xc[1] = xpos + dx;
335  yc[1] = ypos + 0.5 * rr;
336  xc[2] = xpos;
337  yc[2] = ypos + rr;
338  xc[3] = xpos - dx;
339  yc[3] = ypos + 0.5 * rr;
340  xc[4] = xpos + dx;
341  yc[4] = ypos - 0.5 * rr;
342  xc[5] = xpos;
343  yc[5] = ypos - rr;
344  bool cornerAll(true);
345  for (int k = 0; k < 6; ++k) {
346  double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]);
347  if (rpos > rout)
348  cornerAll = false;
349  }
350  if (cornerAll) {
351  double rpos = std::sqrt(xpos * xpos + ypos * ypos);
352  DDTranslation tran(xpos, ypos, zpos);
354  int copy = HGCalTypes::packTypeUV(0, nc, nr);
355  DDName name, nameX;
356  if (type == 1) {
358  std::string name0 = nameIn + "M" + std::to_string(copy);
359  DDLogicalPart glog1 = DDLogicalPart(DDName(name0, idNameSpace_), matter, nameX);
360  cpv.position(glog1.ddname(), glog.ddname(), copyIn, tran, rotation);
361 #ifdef EDM_ML_DEBUG
362  edm::LogVerbatim("HGCalGeom")
363  << "DDHGCalTBModuleX: " << glog1.ddname() << " number " << copyIn << " positioned in " << glog.ddname()
364  << " at " << tran << " with " << rotation;
365 #endif
366  name = (rpos < rMaxFine_) ? DDName(DDSplit(wafer_[0]).first, DDSplit(wafer_[0]).second)
367  : DDName(DDSplit(wafer_[1]).first, DDSplit(wafer_[1]).second);
368  DDTranslation tran1;
369  cpv.position(name, glog1.ddname(), copy, tran1, rotation);
370 #ifdef EDM_ML_DEBUG
371  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " number " << copy << " positioned in "
372  << glog1.ddname() << " at " << tran1 << " with " << rotation;
373 #endif
374  if (copies_.count(copy) == 0 && type == 1)
375  copies_.insert(copy);
376  } else {
378  copy += copyIn * 1000000;
379  cpv.position(name, glog.ddname(), copy, tran, rotation);
380 #ifdef EDM_ML_DEBUG
381  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: " << name << " number " << copy << " positioned in "
382  << glog.ddname() << " at " << tran << " with " << rotation;
383 #endif
384  }
385 #ifdef EDM_ML_DEBUG
386  if (inc > incm)
387  incm = inc;
388  if (inr > inrm)
389  inrm = inr;
390  kount++;
391 #endif
392  }
393  }
394  }
395  }
396 #ifdef EDM_ML_DEBUG
397  edm::LogVerbatim("HGCalGeom") << "DDHGCalTBModuleX: # of columns " << incm << " # of rows " << inrm << " and "
398  << kount << " wafers for " << glog.ddname();
399 #endif
400 }
401 
402 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDHGCalTBModuleX, "hgcal:DDHGCalTBModuleX");
Log< level::Info, true > LogVerbatim
static AlgebraicMatrix initialize()
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=nullptr)
std::vector< std::string > wafer_
std::vector< int > layerFrontOut_
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:45
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
std::vector< std::string > names_
std::vector< std::string > materials_
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:17
std::string to_string(const V &value)
Definition: OMSAccess.h:71
std::vector< int > layerFrontIn_
static std::string & ns()
std::unordered_set< int > copies_
std::vector< int > layerBackIn_
void constructLayers(int block, int layerFront, int layerBack, double zFront, double thick, bool ignore, const DDLogicalPart &, DDCompactView &)
Log< level::Error, false > LogError
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
A DDSolid represents the shape of a part.
Definition: DDSolid.h:39
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:57
U second(std::pair< T, U > const &p)
void constructBlocks(const DDLogicalPart &, DDCompactView &cpv)
const double tan30deg_
std::vector< double > blockThick_
std::vector< int > layerType_
std::vector< std::string > covers_
T sqrt(T t)
Definition: SSEVec.h:19
std::vector< int > layerSense_
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)
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:93
static DDSolid tubs(const DDName &name, double zhalf, double rIn, double rOut, double startPhi, double deltaPhi)
Definition: DDSolid.cc:667
std::vector< int > copyNumber_
static DDSolid box(const DDName &name, double xHalf, double yHalf, double zHalf)
Creates a box with side length 2*xHalf, 2*yHalf, 2*zHalf.
Definition: DDSolid.cc:547
def ignore(seq)
ii
Definition: cuy.py:589
std::vector< int > dbl_to_int(const std::vector< double > &vecdbl)
Converts a std::vector of doubles to a std::vector of int.
Definition: DDutils.h:7
const N & name() const
Definition: DDBase.h:59
void execute(DDCompactView &cpv) override
std::vector< int > layerBackOut_
~DDHGCalTBModuleX() override
const N & ddname() const
Definition: DDBase.h:61
void positionSensitive(double zpos, int copyIn, int type, double rmax, int ncrMax, bool ignoreCenter, const std::string &, const DDMaterial &, const DDLogicalPart &, DDCompactView &cpv)
std::string idNameSpace_
static int32_t packTypeUV(int type, int u, int v)
Definition: HGCalTypes.cc:3
std::vector< int > maxModule_
#define DEFINE_EDM_PLUGIN(factory, type, name)
Log< level::Warning, false > LogWarning
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
std::vector< double > layerThick_
static constexpr double tolerance_