CMS 3D CMS Logo

DDHGCalModuleAlgo.cc
Go to the documentation of this file.
1 // File: DDHGCalModuleAlgo.cc
3 // Description: Geometry factory class for HGCal (EE and HESil)
5 
6 #include <algorithm>
7 #include <cmath>
8 
20 
21 //#define EDM_ML_DEBUG
22 using namespace geant_units::operators;
23 
25 #ifdef EDM_ML_DEBUG
26  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: Creating an instance";
27 #endif
28 }
29 
31 
33  const DDVectorArguments& vArgs,
34  const DDMapArguments&,
35  const DDStringArguments& sArgs,
36  const DDStringVectorArguments& vsArgs) {
37  wafer = vsArgs["WaferName"];
38 #ifdef EDM_ML_DEBUG
39  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << wafer.size()
40  << " wafers";
41  for (unsigned int i = 0; i < wafer.size(); ++i)
42  edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafer[i];
43 #endif
44  materials = vsArgs["MaterialNames"];
45  names = vsArgs["VolumeNames"];
46  thick = vArgs["Thickness"];
47  for (unsigned int i = 0; i < materials.size(); ++i) {
48  copyNumber.emplace_back(1);
49  }
50 #ifdef EDM_ML_DEBUG
51  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << materials.size()
52  << " types of volumes";
53  for (unsigned int i = 0; i < names.size(); ++i)
54  edm::LogVerbatim("HGCalGeom") << "Volume [" << i << "] " << names[i]
55  << " of thickness " << thick[i]
56  << " filled with " << materials[i]
57  << " first copy number " << copyNumber[i];
58 #endif
59  layers = dbl_to_int(vArgs["Layers"]);
60  layerThick = vArgs["LayerThick"];
61 #ifdef EDM_ML_DEBUG
62  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << layers.size()
63  << " blocks";
64  for (unsigned int i = 0; i < layers.size(); ++i)
65  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] of thickness "
66  << layerThick[i] << " with " << layers[i]
67  << " layers";
68 #endif
69  layerType = dbl_to_int(vArgs["LayerType"]);
70  layerSense = dbl_to_int(vArgs["LayerSense"]);
71 #ifdef EDM_ML_DEBUG
72  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << layerType.size()
73  << " layers";
74  for (unsigned int i = 0; i < layerType.size(); ++i)
75  edm::LogVerbatim("HGCalGeom") << "Layer [" << i << "] with material type "
76  << layerType[i] << " sensitive class "
77  << layerSense[i];
78 #endif
79  zMinBlock = nArgs["zMinBlock"];
80  rMaxFine = nArgs["rMaxFine"];
81  waferW = nArgs["waferW"];
82  waferGap = nArgs["waferGap"];
83  sectors = (int)(nArgs["Sectors"]);
84 #ifdef EDM_ML_DEBUG
85  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: zStart " << zMinBlock
86  << " rFineCoarse " << rMaxFine << " wafer width "
87  << waferW << " gap among wafers " << waferGap
88  << " sectors " << sectors;
89 #endif
90  slopeB = vArgs["SlopeBottom"];
91  slopeT = vArgs["SlopeTop"];
92  zFront = vArgs["ZFront"];
93  rMaxFront = vArgs["RMaxFront"];
94 #ifdef EDM_ML_DEBUG
95  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: Bottom slopes "
96  << slopeB[0] << ":" << slopeB[1] << " and "
97  << slopeT.size() << " slopes for top";
98  for (unsigned int i = 0; i < slopeT.size(); ++i)
99  edm::LogVerbatim("HGCalGeom") << "Block [" << i << "] Zmin " << zFront[i]
100  << " Rmax " << rMaxFront[i] << " Slope "
101  << slopeT[i];
102 #endif
103  idNameSpace = DDCurrentNamespace::ns();
104 #ifdef EDM_ML_DEBUG
105  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: NameSpace " << idNameSpace;
106 #endif
107 }
108 
110 // DDHGCalModuleAlgo methods...
112 
114 #ifdef EDM_ML_DEBUG
115  edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalModuleAlgo...";
116 #endif
117  copies.clear();
118  constructLayers(parent(), cpv);
119 #ifdef EDM_ML_DEBUG
120  edm::LogVerbatim("HGCalGeom") << copies.size()<<" different wafer copy numbers";
121 #endif
122  copies.clear();
123 #ifdef EDM_ML_DEBUG
124  edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalModuleAlgo construction";
125 #endif
126 }
127 
129  DDCompactView& cpv) {
130 #ifdef EDM_ML_DEBUG
131  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo test: \t\tInside Layers";
132 #endif
133  double zi(zMinBlock);
134  int laymin(0);
135  const double tol(0.01);
136  for (unsigned int i = 0; i < layers.size(); i++) {
137  double zo = zi + layerThick[i];
138  double routF = rMax(zi);
139  int laymax = laymin + layers[i];
140  double zz = zi;
141  double thickTot(0);
142  for (int ly = laymin; ly < laymax; ++ly) {
143  int ii = layerType[ly];
144  int copy = copyNumber[ii];
145  double rinB = (layerSense[ly] == 0) ? (zo * slopeB[0]) : (zo * slopeB[1]);
146  zz += (0.5 * thick[ii]);
147  thickTot += thick[ii];
148 
149  std::string name = "HGCal" + names[ii] + std::to_string(copy);
150 #ifdef EDM_ML_DEBUG
151  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo test: Layer " << ly
152  << ":" << ii << " Front " << zi << ", "
153  << routF << " Back " << zo << ", " << rinB
154  << " superlayer thickness " << layerThick[i];
155 #endif
156  DDName matName(DDSplit(materials[ii]).first,
157  DDSplit(materials[ii]).second);
158  DDMaterial matter(matName);
159  DDLogicalPart glog;
160  if (layerSense[ly] == 0) {
161  double alpha = geant_units::piRadians / sectors;
162  double rmax = routF * cos(alpha) - tol;
163  std::vector<double> pgonZ, pgonRin, pgonRout;
164  pgonZ.emplace_back(-0.5 * thick[ii]);
165  pgonZ.emplace_back(0.5 * thick[ii]);
166  pgonRin.emplace_back(rinB);
167  pgonRin.emplace_back(rinB);
168  pgonRout.emplace_back(rmax);
169  pgonRout.emplace_back(rmax);
170  DDSolid solid = DDSolidFactory::polyhedra(DDName(name, idNameSpace),
171  sectors, -alpha,
173  pgonZ, pgonRin, pgonRout);
174  glog = DDLogicalPart(solid.ddname(), matter, solid);
175 #ifdef EDM_ML_DEBUG
176  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << solid.name()
177  << " polyhedra of " << sectors
178  << " sectors covering "
179  << convertRadToDeg(-alpha) << ":"
180  << (360.0+convertRadToDeg(-alpha))
181  << " with " << pgonZ.size() << " sections";
182  for (unsigned int k = 0; k < pgonZ.size(); ++k)
183  edm::LogVerbatim("HGCalGeom") << "[" << k << "] z " << pgonZ[k] << " R "
184  << pgonRin[k] << ":" << pgonRout[k];
185 #endif
186  } else {
187  DDSolid solid =
188  DDSolidFactory::tubs(DDName(name, idNameSpace), 0.5 * thick[ii],
189  rinB, routF, 0.0, 2*geant_units::piRadians);
190  glog = DDLogicalPart(solid.ddname(), matter, solid);
191 #ifdef EDM_ML_DEBUG
192  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << solid.name()
193  << " Tubs made of " << matName
194  << " of dimensions " << rinB << ", "
195  << routF << ", " << 0.5 * thick[ii]
196  << ", 0.0, 360.0";
197 #endif
198  positionSensitive(glog, rinB, routF, cpv);
199  }
200  DDTranslation r1(0, 0, zz);
201  DDRotation rot;
202  cpv.position(glog, module, copy, r1, rot);
203  ++copyNumber[ii];
204 #ifdef EDM_ML_DEBUG
205  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo test: " << glog.name() << " number "
206  << copy << " positioned in " << module.name() << " at " << r1
207  << " with " << rot << std::endl;
208 #endif
209  zz += (0.5 * thick[ii]);
210  } // End of loop over layers in a block
211  zi = zo;
212  laymin = laymax;
213  if (fabs(thickTot - layerThick[i]) < 0.00001) {
214  } else if (thickTot > layerThick[i]) {
215  edm::LogError("HGCalGeom")
216  << "Thickness of the partition " << layerThick[i]
217  << " is smaller than thickness " << thickTot
218  << " of all its components **** ERROR ****\n";
219  } else if (thickTot < layerThick[i]) {
220  edm::LogWarning("HGCalGeom")
221  << "Thickness of the partition " << layerThick[i]
222  << " does not match with " << thickTot << " of the components\n";
223  }
224  } // End of loop over blocks
225 }
226 
227 double DDHGCalModuleAlgo::rMax(double z) {
228  double r(0);
229 #ifdef EDM_ML_DEBUG
230  unsigned int ik(0);
231 #endif
232  for (unsigned int k = 0; k < slopeT.size(); ++k) {
233  if (z < zFront[k]) break;
234  r = rMaxFront[k] + (z - zFront[k]) * slopeT[k];
235 #ifdef EDM_ML_DEBUG
236  ik = k;
237 #endif
238  }
239 #ifdef EDM_ML_DEBUG
240  edm::LogVerbatim("HGCalGeom") << "rMax : " << z << ":" << ik << ":" << r << std::endl;
241 #endif
242  return r;
243 }
244 
246  double rout, DDCompactView& cpv) {
247  double ww = (waferW + waferGap);
248  double dx = 0.5 * ww;
249  double dy = 3.0 * dx * tan(30._deg);
250  double rr = 2.0 * dx * tan(30._deg);
251  int ncol = (int)(2.0 * rout / ww) + 1;
252  int nrow = (int)(rout / (ww * tan(30._deg))) + 1;
253  int incm(0), inrm(0), kount(0);
254 #ifdef EDM_ML_DEBUG
255  edm::LogVerbatim("HGCalGeom") << glog.ddname() << " rout " << rout << " Row "
256  << nrow << " Column " << ncol;
257 #endif
258  for (int nr = -nrow; nr <= nrow; ++nr) {
259  int inr = (nr >= 0) ? nr : -nr;
260  for (int nc = -ncol; nc <= ncol; ++nc) {
261  int inc = (nc >= 0) ? nc : -nc;
262  if (inr % 2 == inc % 2) {
263  double xpos = nc * dx;
264  double ypos = nr * dy;
265  std::pair<int, int> corner =
266  HGCalGeomTools::waferCorner(xpos, ypos, dx, rr, rin, rout, true);
267  if (corner.first == (int)(HGCalParameters::k_CornerSize)) {
268  double rpos = std::sqrt(xpos * xpos + ypos * ypos);
269  DDTranslation tran(xpos, ypos, 0.0);
271  int copy = inr * 100 + inc;
272  if (nc < 0) copy += 10000;
273  if (nr < 0) copy += 100000;
274  DDName name =
275  (rpos < rMaxFine)
276  ? DDName(DDSplit(wafer[0]).first, DDSplit(wafer[0]).second)
277  : DDName(DDSplit(wafer[1]).first, DDSplit(wafer[1]).second);
278  cpv.position(name, glog.ddname(), copy, tran, rotation);
279  if (inc > incm) incm = inc;
280  if (inr > inrm) inrm = inr;
281  kount++;
282  if (copies.count(copy) == 0) copies.insert(copy);
283 #ifdef EDM_ML_DEBUG
284  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: " << name << " number " << copy
285  << " positioned in " << glog.ddname() << " at " << tran
286  << " with " << rotation << std::endl;
287 #endif
288  }
289  }
290  }
291  }
292 #ifdef EDM_ML_DEBUG
293  edm::LogVerbatim("HGCalGeom") << "DDHGCalModuleAlgo: # of columns " << incm
294  << " # of rows " << inrm << " and " << kount
295  << " wafers for " << glog.ddname();
296 #endif
297 }
float alpha
Definition: AMPTWrapper.h:95
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
const N & name() const
Definition: DDBase.h:74
void positionSensitive(DDLogicalPart &glog, double rin, double rout, DDCompactView &cpv)
def copy(args, dbName)
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:43
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
constexpr NumType convertRadToDeg(NumType radians)
Definition: GeantUnits.h:98
static std::string & ns()
~DDHGCalModuleAlgo() override
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
constexpr long double piRadians(M_PI)
const std::string names[nVars_]
A DDSolid represents the shape of a part.
Definition: DDSolid.h:39
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:68
U second(std::pair< T, U > const &p)
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
static std::pair< int32_t, int32_t > waferCorner(double xpos, double ypos, double r, double R, double rMin, double rMax, bool oldBug=false)
void execute(DDCompactView &cpv) override
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
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:865
ii
Definition: cuy.py:590
int k[5][pyjets_maxn]
static uint32_t k_CornerSize
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=0)
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
Definition: vlib.h:208
static DDSolid polyhedra(const DDName &name, int sides, double startPhi, double deltaPhi, const std::vector< double > &z, const std::vector< double > &rmin, const std::vector< double > &rmax)
Creates a polyhedra (refere to Geant3 or Geant4 documentation)
Definition: DDSolid.cc:730
void constructLayers(const DDLogicalPart &, DDCompactView &cpv)
double rMax(double z)
const N & ddname() const
Definition: DDBase.h:76