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 =
true;
77 ISvcLocator *svcLocator = Gaudi::svcLocator();
79 if (svcLocator->service(
"DetectorStore",
detStore,
false )==StatusCode::FAILURE) {
80 throw std::runtime_error(
"Error in EndcapCryostatConstruction, cannot access DetectorStore");
83 if (StatusCode::SUCCESS !=
detStore->retrieve(materialManager, std::string(
"MATERIALS")))
return nullptr;
93 std::string
name,symbol;
97 double Totalthick,Totalthicke;
98 double Tgpb,Tgfe,Tggl,Thpb,Thfe,Thgl,Thcu,Thka,ThGten;
99 double FracH,FracO,FracC,FracN,FracAr;
100 double FracGten,Fracpb,Fracfe,Fracgl,Fraccu,Fracka;
101 double aH,aO,aC,aN,aAr;
103 const GeoElement*
H=materialManager->
getElement(
"Hydrogen");
104 const GeoElement* C=materialManager->
getElement(
"Carbon");
105 const GeoElement*
N=materialManager->
getElement(
"Nitrogen");
106 const GeoElement* O=materialManager->
getElement(
"Oxygen");
107 const GeoElement* Al=materialManager->
getElement(
"Aluminium");
108 const GeoElement* Ar=materialManager->
getElement(
"Argon");
109 const GeoElement* Fe=materialManager->
getElement(
"Iron");
110 const GeoElement* Cu=materialManager->
getElement(
"Copper");
111 const GeoElement* Pb=materialManager->
getElement(
"Lead");
157 double Atot=aH+aO+aC;
159 const double inv_Atot = 1. / Atot;
178 const double inv_Atot = 1. / Atot;
183 PermaliE730->add(
H,FracH);
184 PermaliE730->add(O,FracO);
185 PermaliE730->add(C,FracC);
196 const double inv_Atot = 1. / Atot;
216 const double inv_Atot = 1. / Atot;
222 Kapton->add(
H,FracH);
223 Kapton->add(O,FracO);
224 Kapton->add(C,FracC);
225 Kapton->add(
N,FracN);
233 Totalthick=Tggl+Tgfe+Tgpb;
234 m1=Tggl*Glue->getDensity();
235 m2=Tgfe*Iron->getDensity();
236 m3=Tgpb*Lead->getDensity();
237 double Totalmass=
m1+
m2+
m3;
238 density=Totalmass*(1./Totalthick);
240 const double inv_Totalmass = 1. / Totalmass;
241 Fracgl=
m1*inv_Totalmass;
242 Fracfe=
m2*inv_Totalmass;
243 Fracpb=
m3*inv_Totalmass;
245 GeoMaterial* Thin_abs =
new GeoMaterial(
name=
"Thinabs",density);
246 Thin_abs->add(Glue,Fracgl);
247 Thin_abs->add(Iron,Fracfe);
248 Thin_abs->add(Lead,Fracpb);
256 Totalthick=Thgl+Thfe+Thpb;
257 m1=Thgl*Glue->getDensity();
258 m2=Thfe*Iron->getDensity();
259 m3=Thpb*Lead->getDensity();
261 density=Totalmass*(1./Totalthick);
263 const double inv_Totalmass = 1. / Totalmass;
264 Fracgl=
m1*inv_Totalmass;
265 Fracfe=
m2*inv_Totalmass;
266 Fracpb=
m3*inv_Totalmass;
268 GeoMaterial* Thick_abs =
new GeoMaterial(
name=
"Thickabs",density);
269 Thick_abs->add(Glue,Fracgl);
270 Thick_abs->add(Iron,Fracfe);
271 Thick_abs->add(Lead,Fracpb);
278 Totalthicke = Thcu+Thka;
279 m1=Thcu*Copper->getDensity();
280 m2=Thka*Kapton->getDensity();
282 density=Totalmass*(1./Totalthicke);
284 const double inv_Totalmass = 1. / Totalmass;
285 Fraccu=
m1*inv_Totalmass;
286 Fracka=
m2*inv_Totalmass;
288 GeoMaterial* Kapton_Cu=
new GeoMaterial(
name=
"KaptonC",density);
289 Kapton_Cu->add(Copper,Fraccu);
290 Kapton_Cu->add(Kapton,Fracka);
301 const double inv_Atot = 1. / Atot;
307 Elect_LAr->add(
H ,FracH);
308 Elect_LAr->add(C ,FracC);
309 Elect_LAr->add(Ar,FracAr);
312 GeoMaterial* innerAbsorberMaterial = Thick_abs;
313 GeoMaterial* outerAbsorberMaterial = Thin_abs;
314 GeoMaterial* innerElectrodMaterial = Kapton_Cu;
315 GeoMaterial* outerElectrodMaterial = Kapton_Cu;
323 Totalthick =Thfe+Thgl+ThGten;
325 m1=Thfe *Iron->getDensity();
326 m2=Thgl *Glue->getDensity();
327 m3=ThGten*Gten->getDensity();
330 const double inv_Totalmass = 1. / Totalmass;
331 Fracfe =
m1*inv_Totalmass;
332 Fracgl =
m2*inv_Totalmass;
333 FracGten=
m3*inv_Totalmass;
335 density = Totalmass*(1./Totalthick);
337 GeoMaterial* G10FeInner=
338 new GeoMaterial(
name=
"LAr::EMEC::G10FeInner",density);
339 G10FeInner->add(Iron,Fracfe);
340 G10FeInner->add(Glue,Fracgl);
341 G10FeInner->add(Gten,FracGten);
350 Totalthick =Thfe+Thgl+ThGten;
352 m1=Thfe *Iron->getDensity();
353 m2=Thgl *Glue->getDensity();
354 m3=ThGten*Gten->getDensity();
357 const double inv_Totalmass = 1. / Totalmass;
358 Fracfe =
m1*inv_Totalmass;
359 Fracgl =
m2*inv_Totalmass;
360 FracGten=
m3*inv_Totalmass;
362 density = Totalmass*(1./Totalthick);
363 GeoMaterial* G10FeOuter=
364 new GeoMaterial(
name=
"LAr::EMEC::G10FeOuter",density);
365 G10FeOuter->add(Iron,Fracfe);
366 G10FeOuter->add(Glue,Fracgl);
367 G10FeOuter->add(Gten,FracGten);
374 std::string baseName =
"LAr::EMEC";
395 zWheelFrontFace+= dWRPtoFrontFace;
399 double Rin1, Rin2, Rout1, Rout2;
401 if ( m_isInnerWheel ) {
409 if ( m_isOuterWheel ) {
421 double emecMotherRin[] = { Rin1, Rin2 };
422 double emecMotherRout[] = { Rout1, Rout2 };
423 int lastPlaneEmec = (
sizeof( emecMotherZplan )/
sizeof(
double ) );
426 for (
int i = 0;
i < lastPlaneEmec;
i++ ) emecMotherZplan[
i ] -= zWheelFrontFace;
430 double phiPosition =
M_PI/2;
431 double phiSize =
M_PI/8 + 0.065;
444 double eta_mid = 2.5;
445 double eta_low = 1.375;
448 double tanThetaInner = 2. *
exp(-eta_hi ) / (1. -
exp(2.*-eta_hi ));
449 double tanThetaMid = 2. *
exp(-eta_mid) / (1. -
exp(2.*-eta_mid));
450 double tanThetaOuter = 2. *
exp(-eta_low) / (1. -
exp(2.*-eta_low));
457 double zWheelFrontFaceMech = dMechFocaltoWRP + dWRPtoFrontFace;
460 double zWheelBackFaceMech = zWheelFrontFaceMech + zWheelThickness;
462 double zWheelInner[2];
464 zWheelInner[1] = zWheelThickness;
467 rMinInner[0] = zWheelFrontFaceMech * tanThetaInner;
468 rMinInner[1] = zWheelBackFaceMech * tanThetaInner;
475 rMaxInner[0] = zWheelFrontFaceMech * tanThetaMid - gapBetweenWheels/2.;
476 rMaxInner[1] = zWheelBackFaceMech * tanThetaMid - gapBetweenWheels/2.;
481 double zWheelOuter[3];
482 zWheelOuter[0] = zWheelInner[0];
483 zWheelOuter[2] = zWheelInner[1];
486 rMinOuter[0] = rMaxInner[0] + gapBetweenWheels;
487 rMinOuter[2] = rMaxInner[1] + gapBetweenWheels;
490 rMaxOuter[0] = zWheelFrontFaceMech * tanThetaOuter;
491 rMaxOuter[2] = zWheelBackFaceMech * tanThetaOuter;
500 double slopeMinOuter = ( rMinOuter[2] - rMinOuter[0] )
501 / ( zWheelOuter[2] - zWheelOuter[0] );
502 double slopeMaxOuter = ( rMaxOuter[2] - rMaxOuter[0] )
503 / ( zWheelOuter[2] - zWheelOuter[0] );
504 double interceptMinOuter = rMinOuter[0] - slopeMinOuter*zWheelOuter[0];
505 double interceptMaxOuter = rMaxOuter[0] - slopeMaxOuter*zWheelOuter[0];
508 zWheelOuter[1] = ( rOuterCutoff - interceptMaxOuter ) / slopeMaxOuter;
511 rMinOuter[1] = slopeMinOuter * zWheelOuter[1] + interceptMinOuter;
512 rMaxOuter[1] = rOuterCutoff;
515 rMaxOuter[2] = rOuterCutoff;
526 std::cout<<
"InnerWheel,z(0)="<<zWheelInner[0]<<
527 " rmin="<<rMinInner[0]<<
" rmax="<<rMaxInner[0]<<std::endl;
528 std::cout<<
" z(1)="<<zWheelInner[1]<<
529 " rmin="<<rMinInner[1]<<
" rmax="<<rMaxInner[1]<<std::endl;
530 std::cout<<
"OuterWheel,z(0)="<<zWheelOuter[0]<<
531 " rmin="<<rMinOuter[0]<<
" rmax="<<rMaxOuter[0]<<std::endl;
532 std::cout<<
" z(1)="<<zWheelOuter[1]<<
533 " rmin="<<rMinOuter[1]<<
" rmax="<<rMaxOuter[1]<<std::endl;
534 std::cout<<
" z(2)="<<zWheelOuter[2]<<
535 " rmin="<<rMinOuter[2]<<
" rmax="<<rMaxOuter[2]<<std::endl;
542 std::string emecMotherName = baseName +
"::Mother";
544 GeoPcon* emecMotherShape =
new GeoPcon( phiPosition - phiSize, 2.*phiSize );
545 for(
int i = 0;
i < lastPlaneEmec;
i++ ) emecMotherShape->addPlane( emecMotherZplan[
i],
548 const GeoLogVol* emecMotherLogical =
new GeoLogVol( emecMotherName, emecMotherShape,
LAr );
549 GeoIntrusivePtr<GeoFullPhysVol> emecMotherPhysical =
new GeoFullPhysVol( emecMotherLogical );
551 if ( m_isInnerWheel ) {
552 std::string innerName = baseName +
"::InnerWheel";
553 GeoPcon* innerShape=
new GeoPcon( phiPosition - phiSize, 2.*phiSize );
554 innerShape->addPlane( zWheelInner[0], rMinInner[0], rMaxInner[0] );
555 innerShape->addPlane( zWheelInner[1], rMinInner[1], rMaxInner[1] );
556 GeoLogVol* innerLogical =
new GeoLogVol ( innerName, innerShape,
LAr );
557 GeoIntrusivePtr<GeoFullPhysVol> innerPhysical =
new GeoFullPhysVol( innerLogical );
558 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
559 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D( zWheelFrontFace ) ) );
560 emecMotherPhysical->add( innerPhysical );
564 std::string IAWname = innerName +
"::Absorber";
565 std::string IEWname = innerName +
"::Electrode";
567 GeoUnidentifiedShape* innerAbsorberShape =
new GeoUnidentifiedShape(
"LArCustomShape",IAWname);
568 GeoUnidentifiedShape* innerElectrodeShape =
new GeoUnidentifiedShape(
"LArCustomShape", IEWname);
570 GeoLogVol* innerAbsorberLogical =
571 new GeoLogVol( IAWname, innerAbsorberShape , innerAbsorberMaterial );
572 GeoLogVol* innerElectrodeLogical =
573 new GeoLogVol( IEWname, innerElectrodeShape, innerElectrodMaterial );
575 GeoIntrusivePtr<GeoFullPhysVol> innerAbsorberPhysical =
new GeoFullPhysVol( innerAbsorberLogical );
576 GeoIntrusivePtr<GeoPhysVol> innerElectrodePhysical =
new GeoPhysVol( innerElectrodeLogical );
577 innerPhysical->add(
new GeoIdentifierTag( 1 ) );
578 innerPhysical->add( innerAbsorberPhysical );
579 innerPhysical->add(
new GeoIdentifierTag( 1 ) );
580 innerPhysical->add( innerElectrodePhysical );
584 if(!
status.isSuccess())
throw std::runtime_error (
"Cannot store EMEC_INNER_WHEEL");
588 if ( m_isOuterWheel ) {
589 std::string outerName = baseName +
"::OuterWheel";
590 GeoPcon* outerShape=
new GeoPcon( phiPosition - phiSize, 2.*phiSize );
591 outerShape->addPlane( zWheelOuter[0], rMinOuter[0], rMaxOuter[0] );
592 outerShape->addPlane( zWheelOuter[1], rMinOuter[1], rMaxOuter[1] );
593 outerShape->addPlane( zWheelOuter[2], rMinOuter[2], rMaxOuter[2] );
594 GeoLogVol* outerLogical =
new GeoLogVol ( outerName, outerShape,
LAr );
595 GeoIntrusivePtr<GeoFullPhysVol> outerPhysical =
new GeoFullPhysVol(outerLogical);
596 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
597 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D( zWheelFrontFace ) ) );
598 emecMotherPhysical->add( outerPhysical );
602 std::string OAWname = outerName +
"::Absorber";
603 std::string OEWname = outerName +
"::Electrode";
605 GeoUnidentifiedShape* outerAbsorberShape =
new GeoUnidentifiedShape(
"LArCustomShape", OAWname );
606 GeoUnidentifiedShape* outerElectrodeShape =
new GeoUnidentifiedShape(
"LArCustomShape", OEWname );
608 GeoLogVol* outerAbsorberLogical =
609 new GeoLogVol( OAWname,outerAbsorberShape ,outerAbsorberMaterial );
610 GeoLogVol* outerElectrodeLogical =
611 new GeoLogVol( OEWname,outerElectrodeShape, outerElectrodMaterial );
613 GeoIntrusivePtr<GeoPhysVol> outerAbsorberPhysical =
new GeoPhysVol( outerAbsorberLogical );
614 GeoIntrusivePtr<GeoPhysVol> outerElectrodePhysical =
new GeoPhysVol( outerElectrodeLogical );
615 outerPhysical->add(
new GeoIdentifierTag( 1 ) );
616 outerPhysical->add( outerAbsorberPhysical);
617 outerPhysical->add(
new GeoIdentifierTag( 1 ) );
618 outerPhysical->add( outerElectrodePhysical );
622 if(!
status.isSuccess())
throw std::runtime_error (
"Cannot store EMEC_OUTER_WHEEL");
644 if ( m_isInnerWheel && ! m_isOuterWheel ) {
648 else if ( m_isOuterWheel && ! m_isInnerWheel ) {
657 GeoIntrusivePtr<GeoPhysVol> physicalFSM = fsc->
GetEnvelope();
658 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
659 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) );
660 emecMotherPhysical->add( physicalFSM );
664 GeoIntrusivePtr<GeoPhysVol>physicalBSM = bsc->
GetEnvelope();
665 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
667 emecMotherPhysical->add(
new GeoTransform(
GeoTrf::Transform3D(GeoTrf::Translate3D( 0., 0.,
z0 )*rotBSM ) ) );
668 emecMotherPhysical->add( physicalBSM );
670 if ( m_isOuterWheel ) {
673 GeoIntrusivePtr<GeoPhysVol>physicalOSM =
osc->GetEnvelope();
674 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
675 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) );
676 emecMotherPhysical->add( physicalOSM );
679 if ( m_isInnerWheel ) {
682 GeoIntrusivePtr<GeoPhysVol>physicalISM = isc->
GetEnvelope();
683 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
684 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) ) ;
685 emecMotherPhysical->add( physicalISM );
690 GeoIntrusivePtr<GeoPhysVol>physicalMSM = msc->
GetEnvelope();
691 emecMotherPhysical->add(
new GeoIdentifierTag( 1 ) );
692 emecMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(
z0 ) ) ) ;
693 emecMotherPhysical->add( physicalMSM );
695 return emecMotherPhysical;