ATLAS Offline Software
Public Member Functions | Static Private Member Functions | Private Attributes | Friends | List of all members
LArGeo::EndcapCryostatConstruction Class Reference

Description of the LAr End Cap cryostat, including MBTS description. More...

#include <EndcapCryostatConstruction.h>

Collaboration diagram for LArGeo::EndcapCryostatConstruction:

Public Member Functions

 EndcapCryostatConstruction (bool fullGeo, std::string emecVariantInner="Wheel", std::string emecVariantOuter="Wheel", bool activateFT=false, bool enableMBTS=true)
 
virtual ~EndcapCryostatConstruction ()
 
 EndcapCryostatConstruction (const EndcapCryostatConstruction &)=delete
 
EndcapCryostatConstructionoperator= (const EndcapCryostatConstruction &)=delete
 
GeoIntrusivePtr< GeoFullPhysVol > createEnvelope (bool bPos)
 
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope ()
 
void setFCALVisLimit (int limit)
 

Static Private Member Functions

static GeoIntrusivePtr< GeoPhysVol > buildMbtsTrd (const IRDBRecord *rec, StoredMaterialManager *matmanager, GeoIntrusivePtr< GeoPhysVol > parent)
 

Private Attributes

int m_fcalVisLimit
 
IRDBAccessSvcm_pAccessSvc
 
IGeoModelSvcm_geoModelSvc
 
EMECConstruction m_emec
 
HEC2WheelConstruction m_hec2
 
FCALConstructionm_fcal
 
bool m_fullGeo
 
std::string m_EMECVariantInner
 
std::string m_EMECVariantOuter
 
bool m_activateFT
 
bool m_enableMBTS
 

Friends

class ::LArDetectorToolNV
 

Detailed Description

Description of the LAr End Cap cryostat, including MBTS description.

Definition at line 33 of file EndcapCryostatConstruction.h.

Constructor & Destructor Documentation

◆ EndcapCryostatConstruction() [1/2]

LArGeo::EndcapCryostatConstruction::EndcapCryostatConstruction ( bool  fullGeo,
std::string  emecVariantInner = "Wheel",
std::string  emecVariantOuter = "Wheel",
bool  activateFT = false,
bool  enableMBTS = true 
)

Definition at line 74 of file EndcapCryostatConstruction.cxx.

77  :
78  // cryoEnvelopePhysical(NULL),
79  m_fcalVisLimit(-1),
80  m_pAccessSvc(nullptr),
81  m_geoModelSvc(nullptr),
82  m_fullGeo(fullGeo),
83  m_EMECVariantInner(std::move(emecVariantInner)),
84  m_EMECVariantOuter(std::move(emecVariantOuter)),
85  m_activateFT(activateFT),
86  m_enableMBTS(enableMBTS)
87 {
88 
89  m_fcal = new FCALConstruction();
90 
91  ISvcLocator *svcLocator = Gaudi::svcLocator();
92  StatusCode sc;
93  sc=svcLocator->service("RDBAccessSvc",m_pAccessSvc);
94  if (sc != StatusCode::SUCCESS) {
95  throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
96  }
97 
98  sc = svcLocator->service ("GeoModelSvc",m_geoModelSvc);
99  if (sc != StatusCode::SUCCESS) {
100  throw std::runtime_error ("Cannot locate GeoModelSvc!!");
101  }
102 }

◆ ~EndcapCryostatConstruction()

LArGeo::EndcapCryostatConstruction::~EndcapCryostatConstruction ( )
virtual

Definition at line 104 of file EndcapCryostatConstruction.cxx.

105 {
106  delete m_fcal;
107 }

◆ EndcapCryostatConstruction() [2/2]

LArGeo::EndcapCryostatConstruction::EndcapCryostatConstruction ( const EndcapCryostatConstruction )
delete

Member Function Documentation

◆ buildMbtsTrd()

GeoIntrusivePtr< GeoPhysVol > LArGeo::EndcapCryostatConstruction::buildMbtsTrd ( const IRDBRecord rec,
StoredMaterialManager matmanager,
GeoIntrusivePtr< GeoPhysVol >  parent 
)
staticprivate

Definition at line 1099 of file EndcapCryostatConstruction.cxx.

1102 {
1103  // Construct the Trd
1104  double dx1 = rec->getDouble("DX1");
1105  double dx2 = rec->getDouble("DX2");
1106  double dy1 = rec->getDouble("DY1");
1107  double dy2 = rec->getDouble("DY2");
1108  double dz = rec->getDouble("DZ");
1109  GeoTrd* solid = new GeoTrd(dx1,dx2,dy1,dy2,dz);
1110  GeoLogVol* lv = new GeoLogVol(rec->getString("TRD")
1111  ,solid
1112  ,matmanager->getMaterial(rec->getString("MATERIAL")));
1113  GeoIntrusivePtr<GeoPhysVol> pv = new GeoPhysVol(lv);
1114  if(parent) {
1115  double xpos = rec->getDouble("XPOS");
1116  double ypos = rec->getDouble("YPOS");
1117  double zpos = rec->getDouble("ZPOS");
1118  parent->add(new GeoTransform(GeoTrf::TranslateZ3D(zpos)*GeoTrf::TranslateY3D(ypos)*GeoTrf::TranslateX3D(xpos)));
1119  parent->add(pv);
1120  }
1121  return pv;
1122 }

◆ createEnvelope()

GeoIntrusivePtr< GeoFullPhysVol > LArGeo::EndcapCryostatConstruction::createEnvelope ( bool  bPos)

Definition at line 110 of file EndcapCryostatConstruction.cxx.

111 {
112  // Get access to the material manager:
113 
114  ISvcLocator *svcLocator = Gaudi::svcLocator();
115  IMessageSvc * msgSvc;
116  if (svcLocator->service("MessageSvc", msgSvc, true )==StatusCode::FAILURE) {
117  throw std::runtime_error("Error in EndcapCryostatConstruction, cannot access MessageSvc");
118  }
119 
120  MsgStream log(msgSvc, "LArGeo::EndcapCryostatConstruction");
121  log << MSG::DEBUG << "started" << endmsg;
122 
123 
125  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
126  throw std::runtime_error("Error in EndcapCryostatConstruction, cannot access DetectorStore");
127  }
128 
129  // Get the materials from the material manager:-----------------------------------------------------//
130  // //
131  StoredMaterialManager* materialManager = nullptr;
132  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
133 
134  const GeoMaterial *Lead = materialManager->getMaterial("std::Lead");
135  if (!Lead) {
136  throw std::runtime_error("Error in EndcapCryostatConstruction, std::Lead is not found.");
137  }
138 
139  const GeoMaterial *Air = materialManager->getMaterial("std::Air");
140  if (!Air) {
141  throw std::runtime_error("Error in EndcapCryostatConstruction, std::Air is not found.");
142  }
143 
144  const GeoMaterial *Al = materialManager->getMaterial("std::Aluminium");
145  if (!Al) {
146  throw std::runtime_error("Error in EndcapCryostatConstruction, std::Aluminium is not found.");
147  }
148 
149  const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
150  if (!LAr) {
151  throw std::runtime_error("Error in EndcapCryostatConstruction, std::LiquidArgon is not found.");
152  }
153 
154  const GeoMaterial *G10 = materialManager->getMaterial("LAr::G10");
155  if (!G10) throw std::runtime_error("Error in EndcapCryostatConstruction, LAr::G10 is not found.");
156 
157  const GeoMaterial *Copper = materialManager->getMaterial("std::Copper");
158  if (!Copper) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Copper is not found.");
159 
160  const GeoMaterial *Iron = materialManager->getMaterial("std::Iron");
161  if (!Iron) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Iron is not found.");
162 
163  const GeoMaterial *Polystyrene = materialManager->getMaterial("std::Polystyrene");
164  if (!Polystyrene) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Polystyrene is not found.");
165 
166  // //
167  //-------------------------------------------------------------------------------------------------//
168 
169  std::string AtlasVersion = m_geoModelSvc->atlasVersion();
170  std::string LArVersion = m_geoModelSvc->LAr_VersionOverride();
171 
172  std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion;
173  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
174 
175  IRDBRecordset_ptr cryoCylinders = m_pAccessSvc->getRecordsetPtr("CryoCylinders",detectorKey, detectorNode);
176  IRDBRecordset_ptr larPosition = m_pAccessSvc->getRecordsetPtr("LArPosition",detectorKey, detectorNode);
177  if (larPosition->size()==0 ) {
178  larPosition = m_pAccessSvc->getRecordsetPtr("LArPosition", "LArPosition-00");
179  if (larPosition->size()==0 ) {
180  throw std::runtime_error("Error, no lar position table in database!");
181  }
182  }
183 
184 
185 
186 
187  if(cryoCylinders->size()==0) cryoCylinders = m_pAccessSvc->getRecordsetPtr("CryoCylinders","CryoCylinders-00");
188 
189  // Deal with Pcons
190  IRDBRecordset_ptr cryoPcons = m_pAccessSvc->getRecordsetPtr("CryoPcons",detectorKey, detectorNode);
191  if(cryoPcons->size()==0) cryoPcons = m_pAccessSvc->getRecordsetPtr("CryoPcons","CryoPcons-00");
192 
193  planeIndMap cryoMotherPlanes, emhPlanes, fcalNosePlanes;
194  std::vector<planeIndMap> brassPlugPlanesVect;
195  brassPlugPlanesVect.emplace_back();
196  brassPlugPlanesVect.emplace_back();
197  planeIndMap::const_iterator iter;
198 
199  for (unsigned int ind=0; ind<cryoPcons->size(); ind++)
200  {
201  int key = (*cryoPcons)[ind]->getInt("PLANE_ID");
202  const std::string& pconName = (*cryoPcons)[ind]->getString("PCON");
203  if(pconName=="Endcap::CryoMother") {
204  cryoMotherPlanes[key] = ind;
205  }
206  else if(pconName=="Endcap::EMH") {
207  emhPlanes[key] = ind;
208  }
209  else if(pconName=="Endcap::FcalNose") {
210  fcalNosePlanes[key] = ind;
211  }
212  else if(pconName=="Endcap::BrassPlug1") {
213  brassPlugPlanesVect[0][key] = ind;
214  }
215  else if(pconName=="Endcap::BrassPlug2") {
216  brassPlugPlanesVect[1][key] = ind;
217  }
218  }
219 
220 
222  // Define geometry
224 
225  // Set up strings for volume names.
226  std::string baseName = "LAr::Endcap::Cryostat";
227 
228  // Define the mother volume for the endcap cryostat. Everything
229  // else in the endcap (cryostat walls, detectors, etc.) should be
230  // placed inside here.
231 
232  // The position of this volume may change if the thickness of the
233  // cabling in front of the endcaps changes. Therefore, we must get
234  // the z-shift from the database and adjust the volume geometry
235  // accordingly.
236 
237  std::string cryoMotherName = baseName + "::MotherVolume";
238  GeoPcon* cryoMotherShape = new GeoPcon(0.,2.*M_PI);
239 
240  double zStartCryoMother = 0.; // This variable is needed to calculate local transform of the MBTS mother
241 
242  for(unsigned int ind = 0; ind < cryoMotherPlanes.size(); ++ ind){
243  iter = cryoMotherPlanes.find(ind);
244  if(iter == cryoMotherPlanes.end()){
245  throw std::runtime_error(
246  "Error in EndcapCryostatConstruction, missing plane in Endcap Cryo Mother"
247  );
248  } else {
249  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
250  double zplane = currentRecord->getDouble("ZPLANE");
251  double rmin = currentRecord->getDouble("RMIN");
252  double rmax = currentRecord->getDouble("RMAX");
253  /* This sould be corrected in the DB, but we have no time */
254  if(m_activateFT){
255  if(zplane == 0.){
256  zplane = 12.;
257  log << MSG::DEBUG << "Put cryoMother zplane " << ind
258  << " at " << zplane << " to accomodate FEC" << endmsg;
259  }
260  if(rmax == 2476.){
261  rmax = 2506.;
262  log << MSG::DEBUG << "Put cryoMother rmax " << ind
263  << " at " << rmax << " to accomodate FT Chimney" << endmsg;
264  }
265  }
266  cryoMotherShape->addPlane(zplane, rmin, rmax);
267  if(ind == 0) zStartCryoMother = zplane;
268  }
269  }
270 
271  const GeoLogVol* cryoMotherLogical = new GeoLogVol(cryoMotherName, cryoMotherShape, Air);
272  GeoIntrusivePtr<GeoFullPhysVol> cryoMotherPhysical{new GeoFullPhysVol(cryoMotherLogical)};
273 
274  //JT. 04.2013
275  // insert extra material in form of Tubes
276  // between warm and cold wall in front of Emec Presampler
277  // ( walls : warm(cylNumber=3), cold(cylNumber=14)
278  // in case of negative value of the thickness, no volume will be created
279  //
280 
281  // Extra cylinders
282 
283  IRDBRecordset_ptr cryoExtraCyl = m_pAccessSvc->getRecordsetPtr("LArCones",detectorKey, detectorNode);
284 
285  if(m_fullGeo && cryoCylinders->size()>0){
286  unsigned int nextra=cryoExtraCyl->size();
287  if(nextra>0){
288  log << MSG::DEBUG << "activate extra material in front of PS" << endmsg;
289  bool finloop=false;
290  for(unsigned int i=0;i<nextra;i++){
291  const std::string& name=(*cryoExtraCyl)[i]->getString("CONE");
292  if(name.find("EmecCylBeforePS") != std::string::npos){
293  double rmin=(*cryoExtraCyl)[i]->getDouble("RMIN1"); //PS rmin
294  double rmax=(*cryoExtraCyl)[i]->getDouble("RMAX1"); //PS rmax
295  double dz = (*cryoExtraCyl)[i]->getDouble("DZ"); //leadthickness
296  if(dz>0.){
297 
298  double rmin_warm=0.,rmax_warm=0.,dz_warm=0.,zInCryostat_warm=0.;
299  double rmin_cold=0.,rmax_cold=0.,dz_cold=0.,zInCryostat_cold=0.;
300  int wallfind=0;
301 
302  for (unsigned int layer = 0; layer < cryoCylinders->size(); layer++) {
303  const IRDBRecord *currentRecord = (*cryoCylinders)[layer];
304  int cylNumber = currentRecord->getInt("CYL_NUMBER");
305  if(currentRecord->getString("CYL_LOCATION")=="Endcap"){
306  if(cylNumber == 3 )
307  {
308  rmin_warm=currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
309  rmax_warm=currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
310  dz_warm=currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
311  zInCryostat_warm = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm + currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
312  wallfind=wallfind+1;
313  }
314  if(cylNumber == 14 )
315  {
316  rmin_cold=currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
317  rmax_cold=currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
318  dz_cold=currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
319  zInCryostat_cold = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm + currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
320  wallfind=wallfind+1;
321  }
322  }
323  }
324  if(wallfind==2){
325  double maxdz=(zInCryostat_cold-dz_cold)-(zInCryostat_warm+dz_warm);
326  if(dz>maxdz) dz=maxdz;
327  double zpos=((zInCryostat_cold-dz_cold)+(zInCryostat_warm+dz_warm))/2.;
328 
329  std::ostringstream cylStream;
330  cylStream << baseName << "::ExtraCyl";
331  std::string cylName = cylStream.str();
332  cylName = cylName + "_beforePS";
333 
334  double phi0=(*cryoExtraCyl)[i]->getDouble("PHI0");
335  double dphi=(*cryoExtraCyl)[i]->getDouble("DPHI");
336  if(dphi>6.28) dphi=2.*M_PI;
337  const std::string& material=(*cryoExtraCyl)[i]->getString("MATERIAL"); //lead
338  const GeoMaterial *mat = materialManager->getMaterial(material);
339  if (!mat) {
340  throw std::runtime_error("Error in EndcapCryostatConstruction,material for CylBeforePS is not found.");
341  }
342 
343  GeoTubs *solidCyl = new GeoTubs(rmin,rmax,dz/2.,phi0,dphi);
344  const GeoLogVol *logicCyl = new GeoLogVol(cylName,solidCyl,mat);
345  GeoPhysVol *physCyl = new GeoPhysVol(logicCyl);
346 
347  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zpos)));
348  cryoMotherPhysical->add(physCyl);
349 
350  std::cout<<"**************************************************"<<std::endl;
351  std::cout<<"EndcapCryostatConstruction insert extra material between warm and cold wall of cryo at front of PS::"<<std::endl;
352  std::cout<<" ExtraCyl params: name,mat= "<<cylName<<" "<<mat->getName()
353  <<" rmin,rmax,dzthick,zpos="<<rmin<<" "<<rmax<<" "<<dz<<" "<<zpos
354  <<" PhiStart,PhiSize="<<phi0<<" "<<dphi
355  <<std::endl;
356 
357  std::cout<<" warm cyl params: rmin,rmax,dzthick,zpos="<<rmin_warm<<" "<<rmax_warm<<" "<<2.*dz_warm<<" "
358  <<zInCryostat_warm<<std::endl;
359  std::cout<<" cold cyl params: rmin,rmax,dzthick,zpos="<<rmin_cold<<" "<<rmax_cold<<" "<<2.*dz_cold<<" "
360  <<zInCryostat_cold<<std::endl;
361  std::cout<<"**************************************************"<<std::endl;
362 
363  finloop=true;
364  } // warm cold walls found
365  } // dz>0. , extra cyl. thickness is positive
366  } //CylBeforePS ; extracyl is defined in the db record
367  if(finloop) break;
368  } // loop for extra cyls in the db record
369  } // number of items in the db record >0
370  else {
371  log << MSG::DEBUG << "no extra material in front of PS" << endmsg;
372  }
373  } // fullgeo is required and cryocyl reciord is not empty
374 
375  // end of inserting extra lead plate before PS
376 
377 
378  IRDBRecordset_ptr LArEndcapCratePhiPos = m_pAccessSvc->getRecordsetPtr("LArEndcapCratePhiPos",detectorKey, detectorNode);
379 
380 
381  for(unsigned int layer = 0; layer < cryoCylinders->size(); layer++){
382  const IRDBRecord *currentRecord = (*cryoCylinders)[layer];
383  int cylNumber = currentRecord->getInt("CYL_NUMBER");
384  if(m_fullGeo || cylNumber == 14 || cylNumber == 100) {
385  // 100 - is the piece of Shielding. We need to build it for minimal geo too
386 
387  if(currentRecord->getString("CYL_LOCATION")=="Endcap") {
388  std::ostringstream cylStream;
389  cylStream << baseName << "::Cylinder";
390  std::string cylName = (cylNumber == 100?"JDSH_AddShield_Inner":cylStream.str());
391 
392  if(!currentRecord->isFieldNull("QUALIFIER")){
393  const std::string& qualifier = currentRecord->getString("QUALIFIER");
394  if (!qualifier.empty()) cylName = cylName + "::" + qualifier;
395  }
396 
397  const GeoShape* solidCyl = new GeoTubs(
398  currentRecord->getDouble("RMIN")*Gaudi::Units::cm,
399  currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm,
400  currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.,
401  (double) 0.,
402  (double) 2.*M_PI*Gaudi::Units::rad
403  );
404  const GeoMaterial *material = materialManager->getMaterial(currentRecord->getString("MATERIAL"));
405 
406  if(!material){
407  std::ostringstream errorMessage;
408  errorMessage << "Error in EndcapCrysostat Construction" << std::endl;
409  errorMessage << "Material " << currentRecord->getString("MATERIAL") << " is not found" << std::endl;
410  throw std::runtime_error(errorMessage.str().c_str());
411  }
412 
413  if(m_activateFT){ // need to cut holes in cryostat walls for FT
414  if(cylNumber == 13){ // warm wall
415  log << MSG::DEBUG << "Cut holes for feedthroughs in warm wall "
416  << cylName
417  << endmsg;
418  const double rmin = currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
419  const double rmax = currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
420  const double dz = currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
421  const double warmhole_radius = 0.5*340.*Gaudi::Units::mm;
422  const double warmhole_pos = dz - 247.*Gaudi::Units::mm;
423  GeoTube *warmhole = new GeoTube(0., warmhole_radius, (rmax - rmin) * 4);
424  const GeoShapeShift &h1 = (*warmhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
425  const double r = (rmin + rmax) * 0.5;
426  const GeoShape* warmwall = solidCyl;
427  const double dphi = 5.*Gaudi::Units::deg;
428  auto put = [&warmwall, &warmhole_pos, &r, &h1](double pos){
429  const double x = r*cos(pos), y = r*sin(pos);
430  warmwall = &(warmwall->subtract(
431  h1 << GeoTrf::Translate3D(x, y, warmhole_pos)
432  *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
433  ));
434  };
435  for(unsigned int i{0}; i < LArEndcapCratePhiPos->size(); ++ i){
436  const int num = (*LArEndcapCratePhiPos)[i]->getInt("CRATENUM");
437  const double phi = (*LArEndcapCratePhiPos)[i]->getDouble("PHIPOS")*Gaudi::Units::deg;
438  if(num == 10){ // topmost crate has one FT
439  put(phi + dphi); // asymmetric, see DMConstruction
440  } else {
441  put(phi - dphi);
442  put(phi + dphi);
443  }
444  }
445  solidCyl = warmwall;
446  } else if(cylNumber == 20){ // cold wall
447  log << MSG::DEBUG << "Cut holes for feedthroughs in cold wall "
448  << cylName
449  << endmsg;
450  const double rmin = currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
451  const double rmax = currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
452  const double coldhole_radius = 0.5*150.*Gaudi::Units::mm;
453  const double coldhole_pos = 21.5*Gaudi::Units::mm;
454  GeoTube *coldhole = new GeoTube(0., coldhole_radius, (rmax - rmin) * 4);
455  const GeoShapeShift &h1 = (*coldhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
456  const double r = (rmin + rmax) * 0.5;
457  const GeoShape *coldwall = solidCyl;
458  const double dphi = 5.*Gaudi::Units::deg;
459  auto put = [&coldwall, &coldhole_pos, &r, &h1](double pos){
460  const double x = r*cos(pos), y = r*sin(pos);
461  coldwall = &(coldwall->subtract(
462  h1 << GeoTrf::Translate3D(x, y, coldhole_pos)
463  *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
464  ));
465  };
466  for(unsigned int i{0}; i < LArEndcapCratePhiPos->size(); ++ i){
467  const int num = (*LArEndcapCratePhiPos)[i]->getInt("CRATENUM");
468  const double phi = (*LArEndcapCratePhiPos)[i]->getDouble("PHIPOS")*Gaudi::Units::deg;
469  if(num == 10){ // topmost crate has one FT
470  put(phi + dphi); // asymmetric, see DMConstruction
471  } else {
472  put(phi - dphi);
473  put(phi + dphi);
474  }
475  }
476  solidCyl = coldwall;
477  }
478  }
479 
480  const GeoLogVol* logicCyl = new GeoLogVol(cylName,solidCyl,material);
481  GeoIntrusivePtr<GeoPhysVol> physCyl = new GeoPhysVol(logicCyl);
482 
483  double zInCryostat = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm
484  + currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
485  // Don't move the pump even if the rest of the cryostat moves.
486 
487  //if ( cylNumber == 33 ) zInCryostat -= zEmec;
488 
489  // Place each cylinder.
490 
491  cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
492  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
493 
494  // Front cold wall of Cryostat is a mother for Endcap Presampler
495  if ( cylNumber == 14 ) {
496  // its PhysicalVolume has a special name
497  cryoMotherPhysical->add( new GeoNameTag(cylName + "::PresamplerMother") );
498 
499  EndcapPresamplerConstruction endcapPresamplerConstruction;
500 
501  GeoIntrusivePtr<GeoFullPhysVol> emecPSEnvelope = endcapPresamplerConstruction.Envelope();
502  if (emecPSEnvelope) {
503  // Get the position of the presampler from the geometry helper.
504  double Zpos = 30.5*Gaudi::Units::mm;
505 
506  // It is highly debateable whether the endcap presampler is
507  // alignable, but in any case we shall not align it here because
508  // we need to completely redo it, anyway, since it does not
509  // even live "in" this volume, not in real life anyway.
510  GeoTransform *xfPs = new GeoTransform(GeoTrf::TranslateZ3D(Zpos));
511 
512  physCyl->add(xfPs);
513  physCyl->add( emecPSEnvelope );
514 
515  std::string tag = bPos? std::string("PRESAMPLER_EC_POS") : std::string("PRESAMPLER_EC_NEG");
517 
518  StoredPhysVol *sPhysVol = new StoredPhysVol(emecPSEnvelope);
519  status=detStore->record(sPhysVol,tag);
520  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
521  }
522  }
523 
524  // After we've added any additional sub-volumes, add the cylinder.
525  cryoMotherPhysical->add(physCyl);
526  }
527  }
528  }
529 
530  // g.p., 3-Apr-2006
531  // placing Pcones for FCAL nose, instead of cylinders 34,28,29
532  if(m_fullGeo)
533  if (!fcalNosePlanes.empty()) {
534  GeoPcon *fcalNosePcon = new GeoPcon(0,2*M_PI);
535  for(unsigned int ind=0; ind<fcalNosePlanes.size(); ind++) {
536  iter = fcalNosePlanes.find(ind);
537 
538  if(iter==fcalNosePlanes.end()) {
539  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerWall");
540  } else {
541  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
542  fcalNosePcon->addPlane(currentRecord->getDouble("ZPLANE"),
543  currentRecord->getDouble("RMIN"),
544  currentRecord->getDouble("RMAX"));
545  }
546  }
547  int coneNumber = 1;
548  const GeoLogVol *fcalNoseLog = new GeoLogVol("LAr::Endcap::Cryostat::Cone::Mixed", fcalNosePcon, Al);
549  cryoMotherPhysical->add(new GeoIdentifierTag(coneNumber));
550  GeoIntrusivePtr<GeoPhysVol>fcalNosePhys = new GeoPhysVol(fcalNoseLog);
551  cryoMotherPhysical->add(fcalNosePhys);
552  }
553 
554 
555  // There are two LAr regions within the endcap cryostat. The first
556  // is the region that contains the EMEC and HEC (the electromagnetic
557  // and hadronic endcap calorimeters, respectively). The second is
558  // the region that contains the forward calorimeter.
559 
560  // This volumes will be sub-divided into sensitive-detector regions
561  // in the detector.
562 
563  // EMEC + HEC:
564  std::string totalEMHLArName = baseName + "::EmecHecLAr";
565  GeoPcon* totalEMHLArShape = new GeoPcon(0.,2.*M_PI);
566 
567  for(unsigned int ind=0; ind<emhPlanes.size(); ind++)
568  {
569  iter = emhPlanes.find(ind);
570 
571  if(iter==emhPlanes.end())
572  throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in EMH");
573  else
574  {
575  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
576  totalEMHLArShape->addPlane(currentRecord->getDouble("ZPLANE"),
577  currentRecord->getDouble("RMIN"),
578  currentRecord->getDouble("RMAX"));
579  }
580  }
581 
582  const GeoLogVol* totalEMHLArLogical =
583  new GeoLogVol(totalEMHLArName, totalEMHLArShape, LAr);
584 
585  GeoIntrusivePtr<GeoFullPhysVol> totalEMHLArPhysical = new GeoFullPhysVol(totalEMHLArLogical);
586 
587  // Add brass plugs
588  const GeoMaterial *PlugBrass(nullptr);
589  for(size_t i(0);i<2;++i) {
590  const planeIndMap& brassPlugPlanes = brassPlugPlanesVect[i];
591  if (!brassPlugPlanes.empty()) {
592  if(!PlugBrass) {
593  PlugBrass = materialManager->getMaterial("LAr::PlugBrass");
594  if (!PlugBrass) throw std::runtime_error("Error in EndcapCryostatConstruction, LAr::PlugBrass is not found.");
595  }
596  GeoPcon *brassPlugPcon = new GeoPcon(0,2*M_PI);
597  for(unsigned int ind=0; ind<brassPlugPlanes.size(); ind++) {
598  iter = brassPlugPlanes.find(ind);
599 
600  if(iter==brassPlugPlanes.end()) {
601  throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in BrassPlug");
602  } else {
603  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
604  brassPlugPcon->addPlane(currentRecord->getDouble("ZPLANE"),
605  currentRecord->getDouble("RMIN"),
606  currentRecord->getDouble("RMAX"));
607  }
608  }
609  const GeoLogVol *brassPlugLog = new GeoLogVol("LAr::Endcap::Cryostat::BrassPlug", brassPlugPcon, PlugBrass);
610  GeoIntrusivePtr<GeoPhysVol>brassPlugPhys = new GeoPhysVol(brassPlugLog);
611  totalEMHLArPhysical->add(new GeoIdentifierTag(i+1));
612  totalEMHLArPhysical->add(brassPlugPhys);
613  }
614  }
615 
616  if(m_activateFT){
617  // this ring emulates signal cables concentration area
618  // nearby the theedtrougs inside the cryostat
619  const double rcoldwall = 2155.*Gaudi::Units::mm;
620  const double coldhole_radius = 0.5*150.*Gaudi::Units::mm; // copied from above
621  const double icable_dz = coldhole_radius;
622  const double icable_dr =
623  (1920./LArEndcapCratePhiPos->size()) *
624  M_PI * 1.1*1.1/4. * Gaudi::Units::mm2
625  / (icable_dz*2);
626  log << MSG::DEBUG << "adding " << icable_dr/Gaudi::Units::mm << " mm"
627  << " of cables inside EC cryostat in front of FT" << endmsg;
628  const double z_pos = -249.*Gaudi::Units::mm - icable_dz;
629  const GeoMaterial* icable_mat = materialManager->getMaterial("LAr::FT::Cable");
630  GeoShape* icable = new GeoTube(rcoldwall - icable_dr, rcoldwall, icable_dz);
631  GeoLogVol* icableLV = new GeoLogVol("LAr::Endcap::InnerFTCables", icable, icable_mat);
632  GeoIntrusivePtr<GeoPhysVol> icablePV = new GeoPhysVol(icableLV);
633  totalEMHLArPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(z_pos)));
634  totalEMHLArPhysical->add(icablePV);
635  }
636 
637  cryoMotherPhysical->add( totalEMHLArPhysical );
638 
639  {
643  GeoIntrusivePtr<GeoFullPhysVol>envelope = m_emec.GetEnvelope(bPos);
644 
645  //=>
646  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, bPos ? "EMEC_POS":"EMEC_NEG");
647  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
649  GeoAlignableTransform *xfEmec = new GeoAlignableTransform(xfPos);
650 
651  std::string tag = bPos? std::string("EMEC_POS") : std::string("EMEC_NEG");
653 
654  StoredPhysVol *sPhysVol = new StoredPhysVol(envelope);
655  status=detStore->record(sPhysVol,tag);
656  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
657 
658  StoredAlignX *sAlignX = new StoredAlignX(xfEmec);
659  status=detStore->record(sAlignX,tag);
660  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
661 
662 
663  //=>
664  totalEMHLArPhysical->add(xfEmec);
665  totalEMHLArPhysical->add( envelope );
666  }
667 
668  {
669 
670  std::string wheelType="front";
671  bool threeBoards= false;
672  HECWheelConstruction frontHEC(m_fullGeo,wheelType,threeBoards,bPos) ;
673  GeoIntrusivePtr<GeoFullPhysVol> EnvelopeF = frontHEC.GetEnvelope();
674 
676 
677 
678  //--- Make the Front Wheel alignable:
679 
680  const IRDBRecord *posHec1 = GeoDBUtils::getTransformRecord(larPosition, bPos ? "HEC1_POS":"HEC1_NEG");
681  GeoTrf::Transform3D xfPosHec1 = posHec1 ? GeoDBUtils::getTransform(posHec1) : GeoTrf::Translate3D(0.,0.,-2423.0);
682  GeoAlignableTransform *xfHec1 = new GeoAlignableTransform(xfPosHec1);
683 
684  std::string tag1 = bPos? std::string("HEC1_POS") : std::string("HEC1_NEG");
685 
686  StoredPhysVol *sPhysVol1 = new StoredPhysVol(EnvelopeF);
687  status=detStore->record(sPhysVol1,tag1);
688  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
689 
690  StoredAlignX *sAlignX1 = new StoredAlignX(xfHec1);
691  status=detStore->record(sAlignX1,tag1);
692  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
693 
694  totalEMHLArPhysical->add( xfHec1);
695  totalEMHLArPhysical->add(new GeoIdentifierTag(0));
696  totalEMHLArPhysical->add( EnvelopeF );
697 
698 
699 
700  wheelType="rear";
701  threeBoards= false;
702  HECWheelConstruction rearHEC(m_fullGeo,wheelType,threeBoards,bPos) ;
703  GeoIntrusivePtr<GeoFullPhysVol> EnvelopeR = rearHEC.GetEnvelope();
704 
705  const IRDBRecord *posHec2 = GeoDBUtils::getTransformRecord(larPosition, bPos ? "HEC2_POS":"HEC2_NEG");
706  GeoTrf::Transform3D xfPosHec2 = posHec2 ? GeoDBUtils::getTransform(posHec2) : GeoTrf::Translate3D(0.,0.,-1566.0);
707  GeoAlignableTransform *xfHec2 = new GeoAlignableTransform(xfPosHec2);
708 
709  std::string tag2 = bPos? std::string("HEC2_POS") : std::string("HEC2_NEG");
710 
711  StoredPhysVol *sPhysVol2 = new StoredPhysVol(EnvelopeR);
712  status=detStore->record(sPhysVol2,tag2);
713  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
714 
715  StoredAlignX *sAlignX2 = new StoredAlignX(xfHec2);
716  status=detStore->record(sAlignX2,tag2);
717  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
718 
719  totalEMHLArPhysical->add( xfHec2);
720  totalEMHLArPhysical->add(new GeoIdentifierTag(1));
721  totalEMHLArPhysical->add( EnvelopeR );
722 
723 
724  }
725 
726 
727 
728  // 13-Mar-2002 WGS: Place the FCAL detector inside the cryostat.
731  {
732 
733  // The "envelope" determined by the EMB should be a GeoFullPhysVol.
734  GeoIntrusivePtr<GeoVFullPhysVol> fcalEnvelope = m_fcal->GetEnvelope(bPos);
735 
736  /* For now, comment out the FCAL placement, for two reasons:
737  1) The FCAL geometry helper class has been written yet;
738  2) Reconstruction needs each FCAL module to have a
739  separate alignable envelope. We'll work out t hese
740  issues later. */
741 
742 
743  // From FCALConstruction.cxx: */
744  //
745 
746  std::string tag = bPos ? "FCAL_POS" : "FCAL_NEG";
747  // Get default values for alignable transform deltas from SubdetPosHelper
748  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, tag);
749  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
751  GeoAlignableTransform *fcalXF = new GeoAlignableTransform(xfPos);
752 
754  StoredAlignX *sAlignX = new StoredAlignX(fcalXF);
755  status=detStore->record(sAlignX,tag);
756  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
757 
758 
759  const GeoLogVol *envVol = fcalEnvelope->getLogVol();
760  const GeoShape *envShape = envVol->getShape();
761  if (envShape->typeID()!=GeoTubs::getClassTypeID()) {
762  throw std::runtime_error("Cannot recognize FCAL container shape");
763  }
764 
765  const GeoTubs * tubs = (const GeoTubs *) envShape;
766 
767  // Place the FCAL modules.
768  cryoMotherPhysical->add(fcalXF);
769  cryoMotherPhysical->add( new GeoTransform( GeoTrf::TranslateZ3D(tubs->getZHalfLength()) ) );
770  cryoMotherPhysical->add( fcalEnvelope );
771 
772 
773  }
774 
775  //__________________________ MBTS+moderator+JM tube _____________________________________
776  if(m_enableMBTS && !m_pAccessSvc->getChildTag("MBTS",detectorKey, detectorNode).empty()) {
777  // DB related stuff first
778  IRDBRecordset_ptr mbtsTubs = m_pAccessSvc->getRecordsetPtr("MBTSTubs", detectorKey, detectorNode);
779  IRDBRecordset_ptr mbtsScin = m_pAccessSvc->getRecordsetPtr("MBTSScin", detectorKey, detectorNode);
780  IRDBRecordset_ptr mbtsPcons = m_pAccessSvc->getRecordsetPtr("MBTSPcons",detectorKey, detectorNode);
781  IRDBRecordset_ptr mbtsGen = m_pAccessSvc->getRecordsetPtr("MBTSGen", detectorKey, detectorNode);
782  IRDBRecordset_ptr mbtsTrds = m_pAccessSvc->getRecordsetPtr("MBTSTrds", detectorKey, detectorNode);
783 
784  double zposMM = 0.;
785  std::map<std::string,unsigned> trdMap; // Used in the new description only
786  for(unsigned indTrd(0);indTrd<mbtsTrds->size();++indTrd) {
787  const std::string& keyTrd = (*mbtsTrds)[indTrd]->getString("TRD");
788  trdMap[keyTrd]=indTrd;
789  }
790 
791  // Build material geometry only if the FullGeo flag has been set
792  if(m_fullGeo) {
793  // Define iterators
794  IRDBRecordset::const_iterator itMother = mbtsTubs->end();
795  IRDBRecordset::const_iterator itModerator = mbtsTubs->end();
796  IRDBRecordset::const_iterator itTube=mbtsTubs->end();
797 
798  IRDBRecordset::const_iterator first = mbtsTubs->begin();
799  IRDBRecordset::const_iterator last = mbtsTubs->end();
800 
801  // Mother volume
802  GeoIntrusivePtr<GeoPhysVol> pvMM = nullptr;
803 
804  if(mbtsPcons->size()==0) {
805  // ****
806  // In this description the Moderator and the JM tube are constructed as separate volumes (both of them are tubes)
807  // ****
808 
809  for(; first!=last; ++first) {
810  const std::string& strTubeName = (*first)->getString("TUBE");
811  if(strTubeName == "MBTS_mother") {
812  itMother = first;
813  }
814  else if(strTubeName == "Moderator") {
815  itModerator = first;
816  }
817  else if(strTubeName == "JMTUBE") {
818  itTube = first;
819  }
820  }
821 
822  // Build mother volume
823  double rminMM = (*itMother)->getDouble("RMIN")*Gaudi::Units::mm;
824  double rmaxMM = (*itMother)->getDouble("RMAX")*Gaudi::Units::mm;
825  double dzMM = (*itMother)->getDouble("DZ")*Gaudi::Units::mm;
826  zposMM = (*itMother)->getDouble("ZPOS")*Gaudi::Units::mm;
827 
828  const GeoMaterial *matMM = materialManager->getMaterial((*itMother)->getString("MATERIAL"));
829 
830  GeoIntrusivePtr<GeoTube> tubeMM{new GeoTube(rminMM,rmaxMM,dzMM)};
831 
832  GeoTube *tubeJM=nullptr;
833  const GeoShape *solidMM=nullptr;
834  if (itTube!=mbtsTubs->end()) {
835  double dzMod = (*itTube)->getDouble("DZ")*Gaudi::Units::mm;
836  double rMaxMod = (*itTube)->getDouble("RMAX")*Gaudi::Units::mm;
837 
838  GeoPcon *pcon = new GeoPcon(0,2*M_PI);
839  pcon->addPlane(-dzMM,rminMM,rmaxMM);
840  pcon->addPlane( dzMM,rminMM,rmaxMM);
841  pcon->addPlane( dzMM,rminMM,rMaxMod);
842  pcon->addPlane( dzMM+2*dzMod, rminMM,rMaxMod);
843  tubeJM = new GeoTube(rminMM,rMaxMod,dzMod);
844  solidMM=pcon;
845  }
846 
847  if (!solidMM) solidMM = new GeoTube(rminMM,rmaxMM,dzMM);
848 
849  GeoLogVol* lvMM = new GeoLogVol("MBTS_mother",solidMM,matMM);
850  pvMM = new GeoPhysVol(lvMM);
851 
852  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
853  cryoMotherPhysical->add(pvMM);
854 
855  // Moderator cylinder
856  //double rminMod = (*itModerator)->getDouble("RMIN")*Gaudi::Units::mm;
857  //double rmaxMod = (*itModerator)->getDouble("RMAX")*Gaudi::Units::mm;
858  double dzMod = (*itModerator)->getDouble("DZ")*Gaudi::Units::mm;
859  double zposMod = (*itModerator)->getDouble("ZPOS")*Gaudi::Units::mm;
860 
861  const GeoMaterial *matMod = materialManager->getMaterial((*itModerator)->getString("MATERIAL"));
862 
863  GeoTube* solidMod = new GeoTube(rminMM,rmaxMM,dzMod);
864  GeoLogVol* lvMod = new GeoLogVol("Moderator",solidMod, matMod);
865  GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
866 
867  pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMod)));
868  pvMM->add(pvMod);
869 
870  if (tubeJM) {
871  GeoLogVol* lvMod = new GeoLogVol("ModeratorTube",tubeJM, matMod);
872  GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
873 
874  pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D(tubeMM->getZHalfLength()+tubeJM->getZHalfLength())));
875  pvMM->add(pvMod);
876  }
877  } else {
878  // ****
879  // In this description the Moderator and the JM tube are constructed one polycone + one extra part for the moderator
880  // ****
881 
882  planeIndMap mbtsMotherPlanes, jmTubePlanes;
883  planeIndMap::const_iterator iter;
884 
885  for (unsigned int ind=0; ind<mbtsPcons->size(); ind++) {
886  int key = (*mbtsPcons)[ind]->getInt("PLANE_ID");
887  const std::string& pconName = (*mbtsPcons)[ind]->getString("PCON");
888  if(pconName=="MBTS::Mother") {
889  mbtsMotherPlanes[key] = ind;
890  }
891  else if(pconName=="MBTS::JM") {
892  jmTubePlanes[key] = ind;
893  }
894  }
895 
896  double zStartMM = 0.;
897 
898  // construct shapes for the MBTS mother and Moderator+JM
899  GeoPcon* solidMM = new GeoPcon(0.,2.*M_PI);
900  for(unsigned int ind=0; ind<mbtsMotherPlanes.size(); ind++) {
901  iter = mbtsMotherPlanes.find(ind);
902  if(iter==mbtsMotherPlanes.end())
903  throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in MBTS Mother");
904  else {
905  const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
906  solidMM->addPlane(currentRecord->getDouble("ZPLANE"),
907  currentRecord->getDouble("RMIN"),
908  currentRecord->getDouble("RMAX"));
909  if(ind==0)
910  zStartMM = currentRecord->getDouble("ZPLANE");
911  }
912  }
913 
914 
915  GeoPcon* solidMod = new GeoPcon(0.,2.*M_PI);
916  for(unsigned int ind=0; ind<jmTubePlanes.size(); ind++) {
917  iter = jmTubePlanes.find(ind);
918  if(iter==jmTubePlanes.end())
919  throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in Moderator+JM tube volume");
920  else {
921  const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
922  solidMod->addPlane(currentRecord->getDouble("ZPLANE"),
923  currentRecord->getDouble("RMIN"),
924  currentRecord->getDouble("RMAX"));
925  }
926  }
927 
928  // Construct volumes:
929 
930  // Mother
931  GeoLogVol* lvMM = new GeoLogVol("MBTS_mother",solidMM,Air);
932  pvMM = new GeoPhysVol(lvMM);
933 
934  zposMM = zStartCryoMother - zStartMM;
935  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
936  cryoMotherPhysical->add(pvMM);
937 
938  // Extra tube for the moderator:
939  if((mbtsTubs->size()!=1) || ((*mbtsTubs)[0]->getString("TUBE")!="MBTS::JM"))
940  throw std::runtime_error("Error in EndcapCryostatConstruction, unexpected number of tubes or wrong name for the JM tube");
941  GeoTube* tubeJM = new GeoTube((*mbtsTubs)[0]->getDouble("RMIN"),
942  (*mbtsTubs)[0]->getDouble("RMAX"),
943  (*mbtsTubs)[0]->getDouble("DZ"));
944  const GeoMaterial* matJM = materialManager->getMaterial((*mbtsTubs)[0]->getString("MATERIAL"));
945  GeoLogVol* lvJM = new GeoLogVol("ModeratorJMTube",tubeJM, matJM);
946  GeoIntrusivePtr<GeoPhysVol> pvJM = new GeoPhysVol(lvJM);
947 
948  pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D((*mbtsTubs)[0]->getDouble("ZPOS"))));
949  pvMM->add(pvJM);
950 
951  // Moderator+JM polycone
952  GeoLogVol* lvMod = new GeoLogVol("ModeratorJMPcon",solidMod, matJM);
953  GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
954 
955  pvMM->add(pvMod);
956  }
957 
958  // Scintillators
959  if(mbtsGen->size()==0) {
960  // The "old" description: just scintillators, no aluminum envelopes
961  for(unsigned int scinId=0; scinId<mbtsScin->size(); scinId++) {
962  const IRDBRecord* curScin = (*mbtsScin)[scinId];
963 
964  int nScin = curScin->getInt("SCINNUM");
965  double dx1Scin = curScin->getDouble("DX1")*Gaudi::Units::mm;
966  double dx2Scin = curScin->getDouble("DX2")*Gaudi::Units::mm;
967  double dy1Scin = curScin->getDouble("DY1")*Gaudi::Units::mm;
968  double dy2Scin = curScin->getDouble("DY2")*Gaudi::Units::mm;
969  double dzScin = curScin->getDouble("DZ")*Gaudi::Units::mm;
970  double zposScin = curScin->getDouble("ZPOS")*Gaudi::Units::mm;
971  double rposScin = curScin->getDouble("RPOS")*Gaudi::Units::mm;
972 
973  double startPhi = 0.;
974  try {
975  if(!curScin->isFieldNull("STARTPHI"))
976  startPhi = curScin->getDouble("STARTPHI");
977  }
978  catch(std::runtime_error&) {}
979 
980  const GeoMaterial *matScin = materialManager->getMaterial(curScin->getString("MATERIAL"));
981 
982  std::ostringstream ostr;
983  ostr << curScin->getInt("SCIN_ID");
984  std::string scinName = std::string("MBTS")+ostr.str();
985 
986  GeoTrd* solidScin = new GeoTrd(dx1Scin,dx2Scin,dy1Scin,dy2Scin,dzScin);
987  GeoLogVol* lvScin = new GeoLogVol(scinName,solidScin,matScin);
988  GeoIntrusivePtr<GeoPhysVol> pvScin = new GeoPhysVol(lvScin);
989 
990  // parameterizations
991  double deltaPhi = 360./nScin;
992  Variable varInd;
993  GeoSerialTransformer* stScin = nullptr;
994 
995  if(bPos) {
996  GENFUNCTION phiInd = deltaPhi*(varInd + startPhi)*Gaudi::Units::deg;
997  TRANSFUNCTION xfScin = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposScin)*GeoTrf::TranslateX3D(rposScin)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
998  stScin = new GeoSerialTransformer(pvScin,&xfScin,nScin);
999  } else {
1000  GENFUNCTION phiInd = (180 - deltaPhi*(varInd + startPhi))*Gaudi::Units::deg;
1001  TRANSFUNCTION xfScin = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposScin)*GeoTrf::TranslateX3D(rposScin)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
1002  stScin = new GeoSerialTransformer(pvScin,&xfScin,nScin);
1003  }
1004 
1005  pvMM->add(new GeoSerialIdentifier(0));
1006  pvMM->add(stScin);
1007  }
1008  }
1009  else {
1010  // The "new" description: scintillators + aluminum envelopes + plastic plugs + aluminum press bars (only for RUN1)
1011 
1012  // General parameters
1013  int nAirEnv = (*mbtsGen)[0]->getInt("NSCIN");
1014  double startPhi = (*mbtsGen)[0]->getDouble("STARTPHI");
1015  double zposAirEnv = (*mbtsGen)[0]->getDouble("ZPOSENV");
1016  double rposAirEnv = (*mbtsGen)[0]->getDouble("RPOSENV");
1017 
1018  GeoIntrusivePtr<GeoPhysVol>pvAirEnv{}, pvAluEnv{} , pvAirInAlu{};
1019 
1020  // Build the air envelope first
1021  std::map<std::string,unsigned>::const_iterator itTrdMap = trdMap.find("MBTSAirEnv");
1022  if(itTrdMap==trdMap.end())
1023  throw std::runtime_error("Error in EndcapCryostatConstruction, unable to get MBTS air envelope parameters from the database!");
1024  const IRDBRecord* rec = (*mbtsTrds)[itTrdMap->second];
1025  pvAirEnv = buildMbtsTrd(rec,materialManager,nullptr);
1026 
1027  // Build direct children of the air envelope
1028  for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1029  rec = (*mbtsTrds)[itTrdMap->second];
1030  const std::string& trd = rec->getString("TRD");
1031  if(rec->getString("PARENT")=="MBTSAirEnv") {
1032  GeoIntrusivePtr<GeoPhysVol> nevVol = buildMbtsTrd(rec,materialManager,pvAirEnv);
1033  if(trd.compare("MBTSAluEnv")==0)
1034  pvAluEnv = nevVol;
1035  }
1036  }
1037 
1038  // Build direct children of the aluminum envelope
1039  for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1040  rec = (*mbtsTrds)[itTrdMap->second];
1041  const std::string& trd = rec->getString("TRD");
1042  if(rec->getString("PARENT")=="MBTSAluEnv") {
1043  GeoIntrusivePtr<GeoPhysVol> nevVol = buildMbtsTrd(rec,materialManager,pvAluEnv);
1044  if(trd.compare("MBTSAirInAlu")==0)
1045  pvAirInAlu = nevVol;
1046  }
1047  }
1048 
1049  // Build direct children of the 'air-in-aluminum'
1050  for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1051  rec = (*mbtsTrds)[itTrdMap->second];
1052  if(rec->getString("PARENT")=="MBTSAirInAlu")
1053  buildMbtsTrd(rec,materialManager,pvAirInAlu);
1054  }
1055 
1056  // parameterizations
1057  double deltaPhi = 360./nAirEnv;
1058  Variable varInd;
1059  GeoSerialTransformer* stAirEnv = nullptr;
1060  if(bPos) {
1061  GENFUNCTION phiInd = deltaPhi*(varInd + startPhi)*Gaudi::Units::deg;
1062  TRANSFUNCTION xfAirEnv = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposAirEnv)*GeoTrf::TranslateX3D(rposAirEnv)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
1063  stAirEnv = new GeoSerialTransformer(pvAirEnv,&xfAirEnv,nAirEnv);
1064  } else {
1065  GENFUNCTION phiInd = (180 - deltaPhi*(varInd + startPhi))*Gaudi::Units::deg;
1066  TRANSFUNCTION xfAirEnv = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposAirEnv)*GeoTrf::TranslateX3D(rposAirEnv)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
1067  stAirEnv = new GeoSerialTransformer(pvAirEnv,&xfAirEnv,nAirEnv);
1068  }
1069 
1070  pvMM->add(new GeoSerialIdentifier(0));
1071  pvMM->add(stAirEnv);
1072 
1073  }
1074  } // if(m_fullGeo)
1075 
1076  // Build readout for MBTS
1077  // Do it only once for both A and C sides
1078  if(bPos) {
1080  , m_pAccessSvc
1081  , msgSvc
1082  , zposMM
1083  , trdMap
1084  , detectorKey
1085  , detectorNode).isFailure()) {
1086  throw std::runtime_error("Failed to build MBTS readout geometry");
1087  }
1088  }
1089 
1090  }
1091 
1092  // Build endcap dead matter around the cryostat
1093  EndcapDMConstruction crateBuilder(m_activateFT);
1094  crateBuilder.create(cryoMotherPhysical);
1095 
1096  return cryoMotherPhysical;
1097 }

◆ GetEnvelope()

virtual GeoIntrusivePtr<GeoFullPhysVol> LArGeo::EndcapCryostatConstruction::GetEnvelope ( )
inlinevirtual

Definition at line 52 of file EndcapCryostatConstruction.h.

52 { return GeoIntrusivePtr<GeoFullPhysVol>{};}

◆ operator=()

EndcapCryostatConstruction& LArGeo::EndcapCryostatConstruction::operator= ( const EndcapCryostatConstruction )
delete

◆ setFCALVisLimit()

void LArGeo::EndcapCryostatConstruction::setFCALVisLimit ( int  limit)
inline

Definition at line 56 of file EndcapCryostatConstruction.h.

Friends And Related Function Documentation

◆ ::LArDetectorToolNV

friend class ::LArDetectorToolNV
friend

Definition at line 78 of file EndcapCryostatConstruction.h.

Member Data Documentation

◆ m_activateFT

bool LArGeo::EndcapCryostatConstruction::m_activateFT
private

Definition at line 75 of file EndcapCryostatConstruction.h.

◆ m_emec

EMECConstruction LArGeo::EndcapCryostatConstruction::m_emec
private

Definition at line 67 of file EndcapCryostatConstruction.h.

◆ m_EMECVariantInner

std::string LArGeo::EndcapCryostatConstruction::m_EMECVariantInner
private

Definition at line 72 of file EndcapCryostatConstruction.h.

◆ m_EMECVariantOuter

std::string LArGeo::EndcapCryostatConstruction::m_EMECVariantOuter
private

Definition at line 73 of file EndcapCryostatConstruction.h.

◆ m_enableMBTS

bool LArGeo::EndcapCryostatConstruction::m_enableMBTS
private

Definition at line 76 of file EndcapCryostatConstruction.h.

◆ m_fcal

FCALConstruction* LArGeo::EndcapCryostatConstruction::m_fcal
private

Definition at line 69 of file EndcapCryostatConstruction.h.

◆ m_fcalVisLimit

int LArGeo::EndcapCryostatConstruction::m_fcalVisLimit
private

Definition at line 62 of file EndcapCryostatConstruction.h.

◆ m_fullGeo

bool LArGeo::EndcapCryostatConstruction::m_fullGeo
private

Definition at line 71 of file EndcapCryostatConstruction.h.

◆ m_geoModelSvc

IGeoModelSvc* LArGeo::EndcapCryostatConstruction::m_geoModelSvc
private

Definition at line 65 of file EndcapCryostatConstruction.h.

◆ m_hec2

HEC2WheelConstruction LArGeo::EndcapCryostatConstruction::m_hec2
private

Definition at line 68 of file EndcapCryostatConstruction.h.

◆ m_pAccessSvc

IRDBAccessSvc* LArGeo::EndcapCryostatConstruction::m_pAccessSvc
private

Definition at line 64 of file EndcapCryostatConstruction.h.


The documentation for this class was generated from the following files:
IRDBRecord::getInt
virtual int getInt(const std::string &fieldName) const =0
Get int field value.
beamspotman.r
def r
Definition: beamspotman.py:676
LArGeo::buildMbtsReadout
StatusCode buildMbtsReadout(StoreGateSvc *detStore, IRDBAccessSvc *paramSvc, IMessageSvc *msgSvc, double zposMM, const std::map< std::string, unsigned > &trdMap, const std::string &detKey, const std::string &detNode)
Definition: MbtsReadoutBuilder.cxx:22
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
GeoDBUtils::getTransformRecord
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition: GeoDBUtils.h:23
IRDBAccessSvc::getRecordsetPtr
virtual IRDBRecordset_ptr getRecordsetPtr(const std::string &node, const std::string &tag, const std::string &tag2node="", const std::string &connName="ATLASDD")=0
Provides access to the Recordset object containing HVS-tagged data.
LAr
Definition: LArVolumeBuilder.h:36
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:160
mat
GeoMaterial * mat
Definition: LArDetectorConstructionTBEC.cxx:53
IRDBRecord::getString
virtual const std::string & getString(const std::string &fieldName) const =0
Get string field value.
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
StoredAlignX
Definition: StoredAlignX.h:23
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
LArGeo::FCALConstruction::setFCALVisLimit
void setFCALVisLimit(int maxCell)
Definition: FCALConstruction.h:39
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
read_hist_ntuple.h1
h1
Definition: read_hist_ntuple.py:21
x
#define x
GeoDBUtils::getTransform
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
Definition: GeoDBUtils.h:33
LArGeo::EMECConstruction::setOuterVariant
void setOuterVariant(const std::string &v)
Definition: EMECConstruction.h:42
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
StoredPhysVol
Definition: StoredPhysVol.h:27
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
LArGeo::EndcapCryostatConstruction::m_fullGeo
bool m_fullGeo
Definition: EndcapCryostatConstruction.h:71
IGeoModelSvc::LAr_VersionOverride
virtual const std::string & LAr_VersionOverride() const =0
LArGeo::EndcapCryostatConstruction::m_EMECVariantInner
std::string m_EMECVariantInner
Definition: EndcapCryostatConstruction.h:72
LArGeo::EndcapCryostatConstruction::m_fcal
FCALConstruction * m_fcal
Definition: EndcapCryostatConstruction.h:69
EventInfoWrite.AtlasVersion
AtlasVersion
Definition: EventInfoWrite.py:17
IRDBAccessSvc::getChildTag
virtual std::string getChildTag(const std::string &childNode, const std::string &parentTag, const std::string &parentNode, const std::string &connName="ATLASDD")=0
Gets the tag name for the node by giving its parent node tag.
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
lumiFormat.i
int i
Definition: lumiFormat.py:92
LArGeo::EndcapCryostatConstruction::m_EMECVariantOuter
std::string m_EMECVariantOuter
Definition: EndcapCryostatConstruction.h:73
Atlas.StoreGateSvc
StoreGateSvc
Definition: Atlas.UnixStandardJob.py:25
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
plotBeamSpotCompare.tag1
string tag1
Definition: plotBeamSpotCompare.py:75
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
LArGeo::EMECConstruction::GetEnvelope
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(bool bPos=true)
Definition: EMECConstruction.cxx:111
LArGeo::EndcapCryostatConstruction::m_geoModelSvc
IGeoModelSvc * m_geoModelSvc
Definition: EndcapCryostatConstruction.h:65
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
LArGeo::EMECConstruction::setFullGeo
void setFullGeo(bool flag)
Definition: EMECConstruction.cxx:593
test_pyathena.parent
parent
Definition: test_pyathena.py:15
plotBeamSpotCompare.tag2
string tag2
Definition: plotBeamSpotCompare.py:76
LArGeo::FCALConstruction::setFullGeo
void setFullGeo(bool flag)
Definition: FCALConstruction.h:42
LArGeo::EndcapCryostatConstruction::buildMbtsTrd
static GeoIntrusivePtr< GeoPhysVol > buildMbtsTrd(const IRDBRecord *rec, StoredMaterialManager *matmanager, GeoIntrusivePtr< GeoPhysVol > parent)
Definition: EndcapCryostatConstruction.cxx:1099
LArGeo::EndcapCryostatConstruction::m_pAccessSvc
IRDBAccessSvc * m_pAccessSvc
Definition: EndcapCryostatConstruction.h:64
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
LArGeo::FCALConstruction::GetEnvelope
GeoIntrusivePtr< GeoVFullPhysVol > GetEnvelope(bool bPos)
Definition: FCALConstruction.cxx:76
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
LArGeo::EndcapCryostatConstruction::m_activateFT
bool m_activateFT
Definition: EndcapCryostatConstruction.h:75
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
python.SystemOfUnits.mm2
int mm2
Definition: SystemOfUnits.py:84
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
EndcapPresamplerConstruction
GeoModel description of the LAr Endcap Presampler geometry.
Definition: EndcapPresamplerConstruction.h:25
Variable
Wrapper around a histogram which allows for some additional filling patterns and data manipulation.
Definition: Trigger/TrigCost/TrigCostAnalysis/src/Variable.h:39
planeIndMap
std::map< int, unsigned int, std::less< int > > planeIndMap
Definition: BarrelCryostatConstruction.cxx:73
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
LArGeo::EMECConstruction::setInnerVariant
void setInnerVariant(const std::string &v)
Definition: EMECConstruction.h:41
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
LArGeo::EndcapCryostatConstruction::m_enableMBTS
bool m_enableMBTS
Definition: EndcapCryostatConstruction.h:76
y
#define y
IRDBRecord::isFieldNull
virtual bool isFieldNull(const std::string &fieldName) const =0
Check if the field value is NULL.
EndcapPresamplerConstruction::Envelope
GeoIntrusivePtr< GeoFullPhysVol > Envelope()
Definition: EndcapPresamplerConstruction.cxx:53
IRDBRecord
IRDBRecord is one record in the IRDBRecordset object.
Definition: IRDBRecord.h:27
DeMoScan.first
bool first
Definition: DeMoScan.py:534
DEBUG
#define DEBUG
Definition: page_access.h:11
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
python.changerun.pv
pv
Definition: changerun.py:81
StoredMaterialManager::getMaterial
virtual const GeoMaterial * getMaterial(const std::string &name)=0
StoredMaterialManager
This class holds one or more material managers and makes them storeable, under StoreGate.
Definition: StoredMaterialManager.h:28
merge.status
status
Definition: merge.py:17
IRDBRecord::getDouble
virtual double getDouble(const std::string &fieldName) const =0
Get double field value.
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
IGeoModelSvc::atlasVersion
virtual const std::string & atlasVersion() const =0
FCALConstruction
Insert the LAr FCAL into a pre-defined mother volume.
updateCoolNtuple.limit
int limit
Definition: updateCoolNtuple.py:45
checkFileSG.ind
list ind
Definition: checkFileSG.py:118
python.SystemOfUnits.rad
int rad
Definition: SystemOfUnits.py:111
IRDBRecordset::const_iterator
RecordsVector::const_iterator const_iterator
Definition: IRDBRecordset.h:52
LArGeo::EndcapCryostatConstruction::m_emec
EMECConstruction m_emec
Definition: EndcapCryostatConstruction.h:67
LArGeo::EndcapCryostatConstruction::m_fcalVisLimit
int m_fcalVisLimit
Definition: EndcapCryostatConstruction.h:62
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37