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  if (parts < 0)
41  parts = 1;
42  double phi0 = args.value<double>("PhiStart"); // Start phi of the first cassette
43  double dphi = (2._pi) / tagSector.size(); // delta phi of the cassette
44 #ifdef EDM_ML_DEBUG
45  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << tagLayer.size() << " Modules with base name " << parentName
46  << " made of " << material << " T " << thick << " Sectors " << tagSector.size()
47  << " Parts " << parts << " phi0 " << convertRadToDeg(phi0);
48  for (unsigned int i = 0; i < tagLayer.size(); ++i)
49  edm::LogVerbatim("HGCalGeom") << "Layer " << i << " Tag " << tagLayer[i] << " T " << moduleThick;
50  for (unsigned int i = 0; i < tagSector.size(); ++i)
51  edm::LogVerbatim("HGCalGeom") << "Sector " << i << " Tag " << tagSector[i] << " W " << convertRadToDeg(dphi);
52 #endif
53  std::vector<std::string> layerNames = args.value<std::vector<std::string>>("LayerNames"); // Names of the layers
54  std::vector<std::string> materials =
55  args.value<std::vector<std::string>>("LayerMaterials"); // Materials of the layers
56  std::vector<double> layerThick = args.value<std::vector<double>>("LayerThickness"); // Thickness of layers
57 #ifdef EDM_ML_DEBUG
58  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << layerNames.size() << " types of volumes";
59  for (unsigned int i = 0; i < layerNames.size(); ++i)
60  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << layerNames[i] << " of thickness " << layerThick[i]
61  << " filled with " << materials[i];
62 #endif
63 
64  std::vector<int> layerType = args.value<std::vector<int>>("LayerType"); // Layer types
65 #ifdef EDM_ML_DEBUG
66  std::ostringstream st1;
67  for (unsigned int i = 0; i < layerType.size(); ++i)
68  st1 << " [" << i << "] " << layerType[i];
69  edm::LogVerbatim("HGCalGeom") << "There are " << layerType.size() << " blocks" << st1.str();
70 #endif
71 
72  double shiftTop = args.value<double>("ShiftTop"); // Tolerance at the top
73  double shiftBot = args.value<double>("ShiftBottom"); // Tolerance at the bottom
74 #ifdef EDM_ML_DEBUG
75  edm::LogVerbatim("HGCalGeom") << "Shifts st the top " << shiftTop << " and at the bottom " << shiftBot;
76 #endif
77 
78  std::vector<double> slopeB = args.value<std::vector<double>>("SlopeBottom"); // Slope at the lower R
79  std::vector<double> zFrontB = args.value<std::vector<double>>("ZFrontBottom"); // Starting Z values for the slopes
80  std::vector<double> rMinFront = args.value<std::vector<double>>("RMinFront"); // Corresponding rMin's
81  std::vector<double> slopeT = args.value<std::vector<double>>("SlopeTop"); // Slopes at the larger R
82  std::vector<double> zFrontT = args.value<std::vector<double>>("ZFrontTop"); // Starting Z values for the slopes
83  std::vector<double> rMaxFront = args.value<std::vector<double>>("RMaxFront"); // Corresponding rMax's
84 #ifdef EDM_ML_DEBUG
85  for (unsigned int i = 0; i < slopeB.size(); ++i)
86  edm::LogVerbatim("HGCalGeom") << "Bottom Block [" << i << "] Zmin " << zFrontB[i] << " Rmin " << rMinFront[i]
87  << " Slope " << slopeB[i];
88  for (unsigned int i = 0; i < slopeT.size(); ++i)
89  edm::LogVerbatim("HGCalGeom") << "Top Block [" << i << "] Zmin " << zFrontT[i] << " Rmax " << rMaxFront[i]
90  << " Slope " << slopeT[i];
91 
92  edm::LogVerbatim("HGCalGeom") << "==>> Executing DDHGCalPassive...";
93 #endif
94 
95  static constexpr double tol = 0.00001;
96 
97  // Loop over Layers
98  double zim(zMinBlock);
99  //Loop over layers
100  for (unsigned int j = 0; j < tagLayer.size(); ++j) {
101  double routF = HGCalGeomTools::radius(zim, zFrontT, rMaxFront, slopeT) - shiftTop;
102  double zo = zim + moduleThick;
103  double rinB = HGCalGeomTools::radius(zo, zFrontB, rMinFront, slopeB) + shiftBot;
104  zim += moduleThick;
105  for (unsigned int k = 0; k < tagSector.size(); ++k) {
106  std::string parentName = args.parentName() + tagLayer[j] + tagSector[k];
107  double phi1 = phi0 + k * dphi;
108  double dphi0 = dphi / parts;
109  // First the mother
110  int nsec = 2 * parts + 2;
111  std::vector<double> xM(nsec, 0), yM(nsec, 0);
112  for (int n = 0; n <= parts; ++n) {
113  double phi0 = phi1 + n * dphi0;
114  if (n == 0) {
115  xM[0] = rinB * cos(phi0);
116  yM[0] = rinB * sin(phi0);
117  } else {
118  xM[nsec - n] = rinB * cos(phi0);
119  yM[nsec - n] = rinB * sin(phi0);
120  }
121  xM[n + 1] = routF * cos(phi0);
122  yM[n + 1] = routF * sin(phi0);
123  }
124  std::vector<double> zw = {-0.5 * thick, 0.5 * thick};
125  std::vector<double> zx(2, 0), zy(2, 0), scale(2, 1.0);
126  dd4hep::Solid solid = dd4hep::ExtrudedPolygon(xM, yM, zw, zx, zy, scale);
127  ns.addSolidNS(ns.prepend(parentName), solid);
128  dd4hep::Material matter = ns.material(material);
129  dd4hep::Volume glogM = dd4hep::Volume(solid.name(), solid, matter);
130 #ifdef EDM_ML_DEBUG
131  double phi2 = phi1 + dphi;
132  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << solid.name() << " extruded polygon made of "
133  << matter.name() << " z|x|y|s (0) " << zw[0] << ":" << zx[0] << ":" << zy[0]
134  << ":" << scale[0] << " z|x|y|s (1) " << zw[1] << ":" << zx[1] << ":" << zy[1]
135  << ":" << scale[1] << " and " << xM.size() << " edges with " << parts
136  << " parts between " << convertRadToDeg(phi1) << " and " << convertRadToDeg(phi2);
137  for (unsigned int kk = 0; kk < xM.size(); ++kk)
138  edm::LogVerbatim("HGCalGeom") << "[" << kk << "] " << xM[kk] << ":" << yM[kk];
139 #endif
140 
141  // Then the layers
142  std::vector<dd4hep::Volume> glogs(materials.size());
143  std::vector<int> copyNumber(materials.size(), 1);
144  double zi(-0.5 * thick), thickTot(0.0);
145  for (unsigned int l = 0; l < layerType.size(); l++) {
146  unsigned int i = layerType[l];
147  if (copyNumber[i] == 1) {
148  zw[0] = -0.5 * layerThick[i];
149  zw[1] = 0.5 * layerThick[i];
150  std::string layerName = parentName + layerNames[i];
151  solid = dd4hep::ExtrudedPolygon(xM, yM, zw, zx, zy, scale);
152  ns.addSolidNS(ns.prepend(layerName), solid);
153  dd4hep::Material matter = ns.material(materials[i]);
154  glogs[i] = dd4hep::Volume(solid.name(), solid, matter);
155 #ifdef EDM_ML_DEBUG
156  edm::LogVerbatim("HGCalGeom")
157  << "DDHGCalPassive: Layer " << i << ":" << l << ":" << solid.name() << " extruded polygon made of "
158  << matter.name() << " z|x|y|s (0) " << zw[0] << ":" << zx[0] << ":" << zy[0] << ":" << scale[0]
159  << " z|x|y|s (1) " << zw[1] << ":" << zx[1] << ":" << zy[1] << ":" << scale[1] << " and " << xM.size()
160  << " edges";
161  for (unsigned int kk = 0; kk < xM.size(); ++kk)
162  edm::LogVerbatim("HGCalGeom") << "[" << kk << "] " << xM[kk] << ":" << yM[kk];
163 #endif
164  }
165  dd4hep::Position tran0(0, 0, (zi + 0.5 * layerThick[i]));
166  glogM.placeVolume(glogs[i], copyNumber[i], tran0);
167 #ifdef EDM_ML_DEBUG
168  edm::LogVerbatim("HGCalGeom") << "DDHGCalPassive: " << glogs[i].name() << " number " << copyNumber[i]
169  << " positioned in " << glogM.name() << " at (0, 0, "
170  << cms::convert2mm(zi + 0.5 * layerThick[i]) << ") with no rotation";
171 #endif
172  ++copyNumber[i];
173  zi += layerThick[i];
174  thickTot += layerThick[i];
175  }
176  if ((std::abs(thickTot - thick) >= tol) && (!layerType.empty())) {
177  if (thickTot > thick) {
178  edm::LogError("HGCalGeom") << "Thickness of the partition " << thick << " is smaller than " << thickTot
179  << ": thickness of all its components **** ERROR ****";
180  } else {
181  edm::LogWarning("HGCalGeom") << "Thickness of the partition " << thick << " does not match with "
182  << thickTot << " of the components";
183  }
184  }
185  }
186  }
187  }
188 };
189 
190 static long algorithm(dd4hep::Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
191  HGCalPassive passiveAlgo(ctxt, e);
192  return cms::s_executed;
193 }
194 
195 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
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