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 <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 << "DDHGCalModuleAlgo 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 << "DDHGCalModuleAlgo: " << 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.push_back(1);
47  }
48 #ifdef EDM_ML_DEBUG
49  std::cout << "DDHGCalModuleAlgo: " << 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 << "DDHGCalModuleAlgo: " << 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 << "DDHGCalModuleAlgo: " << 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  waferGap = nArgs["waferGap"];
77  sectors = (int)(nArgs["Sectors"]);
78 #ifdef EDM_ML_DEBUG
79  std::cout << "DDHGCalModuleAlgo: zStart " << zMinBlock << " rFineCoarse "
80  << rMaxFine << " wafer width " << waferW << " gap among wafers "
81  << waferGap << " sectors " << sectors << std::endl;
82 #endif
83  slopeB = vArgs["SlopeBottom"];
84  slopeT = vArgs["SlopeTop"];
85  zFront = vArgs["ZFront"];
86  rMaxFront = vArgs["RMaxFront"];
87 #ifdef EDM_ML_DEBUG
88  std::cout << "DDHGCalModuleAlgo: Bottom slopes " << slopeB[0] << ":"
89  << slopeB[1] << " and " << slopeT.size() << " slopes for top"
90  << std::endl;
91  for (unsigned int i=0; i<slopeT.size(); ++i)
92  std::cout << "Block [" << i << "] Zmin " << zFront[i] << " Rmax "
93  << rMaxFront[i] << " Slope " << slopeT[i] << std::endl;
94 #endif
96 #ifdef EDM_ML_DEBUG
97  std::cout << "DDHGCalModuleAlgo: NameSpace " << idNameSpace << std::endl;
98 #endif
99 }
100 
102 // DDHGCalModuleAlgo methods...
104 
106 
107 #ifdef EDM_ML_DEBUG
108  std::cout << "==>> Constructing DDHGCalModuleAlgo..." << std::endl;
109 #endif
110  copies.clear();
111  constructLayers (parent(), cpv);
112 #ifdef EDM_ML_DEBUG
113  std::cout << copies.size() << " different wafer copy numbers" << std::endl;
114 #endif
115  copies.clear();
116 #ifdef EDM_ML_DEBUG
117  std::cout << "<<== End of DDHGCalModuleAlgo construction ..." << std::endl;
118 #endif
119 }
120 
122  DDCompactView& cpv) {
123 
124 #ifdef EDM_ML_DEBUG
125  std::cout << "DDHGCalModuleAlgo test: \t\tInside Layers" << std::endl;
126 #endif
127  double zi(zMinBlock);
128  int laymin(0);
129  const double tol(0.01);
130  for (unsigned int i=0; i<layers.size(); i++) {
131  double zo = zi + layerThick[i];
132  double routF = rMax(zi);
133  int laymax = laymin+layers[i];
134  double zz = zi;
135  double thickTot(0);
136  for (int ly=laymin; ly<laymax; ++ly) {
137  int ii = layerType[ly];
138  int copy = copyNumber[ii];
139  double rinB = (layerSense[ly] == 0) ? (zo*slopeB[0]) : (zo*slopeB[1]);
140  zz += (0.5*thick[ii]);
141  thickTot += thick[ii];
142 
143  std::string name = "HGCal"+names[ii]+std::to_string(copy);
144 #ifdef EDM_ML_DEBUG
145  std::cout << "DDHGCalModuleAlgo test: Layer " << ly << ":" << ii
146  << " Front " << zi << ", " << routF << " Back " << zo << ", "
147  << rinB << " superlayer thickness " << layerThick[i]
148  << std::endl;
149 #endif
150  DDName matName(DDSplit(materials[ii]).first,
151  DDSplit(materials[ii]).second);
152  DDMaterial matter(matName);
153  DDLogicalPart glog;
154  if (layerSense[ly] == 0) {
155  double alpha = CLHEP::pi/sectors;
156  double rmax = routF*cos(alpha) - tol;
157  std::vector<double> pgonZ, pgonRin, pgonRout;
158  pgonZ.push_back(-0.5*thick[ii]); pgonZ.push_back(0.5*thick[ii]);
159  pgonRin.push_back(rinB); pgonRin.push_back(rinB);
160  pgonRout.push_back(rmax); pgonRout.push_back(rmax);
162  sectors, -alpha, CLHEP::twopi,
163  pgonZ, pgonRin, pgonRout);
164  glog = DDLogicalPart(solid.ddname(), matter, solid);
165 #ifdef EDM_ML_DEBUG
166  std::cout << "DDHGCalModuleAlgo test: " << solid.name()
167  << " polyhedra of " << sectors << " sectors covering "
168  << -alpha/CLHEP::deg << ":"
169  << (-alpha+CLHEP::twopi)/CLHEP::deg
170  << " with " << pgonZ.size() << " sections" << std::endl;
171  for (unsigned int k=0; k<pgonZ.size(); ++k)
172  std::cout << "[" << k << "] z " << pgonZ[k] << " R " << pgonRin[k]
173  << ":" << pgonRout[k] << std::endl;
174 #endif
175  } else {
177  0.5*thick[ii], rinB, routF, 0.0,
178  CLHEP::twopi);
179  glog = DDLogicalPart(solid.ddname(), matter, solid);
180 #ifdef EDM_ML_DEBUG
181  std::cout << "DDHGCalModuleAlgo test: " << solid.name()
182  << " Tubs made of " << matName << " of dimensions " << rinB
183  << ", " << routF << ", " << 0.5*thick[ii] << ", 0.0, "
184  << CLHEP::twopi/CLHEP::deg << std::endl;
185 #endif
186  positionSensitive(glog,rinB,routF,cpv);
187  }
188  DDTranslation r1(0,0,zz);
189  DDRotation rot;
190  cpv.position(glog, module, copy, r1, rot);
191  ++copyNumber[ii];
192 #ifdef EDM_ML_DEBUG
193  std::cout << "DDHGCalModuleAlgo test: " << glog.name() << " number "
194  << copy << " positioned in " << module.name() << " at " << r1
195  << " with " << rot << std::endl;
196 #endif
197  zz += (0.5*thick[ii]);
198  } // End of loop over layers in a block
199  zi = zo;
200  laymin = laymax;
201  if (fabs(thickTot-layerThick[i]) < 0.00001) {
202  } else if (thickTot > layerThick[i]) {
203  edm::LogError("HGCalGeom") << "Thickness of the partition " << layerThick[i]
204  << " is smaller than thickness " << thickTot
205  << " of all its components **** ERROR ****\n";
206  } else if (thickTot < layerThick[i]) {
207  edm::LogWarning("HGCalGeom") << "Thickness of the partition "
208  << layerThick[i] << " does not match with "
209  << thickTot << " of the components\n";
210  }
211  } // End of loop over blocks
212 }
213 
214 double DDHGCalModuleAlgo::rMax(double z) {
215  double r(0);
216 #ifdef EDM_ML_DEBUG
217  unsigned int ik(0);
218 #endif
219  for (unsigned int k=0; k<slopeT.size(); ++k) {
220  if (z < zFront[k]) break;
221  r = rMaxFront[k] + (z - zFront[k]) * slopeT[k];
222 #ifdef EDM_ML_DEBUG
223  ik = k;
224 #endif
225  }
226 #ifdef EDM_ML_DEBUG
227  std::cout << "rMax : " << z << ":" << ik << ":" << r << std::endl;
228 #endif
229  return r;
230 }
231 
233  double rout, DDCompactView& cpv) {
234  double ww = (waferW+waferGap);
235  double dx = 0.5*ww;
236  double dy = 3.0*dx*tan(30.0*CLHEP::deg);
237  double rr = 2.0*dx*tan(30.0*CLHEP::deg);
238  int ncol = (int)(2.0*rout/ww) + 1;
239  int nrow = (int)(rout/(ww*tan(30.0*CLHEP::deg))) + 1;
240  int incm(0), inrm(0), kount(0);
241  double xc[6], yc[6];
242 #ifdef EDM_ML_DEBUG
243  std::cout << glog.ddname() << " rout " << rout << " Row " << nrow
244  << " Column " << ncol << std::endl;
245 #endif
246  for (int nr=-nrow; nr <= nrow; ++nr) {
247  int inr = (nr >= 0) ? nr : -nr;
248  for (int nc=-ncol; nc <= ncol; ++nc) {
249  int inc = (nc >= 0) ? nc : -nc;
250  if (inr%2 == inc%2) {
251  double xpos = nc*dx;
252  double ypos = nr*dy;
253  xc[0] = xpos+dx; yc[0] = ypos-0.5*rr;
254  xc[1] = xpos+dx; yc[1] = ypos+0.5*rr;
255  xc[2] = xpos; yc[2] = ypos+rr;
256  xc[3] = xpos-dx; yc[3] = ypos+0.5*rr;
257  xc[4] = xpos+dx; yc[4] = ypos-0.5*rr;
258  xc[5] = xpos; yc[5] = ypos-rr;
259  bool cornerAll(true);
260  for (int k=0; k<6; ++k) {
261  double rpos = std::sqrt(xc[k]*xc[k]+yc[k]*yc[k]);
262  if (rpos < rin || rpos > rout) cornerAll = false;
263  }
264  if (cornerAll) {
265  double rpos = std::sqrt(xpos*xpos+ypos*ypos);
266  DDTranslation tran(xpos, ypos, 0.0);
268  int copy = inr*100 + inc;
269  if (nc < 0) copy += 10000;
270  if (nr < 0) copy += 100000;
271  DDName name = (rpos < rMaxFine) ?
272  DDName(DDSplit(wafer[0]).first, DDSplit(wafer[0]).second) :
273  DDName(DDSplit(wafer[1]).first, DDSplit(wafer[1]).second);
274  cpv.position(name, glog.ddname(), copy, tran, rotation);
275  if (inc > incm) incm = inc;
276  if (inr > inrm) inrm = inr;
277  kount++;
278  if (copies.count(copy) == 0)
279  copies.insert(copy);
280 #ifdef EDM_ML_DEBUG
281  std::cout << "DDHGCalModuleAlgo: " << name << " number " << copy
282  << " positioned in " << glog.ddname() << " at " << tran
283  << " with " << rotation << std::endl;
284 #endif
285  }
286  }
287  }
288  }
289 #ifdef EDM_ML_DEBUG
290  std::cout << "DDHGCalModuleAlgo: # of columns " << incm << " # of rows "
291  << inrm << " and " << kount << " wafers for " << glog.ddname()
292  << std::endl;
293 #endif
294 }
std::vector< int > copyNumber
std::vector< double > thick
float alpha
Definition: AMPTWrapper.h:95
const N & name() const
Definition: DDBase.h:78
void positionSensitive(DDLogicalPart &glog, double rin, double rout, DDCompactView &cpv)
std::unordered_set< int > copies
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:41
void constructLayers(DDLogicalPart, DDCompactView &cpv)
std::vector< std::string > names
void position(const DDLogicalPart &self, const DDLogicalPart &parent, std::string copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=NULL)
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
static std::string & ns()
type of data representation of DDCompactView
Definition: DDCompactView.h:90
A DDSolid represents the shape of a part.
Definition: DDSolid.h:38
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
const Double_t pi
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:64
std::vector< std::string > materials
std::vector< double > rMaxFront
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
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:983
ii
Definition: cuy.py:588
int k[5][pyjets_maxn]
std::vector< double > slopeB
std::string idNameSpace
std::vector< int > layerType
std::vector< int > layers
virtual ~DDHGCalModuleAlgo()
void execute(DDCompactView &cpv)
std::vector< double > slopeT
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:4
std::vector< std::string > wafer
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs)
Definition: vlib.h:208
std::vector< double > zFront
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:843
std::vector< double > layerThick
double rMax(double z)
std::vector< int > layerSense
const N & ddname() const
Definition: DDBase.h:80