93 log << MSG::DEBUG <<
"started" <<
endmsg;
96 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service(
"DetectorStore")};
97 if(!detStore.isValid()) {
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!");
143 std::string AtlasVersion = geoModelSvc->atlasVersion();
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") {
186 emhPlanes[key] = ind;
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");
236 log << MSG::DEBUG <<
"Put cryoMother zplane " << ind
237 <<
" at " << zplane <<
" to accomodate FEC" <<
endmsg;
241 log << MSG::DEBUG <<
"Put cryoMother rmax " << ind
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);
265 unsigned int nextra=cryoExtraCyl->
size();
267 log << MSG::DEBUG <<
"activate extra material in front of PS" <<
endmsg;
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.;
281 for (
unsigned int layer = 0; layer < cryoCylinders->
size(); layer++) {
282 const IRDBRecord *currentRecord = (*cryoCylinders)[layer];
283 int cylNumber = currentRecord->
getInt(
"CYL_NUMBER");
284 if(currentRecord->
getString(
"CYL_LOCATION")==
"Endcap"){
287 rmin_warm=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
288 rmax_warm=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
289 dz_warm=currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
290 zInCryostat_warm = currentRecord->
getDouble(
"ZMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
295 rmin_cold=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
296 rmax_cold=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
297 dz_cold=currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
298 zInCryostat_cold = currentRecord->
getDouble(
"ZMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
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");
317 const GeoMaterial *mat = materialManager->
getMaterial(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;
350 log << MSG::DEBUG <<
"no extra material in front of PS" <<
endmsg;
357 IRDBRecordset_ptr LArEndcapCratePhiPos = rdbAccessSvc->getRecordsetPtr(
"LArEndcapCratePhiPos",detectorKey, detectorNode);
360 for(
unsigned int layer = 0; layer < cryoCylinders->
size(); layer++){
361 const IRDBRecord *currentRecord = (*cryoCylinders)[layer];
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(
377 currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm,
378 currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm,
379 currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.,
381 (
double) 2.*
M_PI*Gaudi::Units::rad
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 "
397 const double rmin = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
398 const double rmax = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
399 const double dz = currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
400 const double warmhole_radius = 0.5*340.*Gaudi::Units::mm;
401 const double warmhole_pos = dz - 247.*Gaudi::Units::mm;
402 GeoTube *warmhole =
new GeoTube(0., warmhole_radius, (rmax - rmin) * 4);
403 const GeoShapeShift &h1 = (*warmhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
404 const double r = (rmin + rmax) * 0.5;
405 const GeoShape* warmwall = solidCyl;
406 const double dphi = 5.*Gaudi::Units::deg;
407 auto put = [&warmwall, &warmhole_pos, &
r, &h1](
double pos){
408 const double x =
r*cos(pos),
y =
r*sin(pos);
409 warmwall = &(warmwall->subtract(
410 h1 << GeoTrf::Translate3D(
x,
y, warmhole_pos)
411 *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
414 for(
unsigned int i{0}; i < LArEndcapCratePhiPos->
size(); ++ i){
415 const int num = (*LArEndcapCratePhiPos)[i]->getInt(
"CRATENUM");
416 const double phi = (*LArEndcapCratePhiPos)[i]->getDouble(
"PHIPOS")*Gaudi::Units::deg;
425 }
else if(cylNumber == 20){
426 log << MSG::DEBUG <<
"Cut holes for feedthroughs in cold wall "
429 const double rmin = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
430 const double rmax = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
431 const double coldhole_radius = 0.5*150.*Gaudi::Units::mm;
432 const double coldhole_pos = 21.5*Gaudi::Units::mm;
433 GeoTube *coldhole =
new GeoTube(0., coldhole_radius, (rmax - rmin) * 4);
434 const GeoShapeShift &h1 = (*coldhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
435 const double r = (rmin + rmax) * 0.5;
436 const GeoShape *coldwall = solidCyl;
437 const double dphi = 5.*Gaudi::Units::deg;
438 auto put = [&coldwall, &coldhole_pos, &
r, &h1](
double pos){
439 const double x =
r*cos(pos),
y =
r*sin(pos);
440 coldwall = &(coldwall->subtract(
441 h1 << GeoTrf::Translate3D(
x,
y, coldhole_pos)
442 *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
445 for(
unsigned int i{0}; i < LArEndcapCratePhiPos->
size(); ++ i){
446 const int num = (*LArEndcapCratePhiPos)[i]->getInt(
"CRATENUM");
447 const double phi = (*LArEndcapCratePhiPos)[i]->getDouble(
"PHIPOS")*Gaudi::Units::deg;
459 const GeoLogVol* logicCyl =
new GeoLogVol(cylName,solidCyl,material);
460 GeoIntrusivePtr<GeoPhysVol> physCyl =
new GeoPhysVol(logicCyl);
462 double zInCryostat = currentRecord->
getDouble(
"ZMIN")*Gaudi::Units::cm
463 + currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
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) {
483 double Zpos = 30.5*Gaudi::Units::mm;
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");
498 status=detStore->record(sPhysVol,tag);
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);
598 const double rcoldwall = 2155.*Gaudi::Units::mm;
599 const double coldhole_radius = 0.5*150.*Gaudi::Units::mm;
600 const double icable_dz = coldhole_radius;
601 const double icable_dr =
602 (1920./LArEndcapCratePhiPos->
size()) *
603 M_PI * 1.1*1.1/4. * Gaudi::Units::mm2
605 log << MSG::DEBUG <<
"adding " << icable_dr/Gaudi::Units::mm <<
" mm"
606 <<
" of cables inside EC cryostat in front of FT" <<
endmsg;
607 const double z_pos = -249.*Gaudi::Units::mm - icable_dz;
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 );
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");
634 status=detStore->record(sPhysVol,tag);
635 if(!status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag).c_str());
638 status=detStore->record(sAlignX,tag);
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");
666 status=detStore->record(sPhysVol1,tag1);
667 if(!status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag1).c_str());
670 status=detStore->record(sAlignX1,tag1);
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");
691 status=detStore->record(sPhysVol2,tag2);
692 if(!status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag2).c_str());
695 status=detStore->record(sAlignX2,tag2);
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 );
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);
734 status=detStore->record(sAlignX,tag);
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 =
static_cast<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) {
788 for(; first!=last; ++first) {
789 const std::string& strTubeName = (*first)->getString(
"TUBE");
790 if(strTubeName ==
"MBTS_mother") {
793 else if(strTubeName ==
"Moderator") {
796 else if(strTubeName ==
"JMTUBE") {
802 double rminMM = (*itMother)->getDouble(
"RMIN")*Gaudi::Units::mm;
803 double rmaxMM = (*itMother)->getDouble(
"RMAX")*Gaudi::Units::mm;
804 double dzMM = (*itMother)->getDouble(
"DZ")*Gaudi::Units::mm;
805 zposMM = (*itMother)->getDouble(
"ZPOS")*Gaudi::Units::mm;
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()) {
814 double dzMod = (*itTube)->getDouble(
"DZ")*Gaudi::Units::mm;
815 double rMaxMod = (*itTube)->getDouble(
"RMAX")*Gaudi::Units::mm;
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);
837 double dzMod = (*itModerator)->getDouble(
"DZ")*Gaudi::Units::mm;
838 double zposMod = (*itModerator)->getDouble(
"ZPOS")*Gaudi::Units::mm;
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") {
871 jmTubePlanes[key] = ind;
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");
944 double dx1Scin = curScin->
getDouble(
"DX1")*Gaudi::Units::mm;
945 double dx2Scin = curScin->
getDouble(
"DX2")*Gaudi::Units::mm;
946 double dy1Scin = curScin->
getDouble(
"DY1")*Gaudi::Units::mm;
947 double dy2Scin = curScin->
getDouble(
"DY2")*Gaudi::Units::mm;
948 double dzScin = curScin->
getDouble(
"DZ")*Gaudi::Units::mm;
949 double zposScin = curScin->
getDouble(
"ZPOS")*Gaudi::Units::mm;
950 double rposScin = curScin->
getDouble(
"RPOS")*Gaudi::Units::mm;
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;
975 GENFUNCTION phiInd =
deltaPhi*(varInd + startPhi)*Gaudi::Units::deg;
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);
979 GENFUNCTION phiInd = (180 -
deltaPhi*(varInd + startPhi))*Gaudi::Units::deg;
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];
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")
1038 GeoSerialTransformer* stAirEnv =
nullptr;
1040 GENFUNCTION phiInd =
deltaPhi*(varInd + startPhi)*Gaudi::Units::deg;
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);
1044 GENFUNCTION phiInd = (180 -
deltaPhi*(varInd + startPhi))*Gaudi::Units::deg;
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;