11 #include <unordered_set>
14 #include "DD4hep/DetFactoryHelper.h"
37 waferNames_ =
args.value<std::vector<std::string>>(
"WaferNames");
39 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << waferNames_.size() <<
" wafers";
40 for (
unsigned int i = 0;
i < waferNames_.size(); ++
i)
43 materials_ =
args.value<std::vector<std::string>>(
"MaterialNames");
44 volumeNames_ =
args.value<std::vector<std::string>>(
"VolumeNames");
45 thickness_ =
args.value<std::vector<double>>(
"Thickness");
46 copyNumber_.resize(materials_.size(), 1);
48 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << materials_.size() <<
" types of volumes";
49 for (
unsigned int i = 0;
i < volumeNames_.size(); ++
i)
50 edm::LogVerbatim(
"HGCalGeom") <<
"Volume [" <<
i <<
"] " << volumeNames_[
i] <<
" of thickness " << thickness_[
i]
51 <<
" filled with " << materials_[
i] <<
" first copy number " << copyNumber_[
i];
53 layerNumbers_ =
args.value<std::vector<int>>(
"Layers");
54 layerThick_ =
args.value<std::vector<double>>(
"LayerThick");
55 rMixLayer_ =
args.value<std::vector<double>>(
"LayerRmix");
57 edm::LogVerbatim(
"HGCalGeom") <<
"There are " << layerNumbers_.size() <<
" blocks";
58 for (
unsigned int i = 0;
i < layerNumbers_.size(); ++
i)
59 edm::LogVerbatim(
"HGCalGeom") <<
"Block [" <<
i <<
"] of thickness " << layerThick_[
i] <<
" Rmid "
60 << rMixLayer_[
i] <<
" with " << layerNumbers_[
i] <<
" layers";
62 layerType_ =
args.value<std::vector<int>>(
"LayerType");
63 layerSense_ =
args.value<std::vector<int>>(
"LayerSense");
64 firstLayer_ =
args.value<
int>(
"FirstLayer");
65 absorbMode_ =
args.value<
int>(
"AbsorberMode");
66 sensitiveMode_ =
args.value<
int>(
"SensitiveMode");
69 <<
"Absober:Sensitive mode " << absorbMode_ <<
":" << sensitiveMode_;
71 layerCenter_ =
args.value<std::vector<int>>(
"LayerCenter");
73 for (
unsigned int i = 0;
i < layerCenter_.size(); ++
i)
76 if (firstLayer_ > 0) {
77 for (
unsigned int i = 0;
i < layerType_.size(); ++
i) {
78 if (layerSense_[
i] > 0) {
79 int ii = layerType_[
i];
80 copyNumber_[
ii] = firstLayer_;
82 edm::LogVerbatim(
"HGCalGeom") <<
"First copy number for layer type " <<
i <<
":" <<
ii <<
" with "
83 << materials_[
ii] <<
" changed to " << copyNumber_[
ii];
90 edm::LogVerbatim(
"HGCalGeom") <<
"There are " << layerType_.size() <<
" layers";
91 for (
unsigned int i = 0;
i < layerType_.size(); ++
i)
92 edm::LogVerbatim(
"HGCalGeom") <<
"Layer [" <<
i <<
"] with material type " << layerType_[
i] <<
" sensitive class "
95 materialsTop_ =
args.value<std::vector<std::string>>(
"TopMaterialNames");
96 namesTop_ =
args.value<std::vector<std::string>>(
"TopVolumeNames");
97 layerThickTop_ =
args.value<std::vector<double>>(
"TopLayerThickness");
98 layerTypeTop_ =
args.value<std::vector<int>>(
"TopLayerType");
99 copyNumberTop_.resize(materialsTop_.size(), 1);
101 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << materialsTop_.size() <<
" types of volumes in the top part";
102 for (
unsigned int i = 0;
i < materialsTop_.size(); ++
i)
103 edm::LogVerbatim(
"HGCalGeom") <<
"Volume [" <<
i <<
"] " << namesTop_[
i] <<
" of thickness " << layerThickTop_[
i]
104 <<
" filled with " << materialsTop_[
i] <<
" first copy number "
105 << copyNumberTop_[
i];
106 edm::LogVerbatim(
"HGCalGeom") <<
"There are " << layerTypeTop_.size() <<
" layers in the top part";
107 for (
unsigned int i = 0;
i < layerTypeTop_.size(); ++
i)
108 edm::LogVerbatim(
"HGCalGeom") <<
"Layer [" <<
i <<
"] with material type " << layerTypeTop_[
i];
110 materialsBot_ =
args.value<std::vector<std::string>>(
"BottomMaterialNames");
111 namesBot_ =
args.value<std::vector<std::string>>(
"BottomVolumeNames");
112 layerTypeBot_ =
args.value<std::vector<int>>(
"BottomLayerType");
113 layerSenseBot_ =
args.value<std::vector<int>>(
"BottomLayerSense");
114 layerThickBot_ =
args.value<std::vector<double>>(
"BottomLayerThickness");
115 copyNumberBot_.resize(materialsBot_.size(), 1);
118 <<
" types of volumes in the bottom part";
119 for (
unsigned int i = 0;
i < materialsBot_.size(); ++
i)
120 edm::LogVerbatim(
"HGCalGeom") <<
"Volume [" <<
i <<
"] " << namesBot_[
i] <<
" of thickness " << layerThickBot_[
i]
121 <<
" filled with " << materialsBot_[
i] <<
" first copy number "
122 << copyNumberBot_[
i];
123 edm::LogVerbatim(
"HGCalGeom") <<
"There are " << layerTypeBot_.size() <<
" layers in the bottom part";
124 for (
unsigned int i = 0;
i < layerTypeBot_.size(); ++
i)
125 edm::LogVerbatim(
"HGCalGeom") <<
"Layer [" <<
i <<
"] with material type " << layerTypeBot_[
i]
126 <<
" sensitive class " << layerSenseBot_[
i];
128 zMinBlock_ =
args.value<
double>(
"zMinBlock");
129 rad100to200_ =
args.value<std::vector<double>>(
"rad100to200");
130 rad200to300_ =
args.value<std::vector<double>>(
"rad200to300");
131 zMinRadPar_ =
args.value<
double>(
"zMinForRadPar");
132 choiceType_ =
args.value<
int>(
"choiceType");
133 nCutRadPar_ =
args.value<
int>(
"nCornerCut");
134 fracAreaMin_ =
args.value<
double>(
"fracAreaMin");
135 waferSize_ =
args.value<
double>(
"waferSize");
136 waferSepar_ =
args.value<
double>(
"SensorSeparation");
137 sectors_ =
args.value<
int>(
"Sectors");
138 alpha_ = (1._pi) / sectors_;
139 cosAlpha_ =
cos(alpha_);
141 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: zStart " << zMinBlock_ <<
" radius for wafer type separation uses "
142 << rad100to200_.size() <<
" parameters; zmin " << zMinRadPar_ <<
" cutoff "
143 << choiceType_ <<
":" << nCutRadPar_ <<
":" << fracAreaMin_ <<
" wafer width "
144 << waferSize_ <<
" separations " << waferSepar_ <<
" sectors " << sectors_ <<
":"
146 for (
unsigned int k = 0;
k < rad100to200_.size(); ++
k)
147 edm::LogVerbatim(
"HGCalGeom") <<
"[" <<
k <<
"] 100-200 " << rad100to200_[
k] <<
" 200-300 " << rad200to300_[
k];
149 slopeB_ =
args.value<std::vector<double>>(
"SlopeBottom");
150 zFrontB_ =
args.value<std::vector<double>>(
"ZFrontBottom");
151 rMinFront_ =
args.value<std::vector<double>>(
"RMinFront");
152 slopeT_ =
args.value<std::vector<double>>(
"SlopeTop");
153 zFrontT_ =
args.value<std::vector<double>>(
"ZFrontTop");
154 rMaxFront_ =
args.value<std::vector<double>>(
"RMaxFront");
156 for (
unsigned int i = 0;
i < slopeB_.size(); ++
i)
157 edm::LogVerbatim(
"HGCalGeom") <<
"Block [" <<
i <<
"] Zmin " << zFrontB_[
i] <<
" Rmin " << rMinFront_[
i]
158 <<
" Slope " << slopeB_[
i];
159 for (
unsigned int i = 0;
i < slopeT_.size(); ++
i)
160 edm::LogVerbatim(
"HGCalGeom") <<
"Block [" <<
i <<
"] Zmin " << zFrontT_[
i] <<
" Rmax " << rMaxFront_[
i]
161 <<
" Slope " << slopeT_[
i];
165 waferType_ = std::make_unique<HGCalWaferType>(
166 rad100to200_, rad200to300_, (waferSize_ + waferSepar_), zMinRadPar_, choiceType_, nCutRadPar_, fracAreaMin_);
173 double zi(zMinBlock_);
175 for (
unsigned int i = 0;
i < layerNumbers_.size();
i++) {
176 double zo = zi + layerThick_[
i];
178 int laymax = laymin + layerNumbers_[
i];
181 for (
int ly = laymin; ly < laymax; ++ly) {
182 int ii = layerType_[ly];
183 int copy = copyNumber_[
ii];
184 double hthick = 0.5 * thickness_[
ii];
187 thickTot += thickness_[
ii];
192 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: Layer " << ly <<
":" <<
ii <<
" Front " << zi <<
", " << routF
193 <<
" Back " << zo <<
", " << rinB <<
" superlayer thickness " << layerThick_[
i];
199 if (layerSense_[ly] < 1) {
200 std::vector<double> pgonZ, pgonRin, pgonRout;
201 if (layerSense_[ly] == 0 || absorbMode_ == 0) {
205 pgonZ.emplace_back(-hthick);
206 pgonZ.emplace_back(hthick);
207 pgonRin.emplace_back(rinB);
208 pgonRin.emplace_back(rinB);
209 pgonRout.emplace_back(rmax);
210 pgonRout.emplace_back(rmax);
224 for (
unsigned int isec = 0; isec < pgonZ.size(); ++isec) {
226 pgonRout[isec] = pgonRout[isec] * cosAlpha_ - tol1_;
230 dd4hep::Solid solid =
236 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << solid.name() <<
" polyhedra of " << sectors_
238 <<
convertRadToDeg(-alpha_ + 2._pi) <<
" with " << pgonZ.size() <<
" sections";
239 for (
unsigned int k = 0;
k < pgonZ.size(); ++
k)
241 <<
"[" <<
k <<
"] z " << pgonZ[
k] <<
" R " << pgonRin[
k] <<
":" << pgonRout[
k];
254 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << solid.name() <<
" Tubs made of " << matter.name()
255 <<
" of dimensions " << rinB <<
":" << rins <<
", " << routF <<
":" << routs
256 <<
", " << hthick <<
", 0.0, 360.0 and positioned in: " << glog.name()
257 <<
" number " <<
copy;
259 positionMix(ctxt,
e, glog,
name,
copy, thickness_[
ii], matter, rins, rMixLayer_[
i], routs,
zz);
263 mother.placeVolume(glog,
copy,
r1);
266 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << glog.name() <<
" number " <<
copy <<
" positioned in "
267 << mother.name() <<
" at " <<
r1 <<
" with no rotation";
273 if (
std::abs(thickTot - layerThick_[
i]) >= tol2_) {
274 if (thickTot > layerThick_[
i]) {
275 edm::LogError(
"HGCalGeom") <<
"Thickness of the partition " << layerThick_[
i] <<
" is smaller than "
276 << thickTot <<
": thickness of all its components **** ERROR ****";
278 edm::LogWarning(
"HGCalGeom") <<
"Thickness of the partition " << layerThick_[
i] <<
" does not match with "
279 << thickTot <<
" of the components";
285 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << copies_.size() <<
" different wafer copy numbers";
287 for (std::unordered_set<int>::const_iterator
itr = copies_.begin();
itr != copies_.end(); ++
itr, ++
k) {
291 edm::LogVerbatim(
"HGCalGeom") <<
"<<== End of DDHGCalHEAlgo construction...";
309 for (
unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) {
310 int ii = layerTypeTop_[ly];
311 copyNumberTop_[
ii] = copyM;
313 for (
unsigned int ly = 0; ly < layerTypeBot_.size(); ++ly) {
314 int ii = layerTypeBot_[ly];
315 copyNumberBot_[
ii] = copyM;
317 double hthick = 0.5 * thick;
326 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << solid.name() <<
" Tubs made of " << matter.name()
327 <<
" of dimensions " << rmid <<
", " << rout <<
", " << hthick <<
", 0.0, 360.0";
329 glog.placeVolume(glog1, 1);
332 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << glog1.name() <<
" number 1 positioned in " << glog.name()
333 <<
" at (0, 0, 0) with no rotation";
335 double thickTot(0), zpos(-hthick);
336 for (
unsigned int ly = 0; ly < layerTypeTop_.size(); ++ly) {
337 int ii = layerTypeTop_[ly];
338 int copy = copyNumberTop_[
ii];
339 double hthickl = 0.5 * layerThickTop_[
ii];
340 thickTot += layerThickTop_[
ii];
343 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: Layer " << ly <<
":" <<
ii <<
" R " << rmid <<
":" << rout
344 <<
" Thick " << layerThickTop_[
ii];
358 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << solid.name() <<
" Tubs made of " << matter1.name()
359 <<
" of dimensions " << rmid <<
", " << rout <<
", " << hthickl <<
", 0.0, 360.0";
364 glog1.placeVolume(glog2,
copy,
r1);
367 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: Position " << glog2.name() <<
" number " <<
copy <<
" in "
368 << glog1.name() <<
" at " <<
r1 <<
" with no rotation";
370 ++copyNumberTop_[
ii];
373 if (
std::abs(thickTot - thick) >= tol2_) {
374 if (thickTot > thick) {
375 edm::LogError(
"HGCalGeom") <<
"Thickness of the partition " << thick <<
" is smaller than " << thickTot
376 <<
": thickness of all its components in the top part **** ERROR ****";
378 edm::LogWarning(
"HGCalGeom") <<
"Thickness of the partition " << thick <<
" does not match with " << thickTot
379 <<
" of the components in top part";
384 name = nameM +
"Bottom";
392 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << solid.name() <<
" Tubs made of " << matter.name()
393 <<
" of dimensions " << rin <<
", " << rmid <<
", " << hthick <<
", 0.0, 360.0";
396 glog.placeVolume(glog1, 1);
398 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << glog1.name() <<
" number 1 positioned in " << glog.name()
399 <<
" at (0, 0, 0) with no rotation";
403 for (
unsigned int ly = 0; ly < layerTypeBot_.size(); ++ly) {
404 int ii = layerTypeBot_[ly];
405 int copy = copyNumberBot_[
ii];
406 double hthickl = 0.5 * layerThickBot_[
ii];
407 thickTot += layerThickBot_[
ii];
410 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: Layer " << ly <<
":" <<
ii <<
" R " << rin <<
":" << rmid
411 <<
" Thick " << layerThickBot_[
ii];
425 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << solid.name() <<
" Tubs made of " << matter1.name()
426 <<
" of dimensions " << rin <<
", " << rmid <<
", " << hthickl <<
", 0.0, 360.0";
431 glog1.placeVolume(glog2,
copy,
r1);
433 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: Position " << glog2.name() <<
" number " <<
copy <<
" in "
434 << glog1.name() <<
" at " <<
r1 <<
" with no rotation";
436 if (layerSenseBot_[ly] != 0) {
439 << (
copy - firstLayer_) <<
":" << layerCenter_[
copy - firstLayer_];
441 positionSensitive(ctxt,
e, glog2, rin, rmid,
zz + zpos, layerSenseBot_[ly], layerCenter_[
copy - firstLayer_]);
444 ++copyNumberBot_[
ii];
446 if (
std::abs(thickTot - thick) >= tol2_) {
447 if (thickTot > thick) {
448 edm::LogError(
"HGCalGeom") <<
"Thickness of the partition " << thick <<
" is smaller than " << thickTot
449 <<
": thickness of all its components in the top part **** ERROR ****";
451 edm::LogWarning(
"HGCalGeom") <<
"Thickness of the partition " << thick <<
" does not match with " << thickTot
452 <<
" of the components in top part";
466 static const double sqrt3 =
std::sqrt(3.0);
467 double r = 0.5 * (waferSize_ + waferSepar_);
468 double R = 2.0 *
r / sqrt3;
469 double dy = 0.75 *
R;
470 int N = (
int)(0.5 * rout /
r) + 2;
471 const auto& xyoff = geomTools_.shiftXY(layercenter, (waferSize_ + waferSepar_));
473 int ium(0), ivm(0), iumAll(0), ivmAll(0), kount(0), ntot(0),
nin(0);
474 std::vector<int> ntype(6, 0);
475 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << glog.name() <<
" rout " << rout <<
" N " <<
N
476 <<
" for maximum u, v Offset; Shift " << xyoff.first <<
":" << xyoff.second
477 <<
" WaferSize " << (waferSize_ + waferSepar_);
479 for (
int u = -
N; u <=
N; ++u) {
480 for (
int v = -
N;
v <=
N; ++
v) {
483 double xpos = xyoff.first + nc *
r;
484 double ypos = xyoff.second +
nr *
dy;
492 int type = waferType_->getType(xpos, ypos, zpos);
500 if (copies_.count(
copy) == 0)
501 copies_.insert(
copy);
519 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: " << glog.name() <<
" number " <<
copy <<
" positioned in "
520 << glog.name() <<
" at " << tran <<
" with no rotation";
527 edm::LogVerbatim(
"HGCalGeom") <<
"DDHGCalHEAlgo: Maximum # of u " << ium <<
":" << iumAll <<
" # of v " << ivm
528 <<
":" << ivmAll <<
" and " <<
nin <<
":" << kount <<
":" << ntot <<
" wafers ("
529 << ntype[0] <<
":" << ntype[1] <<
":" << ntype[2] <<
":" << ntype[3] <<
":"
530 << ntype[4] <<
":" << ntype[5] <<
") for " << glog.name() <<
" R " << rin <<
":"
584 static constexpr
double tol1_ = 0.01;
585 static constexpr
double tol2_ = 0.00001;