CMS 3D CMS Logo

DDHGCalEEAlgo.cc
Go to the documentation of this file.
1 // File: DDHGCalEEAlgo.cc
3 // Description: Geometry factory class for HGCal (EE and HESil)
5 
16 
17 //#define EDM_ML_DEBUG
18 using namespace geant_units::operators;
19 
21 #ifdef EDM_ML_DEBUG
22  edm::LogVerbatim("HGCalGeom") << "DDHGCalEEAlgo: Creating an instance";
23 #endif
24 }
25 
27 
29  const DDVectorArguments& vArgs,
30  const DDMapArguments&,
31  const DDStringArguments& sArgs,
32  const DDStringVectorArguments& vsArgs) {
33  wafers_ = vsArgs["WaferNames"];
34 #ifdef EDM_ML_DEBUG
35  edm::LogVerbatim("HGCalGeom")
36  << "DDHGCalEEAlgo: " << wafers_.size() << " wafers";
37  for (unsigned int i = 0; i < wafers_.size(); ++i)
38  edm::LogVerbatim("HGCalGeom") << "Wafer[" << i << "] " << wafers_[i];
39 #endif
40  materials_ = vsArgs["MaterialNames"];
41  names_ = vsArgs["VolumeNames"];
42  thick_ = vArgs["Thickness"];
43  for (unsigned int i = 0; i < materials_.size(); ++i) {
44  copyNumber_.emplace_back(1);
45  }
46 #ifdef EDM_ML_DEBUG
47  edm::LogVerbatim("HGCalGeom")
48  << "DDHGCalEEAlgo: " << materials_.size() << " types of volumes";
49  for (unsigned int i = 0; i < names_.size(); ++i)
50  edm::LogVerbatim("HGCalGeom")
51  << "Volume [" << i << "] " << names_[i] << " of thickness " << thick_[i]
52  << " filled with " << materials_[i] << " first copy number "
53  << copyNumber_[i];
54 #endif
55  layers_ = dbl_to_int(vArgs["Layers"]);
56  layerThick_ = vArgs["LayerThick"];
57 #ifdef EDM_ML_DEBUG
58  edm::LogVerbatim("HGCalGeom") << "There are " << layers_.size() << " blocks";
59  for (unsigned int i = 0; i < layers_.size(); ++i)
60  edm::LogVerbatim("HGCalGeom")
61  << "Block [" << i << "] of thickness " << layerThick_[i] << " with "
62  << layers_[i] << " layers";
63 #endif
64  layerType_ = dbl_to_int(vArgs["LayerType"]);
65  layerSense_ = dbl_to_int(vArgs["LayerSense"]);
66  firstLayer_ = (int)(nArgs["FirstLayer"]);
67  absorbMode_ = (int)(nArgs["AbsorberMode"]);
68 #ifdef EDM_ML_DEBUG
69  edm::LogVerbatim("HGCalGeom") << "First Layere " << firstLayer_ << " and "
70  << "Absober mode " << absorbMode_;
71 #endif
72  if (firstLayer_ > 0) {
73  for (unsigned int i = 0; i < layerType_.size(); ++i) {
74  if (layerSense_[i] > 0) {
75  int ii = layerType_[i];
76  copyNumber_[ii] = firstLayer_;
77 #ifdef EDM_ML_DEBUG
78  edm::LogVerbatim("HGCalGeom")
79  << "First copy number for layer type " << i << ":" << ii << " with "
80  << materials_[ii] << " changed to " << copyNumber_[ii];
81 #endif
82  break;
83  }
84  }
85  }
86 #ifdef EDM_ML_DEBUG
87  edm::LogVerbatim("HGCalGeom")
88  << "There are " << layerType_.size() << " layers";
89  for (unsigned int i = 0; i < layerType_.size(); ++i)
90  edm::LogVerbatim("HGCalGeom")
91  << "Layer [" << i << "] with material type " << layerType_[i]
92  << " sensitive class " << layerSense_[i];
93 #endif
94  zMinBlock_ = nArgs["zMinBlock"];
95  rad100to200_ = vArgs["rad100to200"];
96  rad200to300_ = vArgs["rad200to300"];
97  zMinRadPar_ = nArgs["zMinForRadPar"];
98  choiceType_ = (int)(nArgs["choiceType"]);
99  nCutRadPar_ = (int)(nArgs["nCornerCut"]);
100  fracAreaMin_ = nArgs["fracAreaMin"];
101  waferSize_ = nArgs["waferSize"];
102  waferSepar_ = nArgs["SensorSeparation"];
103  sectors_ = (int)(nArgs["Sectors"]);
104  alpha_ = (1._pi) / sectors_;
105  cosAlpha_ = cos(alpha_);
106 #ifdef EDM_ML_DEBUG
107  edm::LogVerbatim("HGCalGeom")
108  << "zStart " << zMinBlock_ << " radius for wafer type separation uses "
109  << rad100to200_.size() << " parameters; zmin " << zMinRadPar_
110  << " cutoff " << choiceType_ << ":" << nCutRadPar_ << ":" << fracAreaMin_
111  << " wafer width " << waferSize_ << " separations " << waferSepar_
112  << " sectors " << sectors_ << ":" << convertRadToDeg(alpha_) << ":"
113  << cosAlpha_;
114  for (unsigned int k = 0; k < rad100to200_.size(); ++k)
115  edm::LogVerbatim("HGCalGeom") << "[" << k << "] 100-200 " << rad100to200_[k]
116  << " 200-300 " << rad200to300_[k];
117 #endif
118  slopeB_ = vArgs["SlopeBottom"];
119  zFrontB_ = vArgs["ZFrontBottom"];
120  rMinFront_ = vArgs["RMinFront"];
121  slopeT_ = vArgs["SlopeTop"];
122  zFrontT_ = vArgs["ZFrontTop"];
123  rMaxFront_ = vArgs["RMaxFront"];
124 #ifdef EDM_ML_DEBUG
125  for (unsigned int i = 0; i < slopeB_.size(); ++i)
126  edm::LogVerbatim("HGCalGeom")
127  << "Block [" << i << "] Zmin " << zFrontB_[i] << " Rmin "
128  << rMinFront_[i] << " Slope " << slopeB_[i];
129  for (unsigned int i = 0; i < slopeT_.size(); ++i)
130  edm::LogVerbatim("HGCalGeom")
131  << "Block [" << i << "] Zmin " << zFrontT_[i] << " Rmax "
132  << rMaxFront_[i] << " Slope " << slopeT_[i];
133 #endif
134  nameSpace_ = DDCurrentNamespace::ns();
135 #ifdef EDM_ML_DEBUG
136  edm::LogVerbatim("HGCalGeom") << "DDHGCalEEAlgo: NameSpace " << nameSpace_;
137 #endif
138 
139  waferType_ = std::make_unique<HGCalWaferType>(
140  rad100to200_, rad200to300_, (waferSize_ + waferSepar_), zMinRadPar_,
141  choiceType_, nCutRadPar_, fracAreaMin_);
142 }
143 
145 // DDHGCalEEAlgo methods...
147 
149 #ifdef EDM_ML_DEBUG
150  edm::LogVerbatim("HGCalGeom") << "==>> Constructing DDHGCalEEAlgo...";
151  copies_.clear();
152 #endif
153  constructLayers(parent(), cpv);
154 #ifdef EDM_ML_DEBUG
155  edm::LogVerbatim("HGCalGeom")
156  << "DDHGCalEEAlgo: " << copies_.size() << " different wafer copy numbers";
157  int k(0);
158  for (std::unordered_set<int>::const_iterator itr = copies_.begin();
159  itr != copies_.end(); ++itr, ++k) {
160  edm::LogVerbatim("HGCalGeom") << "Copy [" << k << "] : " << (*itr);
161  }
162  copies_.clear();
163  edm::LogVerbatim("HGCalGeom") << "<<== End of DDHGCalEEAlgo construction...";
164 #endif
165 }
166 
168  DDCompactView& cpv) {
169 #ifdef EDM_ML_DEBUG
170  edm::LogVerbatim("HGCalGeom") << "DDHGCalEEAlgo: \t\tInside Layers";
171 #endif
172  double zi(zMinBlock_);
173  int laymin(0);
174  const double tol(0.01);
175  for (unsigned int i = 0; i < layers_.size(); i++) {
176  double zo = zi + layerThick_[i];
177  double routF = HGCalGeomTools::radius(zi, zFrontT_, rMaxFront_, slopeT_);
178  int laymax = laymin + layers_[i];
179  double zz = zi;
180  double thickTot(0);
181  for (int ly = laymin; ly < laymax; ++ly) {
182  int ii = layerType_[ly];
183  int copy = copyNumber_[ii];
184  double hthick = 0.5 * thick_[ii];
185  double rinB = HGCalGeomTools::radius(zo, zFrontB_, rMinFront_, slopeB_);
186  zz += hthick;
187  thickTot += thick_[ii];
188 
189  std::string name = names_[ii] + std::to_string(copy);
190 #ifdef EDM_ML_DEBUG
191  edm::LogVerbatim("HGCalGeom")
192  << "DDHGCalEEAlgo: Layer " << ly << ":" << ii << " Front " << zi
193  << ", " << routF << " Back " << zo << ", " << rinB
194  << " superlayer thickness " << layerThick_[i];
195 #endif
196  DDName matName(DDSplit(materials_[ii]).first,
197  DDSplit(materials_[ii]).second);
198  DDMaterial matter(matName);
199  DDLogicalPart glog;
200  if (layerSense_[ly] < 1) {
201  std::vector<double> pgonZ, pgonRin, pgonRout;
202  if (layerSense_[ly] == 0 || absorbMode_ == 0) {
203  double rmax = routF * cosAlpha_ - tol;
204  pgonZ.emplace_back(-hthick);
205  pgonZ.emplace_back(hthick);
206  pgonRin.emplace_back(rinB);
207  pgonRin.emplace_back(rinB);
208  pgonRout.emplace_back(rmax);
209  pgonRout.emplace_back(rmax);
210  } else {
211  HGCalGeomTools::radius(zz-hthick, zz+hthick, zFrontB_, rMinFront_,
212  slopeB_, zFrontT_, rMaxFront_, slopeT_,
213  -layerSense_[ly], pgonZ, pgonRin, pgonRout);
214  for (unsigned int isec=0; isec < pgonZ.size(); ++isec) {
215  pgonZ[isec] -= zz;
216  pgonRout[isec] = pgonRout[isec]*cosAlpha_ - tol;
217  }
218  }
219  DDSolid solid =
220  DDSolidFactory::polyhedra(DDName(name, nameSpace_), sectors_,
221  -alpha_, 2._pi, pgonZ, pgonRin, pgonRout);
222  glog = DDLogicalPart(solid.ddname(), matter, solid);
223 #ifdef EDM_ML_DEBUG
224  edm::LogVerbatim("HGCalGeom")
225  << "DDHGCalEEAlgo: " << solid.name() << " polyhedra of " << sectors_
226  << " sectors covering " << convertRadToDeg(-alpha_) << ":"
227  << convertRadToDeg(-alpha_ + 2._pi) << " with " << pgonZ.size()
228  << " sections and filled with " << matName << ":" << &matter;
229  for (unsigned int k = 0; k < pgonZ.size(); ++k)
230  edm::LogVerbatim("HGCalGeom")
231  << "[" << k << "] z " << pgonZ[k] << " R " << pgonRin[k] << ":"
232  << pgonRout[k];
233 #endif
234  } else {
235  DDSolid solid = DDSolidFactory::tubs(DDName(name, nameSpace_), hthick,
236  rinB, routF, 0.0, 2._pi);
237  glog = DDLogicalPart(solid.ddname(), matter, solid);
238 #ifdef EDM_ML_DEBUG
239  edm::LogVerbatim("HGCalGeom")
240  << "DDHGCalEEAlgo: " << solid.name() << " Tubs made of " << matName
241  << ":" << &matter << " of dimensions " << rinB << ", " << routF
242  << ", " << hthick << ", 0.0, 360.0 and position " << glog.name()
243  << " number " << copy;
244 #endif
245  positionSensitive(glog, rinB, routF, zz, layerSense_[ly], cpv);
246  }
247  DDTranslation r1(0, 0, zz);
248  DDRotation rot;
249  cpv.position(glog, module, copy, r1, rot);
250  ++copyNumber_[ii];
251 #ifdef EDM_ML_DEBUG
252  edm::LogVerbatim("HGCalGeom")
253  << "DDHGCalEEAlgo: " << glog.name() << " number " << copy
254  << " positioned in " << module.name() << " at " << r1 << " with "
255  << rot;
256 #endif
257  zz += hthick;
258  } // End of loop over layers in a block
259  zi = zo;
260  laymin = laymax;
261  if (std::abs(thickTot - layerThick_[i]) < 0.00001) {
262  } else if (thickTot > layerThick_[i]) {
263  edm::LogError("HGCalGeom")
264  << "Thickness of the partition " << layerThick_[i]
265  << " is smaller than " << thickTot << ": thickness of all its "
266  << "components **** ERROR ****";
267  } else if (thickTot < layerThick_[i]) {
268  edm::LogWarning("HGCalGeom")
269  << "Thickness of the partition " << layerThick_[i]
270  << " does not match with " << thickTot << " of the components";
271  }
272  } // End of loop over blocks
273 }
274 
275 void DDHGCalEEAlgo::positionSensitive(const DDLogicalPart& glog, double rin,
276  double rout, double zpos, int layertype,
277  DDCompactView& cpv) {
278  static const double sqrt3 = std::sqrt(3.0);
279  double r = 0.5 * (waferSize_ + waferSepar_);
280  double R = 2.0 * r / sqrt3;
281  double dy = 0.75 * R;
282  int N = (int)(0.5 * rout / r) + 2;
283 #ifdef EDM_ML_DEBUG
284  int ium(0), ivm(0), iumAll(0), ivmAll(0), kount(0), ntot(0), nin(0);
285  std::vector<int> ntype(6, 0);
286  edm::LogVerbatim("HGCalGeom")
287  << "DDHGCalEEAlgo: " << glog.ddname() << " rout " << rout << " N " << N
288  << " for maximum u, v; r " << r << " R " << R << " dy " << dy;
289 #endif
290  for (int u = -N; u <= N; ++u) {
291  int iu = std::abs(u);
292  for (int v = -N; v <= N; ++v) {
293  int iv = std::abs(v);
294  int nr = 2 * v;
295  int nc = -2 * u + v;
296  double xpos = nc * r;
297  double ypos = nr * dy;
298  std::pair<int, int> corner =
299  HGCalGeomTools::waferCorner(xpos, ypos, r, R, rin, rout, false);
300 #ifdef EDM_ML_DEBUG
301  ++ntot;
302  if (((corner.first <= 0) && std::abs(u) < 5 && std::abs(v) < 5) ||
303  (std::abs(u) < 2 && std::abs(v) < 2)) {
304  edm::LogVerbatim("HGCalGeom")
305  << "DDHGCalEEAlgo: " << glog.ddname() << " R " << rin << ":" << rout
306  << "\n Z " << zpos << " LayerType " << layertype << " u " << u
307  << " v " << v << " with " << corner.first << " corners";
308  }
309 #endif
310  if (corner.first > 0) {
311  int type = waferType_->getType(xpos, ypos, zpos);
312  int copy = type * 1000000 + iv * 100 + iu;
313  if (u < 0) copy += 10000;
314  if (v < 0) copy += 100000;
315 #ifdef EDM_ML_DEBUG
316  if (iu > ium) ium = iu;
317  if (iv > ivm) ivm = iv;
318  kount++;
319  if (copies_.count(copy) == 0) copies_.insert(copy);
320 #endif
321  if (corner.first == (int)(HGCalParameters::k_CornerSize)) {
322 #ifdef EDM_ML_DEBUG
323  if (iu > iumAll) iumAll = iu;
324  if (iv > ivmAll) ivmAll = iv;
325  ++nin;
326 #endif
327  DDTranslation tran(xpos, ypos, 0.0);
329  if (layertype > 1) type += 3;
330  DDName name = DDName(DDSplit(wafers_[type]).first,
331  DDSplit(wafers_[type]).second);
332  cpv.position(name, glog.ddname(), copy, tran, rotation);
333 #ifdef EDM_ML_DEBUG
334  ++ntype[type];
335  edm::LogVerbatim("HGCalGeom")
336  << " DDHGCalEEAlgo: " << name << " number " << copy
337  << " positioned in " << glog.ddname() << " at " << tran
338  << " with " << rotation;
339 #endif
340  }
341  }
342  }
343  }
344 #ifdef EDM_ML_DEBUG
345  edm::LogVerbatim("HGCalGeom")
346  << "DDHGCalEEAlgo: Maximum # of u " << ium << ":" << iumAll << " # of v "
347  << ivm << ":" << ivmAll << " and " << nin << ":" << kount << ":" << ntot
348  << " wafers (" << ntype[0] << ":" << ntype[1] << ":" << ntype[2] << ":"
349  << ntype[3] << ":" << ntype[4] << ":" << ntype[5] << ") for "
350  << glog.ddname() << " R " << rin << ":" << rout;
351 #endif
352 }
type
Definition: HCALResponse.h:21
void execute(DDCompactView &cpv) override
~DDHGCalEEAlgo() override
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)
const N & name() const
Definition: DDBase.h:74
def copy(args, dbName)
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()
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
A DDSolid represents the shape of a part.
Definition: DDSolid.h:39
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
int nin
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)
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.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
#define N
Definition: blowfish.cc:9
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=0)
void positionSensitive(const DDLogicalPart &glog, double rin, double rout, double zpos, int layertype, DDCompactView &cpv)
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
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
const N & ddname() const
Definition: DDBase.h:76
void constructLayers(const DDLogicalPart &, DDCompactView &cpv)