79 {
81
82 DriftTube
tube(mysql,
name +
" DriftTube");
83 double eps = 0.001;
84 double tuberad =
tube.outerRadius;
86 log << MSG::VERBOSE <<
" MultiLayer::build of " <<
name <<
" logVolName = " <<
logVolName <<
" tube radius, pitch = " << tuberad <<
" , " <<
tubePitch <<
endmsg;
87 }
88
89 const GeoShape *slay = nullptr;
90 const GeoShape *sfoamup = nullptr;
91 const GeoShape *sfoamlow = nullptr;
92
93 double foamthicknesslow =
yy[0] - tuberad;
94 double foamthicknessup;
97 else
99
100 if (foamthicknessup > foamthicknesslow) {
101 foamthicknesslow = 0.;
102 if (std::abs(foamthicknessup - 15 * Gaudi::Units::mm) < 0.1) {
103 foamthicknessup = 15 * Gaudi::Units::mm;
104 } else if (std::abs(foamthicknessup - 30.75 * Gaudi::Units::mm) < 0.1) {
105 foamthicknessup = 30.75 * Gaudi::Units::mm;
106 } else if (std::abs(foamthicknessup - 30.00 * Gaudi::Units::mm) < 0.1) {
107 foamthicknessup = 30.00 * Gaudi::Units::mm;
108 }
else if (std::abs(foamthicknessup - 10.00 * Gaudi::Units::mm) < 0.1 &&
logVolName.find(
"BMG") != std::string::npos) {
109 foamthicknessup = 10.00 * Gaudi::Units::mm;
110 }
else if (
logVolName.find(
"MDT09") != std::string::npos ||
logVolName.find(
"MDT14") != std::string::npos) {
111
112
113 foamthicknesslow = 0.;
114 foamthicknessup = 0.;
115 } else {
116 log << MSG::WARNING <<
" problem with thickness of " << std::abs(foamthicknessup) <<
" for foam in LogVolName " <<
logVolName <<
endmsg;
117 }
118
119 } else {
120 foamthicknessup = 0.;
121 if (std::abs(foamthicknesslow - 15 * Gaudi::Units::mm) < 0.1) {
122 foamthicknesslow = 15 * Gaudi::Units::mm;
123 } else if (std::abs(foamthicknesslow - 30.75 * Gaudi::Units::mm) < 0.1) {
124 foamthicknesslow = 30.75 * Gaudi::Units::mm;
125 } else if (std::abs(foamthicknesslow - 30.00 * Gaudi::Units::mm) < 0.1) {
126 foamthicknesslow = 30.00 * Gaudi::Units::mm;
127 }
else if (std::abs(foamthicknesslow - 10.00 * Gaudi::Units::mm) < 0.1 &&
logVolName.find(
"BMG") != std::string::npos) {
128 foamthicknesslow = 10.00 * Gaudi::Units::mm;
129 }
else if (
logVolName.find(
"MDT09") != std::string::npos ||
logVolName.find(
"MDT14") != std::string::npos) {
130
131
132 foamthicknesslow = 0.;
133 foamthicknessup = 0.;
134 } else {
135 log << MSG::WARNING <<
" problem with thickness of " << std::abs(foamthicknesslow) <<
" for foam in LogVolName " <<
logVolName <<
endmsg;
136 }
137 }
138
139
142
145
147
148
150
153
154
157 GeoTrf::Transform3D submlpos = GeoTrf::Translate3D(0., yPos, zPos);
158
159 const GeoTrd *tempSLay = nullptr;
160 const GeoShape *tempSLay1 = nullptr;
161
162 if (submlthick * submlwidth * submllength > 0) {
163 tempSLay = new GeoTrd(submlthick, submlthick, submlwidth, submlwidth, submllength);
164 tempSLay1 = &((*tempSLay) << submlpos);
165 } else {
166 log << MSG::WARNING <<
" problem with shape of temporary trapezoid in LogVolName " <<
logVolName <<
" thick,width,length=" << submlthick <<
"," << submlwidth
167 <<
"," << submllength <<
endmsg;
168 }
169
170 if (slay) {
171 slay = &(slay->add(*tempSLay1));
172 } else {
173 slay = tempSLay1;
174 }
175 }
176 } else {
177
180 }
182 double submlwidths =
width / 2.;
183 double submlwidthl =
width / 2.;
184 double lengthPos = 0.;
185 double sum_len = 0;
186
189 log << MSG::VERBOSE <<
" cutout region " << isub <<
" has " <<
cutoutNtubes[isub] <<
" tubes " <<
endmsg;
190 }
193 continue;
194 }
195
199 submlwidthl += submllength * TrdDwoverL;
200 lengthPos = -
length / 2. + sum_len + submllength;
201 sum_len += 2. * submllength;
203 GeoTrf::Transform3D submlpos = GeoTrf::Translate3D(0., widthPos, lengthPos);
204
205 const GeoTrd *tempSLay = nullptr;
206 const GeoShape *tempSLay1 = nullptr;
207 const GeoTrd *tempSFoamup = nullptr;
208 const GeoShape *tempSFoamup1 = nullptr;
209 const GeoTrd *tempSFoamlow = nullptr;
210 const GeoShape *tempSFoamlow1 = nullptr;
211
212 if (submlthick * submlwidthl * submllength > 0) {
214 log << MSG::VERBOSE <<
" LogVolName " <<
logVolName <<
" cut step " << isub <<
" thick = " << submlthick <<
" short width = " << submlwidths
215 <<
" long width = " << submlwidthl <<
" length = " << submllength <<
" translated to " << widthPos <<
" , " << lengthPos <<
endmsg;
216 }
218 tempSLay = new GeoTrd(submlthick, submlthick, submlwidths, submlwidthl, submllength);
219 } else {
221 }
222 tempSLay1 = &((*tempSLay) << submlpos);
223 } else {
224 log << MSG::INFO <<
" problem with shape of temporary trapezoid in LogVolName " <<
logVolName <<
" thick,width,length " << submlthick <<
" " << submlwidths
225 <<
" " << submllength <<
endmsg;
226 }
227
228 if (foamthicknessup != 0 || foamthicknesslow != 0) {
229 if (foamthicknessup > foamthicknesslow) {
230 if (foamthicknessup * submlwidths * submllength > 0) {
232 tempSFoamup = new GeoTrd(foamthicknessup / 2., foamthicknessup / 2., submlwidths, submlwidthl, submllength);
233 } else {
235 }
236
237 tempSFoamup1 = &((*tempSFoamup) << submlpos);
238 } else {
239 log << MSG::INFO <<
" problem with shape of upper foam trapezoid in LogVolName " <<
logVolName <<
" thick,width,length " << foamthicknessup <<
" "
240 << submlwidths <<
" " << submllength <<
endmsg;
241 }
242 } else {
243 if (foamthicknesslow * submlwidths * submllength > 0) {
245 tempSFoamlow = new GeoTrd(foamthicknesslow / 2., foamthicknesslow / 2., submlwidths, submlwidthl, submllength);
246 } else {
248 }
249 tempSFoamlow1 = &((*tempSFoamlow) << submlpos);
250 } else {
251 log << MSG::INFO <<
" problem with shape of lower foam trapezoid in LogVolName " <<
logVolName <<
" thick,width,length " << foamthicknesslow <<
" "
252 << submlwidths <<
" " << submllength <<
endmsg;
253 }
254 }
255 }
256
257 submlwidths = submlwidthl;
258
259 if (slay) {
261 log << MSG::VERBOSE <<
" Layer " << slay <<
" in " <<
logVolName <<
" exists - add step section to it " <<
endmsg;
262 }
263 slay = &(slay->add(*tempSLay1));
264 if (foamthicknessup > 0.)
265 sfoamup = &(sfoamup->add(*tempSFoamup1));
266 if (foamthicknesslow > 0.)
267 sfoamlow = &(sfoamlow->add(*tempSFoamlow1));
268
269 } else {
271 log << MSG::VERBOSE <<
" Layer slay in " <<
logVolName <<
" does not yet exist - create it " <<
endmsg;
272 }
273 slay = tempSLay1;
274 if (foamthicknessup > 0.)
275 sfoamup = tempSFoamup1;
276 if (foamthicknesslow > 0.)
277 sfoamlow = tempSFoamlow1;
278 }
279 }
280 }
281
282
283
285 GeoIntrusivePtr<const GeoShape> stube{
new GeoTube(0.0,
tubePitch / 2., tL)};
286 stube = &((*stube) << GeoTrf::RotateX3D(90. * Gaudi::Units::deg));
287 const GeoShape *stubewithcut = nullptr;
292 stubewithcut =
new GeoTube(0.0,
tubePitch / 2., toptubelength / 2.0);
293 stubewithcut = &((*stubewithcut) << GeoTrf::RotateX3D(90. * Gaudi::Units::deg));
294 }
295
297 slay = &(slay->subtract((*sbox) << GeoTrf::Translate3D(0., 0.,
length / 2.)));
298
300
302
304 log << MSG::VERBOSE <<
" Cutting tube at xx = " <<
yy[
i] <<
" z = " << -
length / 2. <<
endmsg;
305 }
306 slay = &(slay->subtract((*stube) << GeoTrf::Translate3D(-
mdtthickness / 2. +
yy[i], 0., -
length / 2.)));
307
308
310
312 log << MSG::VERBOSE <<
" Adding tube at xx = " <<
yy[
i] <<
" z = " <<
length / 2. <<
endmsg;
313 }
315 } else {
316
319 }
321 }
322 }
323 }
324
325
326 const GeoMaterial *mlay = matManager.
getMaterial(
"std::Air");
327 GeoLogVol *llay =
new GeoLogVol(
logVolName, slay, mlay);
328 GeoFullPhysVol *play = new GeoFullPhysVol(llay);
329
330 double foamposition = 0.;
331 const GeoShape *sfoam = nullptr;
332 const GeoMaterial *mfoam = nullptr;
333 GeoLogVol *lfoam = nullptr;
334 GeoPhysVol *pfoam = nullptr;
335
336 if (foamthicknesslow != 0) {
338 if (sfoamlow) {
339 sfoam = sfoamlow;
340 } else {
341 sfoam =
new GeoTrd(foamthicknesslow / 2. - eps, foamthicknesslow / 2. - eps,
width / 2. - eps,
longWidth / 2. - eps,
length / 2.);
342 }
344 sfoam = &(sfoam->subtract((*sboxf) << GeoTrf::Translate3D(0., 0.,
length / 2. -
tubePitch / 4.)));
346 lfoam = new GeoLogVol("MultiLayerFoam", sfoam, mfoam);
347
348 } else if (foamthicknessup != 0) {
350 if (sfoamup) {
351 sfoam = sfoamup;
352 } else {
353 sfoam =
new GeoTrd(foamthicknessup / 2. - eps, foamthicknessup / 2. - eps,
width / 2. - eps,
longWidth / 2. - eps,
length / 2.);
354 }
356 sfoam = &(sfoam->subtract((*sboxf) << GeoTrf::Translate3D(0., 0.,
length / 2. -
tubePitch / 4.)));
358 lfoam = new GeoLogVol("MultiLayerFoam", sfoam, mfoam);
359
360 }
else if (
logVolName.find(
"MDT09") != std::string::npos ||
logVolName.find(
"MDT14") != std::string::npos) {
361
362
363 lfoam = nullptr;
364 } else {
365 log << MSG::ERROR <<
" no foam thickeness, while it was expected " <<
endmsg;
366 throw std::runtime_error("ATTENTION: no foam");
367 }
368
369 if (lfoam) {
370 pfoam = new GeoPhysVol(lfoam);
371 GeoTransform *xf = new GeoTransform(GeoTrf::TranslateX3D(foamposition));
372 GeoNameTag *
nt =
new GeoNameTag(
name +
" MultiLayerFoam");
373 play->add(new GeoIdentifierTag(0));
374 play->add(nt);
375 play->add(xf);
376 play->add(pfoam);
377 }
378
379
380
383 std::vector<GeoVPhysVol *> tubeVector;
384 std::vector<bool> internalCutout;
385 std::vector<double> tubeDX;
386 std::vector<double> tubeL;
387 std::vector<int> Ntubes;
388
389
393
395 log << MSG::VERBOSE <<
" logVolName " <<
logVolName <<
" step = " << j <<
" tube length = " <<
tube.length <<
endmsg;
396 }
397 tubeVector.push_back(
tube.build(matManager));
398 }
399
400
401 } else {
404 }
405 int ntubes = 0;
406
407
408
411 log << MSG::VERBOSE <<
" Building tube vectors for step " << j <<
endmsg;
412 }
414 double tlen = 0.;
415 double previousTlen = -1.;
416 int nTubeToSwitch[5] = {0};
418 std::abort();
419
422 log << MSG::VERBOSE <<
" Building tube vectors for cutout step " << ii <<
endmsg;
423 }
425 if (ii > 0) {
426 for (
int k = ii - 1;
k >= 0;
k--) {
428 }
429 }
431 log << MSG::VERBOSE <<
" nTubeToSwitch[" << ii <<
"]=" << nTubeToSwitch[ii] <<
endmsg;
432 }
433 }
434
435
436 for (
int it = 0;
it < nrTubesPerStep;
it++) {
437 tlen = tlength;
439
440
441 int weAreInCutStep = 0;
443 std::abort();
447 }
448 if (it + nrTubesPerStep * j > nTubeToSwitch[ic])
449 weAreInCutStep++;
450 }
451
453 log << MSG::VERBOSE <<
" Tube " <<
it <<
" is in cut step " << weAreInCutStep <<
endmsg;
454 }
455
456
461 tlen -= 3;
462
463
464
465
466
467
468
469
470
471 }
472
473 if (std::abs(tlen - previousTlen) > 0.001) {
475 tubeVector.push_back(
tube.build(matManager));
476 if (weAreInCutStep < 1) {
477 internalCutout.push_back(false);
478 } else {
480 }
481 tubeDX.push_back(dx);
482 tubeL.push_back(tlen);
483 previousTlen = tlen;
484 if (ntubes > 0)
485 Ntubes.push_back(ntubes);
486 ntubes = 1;
487
488 } else {
489 ntubes++;
490 }
491
493 Ntubes.push_back(ntubes);
495 log << MSG::VERBOSE <<
" ntubes = " << ntubes <<
endmsg;
496 }
497 }
498 }
499 }
500
501
502
503 double lstart;
505 GeoSerialDenominator *
sd =
new GeoSerialDenominator(
"DriftTube");
506 play->add(sd);
507
509
510 std::array<bool, 3> internalCutoutBMG{false, true, false};
511 std::array<std::array<int, 3>, 4> NtubesBMG{};
512
514 NtubesBMG = {{{{23, 7, 24}}, {{24, 7, 23}}, {{24, 7, 23}}, {{25, 7, 22}}}};
516 NtubesBMG = {{{{29, 7, 18}}, {{30, 7, 17}}, {{30, 7, 17}}, {{31, 7, 16}}}};
518 NtubesBMG = {{{{13, 8, 33}}, {{14, 8, 32}}, {{14, 8, 32}}, {{15, 8, 31}}}};
520 NtubesBMG = {{{{25, 8, 21}}, {{26, 8, 20}}, {{26, 8, 20}}, {{27, 8, 19}}}};
522 NtubesBMG = {{{{14, 14, 26}}, {{16, 14, 24}}, {{16, 14, 24}}, {{18, 14, 22}}}};
524 NtubesBMG = {{{{31, 14, 9}}, {{33, 14, 7}}, {{33, 14, 7}}, {{35, 14, 5}}}};
526 NtubesBMG = {{{{24, 6, 24}}, {{23, 7, 24}}, {{24, 7, 23}}, {{24, 7, 23}}}};
528 NtubesBMG = {{{{30, 7, 17}}, {{29, 8, 17}}, {{31, 7, 16}}, {{31, 6, 17}}}};
530 NtubesBMG = {{{{13, 8, 33}}, {{13, 8, 33}}, {{14, 9, 31}}, {{15, 8, 31}}}};
532 NtubesBMG = {{{{25, 8, 21}}, {{25, 8, 21}}, {{27, 8, 19}}, {{27, 8, 19}}}};
534 NtubesBMG = {{{{15, 13, 26}}, {{15, 14, 25}}, {{17, 13, 24}}, {{17, 14, 23}}}};
536 NtubesBMG = {{{{32, 14, 8}}, {{32, 14, 8}}, {{34, 14, 6}}, {{34, 14, 6}}}};
538 NtubesBMG = {{{{24, 6, 24}}, {{23, 7, 24}}, {{24, 7, 23}}, {{24, 7, 23}}}};
540 NtubesBMG = {{{{30, 7, 17}}, {{29, 8, 17}}, {{31, 7, 16}}, {{31, 6, 17}}}};
542 NtubesBMG = {{{{13, 8, 33}}, {{13, 8, 33}}, {{14, 9, 31}}, {{15, 8, 31}}}};
544 NtubesBMG = {{{{25, 8, 21}}, {{25, 8, 21}}, {{27, 8, 19}}, {{27, 8, 19}}}};
546 NtubesBMG = {{{{19, 9, 26}}, {{19, 10, 25}}, {{21, 9, 24}}, {{21, 10, 23}}}};
548 NtubesBMG = {{{{36, 10, 8}}, {{37, 9, 8}}, {{38, 10, 6}}, {{39, 9, 6}}}};
550 NtubesBMG = {{{{23, 7, 24}}, {{24, 7, 23}}, {{24, 7, 23}}, {{25, 7, 22}}}};
552 NtubesBMG = {{{{29, 7, 18}}, {{30, 7, 17}}, {{30, 7, 17}}, {{31, 7, 16}}}};
554 NtubesBMG = {{{{13, 8, 33}}, {{14, 8, 32}}, {{14, 8, 32}}, {{15, 8, 31}}}};
556 NtubesBMG = {{{{25, 8, 21}}, {{26, 8, 20}}, {{26, 8, 20}}, {{27, 8, 19}}}};
558 NtubesBMG = {{{{18, 10, 26}}, {{20, 10, 24}}, {{20, 10, 24}}, {{22, 10, 22}}}};
560 NtubesBMG = {{{{36, 9, 9}}, {{37, 10, 7}}, {{38, 9, 7}}, {{39, 10, 5}}}};
561 } else {
562 NtubesBMG = {{{{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}}}};
563 log << MSG::ERROR <<
"massive error placing tubes for BMG chambers" <<
endmsg;
564 std::abort();
565 }
566
569 log << MSG::VERBOSE <<
"Tube Layers n. " <<
i <<
endmsg;
570 }
571
573 double loffset = 0.;
574 int nttot = 0;
575 for (
unsigned int j = 0; j <
sizeof(NtubesBMG[
i]) /
sizeof(
int); j++) {
576
577 GeoVPhysVol *tV = tubeVector[0];
578 int nt = NtubesBMG[
i][j];
579
581 log << MSG::VERBOSE <<
"cutout region " << j <<
" n. of tubes affected should be " << NtubesBMG[
i][j] <<
" internal cutout " << internalCutoutBMG[j]
583 }
584
585
586 if (nt > 0 && !internalCutoutBMG[j]) {
589 GeoGenfun::Variable K;
590 GeoGenfun::GENFUNCTION
f =
tubePitch * K + lstart;
591 TRANSFUNCTION
t = GeoTrf::TranslateY3D(0.) * GeoTrf::RotateX3D(90 * Gaudi::Units::deg) * GeoTrf::TranslateX3D(tstart) * Pow(GeoTrf::TranslateY3D(1.0), f);
592 GeoSerialTransformer *
s =
new GeoSerialTransformer(tV, &t, nt);
593 play->add(new GeoSerialIdentifier(maxNTubesPerLayer * (i + 1) + nttot + 1));
594 play->add(s);
595
598 log << MSG::VERBOSE <<
" placing " <<
nt <<
" starting at t = " <<
tstart <<
" , y = " << lstart <<
" with " << nttot <<
" tubes so far " <<
endmsg;
599 }
600 } else {
603 log << MSG::VERBOSE <<
" *NOT* placing " <<
nt <<
" starting at t = " <<
tstart <<
" , y = " << lstart <<
" with " << nttot <<
" tubes so far "
605 }
606 }
607 }
608 }
609
611 bool arrowpointoutwards = false;
613 if (
xx[1] -
xx[0] > 0.) {
614
615 arrowpointoutwards = true;
616 }
617
620 log << MSG::VERBOSE <<
"Tube Layers n. " <<
i <<
endmsg;
621 }
622
624 double loffset = 0.;
625 int nttot = 0;
626 bool nextTimeSubtract = false;
627
628 for (unsigned int j = 0; j < tubeVector.size(); j++) {
629 GeoVPhysVol *tV = tubeVector[j];
630 double dy = tubeDX[j];
632
633 if (arrowpointoutwards && cutAtAngle) {
634 if (j < tubeVector.size() - 1) {
635 if (internalCutout[j + 1]) {
636
637
638 if (i > 1)
640 }
641 }
642
643 if (j > 0) {
644 if (internalCutout[j - 1]) {
645
646
647 if (i > 1)
649 }
650 }
651 }
652
654 log << MSG::VERBOSE <<
"staircasing or cutout region " << j <<
" n. of tubes affected should be " << Ntubes[j] <<
" and are " <<
nt <<
" internal cutout "
655 << internalCutout[j] <<
" next time subtract " << nextTimeSubtract <<
endmsg;
656 }
657
658 if (nt > 0) {
661 GeoGenfun::Variable K;
662 GeoGenfun::GENFUNCTION
f =
tubePitch * K + lstart;
663 TRANSFUNCTION
t = GeoTrf::TranslateY3D(dy) * GeoTrf::RotateX3D(90 * Gaudi::Units::deg) * GeoTrf::TranslateX3D(tstart) * Pow(GeoTrf::TranslateY3D(1.0), f);
664 GeoSerialTransformer *
s =
new GeoSerialTransformer(tV, &t, nt);
665 play->add(new GeoSerialIdentifier(maxNTubesPerLayer * (i + 1) + nttot + 1));
666 play->add(s);
667
670 log << MSG::VERBOSE <<
" placing " <<
nt <<
" tubes of length " << tubeL[j] <<
" starting at t = " <<
tstart <<
" , y = " << lstart <<
" and x = " <<
dy
671 <<
" with " << nttot <<
" tubes so far " <<
endmsg;
672 }
673 }
674 }
675
677
681 GeoGenfun::Variable K;
682 GeoGenfun::GENFUNCTION
f =
tubePitch * K + lstart;
683 TRANSFUNCTION
t = GeoTrf::RotateX3D(90 * Gaudi::Units::deg) * GeoTrf::TranslateX3D(tstart) * Pow(GeoTrf::TranslateY3D(1.0), f);
684 GeoVPhysVol *tV = tubeVector[0];
685 GeoSerialTransformer *
s =
new GeoSerialTransformer(tV, &t,
nrOfTubes);
686 play->add(new GeoSerialIdentifier(maxNTubesPerLayer * (i + 1) + 1));
687 play->add(s);
688 }
689 } else {
690
691 lstart = 0.;
694 double loffset = 0.;
695
697 GeoVPhysVol *tV = tubeVector[j];
698 loffset = j * nrTubesPerStep *
tubePitch;
700 GeoGenfun::Variable K;
701 GeoGenfun::GENFUNCTION
f =
tubePitch * K + lstart;
702 TRANSFUNCTION
t = GeoTrf::RotateX3D(90 * Gaudi::Units::deg) * GeoTrf::TranslateX3D(tstart) * Pow(GeoTrf::TranslateY3D(1.0), f);
703 GeoSerialTransformer *
s =
new GeoSerialTransformer(tV, &t, nrTubesPerStep);
704 play->add(new GeoSerialIdentifier(maxNTubesPerLayer * (i + 1) + j * nrTubesPerStep + 1));
705 play->add(s);
706 }
707 }
708 }
709
710 return play;
711 }
#define verbose_multilayer
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
std::array< double, 5 > cutoutTubeLength
std::array< double, 5 > cutoutYmax
std::vector< std::pair< double, double > > m_nonCutoutYSteps
std::array< int, 5 > cutoutNtubes
std::array< bool, 5 > cutoutFullLength
std::array< double, 5 > cutoutXtubes
std::vector< std::pair< double, double > > m_nonCutoutXSteps
virtual const GeoMaterial * getMaterial(const std::string &name)=0