27 #include "GeoModelKernel/GeoUnidentifiedShape.h"
28 #include "GeoModelKernel/GeoElement.h"
29 #include "GeoModelKernel/GeoMaterial.h"
30 #include "GeoModelKernel/GeoFullPhysVol.h"
31 #include "GeoModelKernel/GeoPhysVol.h"
32 #include "GeoModelKernel/GeoVPhysVol.h"
33 #include "GeoModelKernel/GeoLogVol.h"
34 #include "GeoModelKernel/GeoPcon.h"
35 #include "GeoModelKernel/GeoCons.h"
36 #include "GeoModelKernel/GeoTubs.h"
37 #include "GeoModelKernel/GeoTube.h"
38 #include "GeoModelKernel/GeoNameTag.h"
39 #include "GeoModelKernel/GeoTransform.h"
40 #include "GeoModelKernel/GeoAlignableTransform.h"
41 #include "GeoModelKernel/GeoIdentifierTag.h"
42 #include "GeoModelKernel/GeoDefinitions.h"
43 #include "GeoModelKernel/Units.h"
47 #include "GaudiKernel/MsgStream.h"
48 #include "GaudiKernel/Bootstrap.h"
49 #include "GaudiKernel/IService.h"
50 #include "GaudiKernel/ISvcLocator.h"
51 #include "GaudiKernel/SystemOfUnits.h"
57 static const bool DEBUG_EMEC =
false;
77 SmartIF<StoreGateSvc>
detStore{Gaudi::svcLocator()->service(
"DetectorStore")};
79 throw std::runtime_error(
"Error in EndcapCryostatConstruction, cannot access DetectorStore");
82 if (StatusCode::SUCCESS !=
detStore->retrieve(materialManager, std::string(
"MATERIALS")))
return nullptr;
92 std::string
name,symbol;
96 double Totalthick,Totalthicke;
97 double Tgpb,Tgfe,Tggl,Thpb,Thfe,Thgl,Thcu,Thka,ThGten;
98 double FracH,FracO,FracC,FracN,FracAr;
99 double FracGten,Fracpb,Fracfe,Fracgl,Fraccu,Fracka;
100 double aH,aO,aC,aN,aAr;
102 const GeoElement*
H=materialManager->
getElement(
"Hydrogen");
103 const GeoElement* C=materialManager->
getElement(
"Carbon");
104 const GeoElement*
N=materialManager->
getElement(
"Nitrogen");
105 const GeoElement* O=materialManager->
getElement(
"Oxygen");
106 const GeoElement* Al=materialManager->
getElement(
"Aluminium");
107 const GeoElement* Ar=materialManager->
getElement(
"Argon");
108 const GeoElement* Fe=materialManager->
getElement(
"Iron");
109 const GeoElement* Cu=materialManager->
getElement(
"Copper");
110 const GeoElement* Pb=materialManager->
getElement(
"Lead");
156 double Atot=aH+aO+aC;
158 const double inv_Atot = 1. / Atot;
177 const double inv_Atot = 1. / Atot;
182 PermaliE730->add(
H,FracH);
183 PermaliE730->add(O,FracO);
184 PermaliE730->add(C,FracC);
195 const double inv_Atot = 1. / Atot;
215 const double inv_Atot = 1. / Atot;
221 Kapton->add(
H,FracH);
222 Kapton->add(O,FracO);
223 Kapton->add(C,FracC);
224 Kapton->add(
N,FracN);
232 Totalthick=Tggl+Tgfe+Tgpb;
233 m1=Tggl*Glue->getDensity();
234 m2=Tgfe*Iron->getDensity();
235 m3=Tgpb*Lead->getDensity();
236 double Totalmass=
m1+
m2+
m3;
237 density=Totalmass*(1./Totalthick);
239 const double inv_Totalmass = 1. / Totalmass;
240 Fracgl=
m1*inv_Totalmass;
241 Fracfe=
m2*inv_Totalmass;
242 Fracpb=
m3*inv_Totalmass;
244 GeoMaterial* Thin_abs =
new GeoMaterial(
name=
"Thinabs",density);
245 Thin_abs->add(Glue,Fracgl);
246 Thin_abs->add(Iron,Fracfe);
247 Thin_abs->add(Lead,Fracpb);
255 Totalthick=Thgl+Thfe+Thpb;
256 m1=Thgl*Glue->getDensity();
257 m2=Thfe*Iron->getDensity();
258 m3=Thpb*Lead->getDensity();
260 density=Totalmass*(1./Totalthick);
262 const double inv_Totalmass = 1. / Totalmass;
263 Fracgl=
m1*inv_Totalmass;
264 Fracfe=
m2*inv_Totalmass;
265 Fracpb=
m3*inv_Totalmass;
267 GeoMaterial* Thick_abs =
new GeoMaterial(
name=
"Thickabs",density);
268 Thick_abs->add(Glue,Fracgl);
269 Thick_abs->add(Iron,Fracfe);
270 Thick_abs->add(Lead,Fracpb);
277 Totalthicke = Thcu+Thka;
278 m1=Thcu*Copper->getDensity();
279 m2=Thka*Kapton->getDensity();
281 density=Totalmass*(1./Totalthicke);
283 const double inv_Totalmass = 1. / Totalmass;
284 Fraccu=
m1*inv_Totalmass;
285 Fracka=
m2*inv_Totalmass;
287 GeoMaterial* Kapton_Cu=
new GeoMaterial(
name=
"KaptonC",density);
288 Kapton_Cu->add(Copper,Fraccu);
289 Kapton_Cu->add(Kapton,Fracka);
300 const double inv_Atot = 1. / Atot;
306 Elect_LAr->add(
H ,FracH);
307 Elect_LAr->add(C ,FracC);
308 Elect_LAr->add(Ar,FracAr);
311 GeoMaterial* innerAbsorberMaterial = Thick_abs;
312 GeoMaterial* outerAbsorberMaterial = Thin_abs;
313 GeoMaterial* innerElectrodMaterial = Kapton_Cu;
314 GeoMaterial* outerElectrodMaterial = Kapton_Cu;
322 Totalthick =Thfe+Thgl+ThGten;
324 m1=Thfe *Iron->getDensity();
325 m2=Thgl *Glue->getDensity();
326 m3=ThGten*Gten->getDensity();
329 const double inv_Totalmass = 1. / Totalmass;
330 Fracfe =
m1*inv_Totalmass;
331 Fracgl =
m2*inv_Totalmass;
332 FracGten=
m3*inv_Totalmass;
334 density = Totalmass*(1./Totalthick);
336 GeoMaterial* G10FeInner=
337 new GeoMaterial(
name=
"LAr::EMEC::G10FeInner",density);
338 G10FeInner->add(Iron,Fracfe);
339 G10FeInner->add(Glue,Fracgl);
340 G10FeInner->add(Gten,FracGten);
349 Totalthick =Thfe+Thgl+ThGten;
351 m1=Thfe *Iron->getDensity();
352 m2=Thgl *Glue->getDensity();
353 m3=ThGten*Gten->getDensity();
356 const double inv_Totalmass = 1. / Totalmass;
357 Fracfe =
m1*inv_Totalmass;
358 Fracgl =
m2*inv_Totalmass;
359 FracGten=
m3*inv_Totalmass;
361 density = Totalmass*(1./Totalthick);
362 GeoMaterial* G10FeOuter=
363 new GeoMaterial(
name=
"LAr::EMEC::G10FeOuter",density);
364 G10FeOuter->add(Iron,Fracfe);
365 G10FeOuter->add(Glue,Fracgl);
366 G10FeOuter->add(Gten,FracGten);
373 std::string baseName =
"LAr::EMEC";
394 zWheelFrontFace+= dWRPtoFrontFace;
398 double Rin1, Rin2, Rout1, Rout2;
400 if ( m_isInnerWheel ) {
408 if ( m_isOuterWheel ) {
420 double emecMotherRin[] = { Rin1, Rin2 };
421 double emecMotherRout[] = { Rout1, Rout2 };
422 int lastPlaneEmec = (
sizeof( emecMotherZplan )/
sizeof(
double ) );
425 for (
int i = 0;
i < lastPlaneEmec;
i++ ) emecMotherZplan[
i ] -= zWheelFrontFace;
429 double phiPosition =
M_PI/2;
430 double phiSize =
M_PI/8 + 0.065;
443 double eta_mid = 2.5;
444 double eta_low = 1.375;
447 double tanThetaInner = 2. *
exp(-eta_hi ) / (1. -
exp(2.*-eta_hi ));
448 double tanThetaMid = 2. *
exp(-eta_mid) / (1. -
exp(2.*-eta_mid));
449 double tanThetaOuter = 2. *
exp(-eta_low) / (1. -
exp(2.*-eta_low));
456 double zWheelFrontFaceMech = dMechFocaltoWRP + dWRPtoFrontFace;
459 double zWheelBackFaceMech = zWheelFrontFaceMech + zWheelThickness;
461 double zWheelInner[2];
463 zWheelInner[1] = zWheelThickness;
466 rMinInner[0] = zWheelFrontFaceMech * tanThetaInner;
467 rMinInner[1] = zWheelBackFaceMech * tanThetaInner;
474 rMaxInner[0] = zWheelFrontFaceMech * tanThetaMid - gapBetweenWheels/2.;
475 rMaxInner[1] = zWheelBackFaceMech * tanThetaMid - gapBetweenWheels/2.;
480 double zWheelOuter[3];
481 zWheelOuter[0] = zWheelInner[0];
482 zWheelOuter[2] = zWheelInner[1];
485 rMinOuter[0] = rMaxInner[0] + gapBetweenWheels;
486 rMinOuter[2] = rMaxInner[1] + gapBetweenWheels;
489 rMaxOuter[0] = zWheelFrontFaceMech * tanThetaOuter;
490 rMaxOuter[2] = zWheelBackFaceMech * tanThetaOuter;
499 double slopeMinOuter = ( rMinOuter[2] - rMinOuter[0] )
500 / ( zWheelOuter[2] - zWheelOuter[0] );
501 double slopeMaxOuter = ( rMaxOuter[2] - rMaxOuter[0] )
502 / ( zWheelOuter[2] - zWheelOuter[0] );
503 double interceptMinOuter = rMinOuter[0] - slopeMinOuter*zWheelOuter[0];
504 double interceptMaxOuter = rMaxOuter[0] - slopeMaxOuter*zWheelOuter[0];
507 zWheelOuter[1] = ( rOuterCutoff - interceptMaxOuter ) / slopeMaxOuter;
510 rMinOuter[1] = slopeMinOuter * zWheelOuter[1] + interceptMinOuter;
511 rMaxOuter[1] = rOuterCutoff;
514 rMaxOuter[2] = rOuterCutoff;
525 std::cout<<
"InnerWheel,z(0)="<<zWheelInner[0]<<
526 " rmin="<<rMinInner[0]<<
" rmax="<<rMaxInner[0]<<std::endl;
527 std::cout<<
" z(1)="<<zWheelInner[1]<<
528 " rmin="<<rMinInner[1]<<
" rmax="<<rMaxInner[1]<<std::endl;
529 std::cout<<
"OuterWheel,z(0)="<<zWheelOuter[0]<<
530 " rmin="<<rMinOuter[0]<<
" rmax="<<rMaxOuter[0]<<std::endl;
531 std::cout<<
" z(1)="<<zWheelOuter[1]<<
532 " rmin="<<rMinOuter[1]<<
" rmax="<<rMaxOuter[1]<<std::endl;
533 std::cout<<
" z(2)="<<zWheelOuter[2]<<
534 " rmin="<<rMinOuter[2]<<
" rmax="<<rMaxOuter[2]<<std::endl;
541 std::string emecMotherName = baseName +
"::Mother";
543 GeoPcon* emecMotherShape =
new GeoPcon( phiPosition - phiSize, 2.*phiSize );
544 for(
int i = 0;
i < lastPlaneEmec;
i++ ) emecMotherShape->addPlane( emecMotherZplan[
i],
547 const GeoLogVol* emecMotherLogical =
new GeoLogVol( emecMotherName, emecMotherShape,
LAr );
548 GeoIntrusivePtr<GeoFullPhysVol> emecMotherPhysical =
new GeoFullPhysVol( emecMotherLogical );
550 if ( m_isInnerWheel ) {
551 std::string innerName = baseName +
"::InnerWheel";
552 GeoPcon* innerShape=
new GeoPcon( phiPosition - phiSize, 2.*phiSize );
553 innerShape->addPlane( zWheelInner[0], rMinInner[0], rMaxInner[0] );
554 innerShape->addPlane( zWheelInner[1], rMinInner[1], rMaxInner[1] );
555 GeoLogVol* innerLogical =
new GeoLogVol ( innerName, innerShape,
LAr );
556 GeoIntrusivePtr<GeoFullPhysVol> innerPhysical =
new GeoFullPhysVol( innerLogical );
557 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
558 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D( zWheelFrontFace ) ) );
559 emecMotherPhysical->add( innerPhysical );
563 std::string IAWname = innerName +
"::Absorber";
564 std::string IEWname = innerName +
"::Electrode";
566 GeoUnidentifiedShape* innerAbsorberShape =
new GeoUnidentifiedShape(
"LArCustomShape",IAWname);
567 GeoUnidentifiedShape* innerElectrodeShape =
new GeoUnidentifiedShape(
"LArCustomShape", IEWname);
569 GeoLogVol* innerAbsorberLogical =
570 new GeoLogVol( IAWname, innerAbsorberShape , innerAbsorberMaterial );
571 GeoLogVol* innerElectrodeLogical =
572 new GeoLogVol( IEWname, innerElectrodeShape, innerElectrodMaterial );
574 GeoIntrusivePtr<GeoFullPhysVol> innerAbsorberPhysical =
new GeoFullPhysVol( innerAbsorberLogical );
575 GeoIntrusivePtr<GeoPhysVol> innerElectrodePhysical =
new GeoPhysVol( innerElectrodeLogical );
576 innerPhysical->add(
new GeoIdentifierTag( 1 ) );
577 innerPhysical->add( innerAbsorberPhysical );
578 innerPhysical->add(
new GeoIdentifierTag( 1 ) );
579 innerPhysical->add( innerElectrodePhysical );
583 if(!
status.isSuccess())
throw std::runtime_error (
"Cannot store EMEC_INNER_WHEEL");
587 if ( m_isOuterWheel ) {
588 std::string outerName = baseName +
"::OuterWheel";
589 GeoPcon* outerShape=
new GeoPcon( phiPosition - phiSize, 2.*phiSize );
590 outerShape->addPlane( zWheelOuter[0], rMinOuter[0], rMaxOuter[0] );
591 outerShape->addPlane( zWheelOuter[1], rMinOuter[1], rMaxOuter[1] );
592 outerShape->addPlane( zWheelOuter[2], rMinOuter[2], rMaxOuter[2] );
593 GeoLogVol* outerLogical =
new GeoLogVol ( outerName, outerShape,
LAr );
594 GeoIntrusivePtr<GeoFullPhysVol> outerPhysical =
new GeoFullPhysVol(outerLogical);
595 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
596 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D( zWheelFrontFace ) ) );
597 emecMotherPhysical->add( outerPhysical );
601 std::string OAWname = outerName +
"::Absorber";
602 std::string OEWname = outerName +
"::Electrode";
604 GeoUnidentifiedShape* outerAbsorberShape =
new GeoUnidentifiedShape(
"LArCustomShape", OAWname );
605 GeoUnidentifiedShape* outerElectrodeShape =
new GeoUnidentifiedShape(
"LArCustomShape", OEWname );
607 GeoLogVol* outerAbsorberLogical =
608 new GeoLogVol( OAWname,outerAbsorberShape ,outerAbsorberMaterial );
609 GeoLogVol* outerElectrodeLogical =
610 new GeoLogVol( OEWname,outerElectrodeShape, outerElectrodMaterial );
612 GeoIntrusivePtr<GeoPhysVol> outerAbsorberPhysical =
new GeoPhysVol( outerAbsorberLogical );
613 GeoIntrusivePtr<GeoPhysVol> outerElectrodePhysical =
new GeoPhysVol( outerElectrodeLogical );
614 outerPhysical->add(
new GeoIdentifierTag( 1 ) );
615 outerPhysical->add( outerAbsorberPhysical);
616 outerPhysical->add(
new GeoIdentifierTag( 1 ) );
617 outerPhysical->add( outerElectrodePhysical );
621 if(!
status.isSuccess())
throw std::runtime_error (
"Cannot store EMEC_OUTER_WHEEL");
643 if ( m_isInnerWheel && ! m_isOuterWheel ) {
647 else if ( m_isOuterWheel && ! m_isInnerWheel ) {
656 GeoIntrusivePtr<GeoPhysVol> physicalFSM = fsc->
GetEnvelope();
657 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
658 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) );
659 emecMotherPhysical->add( physicalFSM );
663 GeoIntrusivePtr<GeoPhysVol>physicalBSM = bsc->
GetEnvelope();
664 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
666 emecMotherPhysical->add(
new GeoTransform(
GeoTrf::Transform3D(GeoTrf::Translate3D( 0., 0.,
z0 )*rotBSM ) ) );
667 emecMotherPhysical->add( physicalBSM );
669 if ( m_isOuterWheel ) {
672 GeoIntrusivePtr<GeoPhysVol>physicalOSM =
osc->GetEnvelope();
673 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
674 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) );
675 emecMotherPhysical->add( physicalOSM );
678 if ( m_isInnerWheel ) {
681 GeoIntrusivePtr<GeoPhysVol>physicalISM = isc->
GetEnvelope();
682 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
683 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) ) ;
684 emecMotherPhysical->add( physicalISM );
689 GeoIntrusivePtr<GeoPhysVol>physicalMSM = msc->
GetEnvelope();
690 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
691 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) ) ;
692 emecMotherPhysical->add( physicalMSM );
694 return emecMotherPhysical;