CMS 3D CMS Logo

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