ATLAS Offline Software
EndcapCryostatConstruction.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // EndcapCryostatConstruction
6 
7 // 04-Jan-2002 WGS: Revised to create cryostat mother volume, and to
8 // place all endcap components (EMEC, HEC, FCAL) within this volume.
9 
13 #include "EndcapDMConstruction.h"
14 
16 
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"
36 #include "StoreGate/StoreGateSvc.h"
42 #include "GeoModelKernel/GeoShapeUnion.h"
43 #include "GeoModelKernel/GeoShapeShift.h"
44 
45 #include "GeoGenericFunctions/AbsFunction.h"
46 #include "GeoGenericFunctions/Variable.h"
47 
48 // For the database:
52 
53 #include "GaudiKernel/MsgStream.h"
54 #include "GaudiKernel/Bootstrap.h"
55 #include "GaudiKernel/SystemOfUnits.h"
56 
58 
59 #include <cmath>
60 #include <iomanip>
61 #include <map>
62 #include <string>
63 #include <utility>
64 
65 using namespace GeoGenfun;
66 using namespace GeoXF;
67 
68 
69 
70 // The objects for mapping plane indexes in Pcon to the record index
71 // in RDBRecordset
72 using planeIndMap = std::map<int, unsigned int, std::less<int>>;
73 
74 
76  , std::string emecVariantInner
77  , std::string emecVariantOuter
78  , bool activateFT
79  , bool enableMBTS)
80  : m_fcalVisLimit(-1),
81  m_fullGeo(fullGeo),
82  m_EMECVariantInner(std::move(emecVariantInner)),
83  m_EMECVariantOuter(std::move(emecVariantOuter)),
84  m_activateFT(activateFT),
85  m_enableMBTS(enableMBTS)
86 {
87 }
88 
89 GeoIntrusivePtr<GeoFullPhysVol> LArGeo::EndcapCryostatConstruction::createEnvelope(bool bPos)
90 {
91  // Get access to the material manager:
92  MsgStream log(Athena::getMessageSvc(), "LArGeo::EndcapCryostatConstruction");
93  log << MSG::DEBUG << "started" << endmsg;
94 
95 
96  SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
97  if(!detStore.isValid()) {
98  throw std::runtime_error("Error in EndcapCryostatConstruction, cannot access DetectorStore");
99  }
100 
101  // Get the materials from the material manager:-----------------------------------------------------//
102  // //
103  StoredMaterialManager* materialManager = nullptr;
104  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
105 
106  const GeoMaterial *Lead = materialManager->getMaterial("std::Lead");
107  if (!Lead) {
108  throw std::runtime_error("Error in EndcapCryostatConstruction, std::Lead is not found.");
109  }
110 
111  const GeoMaterial *Air = materialManager->getMaterial("std::Air");
112  if (!Air) {
113  throw std::runtime_error("Error in EndcapCryostatConstruction, std::Air is not found.");
114  }
115 
116  const GeoMaterial *Al = materialManager->getMaterial("std::Aluminium");
117  if (!Al) {
118  throw std::runtime_error("Error in EndcapCryostatConstruction, std::Aluminium is not found.");
119  }
120 
121  const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
122  if (!LAr) {
123  throw std::runtime_error("Error in EndcapCryostatConstruction, std::LiquidArgon is not found.");
124  }
125 
126  const GeoMaterial *G10 = materialManager->getMaterial("LAr::G10");
127  if (!G10) throw std::runtime_error("Error in EndcapCryostatConstruction, LAr::G10 is not found.");
128 
129  const GeoMaterial *Copper = materialManager->getMaterial("std::Copper");
130  if (!Copper) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Copper is not found.");
131 
132  const GeoMaterial *Iron = materialManager->getMaterial("std::Iron");
133  if (!Iron) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Iron is not found.");
134 
135  const GeoMaterial *Polystyrene = materialManager->getMaterial("std::Polystyrene");
136  if (!Polystyrene) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Polystyrene is not found.");
137 
138  // //
139  //-------------------------------------------------------------------------------------------------//
140  SmartIF<IGeoModelSvc> geoModelSvc{Gaudi::svcLocator()->service("GeoModelSvc")};
141  if(!geoModelSvc.isValid()) throw std::runtime_error("Cannot locate GeoModelSvc!");
142 
143  std::string AtlasVersion = geoModelSvc->atlasVersion();
144  std::string LArVersion = geoModelSvc->LAr_VersionOverride();
145 
146  std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion;
147  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
148 
149  SmartIF<IRDBAccessSvc> rdbAccessSvc{Gaudi::svcLocator()->service("RDBAccessSvc")};
150  if(!rdbAccessSvc.isValid()) {
151  throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
152  }
153 
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!");
160  }
161  }
162 
163 
164 
165 
166  if(cryoCylinders->size()==0) cryoCylinders = rdbAccessSvc->getRecordsetPtr("CryoCylinders","CryoCylinders-00");
167 
168  // Deal with Pcons
169  IRDBRecordset_ptr cryoPcons = rdbAccessSvc->getRecordsetPtr("CryoPcons",detectorKey, detectorNode);
170  if(cryoPcons->size()==0) cryoPcons = rdbAccessSvc->getRecordsetPtr("CryoPcons","CryoPcons-00");
171 
172  planeIndMap cryoMotherPlanes, emhPlanes, fcalNosePlanes;
173  std::vector<planeIndMap> brassPlugPlanesVect;
174  brassPlugPlanesVect.emplace_back();
175  brassPlugPlanesVect.emplace_back();
176  planeIndMap::const_iterator iter;
177 
178  for (unsigned int ind=0; ind<cryoPcons->size(); ind++)
179  {
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;
184  }
185  else if(pconName=="Endcap::EMH") {
186  emhPlanes[key] = ind;
187  }
188  else if(pconName=="Endcap::FcalNose") {
189  fcalNosePlanes[key] = ind;
190  }
191  else if(pconName=="Endcap::BrassPlug1") {
192  brassPlugPlanesVect[0][key] = ind;
193  }
194  else if(pconName=="Endcap::BrassPlug2") {
195  brassPlugPlanesVect[1][key] = ind;
196  }
197  }
198 
199 
201  // Define geometry
203 
204  // Set up strings for volume names.
205  std::string baseName = "LAr::Endcap::Cryostat";
206 
207  // Define the mother volume for the endcap cryostat. Everything
208  // else in the endcap (cryostat walls, detectors, etc.) should be
209  // placed inside here.
210 
211  // The position of this volume may change if the thickness of the
212  // cabling in front of the endcaps changes. Therefore, we must get
213  // the z-shift from the database and adjust the volume geometry
214  // accordingly.
215 
216  std::string cryoMotherName = baseName + "::MotherVolume";
217  GeoPcon* cryoMotherShape = new GeoPcon(0.,2.*M_PI);
218 
219  double zStartCryoMother = 0.; // This variable is needed to calculate local transform of the MBTS mother
220 
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"
226  );
227  } else {
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");
232  /* This sould be corrected in the DB, but we have no time */
233  if(m_activateFT){
234  if(zplane == 0.){
235  zplane = 12.;
236  log << MSG::DEBUG << "Put cryoMother zplane " << ind
237  << " at " << zplane << " to accomodate FEC" << endmsg;
238  }
239  if(rmax == 2476.){
240  rmax = 2506.;
241  log << MSG::DEBUG << "Put cryoMother rmax " << ind
242  << " at " << rmax << " to accomodate FT Chimney" << endmsg;
243  }
244  }
245  cryoMotherShape->addPlane(zplane, rmin, rmax);
246  if(ind == 0) zStartCryoMother = zplane;
247  }
248  }
249 
250  const GeoLogVol* cryoMotherLogical = new GeoLogVol(cryoMotherName, cryoMotherShape, Air);
251  GeoIntrusivePtr<GeoFullPhysVol> cryoMotherPhysical{new GeoFullPhysVol(cryoMotherLogical)};
252 
253  //JT. 04.2013
254  // insert extra material in form of Tubes
255  // between warm and cold wall in front of Emec Presampler
256  // ( walls : warm(cylNumber=3), cold(cylNumber=14)
257  // in case of negative value of the thickness, no volume will be created
258  //
259 
260  // Extra cylinders
261 
262  IRDBRecordset_ptr cryoExtraCyl = rdbAccessSvc->getRecordsetPtr("LArCones",detectorKey, detectorNode);
263 
264  if(m_fullGeo && cryoCylinders->size()>0){
265  unsigned int nextra=cryoExtraCyl->size();
266  if(nextra>0){
267  log << MSG::DEBUG << "activate extra material in front of PS" << endmsg;
268  bool finloop=false;
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"); //PS rmin
273  double rmax=(*cryoExtraCyl)[i]->getDouble("RMAX1"); //PS rmax
274  double dz = (*cryoExtraCyl)[i]->getDouble("DZ"); //leadthickness
275  if(dz>0.){
276 
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.;
279  int wallfind=0;
280 
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"){
285  if(cylNumber == 3 )
286  {
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.;
291  wallfind=wallfind+1;
292  }
293  if(cylNumber == 14 )
294  {
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.;
299  wallfind=wallfind+1;
300  }
301  }
302  }
303  if(wallfind==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.;
307 
308  std::ostringstream cylStream;
309  cylStream << baseName << "::ExtraCyl";
310  std::string cylName = cylStream.str();
311  cylName = cylName + "_beforePS";
312 
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"); //lead
317  const GeoMaterial *mat = materialManager->getMaterial(material);
318  if (!mat) {
319  throw std::runtime_error("Error in EndcapCryostatConstruction,material for CylBeforePS is not found.");
320  }
321 
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);
325 
326  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zpos)));
327  cryoMotherPhysical->add(physCyl);
328 
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
334  <<std::endl;
335 
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;
341 
342  finloop=true;
343  } // warm cold walls found
344  } // dz>0. , extra cyl. thickness is positive
345  } //CylBeforePS ; extracyl is defined in the db record
346  if(finloop) break;
347  } // loop for extra cyls in the db record
348  } // number of items in the db record >0
349  else {
350  log << MSG::DEBUG << "no extra material in front of PS" << endmsg;
351  }
352  } // fullgeo is required and cryocyl reciord is not empty
353 
354  // end of inserting extra lead plate before PS
355 
356 
357  IRDBRecordset_ptr LArEndcapCratePhiPos = rdbAccessSvc->getRecordsetPtr("LArEndcapCratePhiPos",detectorKey, detectorNode);
358 
359 
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) {
364  // 100 - is the piece of Shielding. We need to build it for minimal geo too
365 
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());
370 
371  if(!currentRecord->isFieldNull("QUALIFIER")){
372  const std::string& qualifier = currentRecord->getString("QUALIFIER");
373  if (!qualifier.empty()) cylName = cylName + "::" + qualifier;
374  }
375 
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.,
380  (double) 0.,
381  (double) 2.*M_PI*Gaudi::Units::rad
382  );
383  const GeoMaterial *material = materialManager->getMaterial(currentRecord->getString("MATERIAL"));
384 
385  if(!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());
390  }
391 
392  if(m_activateFT){ // need to cut holes in cryostat walls for FT
393  if(cylNumber == 13){ // warm wall
394  log << MSG::DEBUG << "Cut holes for feedthroughs in warm wall "
395  << cylName
396  << endmsg;
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)
412  ));
413  };
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;
417  if(num == 10){ // topmost crate has one FT
418  put(phi + dphi); // asymmetric, see DMConstruction
419  } else {
420  put(phi - dphi);
421  put(phi + dphi);
422  }
423  }
424  solidCyl = warmwall;
425  } else if(cylNumber == 20){ // cold wall
426  log << MSG::DEBUG << "Cut holes for feedthroughs in cold wall "
427  << cylName
428  << endmsg;
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)
443  ));
444  };
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;
448  if(num == 10){ // topmost crate has one FT
449  put(phi + dphi); // asymmetric, see DMConstruction
450  } else {
451  put(phi - dphi);
452  put(phi + dphi);
453  }
454  }
455  solidCyl = coldwall;
456  }
457  }
458 
459  const GeoLogVol* logicCyl = new GeoLogVol(cylName,solidCyl,material);
460  GeoIntrusivePtr<GeoPhysVol> physCyl = new GeoPhysVol(logicCyl);
461 
462  double zInCryostat = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm
463  + currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
464  // Don't move the pump even if the rest of the cryostat moves.
465 
466  //if ( cylNumber == 33 ) zInCryostat -= zEmec;
467 
468  // Place each cylinder.
469 
470  cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
471  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
472 
473  // Front cold wall of Cryostat is a mother for Endcap Presampler
474  if ( cylNumber == 14 ) {
475  // its PhysicalVolume has a special name
476  cryoMotherPhysical->add( new GeoNameTag(cylName + "::PresamplerMother") );
477 
478  EndcapPresamplerConstruction endcapPresamplerConstruction;
479 
480  GeoIntrusivePtr<GeoFullPhysVol> emecPSEnvelope = endcapPresamplerConstruction.Envelope();
481  if (emecPSEnvelope) {
482  // Get the position of the presampler from the geometry helper.
483  double Zpos = 30.5*Gaudi::Units::mm;
484 
485  // It is highly debateable whether the endcap presampler is
486  // alignable, but in any case we shall not align it here because
487  // we need to completely redo it, anyway, since it does not
488  // even live "in" this volume, not in real life anyway.
489  GeoTransform *xfPs = new GeoTransform(GeoTrf::TranslateZ3D(Zpos));
490 
491  physCyl->add(xfPs);
492  physCyl->add( emecPSEnvelope );
493 
494  std::string tag = bPos? std::string("PRESAMPLER_EC_POS") : std::string("PRESAMPLER_EC_NEG");
496 
497  StoredPhysVol *sPhysVol = new StoredPhysVol(emecPSEnvelope);
498  status=detStore->record(sPhysVol,tag);
499  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
500  }
501  }
502 
503  // After we've added any additional sub-volumes, add the cylinder.
504  cryoMotherPhysical->add(physCyl);
505  }
506  }
507  }
508 
509  // g.p., 3-Apr-2006
510  // placing Pcones for FCAL nose, instead of cylinders 34,28,29
511  if(m_fullGeo)
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);
516 
517  if(iter==fcalNosePlanes.end()) {
518  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerWall");
519  } else {
520  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
521  fcalNosePcon->addPlane(currentRecord->getDouble("ZPLANE"),
522  currentRecord->getDouble("RMIN"),
523  currentRecord->getDouble("RMAX"));
524  }
525  }
526  int coneNumber = 1;
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);
531  }
532 
533 
534  // There are two LAr regions within the endcap cryostat. The first
535  // is the region that contains the EMEC and HEC (the electromagnetic
536  // and hadronic endcap calorimeters, respectively). The second is
537  // the region that contains the forward calorimeter.
538 
539  // This volumes will be sub-divided into sensitive-detector regions
540  // in the detector.
541 
542  // EMEC + HEC:
543  std::string totalEMHLArName = baseName + "::EmecHecLAr";
544  GeoPcon* totalEMHLArShape = new GeoPcon(0.,2.*M_PI);
545 
546  for(unsigned int ind=0; ind<emhPlanes.size(); ind++)
547  {
548  iter = emhPlanes.find(ind);
549 
550  if(iter==emhPlanes.end())
551  throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in EMH");
552  else
553  {
554  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
555  totalEMHLArShape->addPlane(currentRecord->getDouble("ZPLANE"),
556  currentRecord->getDouble("RMIN"),
557  currentRecord->getDouble("RMAX"));
558  }
559  }
560 
561  const GeoLogVol* totalEMHLArLogical =
562  new GeoLogVol(totalEMHLArName, totalEMHLArShape, LAr);
563 
564  GeoIntrusivePtr<GeoFullPhysVol> totalEMHLArPhysical = new GeoFullPhysVol(totalEMHLArLogical);
565 
566  // Add brass plugs
567  const GeoMaterial *PlugBrass(nullptr);
568  for(size_t i(0);i<2;++i) {
569  const planeIndMap& brassPlugPlanes = brassPlugPlanesVect[i];
570  if (!brassPlugPlanes.empty()) {
571  if(!PlugBrass) {
572  PlugBrass = materialManager->getMaterial("LAr::PlugBrass");
573  if (!PlugBrass) throw std::runtime_error("Error in EndcapCryostatConstruction, LAr::PlugBrass is not found.");
574  }
575  GeoPcon *brassPlugPcon = new GeoPcon(0,2*M_PI);
576  for(unsigned int ind=0; ind<brassPlugPlanes.size(); ind++) {
577  iter = brassPlugPlanes.find(ind);
578 
579  if(iter==brassPlugPlanes.end()) {
580  throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in BrassPlug");
581  } else {
582  const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
583  brassPlugPcon->addPlane(currentRecord->getDouble("ZPLANE"),
584  currentRecord->getDouble("RMIN"),
585  currentRecord->getDouble("RMAX"));
586  }
587  }
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);
592  }
593  }
594 
595  if(m_activateFT){
596  // this ring emulates signal cables concentration area
597  // nearby the theedtrougs inside the cryostat
598  const double rcoldwall = 2155.*Gaudi::Units::mm;
599  const double coldhole_radius = 0.5*150.*Gaudi::Units::mm; // copied from above
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
604  / (icable_dz*2);
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);
614  }
615 
616  cryoMotherPhysical->add( totalEMHLArPhysical );
617 
618  {
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);
623 
624  //=>
625  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, bPos ? "EMEC_POS":"EMEC_NEG");
626  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
628  GeoAlignableTransform *xfEmec = new GeoAlignableTransform(xfPos);
629 
630  std::string tag = bPos? std::string("EMEC_POS") : std::string("EMEC_NEG");
632 
633  StoredPhysVol *sPhysVol = new StoredPhysVol(envelope);
634  status=detStore->record(sPhysVol,tag);
635  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
636 
637  StoredAlignX *sAlignX = new StoredAlignX(xfEmec);
638  status=detStore->record(sAlignX,tag);
639  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
640 
641 
642  //=>
643  totalEMHLArPhysical->add(xfEmec);
644  totalEMHLArPhysical->add( envelope );
645  }
646 
647  {
648 
649  std::string wheelType="front";
650  bool threeBoards= false;
651  HECWheelConstruction frontHEC(m_fullGeo,wheelType,threeBoards,bPos) ;
652  GeoIntrusivePtr<GeoFullPhysVol> EnvelopeF = frontHEC.GetEnvelope();
653 
655 
656 
657  //--- Make the Front Wheel alignable:
658 
659  const IRDBRecord *posHec1 = GeoDBUtils::getTransformRecord(larPosition, bPos ? "HEC1_POS":"HEC1_NEG");
660  GeoTrf::Transform3D xfPosHec1 = posHec1 ? GeoDBUtils::getTransform(posHec1) : GeoTrf::Translate3D(0.,0.,-2423.0);
661  GeoAlignableTransform *xfHec1 = new GeoAlignableTransform(xfPosHec1);
662 
663  std::string tag1 = bPos? std::string("HEC1_POS") : std::string("HEC1_NEG");
664 
665  StoredPhysVol *sPhysVol1 = new StoredPhysVol(EnvelopeF);
666  status=detStore->record(sPhysVol1,tag1);
667  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
668 
669  StoredAlignX *sAlignX1 = new StoredAlignX(xfHec1);
670  status=detStore->record(sAlignX1,tag1);
671  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
672 
673  totalEMHLArPhysical->add( xfHec1);
674  totalEMHLArPhysical->add(new GeoIdentifierTag(0));
675  totalEMHLArPhysical->add( EnvelopeF );
676 
677 
678 
679  wheelType="rear";
680  threeBoards= false;
681  HECWheelConstruction rearHEC(m_fullGeo,wheelType,threeBoards,bPos) ;
682  GeoIntrusivePtr<GeoFullPhysVol> EnvelopeR = rearHEC.GetEnvelope();
683 
684  const IRDBRecord *posHec2 = GeoDBUtils::getTransformRecord(larPosition, bPos ? "HEC2_POS":"HEC2_NEG");
685  GeoTrf::Transform3D xfPosHec2 = posHec2 ? GeoDBUtils::getTransform(posHec2) : GeoTrf::Translate3D(0.,0.,-1566.0);
686  GeoAlignableTransform *xfHec2 = new GeoAlignableTransform(xfPosHec2);
687 
688  std::string tag2 = bPos? std::string("HEC2_POS") : std::string("HEC2_NEG");
689 
690  StoredPhysVol *sPhysVol2 = new StoredPhysVol(EnvelopeR);
691  status=detStore->record(sPhysVol2,tag2);
692  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
693 
694  StoredAlignX *sAlignX2 = new StoredAlignX(xfHec2);
695  status=detStore->record(sAlignX2,tag2);
696  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
697 
698  totalEMHLArPhysical->add( xfHec2);
699  totalEMHLArPhysical->add(new GeoIdentifierTag(1));
700  totalEMHLArPhysical->add( EnvelopeR );
701 
702 
703  }
704 
705 
706 
707  // 13-Mar-2002 WGS: Place the FCAL detector inside the cryostat.
708  m_fcal.setFCALVisLimit(m_fcalVisLimit);
709  m_fcal.setFullGeo(m_fullGeo);
710  {
711 
712  // The "envelope" determined by the EMB should be a GeoFullPhysVol.
713  GeoIntrusivePtr<GeoVFullPhysVol> fcalEnvelope = m_fcal.GetEnvelope(bPos);
714 
715  /* For now, comment out the FCAL placement, for two reasons:
716  1) The FCAL geometry helper class has been written yet;
717  2) Reconstruction needs each FCAL module to have a
718  separate alignable envelope. We'll work out t hese
719  issues later. */
720 
721 
722  // From FCALConstruction.cxx: */
723  //
724 
725  std::string tag = bPos ? "FCAL_POS" : "FCAL_NEG";
726  // Get default values for alignable transform deltas from SubdetPosHelper
727  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, tag);
728  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
730  GeoAlignableTransform *fcalXF = new GeoAlignableTransform(xfPos);
731 
733  StoredAlignX *sAlignX = new StoredAlignX(fcalXF);
734  status=detStore->record(sAlignX,tag);
735  if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
736 
737 
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");
742  }
743 
744  const GeoTubs * tubs = (const GeoTubs *) envShape;
745 
746  // Place the FCAL modules.
747  cryoMotherPhysical->add(fcalXF);
748  cryoMotherPhysical->add( new GeoTransform( GeoTrf::TranslateZ3D(tubs->getZHalfLength()) ) );
749  cryoMotherPhysical->add( fcalEnvelope );
750 
751 
752  }
753 
754  //__________________________ MBTS+moderator+JM tube _____________________________________
755  if(m_enableMBTS && !rdbAccessSvc->getChildTag("MBTS",detectorKey, detectorNode).empty()) {
756  // DB related stuff first
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);
762 
763  double zposMM = 0.;
764  std::map<std::string,unsigned> trdMap; // Used in the new description only
765  for(unsigned indTrd(0);indTrd<mbtsTrds->size();++indTrd) {
766  const std::string& keyTrd = (*mbtsTrds)[indTrd]->getString("TRD");
767  trdMap[keyTrd]=indTrd;
768  }
769 
770  // Build material geometry only if the FullGeo flag has been set
771  if(m_fullGeo) {
772  // Define iterators
773  IRDBRecordset::const_iterator itMother = mbtsTubs->end();
774  IRDBRecordset::const_iterator itModerator = mbtsTubs->end();
775  IRDBRecordset::const_iterator itTube=mbtsTubs->end();
776 
777  IRDBRecordset::const_iterator first = mbtsTubs->begin();
778  IRDBRecordset::const_iterator last = mbtsTubs->end();
779 
780  // Mother volume
781  GeoIntrusivePtr<GeoPhysVol> pvMM = nullptr;
782 
783  if(mbtsPcons->size()==0) {
784  // ****
785  // In this description the Moderator and the JM tube are constructed as separate volumes (both of them are tubes)
786  // ****
787 
788  for(; first!=last; ++first) {
789  const std::string& strTubeName = (*first)->getString("TUBE");
790  if(strTubeName == "MBTS_mother") {
791  itMother = first;
792  }
793  else if(strTubeName == "Moderator") {
794  itModerator = first;
795  }
796  else if(strTubeName == "JMTUBE") {
797  itTube = first;
798  }
799  }
800 
801  // Build mother volume
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;
806 
807  const GeoMaterial *matMM = materialManager->getMaterial((*itMother)->getString("MATERIAL"));
808 
809  GeoIntrusivePtr<GeoTube> tubeMM{new GeoTube(rminMM,rmaxMM,dzMM)};
810 
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;
816 
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);
823  solidMM=pcon;
824  }
825 
826  if (!solidMM) solidMM = new GeoTube(rminMM,rmaxMM,dzMM);
827 
828  GeoLogVol* lvMM = new GeoLogVol("MBTS_mother",solidMM,matMM);
829  pvMM = new GeoPhysVol(lvMM);
830 
831  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
832  cryoMotherPhysical->add(pvMM);
833 
834  // Moderator cylinder
835  //double rminMod = (*itModerator)->getDouble("RMIN")*Gaudi::Units::mm;
836  //double rmaxMod = (*itModerator)->getDouble("RMAX")*Gaudi::Units::mm;
837  double dzMod = (*itModerator)->getDouble("DZ")*Gaudi::Units::mm;
838  double zposMod = (*itModerator)->getDouble("ZPOS")*Gaudi::Units::mm;
839 
840  const GeoMaterial *matMod = materialManager->getMaterial((*itModerator)->getString("MATERIAL"));
841 
842  GeoTube* solidMod = new GeoTube(rminMM,rmaxMM,dzMod);
843  GeoLogVol* lvMod = new GeoLogVol("Moderator",solidMod, matMod);
844  GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
845 
846  pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMod)));
847  pvMM->add(pvMod);
848 
849  if (tubeJM) {
850  GeoLogVol* lvMod = new GeoLogVol("ModeratorTube",tubeJM, matMod);
851  GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
852 
853  pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D(tubeMM->getZHalfLength()+tubeJM->getZHalfLength())));
854  pvMM->add(pvMod);
855  }
856  } else {
857  // ****
858  // In this description the Moderator and the JM tube are constructed one polycone + one extra part for the moderator
859  // ****
860 
861  planeIndMap mbtsMotherPlanes, jmTubePlanes;
862  planeIndMap::const_iterator iter;
863 
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;
869  }
870  else if(pconName=="MBTS::JM") {
871  jmTubePlanes[key] = ind;
872  }
873  }
874 
875  double zStartMM = 0.;
876 
877  // construct shapes for the MBTS mother and Moderator+JM
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");
883  else {
884  const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
885  solidMM->addPlane(currentRecord->getDouble("ZPLANE"),
886  currentRecord->getDouble("RMIN"),
887  currentRecord->getDouble("RMAX"));
888  if(ind==0)
889  zStartMM = currentRecord->getDouble("ZPLANE");
890  }
891  }
892 
893 
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");
899  else {
900  const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
901  solidMod->addPlane(currentRecord->getDouble("ZPLANE"),
902  currentRecord->getDouble("RMIN"),
903  currentRecord->getDouble("RMAX"));
904  }
905  }
906 
907  // Construct volumes:
908 
909  // Mother
910  GeoLogVol* lvMM = new GeoLogVol("MBTS_mother",solidMM,Air);
911  pvMM = new GeoPhysVol(lvMM);
912 
913  zposMM = zStartCryoMother - zStartMM;
914  cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
915  cryoMotherPhysical->add(pvMM);
916 
917  // Extra tube for the moderator:
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);
926 
927  pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D((*mbtsTubs)[0]->getDouble("ZPOS"))));
928  pvMM->add(pvJM);
929 
930  // Moderator+JM polycone
931  GeoLogVol* lvMod = new GeoLogVol("ModeratorJMPcon",solidMod, matJM);
932  GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
933 
934  pvMM->add(pvMod);
935  }
936 
937  // Scintillators
938  if(mbtsGen->size()==0) {
939  // The "old" description: just scintillators, no aluminum envelopes
940  for(unsigned int scinId=0; scinId<mbtsScin->size(); scinId++) {
941  const IRDBRecord* curScin = (*mbtsScin)[scinId];
942 
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;
951 
952  double startPhi = 0.;
953  try {
954  if(!curScin->isFieldNull("STARTPHI"))
955  startPhi = curScin->getDouble("STARTPHI");
956  }
957  catch(std::runtime_error&) {}
958 
959  const GeoMaterial *matScin = materialManager->getMaterial(curScin->getString("MATERIAL"));
960 
961  std::ostringstream ostr;
962  ostr << curScin->getInt("SCIN_ID");
963  std::string scinName = std::string("MBTS")+ostr.str();
964 
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);
968 
969  // parameterizations
970  double deltaPhi = 360./nScin;
971  Variable varInd;
972  GeoSerialTransformer* stScin = nullptr;
973 
974  if(bPos) {
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);
978  } else {
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);
982  }
983 
984  pvMM->add(new GeoSerialIdentifier(0));
985  pvMM->add(stScin);
986  }
987  }
988  else {
989  // The "new" description: scintillators + aluminum envelopes + plastic plugs + aluminum press bars (only for RUN1)
990 
991  // General parameters
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");
996 
997  GeoIntrusivePtr<GeoPhysVol>pvAirEnv{}, pvAluEnv{} , pvAirInAlu{};
998 
999  // Build the air envelope first
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);
1005 
1006  // Build direct children of the air envelope
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)
1013  pvAluEnv = nevVol;
1014  }
1015  }
1016 
1017  // Build direct children of the aluminum envelope
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;
1025  }
1026  }
1027 
1028  // Build direct children of the 'air-in-aluminum'
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);
1033  }
1034 
1035  // parameterizations
1036  double deltaPhi = 360./nAirEnv;
1037  Variable varInd;
1038  GeoSerialTransformer* stAirEnv = nullptr;
1039  if(bPos) {
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);
1043  } else {
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);
1047  }
1048 
1049  pvMM->add(new GeoSerialIdentifier(0));
1050  pvMM->add(stAirEnv);
1051 
1052  }
1053  } // if(m_fullGeo)
1054 
1055  // Build readout for MBTS
1056  // Do it only once for both A and C sides
1057  if(bPos) {
1059  , rdbAccessSvc.get()
1061  , zposMM
1062  , trdMap
1063  , detectorKey
1064  , detectorNode).isFailure()) {
1065  throw std::runtime_error("Failed to build MBTS readout geometry");
1066  }
1067  }
1068 
1069  }
1070 
1071  // Build endcap dead matter around the cryostat
1072  EndcapDMConstruction crateBuilder(m_activateFT);
1073  crateBuilder.create(cryoMotherPhysical);
1074 
1075  return cryoMotherPhysical;
1076 }
1077 
1078 GeoIntrusivePtr<GeoPhysVol> LArGeo::EndcapCryostatConstruction::buildMbtsTrd(const IRDBRecord* rec
1079  , StoredMaterialManager* matmanager
1080  , GeoIntrusivePtr<GeoPhysVol> parent)
1081 {
1082  // Construct the Trd
1083  double dx1 = rec->getDouble("DX1");
1084  double dx2 = rec->getDouble("DX2");
1085  double dy1 = rec->getDouble("DY1");
1086  double dy2 = rec->getDouble("DY2");
1087  double dz = rec->getDouble("DZ");
1088  GeoTrd* solid = new GeoTrd(dx1,dx2,dy1,dy2,dz);
1089  GeoLogVol* lv = new GeoLogVol(rec->getString("TRD")
1090  ,solid
1091  ,matmanager->getMaterial(rec->getString("MATERIAL")));
1092  GeoIntrusivePtr<GeoPhysVol> pv = new GeoPhysVol(lv);
1093  if(parent) {
1094  double xpos = rec->getDouble("XPOS");
1095  double ypos = rec->getDouble("YPOS");
1096  double zpos = rec->getDouble("ZPOS");
1097  parent->add(new GeoTransform(GeoTrf::TranslateZ3D(zpos)*GeoTrf::TranslateY3D(ypos)*GeoTrf::TranslateX3D(xpos)));
1098  parent->add(pv);
1099  }
1100  return pv;
1101 }
IRDBRecord::getInt
virtual int getInt(const std::string &fieldName) const =0
Get int field value.
beamspotman.r
def r
Definition: beamspotman.py:676
LArGeo::EndcapDMConstruction::create
void create(GeoIntrusivePtr< GeoFullPhysVol > envelope) const
Definition: EndcapDMConstruction.cxx:49
LArGeo::HECWheelConstruction::GetEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope()
Definition: HECWheelConstruction.cxx:75
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
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
GeoDBUtils::getTransformRecord
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition: GeoDBUtils.h:23
LArGeo::EndcapDMConstruction
Definition: EndcapDMConstruction.h:14
LAr
Definition: LArVolumeBuilder.h:36
EndcapCryostatConstruction.h
Declaration of EndcapCryostatConstruction class.
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:55
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
StoredAlignX.h
EndcapDMConstruction.h
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
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
StoredPhysVol
Definition: StoredPhysVol.h:27
HECWheelConstruction.h
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
EventInfoWrite.AtlasVersion
AtlasVersion
Definition: EventInfoWrite.py:17
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
lumiFormat.i
int i
Definition: lumiFormat.py:85
GeoDBUtils.h
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
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
test_pyathena.parent
parent
Definition: test_pyathena.py:15
plotBeamSpotCompare.tag2
string tag2
Definition: plotBeamSpotCompare.py:76
LArGeo::EndcapCryostatConstruction::buildMbtsTrd
static GeoIntrusivePtr< GeoPhysVol > buildMbtsTrd(const IRDBRecord *rec, StoredMaterialManager *matmanager, GeoIntrusivePtr< GeoPhysVol > parent)
Definition: EndcapCryostatConstruction.cxx:1078
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
LArGeo::EndcapCryostatConstruction::EndcapCryostatConstruction
EndcapCryostatConstruction(bool fullGeo, std::string emecVariantInner="Wheel", std::string emecVariantOuter="Wheel", bool activateFT=false, bool enableMBTS=true)
Definition: EndcapCryostatConstruction.cxx:75
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
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:221
StoredMaterialManager.h
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
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
EndcapPresamplerConstruction.h
Declaration of EndcapPresamplerConstruction class.
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
y
#define y
LArGeo::HECWheelConstruction
Definition: HECWheelConstruction.h:23
GeoGenfun
Definition: ArrayFunction.cxx:7
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:536
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
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
IGeoModelSvc.h
StoreGateSvc.h
MbtsReadoutBuilder.h
Helper function for building readout geometry of the MBTS.
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
StoredPhysVol.h
LArGeo::EndcapCryostatConstruction::createEnvelope
GeoIntrusivePtr< GeoFullPhysVol > createEnvelope(bool bPos)
Definition: EndcapCryostatConstruction.cxx:89
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37