17 #include "GeoModelKernel/GeoElement.h"
18 #include "GeoModelKernel/GeoMaterial.h"
19 #include "GeoModelKernel/GeoFullPhysVol.h"
20 #include "GeoModelKernel/GeoPhysVol.h"
21 #include "GeoModelKernel/GeoVPhysVol.h"
22 #include "GeoModelKernel/GeoLogVol.h"
23 #include "GeoModelKernel/GeoPcon.h"
24 #include "GeoModelKernel/GeoTubs.h"
25 #include "GeoModelKernel/GeoTube.h"
26 #include "GeoModelKernel/GeoTrd.h"
27 #include "GeoModelKernel/GeoNameTag.h"
28 #include "GeoModelKernel/GeoTransform.h"
29 #include "GeoModelKernel/GeoAlignableTransform.h"
30 #include "GeoModelKernel/GeoIdentifierTag.h"
31 #include "GeoModelKernel/GeoSerialIdentifier.h"
32 #include "GeoModelKernel/GeoXF.h"
33 #include "GeoModelKernel/GeoSerialTransformer.h"
34 #include "GeoModelKernel/GeoShapeSubtraction.h"
35 #include "GeoModelKernel/GeoDefinitions.h"
42 #include "GeoModelKernel/GeoShapeUnion.h"
43 #include "GeoModelKernel/GeoShapeShift.h"
45 #include "GeoGenericFunctions/AbsFunction.h"
46 #include "GeoGenericFunctions/Variable.h"
53 #include "GaudiKernel/MsgStream.h"
54 #include "GaudiKernel/Bootstrap.h"
55 #include "GaudiKernel/SystemOfUnits.h"
66 using namespace GeoXF;
72 using planeIndMap = std::map<int, unsigned int, std::less<int>>;
76 , std::string emecVariantInner
77 , std::string emecVariantOuter
82 m_EMECVariantInner(std::move(emecVariantInner)),
83 m_EMECVariantOuter(std::move(emecVariantOuter)),
84 m_activateFT(activateFT),
85 m_enableMBTS(enableMBTS)
96 SmartIF<StoreGateSvc>
detStore{Gaudi::svcLocator()->service(
"DetectorStore")};
98 throw std::runtime_error(
"Error in EndcapCryostatConstruction, cannot access DetectorStore");
104 if (StatusCode::SUCCESS !=
detStore->retrieve(materialManager, std::string(
"MATERIALS")))
return nullptr;
106 const GeoMaterial *Lead = materialManager->
getMaterial(
"std::Lead");
108 throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::Lead is not found.");
111 const GeoMaterial *Air = materialManager->
getMaterial(
"std::Air");
113 throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::Air is not found.");
116 const GeoMaterial *Al = materialManager->
getMaterial(
"std::Aluminium");
118 throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::Aluminium is not found.");
121 const GeoMaterial *
LAr = materialManager->
getMaterial(
"std::LiquidArgon");
123 throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::LiquidArgon is not found.");
126 const GeoMaterial *G10 = materialManager->
getMaterial(
"LAr::G10");
127 if (!G10)
throw std::runtime_error(
"Error in EndcapCryostatConstruction, LAr::G10 is not found.");
129 const GeoMaterial *Copper = materialManager->
getMaterial(
"std::Copper");
130 if (!Copper)
throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::Copper is not found.");
132 const GeoMaterial *Iron = materialManager->
getMaterial(
"std::Iron");
133 if (!Iron)
throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::Iron is not found.");
135 const GeoMaterial *Polystyrene = materialManager->
getMaterial(
"std::Polystyrene");
136 if (!Polystyrene)
throw std::runtime_error(
"Error in EndcapCryostatConstruction, std::Polystyrene is not found.");
140 SmartIF<IGeoModelSvc> geoModelSvc{Gaudi::svcLocator()->service(
"GeoModelSvc")};
141 if(!geoModelSvc.isValid())
throw std::runtime_error(
"Cannot locate GeoModelSvc!");
144 std::string LArVersion = geoModelSvc->LAr_VersionOverride();
146 std::string detectorKey = LArVersion.empty() ?
AtlasVersion : LArVersion;
147 std::string detectorNode = LArVersion.empty() ?
"ATLAS" :
"LAr";
149 SmartIF<IRDBAccessSvc> rdbAccessSvc{Gaudi::svcLocator()->service(
"RDBAccessSvc")};
150 if(!rdbAccessSvc.isValid()) {
151 throw std::runtime_error (
"Cannot locate RDBAccessSvc!!");
154 IRDBRecordset_ptr cryoCylinders = rdbAccessSvc->getRecordsetPtr(
"CryoCylinders",detectorKey, detectorNode);
155 IRDBRecordset_ptr larPosition = rdbAccessSvc->getRecordsetPtr(
"LArPosition",detectorKey, detectorNode);
156 if (larPosition->size()==0 ) {
157 larPosition = rdbAccessSvc->getRecordsetPtr(
"LArPosition",
"LArPosition-00");
158 if (larPosition->size()==0 ) {
159 throw std::runtime_error(
"Error, no lar position table in database!");
166 if(cryoCylinders->size()==0) cryoCylinders = rdbAccessSvc->getRecordsetPtr(
"CryoCylinders",
"CryoCylinders-00");
169 IRDBRecordset_ptr cryoPcons = rdbAccessSvc->getRecordsetPtr(
"CryoPcons",detectorKey, detectorNode);
170 if(cryoPcons->size()==0) cryoPcons = rdbAccessSvc->getRecordsetPtr(
"CryoPcons",
"CryoPcons-00");
172 planeIndMap cryoMotherPlanes, emhPlanes, fcalNosePlanes;
173 std::vector<planeIndMap> brassPlugPlanesVect;
174 brassPlugPlanesVect.emplace_back();
175 brassPlugPlanesVect.emplace_back();
176 planeIndMap::const_iterator iter;
178 for (
unsigned int ind=0;
ind<cryoPcons->size();
ind++)
180 int key = (*cryoPcons)[
ind]->getInt(
"PLANE_ID");
181 const std::string& pconName = (*cryoPcons)[
ind]->getString(
"PCON");
182 if(pconName==
"Endcap::CryoMother") {
183 cryoMotherPlanes[
key] =
ind;
185 else if(pconName==
"Endcap::EMH") {
188 else if(pconName==
"Endcap::FcalNose") {
189 fcalNosePlanes[
key] =
ind;
191 else if(pconName==
"Endcap::BrassPlug1") {
192 brassPlugPlanesVect[0][
key] =
ind;
194 else if(pconName==
"Endcap::BrassPlug2") {
195 brassPlugPlanesVect[1][
key] =
ind;
205 std::string baseName =
"LAr::Endcap::Cryostat";
216 std::string cryoMotherName = baseName +
"::MotherVolume";
217 GeoPcon* cryoMotherShape =
new GeoPcon(0.,2.*
M_PI);
219 double zStartCryoMother = 0.;
221 for(
unsigned int ind = 0;
ind < cryoMotherPlanes.size(); ++
ind){
222 iter = cryoMotherPlanes.find(
ind);
223 if(iter == cryoMotherPlanes.end()){
224 throw std::runtime_error(
225 "Error in EndcapCryostatConstruction, missing plane in Endcap Cryo Mother"
228 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
229 double zplane = currentRecord->
getDouble(
"ZPLANE");
230 double rmin = currentRecord->
getDouble(
"RMIN");
231 double rmax = currentRecord->
getDouble(
"RMAX");
237 <<
" at " << zplane <<
" to accomodate FEC" <<
endmsg;
242 <<
" at " << rmax <<
" to accomodate FT Chimney" <<
endmsg;
245 cryoMotherShape->addPlane(zplane, rmin, rmax);
246 if(
ind == 0) zStartCryoMother = zplane;
250 const GeoLogVol* cryoMotherLogical =
new GeoLogVol(cryoMotherName, cryoMotherShape, Air);
251 GeoIntrusivePtr<GeoFullPhysVol> cryoMotherPhysical{
new GeoFullPhysVol(cryoMotherLogical)};
262 IRDBRecordset_ptr cryoExtraCyl = rdbAccessSvc->getRecordsetPtr(
"LArCones",detectorKey, detectorNode);
264 if(m_fullGeo && cryoCylinders->size()>0){
265 unsigned int nextra=cryoExtraCyl->size();
269 for(
unsigned int i=0;
i<nextra;
i++){
270 const std::string&
name=(*cryoExtraCyl)[
i]->getString(
"CONE");
271 if(
name.find(
"EmecCylBeforePS") != std::string::npos){
272 double rmin=(*cryoExtraCyl)[
i]->getDouble(
"RMIN1");
273 double rmax=(*cryoExtraCyl)[
i]->getDouble(
"RMAX1");
274 double dz = (*cryoExtraCyl)[
i]->getDouble(
"DZ");
277 double rmin_warm=0.,rmax_warm=0.,dz_warm=0.,zInCryostat_warm=0.;
278 double rmin_cold=0.,rmax_cold=0.,dz_cold=0.,zInCryostat_cold=0.;
283 int cylNumber = currentRecord->
getInt(
"CYL_NUMBER");
284 if(currentRecord->
getString(
"CYL_LOCATION")==
"Endcap"){
304 double maxdz=(zInCryostat_cold-dz_cold)-(zInCryostat_warm+dz_warm);
305 if(dz>maxdz) dz=maxdz;
306 double zpos=((zInCryostat_cold-dz_cold)+(zInCryostat_warm+dz_warm))/2.;
308 std::ostringstream cylStream;
309 cylStream << baseName <<
"::ExtraCyl";
310 std::string cylName = cylStream.str();
311 cylName = cylName +
"_beforePS";
313 double phi0=(*cryoExtraCyl)[
i]->getDouble(
"PHI0");
314 double dphi=(*cryoExtraCyl)[
i]->getDouble(
"DPHI");
315 if(dphi>6.28) dphi=2.*
M_PI;
316 const std::string& material=(*cryoExtraCyl)[
i]->getString(
"MATERIAL");
319 throw std::runtime_error(
"Error in EndcapCryostatConstruction,material for CylBeforePS is not found.");
322 GeoTubs *solidCyl =
new GeoTubs(rmin,rmax,dz/2.,
phi0,dphi);
323 const GeoLogVol *logicCyl =
new GeoLogVol(cylName,solidCyl,
mat);
324 GeoPhysVol *physCyl =
new GeoPhysVol(logicCyl);
326 cryoMotherPhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(zpos)));
327 cryoMotherPhysical->add(physCyl);
329 std::cout<<
"**************************************************"<<std::endl;
330 std::cout<<
"EndcapCryostatConstruction insert extra material between warm and cold wall of cryo at front of PS::"<<std::endl;
331 std::cout<<
" ExtraCyl params: name,mat= "<<cylName<<
" "<<
mat->getName()
332 <<
" rmin,rmax,dzthick,zpos="<<rmin<<
" "<<rmax<<
" "<<dz<<
" "<<zpos
333 <<
" PhiStart,PhiSize="<<
phi0<<
" "<<dphi
336 std::cout<<
" warm cyl params: rmin,rmax,dzthick,zpos="<<rmin_warm<<
" "<<rmax_warm<<
" "<<2.*dz_warm<<
" "
337 <<zInCryostat_warm<<std::endl;
338 std::cout<<
" cold cyl params: rmin,rmax,dzthick,zpos="<<rmin_cold<<
" "<<rmax_cold<<
" "<<2.*dz_cold<<
" "
339 <<zInCryostat_cold<<std::endl;
340 std::cout<<
"**************************************************"<<std::endl;
357 IRDBRecordset_ptr LArEndcapCratePhiPos = rdbAccessSvc->getRecordsetPtr(
"LArEndcapCratePhiPos",detectorKey, detectorNode);
362 int cylNumber = currentRecord->
getInt(
"CYL_NUMBER");
363 if(m_fullGeo || cylNumber == 14 || cylNumber == 100) {
366 if(currentRecord->
getString(
"CYL_LOCATION")==
"Endcap") {
367 std::ostringstream cylStream;
368 cylStream << baseName <<
"::Cylinder";
369 std::string cylName = (cylNumber == 100?
"JDSH_AddShield_Inner":cylStream.str());
372 const std::string& qualifier = currentRecord->
getString(
"QUALIFIER");
373 if (!qualifier.empty()) cylName = cylName +
"::" + qualifier;
376 const GeoShape* solidCyl =
new GeoTubs(
383 const GeoMaterial *material = materialManager->
getMaterial(currentRecord->
getString(
"MATERIAL"));
386 std::ostringstream errorMessage;
387 errorMessage <<
"Error in EndcapCrysostat Construction" << std::endl;
388 errorMessage <<
"Material " << currentRecord->
getString(
"MATERIAL") <<
" is not found" << std::endl;
389 throw std::runtime_error(errorMessage.str().c_str());
394 log <<
MSG::DEBUG <<
"Cut holes for feedthroughs in warm wall "
402 GeoTube *warmhole =
new GeoTube(0., warmhole_radius, (rmax - rmin) * 4);
404 const double r = (rmin + rmax) * 0.5;
405 const GeoShape* warmwall = solidCyl;
407 auto put = [&warmwall, &warmhole_pos, &
r, &
h1](
double pos){
409 warmwall = &(warmwall->subtract(
410 h1 << GeoTrf::Translate3D(
x,
y, warmhole_pos)
414 for(
unsigned int i{0};
i < LArEndcapCratePhiPos->size(); ++
i){
415 const int num = (*LArEndcapCratePhiPos)[
i]->getInt(
"CRATENUM");
425 }
else if(cylNumber == 20){
426 log <<
MSG::DEBUG <<
"Cut holes for feedthroughs in cold wall "
433 GeoTube *coldhole =
new GeoTube(0., coldhole_radius, (rmax - rmin) * 4);
435 const double r = (rmin + rmax) * 0.5;
436 const GeoShape *coldwall = solidCyl;
438 auto put = [&coldwall, &coldhole_pos, &
r, &
h1](
double pos){
440 coldwall = &(coldwall->subtract(
441 h1 << GeoTrf::Translate3D(
x,
y, coldhole_pos)
445 for(
unsigned int i{0};
i < LArEndcapCratePhiPos->size(); ++
i){
446 const int num = (*LArEndcapCratePhiPos)[
i]->getInt(
"CRATENUM");
459 const GeoLogVol* logicCyl =
new GeoLogVol(cylName,solidCyl,material);
460 GeoIntrusivePtr<GeoPhysVol> physCyl =
new GeoPhysVol(logicCyl);
470 cryoMotherPhysical->add(
new GeoIdentifierTag(cylNumber));
471 cryoMotherPhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
474 if ( cylNumber == 14 ) {
476 cryoMotherPhysical->add(
new GeoNameTag(cylName +
"::PresamplerMother") );
480 GeoIntrusivePtr<GeoFullPhysVol> emecPSEnvelope = endcapPresamplerConstruction.
Envelope();
481 if (emecPSEnvelope) {
489 GeoTransform *xfPs =
new GeoTransform(GeoTrf::TranslateZ3D(Zpos));
492 physCyl->add( emecPSEnvelope );
494 std::string
tag = bPos? std::string(
"PRESAMPLER_EC_POS") : std::string(
"PRESAMPLER_EC_NEG");
499 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
504 cryoMotherPhysical->add(physCyl);
512 if (!fcalNosePlanes.empty()) {
513 GeoPcon *fcalNosePcon =
new GeoPcon(0,2*
M_PI);
514 for(
unsigned int ind=0;
ind<fcalNosePlanes.size();
ind++) {
515 iter = fcalNosePlanes.find(
ind);
517 if(iter==fcalNosePlanes.end()) {
518 throw std::runtime_error(
"Error in BarrelCryostatConstruction, missing plane in InnerWall");
520 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
521 fcalNosePcon->addPlane(currentRecord->
getDouble(
"ZPLANE"),
527 const GeoLogVol *fcalNoseLog =
new GeoLogVol(
"LAr::Endcap::Cryostat::Cone::Mixed", fcalNosePcon, Al);
528 cryoMotherPhysical->add(
new GeoIdentifierTag(coneNumber));
529 GeoIntrusivePtr<GeoPhysVol>fcalNosePhys =
new GeoPhysVol(fcalNoseLog);
530 cryoMotherPhysical->add(fcalNosePhys);
543 std::string totalEMHLArName = baseName +
"::EmecHecLAr";
544 GeoPcon* totalEMHLArShape =
new GeoPcon(0.,2.*
M_PI);
546 for(
unsigned int ind=0;
ind<emhPlanes.size();
ind++)
548 iter = emhPlanes.find(
ind);
550 if(iter==emhPlanes.end())
551 throw std::runtime_error(
"Error in EndcapCryostatConstruction, missing plane in EMH");
554 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
555 totalEMHLArShape->addPlane(currentRecord->
getDouble(
"ZPLANE"),
561 const GeoLogVol* totalEMHLArLogical =
562 new GeoLogVol(totalEMHLArName, totalEMHLArShape,
LAr);
564 GeoIntrusivePtr<GeoFullPhysVol> totalEMHLArPhysical =
new GeoFullPhysVol(totalEMHLArLogical);
567 const GeoMaterial *PlugBrass(
nullptr);
568 for(
size_t i(0);
i<2;++
i) {
569 const planeIndMap& brassPlugPlanes = brassPlugPlanesVect[
i];
570 if (!brassPlugPlanes.empty()) {
572 PlugBrass = materialManager->
getMaterial(
"LAr::PlugBrass");
573 if (!PlugBrass)
throw std::runtime_error(
"Error in EndcapCryostatConstruction, LAr::PlugBrass is not found.");
575 GeoPcon *brassPlugPcon =
new GeoPcon(0,2*
M_PI);
576 for(
unsigned int ind=0;
ind<brassPlugPlanes.size();
ind++) {
577 iter = brassPlugPlanes.find(
ind);
579 if(iter==brassPlugPlanes.end()) {
580 throw std::runtime_error(
"Error in EndcapCryostatConstruction, missing plane in BrassPlug");
582 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
583 brassPlugPcon->addPlane(currentRecord->
getDouble(
"ZPLANE"),
588 const GeoLogVol *brassPlugLog =
new GeoLogVol(
"LAr::Endcap::Cryostat::BrassPlug", brassPlugPcon, PlugBrass);
589 GeoIntrusivePtr<GeoPhysVol>brassPlugPhys =
new GeoPhysVol(brassPlugLog);
590 totalEMHLArPhysical->add(
new GeoIdentifierTag(
i+1));
591 totalEMHLArPhysical->add(brassPlugPhys);
600 const double icable_dz = coldhole_radius;
601 const double icable_dr =
602 (1920./LArEndcapCratePhiPos->size()) *
606 <<
" of cables inside EC cryostat in front of FT" <<
endmsg;
608 const GeoMaterial* icable_mat = materialManager->
getMaterial(
"LAr::FT::Cable");
609 GeoShape* icable =
new GeoTube(rcoldwall - icable_dr, rcoldwall, icable_dz);
610 GeoLogVol* icableLV =
new GeoLogVol(
"LAr::Endcap::InnerFTCables", icable, icable_mat);
611 GeoIntrusivePtr<GeoPhysVol> icablePV =
new GeoPhysVol(icableLV);
612 totalEMHLArPhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(z_pos)));
613 totalEMHLArPhysical->add(icablePV);
616 cryoMotherPhysical->add( totalEMHLArPhysical );
619 m_emec.setFullGeo(m_fullGeo);
620 m_emec.setInnerVariant(m_EMECVariantInner);
621 m_emec.setOuterVariant(m_EMECVariantOuter);
622 GeoIntrusivePtr<GeoFullPhysVol>envelope = m_emec.GetEnvelope(bPos);
626 if (!posRec)
throw std::runtime_error(
"Error, no lar position record in the database") ;
628 GeoAlignableTransform *xfEmec =
new GeoAlignableTransform(xfPos);
630 std::string
tag = bPos? std::string(
"EMEC_POS") : std::string(
"EMEC_NEG");
635 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
639 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
643 totalEMHLArPhysical->add(xfEmec);
644 totalEMHLArPhysical->add( envelope );
649 std::string wheelType=
"front";
650 bool threeBoards=
false;
652 GeoIntrusivePtr<GeoFullPhysVol> EnvelopeF = frontHEC.
GetEnvelope();
661 GeoAlignableTransform *xfHec1 =
new GeoAlignableTransform(xfPosHec1);
663 std::string
tag1 = bPos? std::string(
"HEC1_POS") : std::string(
"HEC1_NEG");
667 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag1).c_str());
671 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag1).c_str());
673 totalEMHLArPhysical->add( xfHec1);
674 totalEMHLArPhysical->add(
new GeoIdentifierTag(0));
675 totalEMHLArPhysical->add( EnvelopeF );
682 GeoIntrusivePtr<GeoFullPhysVol> EnvelopeR = rearHEC.
GetEnvelope();
686 GeoAlignableTransform *xfHec2 =
new GeoAlignableTransform(xfPosHec2);
688 std::string
tag2 = bPos? std::string(
"HEC2_POS") : std::string(
"HEC2_NEG");
692 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag2).c_str());
696 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag2).c_str());
698 totalEMHLArPhysical->add( xfHec2);
699 totalEMHLArPhysical->add(
new GeoIdentifierTag(1));
700 totalEMHLArPhysical->add( EnvelopeR );
708 m_fcal.setFCALVisLimit(m_fcalVisLimit);
709 m_fcal.setFullGeo(m_fullGeo);
713 GeoIntrusivePtr<GeoVFullPhysVol> fcalEnvelope = m_fcal.GetEnvelope(bPos);
725 std::string
tag = bPos ?
"FCAL_POS" :
"FCAL_NEG";
728 if (!posRec)
throw std::runtime_error(
"Error, no lar position record in the database") ;
730 GeoAlignableTransform *fcalXF =
new GeoAlignableTransform(xfPos);
735 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
738 const GeoLogVol *envVol = fcalEnvelope->getLogVol();
739 const GeoShape *envShape = envVol->getShape();
740 if (envShape->typeID()!=GeoTubs::getClassTypeID()) {
741 throw std::runtime_error(
"Cannot recognize FCAL container shape");
744 const GeoTubs * tubs = (
const GeoTubs *) envShape;
747 cryoMotherPhysical->add(fcalXF);
748 cryoMotherPhysical->add(
new GeoTransform( GeoTrf::TranslateZ3D(tubs->getZHalfLength()) ) );
749 cryoMotherPhysical->add( fcalEnvelope );
755 if(m_enableMBTS && !rdbAccessSvc->getChildTag(
"MBTS",detectorKey, detectorNode).empty()) {
757 IRDBRecordset_ptr mbtsTubs = rdbAccessSvc->getRecordsetPtr(
"MBTSTubs", detectorKey, detectorNode);
758 IRDBRecordset_ptr mbtsScin = rdbAccessSvc->getRecordsetPtr(
"MBTSScin", detectorKey, detectorNode);
759 IRDBRecordset_ptr mbtsPcons = rdbAccessSvc->getRecordsetPtr(
"MBTSPcons",detectorKey, detectorNode);
760 IRDBRecordset_ptr mbtsGen = rdbAccessSvc->getRecordsetPtr(
"MBTSGen", detectorKey, detectorNode);
761 IRDBRecordset_ptr mbtsTrds = rdbAccessSvc->getRecordsetPtr(
"MBTSTrds", detectorKey, detectorNode);
764 std::map<std::string,unsigned> trdMap;
765 for(
unsigned indTrd(0);indTrd<mbtsTrds->size();++indTrd) {
766 const std::string& keyTrd = (*mbtsTrds)[indTrd]->getString(
"TRD");
767 trdMap[keyTrd]=indTrd;
781 GeoIntrusivePtr<GeoPhysVol> pvMM =
nullptr;
783 if(mbtsPcons->size()==0) {
789 const std::string& strTubeName = (*first)->getString(
"TUBE");
790 if(strTubeName ==
"MBTS_mother") {
793 else if(strTubeName ==
"Moderator") {
796 else if(strTubeName ==
"JMTUBE") {
807 const GeoMaterial *matMM = materialManager->
getMaterial((*itMother)->getString(
"MATERIAL"));
809 GeoIntrusivePtr<GeoTube> tubeMM{
new GeoTube(rminMM,rmaxMM,dzMM)};
811 GeoTube *tubeJM=
nullptr;
812 const GeoShape *solidMM=
nullptr;
813 if (itTube!=mbtsTubs->end()) {
817 GeoPcon *pcon =
new GeoPcon(0,2*
M_PI);
818 pcon->addPlane(-dzMM,rminMM,rmaxMM);
819 pcon->addPlane( dzMM,rminMM,rmaxMM);
820 pcon->addPlane( dzMM,rminMM,rMaxMod);
821 pcon->addPlane( dzMM+2*dzMod, rminMM,rMaxMod);
822 tubeJM =
new GeoTube(rminMM,rMaxMod,dzMod);
826 if (!solidMM) solidMM =
new GeoTube(rminMM,rmaxMM,dzMM);
828 GeoLogVol* lvMM =
new GeoLogVol(
"MBTS_mother",solidMM,matMM);
829 pvMM =
new GeoPhysVol(lvMM);
831 cryoMotherPhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
832 cryoMotherPhysical->add(pvMM);
840 const GeoMaterial *matMod = materialManager->
getMaterial((*itModerator)->getString(
"MATERIAL"));
842 GeoTube* solidMod =
new GeoTube(rminMM,rmaxMM,dzMod);
843 GeoLogVol* lvMod =
new GeoLogVol(
"Moderator",solidMod, matMod);
844 GeoIntrusivePtr<GeoPhysVol> pvMod =
new GeoPhysVol(lvMod);
846 pvMM->add(
new GeoTransform(GeoTrf::TranslateZ3D(zposMod)));
850 GeoLogVol* lvMod =
new GeoLogVol(
"ModeratorTube",tubeJM, matMod);
851 GeoIntrusivePtr<GeoPhysVol> pvMod =
new GeoPhysVol(lvMod);
853 pvMM->add(
new GeoTransform(GeoTrf::TranslateZ3D(tubeMM->getZHalfLength()+tubeJM->getZHalfLength())));
862 planeIndMap::const_iterator iter;
864 for (
unsigned int ind=0;
ind<mbtsPcons->size();
ind++) {
865 int key = (*mbtsPcons)[
ind]->getInt(
"PLANE_ID");
866 const std::string& pconName = (*mbtsPcons)[
ind]->getString(
"PCON");
867 if(pconName==
"MBTS::Mother") {
868 mbtsMotherPlanes[
key] =
ind;
870 else if(pconName==
"MBTS::JM") {
875 double zStartMM = 0.;
878 GeoPcon* solidMM =
new GeoPcon(0.,2.*
M_PI);
879 for(
unsigned int ind=0;
ind<mbtsMotherPlanes.size();
ind++) {
880 iter = mbtsMotherPlanes.find(
ind);
881 if(iter==mbtsMotherPlanes.end())
882 throw std::runtime_error(
"Error in EndcapCryostatConstruction, missing plane in MBTS Mother");
884 const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
885 solidMM->addPlane(currentRecord->
getDouble(
"ZPLANE"),
889 zStartMM = currentRecord->
getDouble(
"ZPLANE");
894 GeoPcon* solidMod =
new GeoPcon(0.,2.*
M_PI);
895 for(
unsigned int ind=0;
ind<jmTubePlanes.size();
ind++) {
896 iter = jmTubePlanes.find(
ind);
897 if(iter==jmTubePlanes.end())
898 throw std::runtime_error(
"Error in EndcapCryostatConstruction, missing plane in Moderator+JM tube volume");
900 const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
901 solidMod->addPlane(currentRecord->
getDouble(
"ZPLANE"),
910 GeoLogVol* lvMM =
new GeoLogVol(
"MBTS_mother",solidMM,Air);
911 pvMM =
new GeoPhysVol(lvMM);
913 zposMM = zStartCryoMother - zStartMM;
914 cryoMotherPhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
915 cryoMotherPhysical->add(pvMM);
918 if((mbtsTubs->size()!=1) || ((*mbtsTubs)[0]->getString(
"TUBE")!=
"MBTS::JM"))
919 throw std::runtime_error(
"Error in EndcapCryostatConstruction, unexpected number of tubes or wrong name for the JM tube");
920 GeoTube* tubeJM =
new GeoTube((*mbtsTubs)[0]->getDouble(
"RMIN"),
921 (*mbtsTubs)[0]->getDouble(
"RMAX"),
922 (*mbtsTubs)[0]->getDouble(
"DZ"));
923 const GeoMaterial* matJM = materialManager->
getMaterial((*mbtsTubs)[0]->getString(
"MATERIAL"));
924 GeoLogVol* lvJM =
new GeoLogVol(
"ModeratorJMTube",tubeJM, matJM);
925 GeoIntrusivePtr<GeoPhysVol> pvJM =
new GeoPhysVol(lvJM);
927 pvMM->add(
new GeoTransform(GeoTrf::TranslateZ3D((*mbtsTubs)[0]->getDouble(
"ZPOS"))));
931 GeoLogVol* lvMod =
new GeoLogVol(
"ModeratorJMPcon",solidMod, matJM);
932 GeoIntrusivePtr<GeoPhysVol> pvMod =
new GeoPhysVol(lvMod);
938 if(mbtsGen->size()==0) {
940 for(
unsigned int scinId=0; scinId<mbtsScin->size(); scinId++) {
941 const IRDBRecord* curScin = (*mbtsScin)[scinId];
943 int nScin = curScin->
getInt(
"SCINNUM");
952 double startPhi = 0.;
955 startPhi = curScin->
getDouble(
"STARTPHI");
957 catch(std::runtime_error&) {}
961 std::ostringstream ostr;
962 ostr << curScin->
getInt(
"SCIN_ID");
963 std::string scinName = std::string(
"MBTS")+ostr.str();
965 GeoTrd* solidScin =
new GeoTrd(dx1Scin,dx2Scin,dy1Scin,dy2Scin,dzScin);
966 GeoLogVol* lvScin =
new GeoLogVol(scinName,solidScin,matScin);
967 GeoIntrusivePtr<GeoPhysVol> pvScin =
new GeoPhysVol(lvScin);
972 GeoSerialTransformer* stScin =
nullptr;
976 TRANSFUNCTION xfScin = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposScin)*GeoTrf::TranslateX3D(rposScin)*GeoTrf::RotateY3D(90*
Gaudi::Units::deg);
977 stScin =
new GeoSerialTransformer(pvScin,&xfScin,nScin);
980 TRANSFUNCTION xfScin = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposScin)*GeoTrf::TranslateX3D(rposScin)*GeoTrf::RotateY3D(90*
Gaudi::Units::deg);
981 stScin =
new GeoSerialTransformer(pvScin,&xfScin,nScin);
984 pvMM->add(
new GeoSerialIdentifier(0));
992 int nAirEnv = (*mbtsGen)[0]->getInt(
"NSCIN");
993 double startPhi = (*mbtsGen)[0]->getDouble(
"STARTPHI");
994 double zposAirEnv = (*mbtsGen)[0]->getDouble(
"ZPOSENV");
995 double rposAirEnv = (*mbtsGen)[0]->getDouble(
"RPOSENV");
997 GeoIntrusivePtr<GeoPhysVol>pvAirEnv{}, pvAluEnv{} , pvAirInAlu{};
1000 std::map<std::string,unsigned>::const_iterator itTrdMap = trdMap.find(
"MBTSAirEnv");
1001 if(itTrdMap==trdMap.end())
1002 throw std::runtime_error(
"Error in EndcapCryostatConstruction, unable to get MBTS air envelope parameters from the database!");
1003 const IRDBRecord* rec = (*mbtsTrds)[itTrdMap->second];
1004 pvAirEnv = buildMbtsTrd(rec,materialManager,
nullptr);
1007 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1008 rec = (*mbtsTrds)[itTrdMap->second];
1009 const std::string& trd = rec->
getString(
"TRD");
1010 if(rec->
getString(
"PARENT")==
"MBTSAirEnv") {
1011 GeoIntrusivePtr<GeoPhysVol> nevVol = buildMbtsTrd(rec,materialManager,pvAirEnv);
1012 if(trd.compare(
"MBTSAluEnv")==0)
1018 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1019 rec = (*mbtsTrds)[itTrdMap->second];
1020 const std::string& trd = rec->
getString(
"TRD");
1021 if(rec->
getString(
"PARENT")==
"MBTSAluEnv") {
1022 GeoIntrusivePtr<GeoPhysVol> nevVol = buildMbtsTrd(rec,materialManager,pvAluEnv);
1023 if(trd.compare(
"MBTSAirInAlu")==0)
1024 pvAirInAlu = nevVol;
1029 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1030 rec = (*mbtsTrds)[itTrdMap->second];
1031 if(rec->
getString(
"PARENT")==
"MBTSAirInAlu")
1032 buildMbtsTrd(rec,materialManager,pvAirInAlu);
1038 GeoSerialTransformer* stAirEnv =
nullptr;
1041 TRANSFUNCTION xfAirEnv = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposAirEnv)*GeoTrf::TranslateX3D(rposAirEnv)*GeoTrf::RotateY3D(90*
Gaudi::Units::deg);
1042 stAirEnv =
new GeoSerialTransformer(pvAirEnv,&xfAirEnv,nAirEnv);
1045 TRANSFUNCTION xfAirEnv = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposAirEnv)*GeoTrf::TranslateX3D(rposAirEnv)*GeoTrf::RotateY3D(90*
Gaudi::Units::deg);
1046 stAirEnv =
new GeoSerialTransformer(pvAirEnv,&xfAirEnv,nAirEnv);
1049 pvMM->add(
new GeoSerialIdentifier(0));
1050 pvMM->add(stAirEnv);
1059 , rdbAccessSvc.get()
1064 , detectorNode).isFailure()) {
1065 throw std::runtime_error(
"Failed to build MBTS readout geometry");
1073 crateBuilder.
create(cryoMotherPhysical);
1075 return cryoMotherPhysical;
1080 , GeoIntrusivePtr<GeoPhysVol>
parent)
1088 GeoTrd* solid =
new GeoTrd(dx1,dx2,dy1,dy2,dz);
1089 GeoLogVol* lv =
new GeoLogVol(rec->
getString(
"TRD")
1092 GeoIntrusivePtr<GeoPhysVol>
pv =
new GeoPhysVol(lv);
1097 parent->add(
new GeoTransform(GeoTrf::TranslateZ3D(zpos)*GeoTrf::TranslateY3D(ypos)*GeoTrf::TranslateX3D(xpos)));