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;