8 #include "GaudiKernel/SystemOfUnits.h"
9 #include "GeoGenericFunctions/AbsFunction.h"
10 #include "GeoGenericFunctions/Variable.h"
12 #include "GeoModelKernel/GeoDefinitions.h"
13 #include "GeoModelKernel/GeoFullPhysVol.h"
14 #include "GeoModelKernel/GeoIdentifierTag.h"
15 #include "GeoModelKernel/GeoLogVol.h"
16 #include "GeoModelKernel/GeoNameTag.h"
17 #include "GeoModelKernel/GeoPhysVol.h"
18 #include "GeoModelKernel/GeoSerialDenominator.h"
19 #include "GeoModelKernel/GeoSerialIdentifier.h"
20 #include "GeoModelKernel/GeoSerialTransformer.h"
21 #include "GeoModelKernel/GeoShape.h"
22 #include "GeoModelKernel/GeoShapeShift.h"
23 #include "GeoModelKernel/GeoShapeSubtraction.h"
24 #include "GeoModelKernel/GeoShapeUnion.h"
25 #include "GeoModelKernel/GeoTransform.h"
26 #include "GeoModelKernel/GeoTrd.h"
27 #include "GeoModelKernel/GeoTube.h"
28 #include "GeoModelKernel/GeoXF.h"
33 #include <GaudiKernel/IMessageSvc.h>
34 #include <GaudiKernel/MsgStream.h>
46 using namespace GeoXF;
48 #define verbose_multilayer false
57 MultiLayer::MultiLayer(
const MYSQL& mysql,
const std::string&
n)
73 log << MSG::ERROR <<
"Multilayer constructor - a problem here !!! MDT named " <<
name <<
" not found \n Cannot init correctly !" <<
endmsg;
84 double tuberad =
tube.outerRadius;
89 const GeoShape *slay =
nullptr;
90 const GeoShape *sfoamup =
nullptr;
91 const GeoShape *sfoamlow =
nullptr;
93 double foamthicknesslow =
yy[0] - tuberad;
94 double foamthicknessup;
100 if (foamthicknessup > foamthicknesslow) {
101 foamthicknesslow = 0.;
110 }
else if (
logVolName.find(
"MDT09") != std::string::npos ||
logVolName.find(
"MDT14") != std::string::npos) {
113 foamthicknesslow = 0.;
114 foamthicknessup = 0.;
116 log << MSG::WARNING <<
" problem with thickness of " << std::abs(foamthicknessup) <<
" for foam in LogVolName " <<
logVolName <<
endmsg;
120 foamthicknessup = 0.;
129 }
else if (
logVolName.find(
"MDT09") != std::string::npos ||
logVolName.find(
"MDT14") != std::string::npos) {
132 foamthicknesslow = 0.;
133 foamthicknessup = 0.;
135 log << MSG::WARNING <<
" problem with thickness of " << std::abs(foamthicknesslow) <<
" for foam in LogVolName " <<
logVolName <<
endmsg;
159 const GeoTrd *tempSLay =
nullptr;
160 const GeoShape *tempSLay1 =
nullptr;
162 if (submlthick * submlwidth * submllength > 0) {
163 tempSLay =
new GeoTrd(submlthick, submlthick, submlwidth, submlwidth, submllength);
164 tempSLay1 = &((*tempSLay) << submlpos);
166 log << MSG::WARNING <<
" problem with shape of temporary trapezoid in LogVolName " <<
logVolName <<
" thick,width,length=" << submlthick <<
"," << submlwidth
167 <<
"," << submllength <<
endmsg;
171 slay = &(slay->add(*tempSLay1));
182 double submlwidths =
width / 2.;
183 double submlwidthl =
width / 2.;
184 double lengthPos = 0.;
199 submlwidthl += submllength * TrdDwoverL;
200 lengthPos = -
length / 2. + sum_len + submllength;
201 sum_len += 2. * submllength;
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;
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;
218 tempSLay =
new GeoTrd(submlthick, submlthick, submlwidths, submlwidthl, submllength);
222 tempSLay1 = &((*tempSLay) << submlpos);
224 log << MSG::INFO <<
" problem with shape of temporary trapezoid in LogVolName " <<
logVolName <<
" thick,width,length " << submlthick <<
" " << submlwidths
225 <<
" " << submllength <<
endmsg;
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);
237 tempSFoamup1 = &((*tempSFoamup) << submlpos);
239 log << MSG::INFO <<
" problem with shape of upper foam trapezoid in LogVolName " <<
logVolName <<
" thick,width,length " << foamthicknessup <<
" "
240 << submlwidths <<
" " << submllength <<
endmsg;
243 if (foamthicknesslow * submlwidths * submllength > 0) {
245 tempSFoamlow =
new GeoTrd(foamthicknesslow / 2., foamthicknesslow / 2., submlwidths, submlwidthl, submllength);
249 tempSFoamlow1 = &((*tempSFoamlow) << submlpos);
251 log << MSG::INFO <<
" problem with shape of lower foam trapezoid in LogVolName " <<
logVolName <<
" thick,width,length " << foamthicknesslow <<
" "
252 << submlwidths <<
" " << submllength <<
endmsg;
257 submlwidths = submlwidthl;
263 slay = &(slay->add(*tempSLay1));
264 if (foamthicknessup > 0.)
265 sfoamup = &(sfoamup->add(*tempSFoamup1));
266 if (foamthicknesslow > 0.)
267 sfoamlow = &(sfoamlow->add(*tempSFoamlow1));
274 if (foamthicknessup > 0.)
275 sfoamup = tempSFoamup1;
276 if (foamthicknesslow > 0.)
277 sfoamlow = tempSFoamlow1;
285 GeoIntrusivePtr<const GeoShape> stube{
new GeoTube(0.0,
tubePitch / 2., tL)};
287 const GeoShape *stubewithcut =
nullptr;
292 stubewithcut =
new GeoTube(0.0,
tubePitch / 2., toptubelength / 2.0);
297 slay = &(slay->subtract((*sbox) << GeoTrf::Translate3D(0., 0.,
length / 2.)));
306 slay = &(slay->subtract((*stube) << GeoTrf::Translate3D(-
mdtthickness / 2. +
yy[
i], 0., -
length / 2.)));
326 const GeoMaterial *mlay = matManager.
getMaterial(
"std::Air");
327 GeoLogVol *llay =
new GeoLogVol(
logVolName, slay, mlay);
328 GeoFullPhysVol *play =
new GeoFullPhysVol(llay);
330 double foamposition = 0.;
331 const GeoShape *sfoam =
nullptr;
332 const GeoMaterial *mfoam =
nullptr;
333 GeoLogVol *lfoam =
nullptr;
334 GeoPhysVol *pfoam =
nullptr;
336 if (foamthicknesslow != 0) {
341 sfoam =
new GeoTrd(foamthicknesslow / 2. - eps, foamthicknesslow / 2. - eps,
width / 2. - eps,
longWidth / 2. - eps,
length / 2.);
344 sfoam = &(sfoam->subtract((*sboxf) << GeoTrf::Translate3D(0., 0.,
length / 2. -
tubePitch / 4.)));
346 lfoam =
new GeoLogVol(
"MultiLayerFoam", sfoam, mfoam);
348 }
else if (foamthicknessup != 0) {
353 sfoam =
new GeoTrd(foamthicknessup / 2. - eps, foamthicknessup / 2. - eps,
width / 2. - eps,
longWidth / 2. - eps,
length / 2.);
356 sfoam = &(sfoam->subtract((*sboxf) << GeoTrf::Translate3D(0., 0.,
length / 2. -
tubePitch / 4.)));
358 lfoam =
new GeoLogVol(
"MultiLayerFoam", sfoam, mfoam);
360 }
else if (
logVolName.find(
"MDT09") != std::string::npos ||
logVolName.find(
"MDT14") != std::string::npos) {
365 log << MSG::ERROR <<
" no foam thickeness, while it was expected " <<
endmsg;
366 throw std::runtime_error(
"ATTENTION: no foam");
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));
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;
397 tubeVector.push_back(
tube.build(matManager));
415 double previousTlen = -1.;
416 int nTubeToSwitch[5] = {0};
426 for (
int k = ii - 1;
k >= 0;
k--) {
436 for (
int it = 0;
it < nrTubesPerStep;
it++) {
441 int weAreInCutStep = 0;
448 if (
it + nrTubesPerStep * j > nTubeToSwitch[
ic])
473 if (std::abs(tlen - previousTlen) > 0.001) {
475 tubeVector.push_back(
tube.build(matManager));
476 if (weAreInCutStep < 1) {
477 internalCutout.push_back(
false);
481 tubeDX.push_back(
dx);
482 tubeL.push_back(tlen);
485 Ntubes.push_back(ntubes);
493 Ntubes.push_back(ntubes);
505 GeoSerialDenominator *
sd =
new GeoSerialDenominator(
"DriftTube");
508 if (cutoutNsteps < -10000 && cutoutNsteps > -40000) {
510 std::array<bool, 3> internalCutoutBMG{
false,
true,
false};
511 std::array<std::array<int, 3>, 4> NtubesBMG{};
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}}}};
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;
575 for (
unsigned int j = 0; j <
sizeof(NtubesBMG[
i]) /
sizeof(
int); j++) {
577 GeoVPhysVol *tV = tubeVector[0];
578 int nt = NtubesBMG[
i][j];
581 log <<
MSG::VERBOSE <<
"cutout region " << j <<
" n. of tubes affected should be " << NtubesBMG[
i][j] <<
" internal cutout " << internalCutoutBMG[j]
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));
598 log <<
MSG::VERBOSE <<
" placing " <<
nt <<
" starting at t = " <<
tstart <<
" , y = " << lstart <<
" with " << nttot <<
" tubes so far " <<
endmsg;
603 log <<
MSG::VERBOSE <<
" *NOT* placing " <<
nt <<
" starting at t = " <<
tstart <<
" , y = " << lstart <<
" with " << nttot <<
" tubes so far "
611 bool arrowpointoutwards =
false;
613 if (
xx[1] -
xx[0] > 0.) {
615 arrowpointoutwards =
true;
626 bool nextTimeSubtract =
false;
628 for (
unsigned int j = 0; j < tubeVector.size(); j++) {
629 GeoVPhysVol *tV = tubeVector[j];
630 double dy = tubeDX[j];
633 if (arrowpointoutwards && cutAtAngle) {
634 if (j < tubeVector.size() - 1) {
635 if (internalCutout[j + 1]) {
644 if (internalCutout[j - 1]) {
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;
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));
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;
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));
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));
715 log << MSG::INFO <<
"Multi Layer " <<
name.c_str() <<
" :" <<
endmsg;