CMS 3D CMS Logo

DDHGCalPassive.cc
Go to the documentation of this file.
1 // File: DDHGCalPassive.cc
3 // Description: Geometry factory class for the passive part of a full silicon
4 // module
5 // Created by Sunanda Banerjee
7 
8 #include <string>
9 #include <vector>
10 #include <sstream>
11 
12 #include "DD4hep/DetFactoryHelper.h"
18 
19 //#define EDM_ML_DEBUG
20 using namespace angle_units::operators;
21 
22 struct HGCalPassive {
23  HGCalPassive() { throw cms::Exception("HGCalGeom") << "Wrong initialization to HGCalPassive"; }
25  cms::DDNamespace ns(ctxt, e, true);
27 #ifdef EDM_ML_DEBUG
28  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: Creating an instance";
29 #endif
30  std::string parentName = args.parentName();
31  std::string material = args.value<std::string>("ModuleMaterial"); // Material name for mother volume
32  double thick = args.value<double>("Thickness"); // Thickness of the section
33  double zMinBlock = args.value<double>("zMinBlock"); // z-position of the first layer
34  double moduleThick = args.value<double>("ModuleThick"); // Thickness of the overall module
35  std::vector<std::string> tagLayer =
36  args.value<std::vector<std::string>>("TagLayer"); // Tag of the layer (to be added to name)
37  std::vector<std::string> tagSector =
38  args.value<std::vector<std::string>>("TagSector"); // Tag of the sector (to be added to name)
39  int parts = args.value<int>("Parts"); // number of parts in units of 30 degree
40  double phi0 = args.value<double>("PhiStart"); // Start phi of the first cassette
41  double dphi = (2._pi) / tagSector.size(); // delta phi of the cassette
42 #ifdef EDM_ML_DEBUG
43  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << tagLayer.size() << " Modules with base name " << parentName
44  << " made of " << material << " T " << thick << " Sectors " << tagSector.size()
45  << " Parts " << parts << " phi0 " << convertRadToDeg(phi0);
46  for (unsigned int i = 0; i < tagLayer.size(); ++i)
47  edm::LogVerbatim("HGCalGeom") << "Layer " << i << " Tag " << tagLayer[i] << " T " << moduleThick;
48  for (unsigned int i = 0; i < tagSector.size(); ++i)
49  edm::LogVerbatim("HGCalGeom") << "Sector " << i << " Tag " << tagSector[i] << " W " << convertRadToDeg(dphi);
50 #endif
51  std::vector<std::string> layerNames = args.value<std::vector<std::string>>("LayerNames"); // Names of the layers
52  std::vector<std::string> materials =
53  args.value<std::vector<std::string>>("LayerMaterials"); // Materials of the layers
54  std::vector<double> layerThick = args.value<std::vector<double>>("LayerThickness"); // Thickness of layers
55 #ifdef EDM_ML_DEBUG
56  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << layerNames.size() << " types of volumes";
57  for (unsigned int i = 0; i < layerNames.size(); ++i)
58  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << layerNames[i] << " of thickness " << layerThick[i]
59  << " filled with " << materials[i];
60 #endif
61 
62  std::vector<int> layerType = args.value<std::vector<int>>("LayerType"); // Layer types
63 #ifdef EDM_ML_DEBUG
64  std::ostringstream st1;
65  for (unsigned int i = 0; i < layerType.size(); ++i)
66  st1 << " [" << i << "] " << layerType[i];
67  edm::LogVerbatim("HGCalGeom") << "There are " << layerType.size() << " blocks" << st1.str();
68 #endif
69 
70  double shiftTop = args.value<double>("ShiftTop"); // Tolerance at the top
71  double shiftBot = args.value<double>("ShiftBottom"); // Tolerance at the bottom
72 #ifdef EDM_ML_DEBUG
73  edm::LogVerbatim("HGCalGeom") << "Shifts st the top " << shiftTop << " and at the bottom " << shiftBot;
74 #endif
75 
76  std::vector<double> slopeB = args.value<std::vector<double>>("SlopeBottom"); // Slope at the lower R
77  std::vector<double> zFrontB = args.value<std::vector<double>>("ZFrontBottom"); // Starting Z values for the slopes
78  std::vector<double> rMinFront = args.value<std::vector<double>>("RMinFront"); // Corresponding rMin's
79  std::vector<double> slopeT = args.value<std::vector<double>>("SlopeTop"); // Slopes at the larger R
80  std::vector<double> zFrontT = args.value<std::vector<double>>("ZFrontTop"); // Starting Z values for the slopes
81  std::vector<double> rMaxFront = args.value<std::vector<double>>("RMaxFront"); // Corresponding rMax's
82 #ifdef EDM_ML_DEBUG
83  for (unsigned int i = 0; i < slopeB.size(); ++i)
84  edm::LogVerbatim("HGCalGeom") << "Bottom Block [" << i << "] Zmin " << zFrontB[i] << " Rmin " << rMinFront[i]
85  << " Slope " << slopeB[i];
86  for (unsigned int i = 0; i < slopeT.size(); ++i)
87  edm::LogVerbatim("HGCalGeom") << "Top Block [" << i << "] Zmin " << zFrontT[i] << " Rmax " << rMaxFront[i]
88  << " Slope " << slopeT[i];
89 
90  edm::LogVerbatim("HGCalGeom") << "==>> Executing DDHGCalPassive...";
91 #endif
92 
93  static constexpr double tol = 0.00001;
94 
95  // Loop over Layers
96  double zim(zMinBlock);
97  //Loop over layers
98  for (unsigned int j = 0; j < tagLayer.size(); ++j) {
99  double routF = HGCalGeomTools::radius(zim, zFrontT, rMaxFront, slopeT) - shiftTop;
100  double zo = zim + moduleThick;
101  double rinB = HGCalGeomTools::radius(zo, zFrontB, rMinFront, slopeB) + shiftBot;
102  zim += moduleThick;
103  for (unsigned int k = 0; k < tagSector.size(); ++k) {
104  std::string parentName = args.parentName() + tagLayer[j] + tagSector[k];
105  double phi1 = phi0 + k * dphi;
106  double phi2 = phi1 + dphi;
107  double phi0 = phi1 + 0.5 * dphi;
108  // First the mother
109  std::vector<double> xM, yM;
110  if (parts == 1) {
111  xM = {rinB * cos(phi1), routF * cos(phi1), routF * cos(phi2), rinB * cos(phi2)};
112  yM = {rinB * sin(phi1), routF * sin(phi1), routF * sin(phi2), rinB * sin(phi2)};
113  } else {
114  // workaround for https://github.com/cms-sw/cmssw/issues/44931#issuecomment-2134850535
115  std::vector<double> xTmp = {rinB * cos(phi1),
116  routF * cos(phi1),
117  routF * cos(phi0),
118  routF * cos(phi2),
119  rinB * cos(phi2),
120  rinB * cos(phi0)};
121  std::vector<double> yTmp = {rinB * sin(phi1),
122  routF * sin(phi1),
123  routF * sin(phi0),
124  routF * sin(phi2),
125  rinB * sin(phi2),
126  rinB * sin(phi0)};
127  xM = std::move(xTmp);
128  yM = std::move(yTmp);
129  }
130  std::vector<double> zw = {-0.5 * thick, 0.5 * thick};
131  std::vector<double> zx(2, 0), zy(2, 0), scale(2, 1.0);
132  dd4hep::Solid solid = dd4hep::ExtrudedPolygon(xM, yM, zw, zx, zy, scale);
133  ns.addSolidNS(ns.prepend(parentName), solid);
134  dd4hep::Material matter = ns.material(material);
135  dd4hep::Volume glogM = dd4hep::Volume(solid.name(), solid, matter);
136 #ifdef EDM_ML_DEBUG
137  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << solid.name() << " extruded polygon made of "
138  << matter.name() << " z|x|y|s (0) " << zw[0] << ":" << zx[0] << ":" << zy[0]
139  << ":" << scale[0] << " z|x|y|s (1) " << zw[1] << ":" << zx[1] << ":" << zy[1]
140  << ":" << scale[1] << " and " << xM.size() << " edges";
141  for (unsigned int kk = 0; kk < xM.size(); ++kk)
142  edm::LogVerbatim("HGCalGeom") << "[" << kk << "] " << xM[kk] << ":" << yM[kk];
143 #endif
144 
145  // Then the layers
146  std::vector<dd4hep::Volume> glogs(materials.size());
147  std::vector<int> copyNumber(materials.size(), 1);
148  double zi(-0.5 * thick), thickTot(0.0);
149  for (unsigned int l = 0; l < layerType.size(); l++) {
150  unsigned int i = layerType[l];
151  if (copyNumber[i] == 1) {
152  zw[0] = -0.5 * layerThick[i];
153  zw[1] = 0.5 * layerThick[i];
154  std::string layerName = parentName + layerNames[i];
155  solid = dd4hep::ExtrudedPolygon(xM, yM, zw, zx, zy, scale);
156  ns.addSolidNS(ns.prepend(layerName), solid);
157  dd4hep::Material matter = ns.material(materials[i]);
158  glogs[i] = dd4hep::Volume(solid.name(), solid, matter);
159 #ifdef EDM_ML_DEBUG
160  edm::LogVerbatim("HGCalGeom")
161  << "DDHGCalPassive: Layer " << i << ":" << l << ":" << solid.name() << " extruded polygon made of "
162  << matter.name() << " z|x|y|s (0) " << zw[0] << ":" << zx[0] << ":" << zy[0] << ":" << scale[0]
163  << " z|x|y|s (1) " << zw[1] << ":" << zx[1] << ":" << zy[1] << ":" << scale[1] << " and " << xM.size()
164  << " edges";
165  for (unsigned int kk = 0; kk < xM.size(); ++kk)
166  edm::LogVerbatim("HGCalGeom") << "[" << kk << "] " << xM[kk] << ":" << yM[kk];
167 #endif
168  }
169  dd4hep::Position tran0(0, 0, (zi + 0.5 * layerThick[i]));
170  glogM.placeVolume(glogs[i], copyNumber[i], tran0);
171 #ifdef EDM_ML_DEBUG
172  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << glogs[i].name() << " number " << copyNumber[i]
173  << " positioned in " << glogM.name() << " at (0, 0, "
174  << cms::convert2mm(zi + 0.5 * layerThick[i]) << ") with no rotation";
175 #endif
176  ++copyNumber[i];
177  zi += layerThick[i];
178  thickTot += layerThick[i];
179  }
180  if ((std::abs(thickTot - thick) >= tol) && (!layerType.empty())) {
181  if (thickTot > thick) {
182  edm::LogError("HGCalGeom") << "Thickness of the partition " << thick << " is smaller than " << thickTot
183  << ": thickness of all its components **** ERROR ****";
184  } else {
185  edm::LogWarning("HGCalGeom") << "Thickness of the partition " << thick << " does not match with "
186  << thickTot << " of the components";
187  }
188  }
189  }
190  }
191  }
192 };
193 
194 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
195  HGCalPassive passiveAlgo(ctxt, e);
196  return cms::s_executed;
197 }
198 
199 DECLARE_DDCMS_DETELEMENT(DDCMS_hgcal_DDHGCalPassive, algorithm)
Log< level::Info, true > LogVerbatim
HGCalPassive(cms::DDParsingContext &ctxt, xml_h e)
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
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Log< level::Error, false > LogError
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:166
#define DECLARE_DDCMS_DETELEMENT(name, func)
Definition: DDPlugins.h:25
static long algorithm(dd4hep::Detector &, cms::DDParsingContext &ctxt, xml_h e)
static constexpr long s_executed
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
dd4hep::Volume Volume
auto zw(V v) -> Vec2< typename std::remove_reference< decltype(v[0])>::type >
Definition: ExtVec.h:84
Log< level::Warning, false > LogWarning
def move(src, dest)
Definition: eostools.py:511
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