ATLAS Offline Software
BarrelCryostatConstruction.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 // BarrelCryostatConstruction
6 
7 // 28-Nov-2001 WGS: Revise to create cryostat mother volume, and to
8 // place all components of the barrel within this volume.
9 
14 
15 #include "GeoModelKernel/GeoElement.h"
16 #include "GeoModelKernel/GeoMaterial.h"
17 #include "GeoModelKernel/GeoFullPhysVol.h"
18 #include "GeoModelKernel/GeoPhysVol.h"
19 #include "GeoModelKernel/GeoVPhysVol.h"
20 #include "GeoModelKernel/GeoLogVol.h"
21 #include "GeoModelKernel/GeoPcon.h"
22 #include "GeoModelKernel/GeoTubs.h"
23 #include "GeoModelKernel/GeoTube.h"
24 #include "GeoModelKernel/GeoBox.h"
25 #include "GeoModelKernel/GeoCons.h"
26 #include "GeoModelKernel/GeoTransform.h"
27 #include "GeoModelKernel/GeoNameTag.h"
28 #include "GeoModelKernel/GeoAlignableTransform.h"
29 #include "GeoModelKernel/GeoIdentifierTag.h"
30 #include "GeoModelKernel/GeoVolumeTagCatalog.h"
31 #include "GeoModelKernel/GeoShapeIntersection.h"
32 #include "GeoModelKernel/GeoShapeSubtraction.h"
33 #include "GeoModelKernel/GeoShapeShift.h"
34 #include "GeoModelKernel/GeoShapeUnion.h"
35 #include "GeoModelKernel/GeoSerialTransformer.h"
42 #include "StoreGate/StoreGateSvc.h"
43 #include "GaudiKernel/MsgStream.h"
44 #include "GaudiKernel/Bootstrap.h"
45 
49 
50 // For transforms:
51 #include "CLHEP/Geometry/Transform3D.h"
52 // For units:
53 #include "GaudiKernel/PhysicalConstants.h"
54 // For Transformation Fields:
55 #include "GeoGenericFunctions/Abs.h"
56 #include "GeoGenericFunctions/Mod.h"
57 #include "GeoGenericFunctions/Rectangular.h"
58 #include "GeoGenericFunctions/Variable.h"
59 #include "GeoGenericFunctions/FixedConstant.h"
60 #include "GeoGenericFunctions/Sin.h"
61 #include "GeoGenericFunctions/Cos.h"
62 
63 #include <string>
64 #include <cmath>
65 #include <map>
66 #include <climits>
67 #include <stdexcept>
68 using namespace GeoXF;
69 using namespace GeoGenfun;
70 
71 // The objects for mapping plane indexes in Pcon to the record index
72 // in RDBRecordset
73 using planeIndMap = std::map<int, unsigned int, std::less<int>>;
74 
76  : AthMessaging("LAr::BarrelCryostatConstruction")
77  , m_barrelSagging(0)
78  , m_barrelVisLimit(-1)
79  , m_cryoMotherPhysical(nullptr)
80  , m_fullGeo(fullGeo)
81  , m_activateFT(ft)
82 {}
83 
85 
86 
88 {
89  if (m_cryoMotherPhysical) return m_cryoMotherPhysical;
90 
91  // Get access to the material manager:
92  ATH_MSG_DEBUG("started");
93 
94  SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
95  if (!detStore.isValid()) {
96  throw std::runtime_error("Error in LArDetectorFactory, cannot access DetectorStore");
97  }
98 
99  // Get the materials from the material manager:-----------------------------------------------------//
100  // //
101  StoredMaterialManager* materialManager = nullptr;
102  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
103 
104  const GeoMaterial *Air = materialManager->getMaterial("std::Air");
105  if (!Air) {
106  throw std::runtime_error("Error in BarrelCryostatConstruction, std::Air is not found.");
107  }
108 
109  const GeoMaterial *Aluminium = materialManager->getMaterial("std::Aluminium");
110  if (!Aluminium) {
111  throw std::runtime_error("Error in BarrelCryostatConstruction, std::Aluminium is not found.");
112  }
113 
114  const GeoMaterial *Titanium = materialManager->getMaterial("std::Titanium");
115  if (!Titanium) {
116  Titanium = Aluminium;
117  // No need to throw an error. Some configurations do not build anything out of titanium.
118  // throw std::runtime_error("Error in BarrelCryostatConstruction, std::Titanium is not found.");
119  }
120 
121  const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
122  if (!LAr) {
123  throw std::runtime_error("Error in BarrelCryostatConstruction, std::LiquidArgon is not found.");
124  }
125 
126 
127  // ----- ----- ------ Get primary numbers from the GeomDB ----- ----- -----
128  SmartIF<IGeoModelSvc> geoModel{Gaudi::svcLocator()->service("GeoModelSvc")};
129  if(!geoModel.isValid())
130  throw std::runtime_error("Error in BarrelCryostatConstruction, cannot access GeoModelSvc");
131  SmartIF<IRDBAccessSvc> rdbAccess{Gaudi::svcLocator()->service("RDBAccessSvc")};
132  if(!rdbAccess.isValid())
133  throw std::runtime_error("Error in BarrelCryostatConstruction, cannot access RDBAccessSvc");
134 
135  planeIndMap innerWallPlanes, innerEndWallPlanes, outerWallPlanes, cryoMotherPlanes, totalLarPlanes, halfLarPlanes, sctEcCoolingPlanes;
136  planeIndMap::const_iterator iter;
137  const IRDBRecord* currentRecord{nullptr};
138 
139  DecodeVersionKey larVersionKey(geoModel, "LAr");
140  ATH_MSG_DEBUG("Getting primary numbers for " << larVersionKey.node() << ", " << larVersionKey.tag());
141 
142  // ---- Alignable transforms for the barrel:
143  // 1. HalfLar + Presampler (pos/neg)
144  // 2. Coil
145  std::string names[]={"EMB_POS","EMB_NEG","SOLENOID"};
146  GeoAlignableTransform *xf[]={nullptr,nullptr,nullptr};
147  for (int n=0;n<3;n++) {
148 
149  IRDBRecordset_ptr larPosition = rdbAccess->getRecordsetPtr("LArPosition",larVersionKey.tag(), larVersionKey.node());
150 
151  if (larPosition->size()==0 ) {
152  larPosition = rdbAccess->getRecordsetPtr("LArPosition", "LArPosition-00");
153  if (larPosition->size()==0 ) {
154  throw std::runtime_error("Error, no lar position table in database!");
155  }
156  }
157 
158  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, names[n]);
159  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
161  xf[n] = new GeoAlignableTransform(xfPos);
162 
163  StoredAlignX *sAlignX = new StoredAlignX(xf[n]);
164  StatusCode status=detStore->record(sAlignX,names[n]);
165  if(!status.isSuccess()) throw std::runtime_error (("Cannot store " + names[n]).c_str() );
166  }
167 
168  GeoAlignableTransform *xfHalfLArPos=xf[0], *xfHalfLArNeg=xf[1], *xfSolenoid=xf[2];
169 
170 
171 
172 
173  IRDBRecordset_ptr cryoEars = rdbAccess->getRecordsetPtr("CryoEars", larVersionKey.tag(),larVersionKey.node());
174  IRDBRecordset_ptr idSupportRails = rdbAccess->getRecordsetPtr("IdSupportRail", larVersionKey.tag(), larVersionKey.node());
175  IRDBRecordset_ptr cryoCylinders = rdbAccess->getRecordsetPtr("CryoCylinders",
176  larVersionKey.tag(),
177  larVersionKey.node());
178  if(cryoCylinders->size()==0)
179  cryoCylinders = rdbAccess->getRecordsetPtr("CryoCylinders","CryoCylinders-00");
180 
181 
182  IRDBRecordset_ptr cryoPcons = rdbAccess->getRecordsetPtr("CryoPcons",
183  larVersionKey.tag(),
184  larVersionKey.node());
185  if(cryoPcons->size()==0)
186  cryoPcons = rdbAccess->getRecordsetPtr("CryoPcons","CryoPcons-00");
187 
188 
189  for (unsigned int ind=0; ind<cryoPcons->size(); ind++)
190  {
191  int key = (*cryoPcons)[ind]->getInt("PLANE_ID");
192  const std::string& pconName = (*cryoPcons)[ind]->getString("PCON");
193  if(pconName=="Barrel::InnerWall")
194  innerWallPlanes[key] = ind;
195  if (pconName=="Barrel::InnerEndWall")
196  innerEndWallPlanes[key] = ind;
197  else if(pconName=="Barrel::OuterWall")
198  outerWallPlanes[key] = ind;
199  else if(pconName=="Barrel::CryoMother")
200  cryoMotherPlanes[key] = ind;
201  else if(pconName=="Barrel::TotalLAr")
202  totalLarPlanes[key] = ind;
203  else if(pconName=="Barrel::HalfLAr")
204  halfLarPlanes[key] = ind;
205  else if(pconName=="Barrel::SctEcCooling")
206  sctEcCoolingPlanes[key] = ind;
207  }
208  // ----- ----- ------ Get primary numbers from the GeomDB ----- ----- -----
209 
211  // Define geometry
213 
214  // 1) There is mother volume.
215  // 2) There are ~ 60 cylindrical layers in the mother
216  // Also ~ 12 conical layers in the mother.
217  // Also the liquid argon volume.
218  // 3) There are 3 half barrels in the liquid argon volume.
219 
220  // 1) The mother volume. ---------------------------------------------------------------------------//
221  // //
222  std::string cryoMotherName = "LAr::Barrel::Cryostat::MotherVolume"; //
223 
224  // Define the mother volume for the entire barrel cryostat.
225  // Everything else in the barrel (cryostat walls, detector,
226  // presampler) should be placed inside here.
227 
228  // The size of this volume may change if the thickness of the
229  // cabling in front of the endcaps changes. Therefore, we must get
230  // the z-shift from the LAr information database
231  // (LArVDetectorParameters) and adjust the volume geometry
232  // accordingly.
233 
234  // double cryoMotherRin[] = {1149.8*Gaudi::Units::mm, 1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm};
235  // double cryoMotherRout[] = {2890. *Gaudi::Units::mm, 2890. *Gaudi::Units::mm,2250. *Gaudi::Units::mm,2250. *Gaudi::Units::mm,2890. *Gaudi::Units::mm,2890. *Gaudi::Units::mm};
236  // double cryoMotherZplan[] = {-3490.*Gaudi::Units::mm,-2850.*Gaudi::Units::mm,-2849.*Gaudi::Units::mm, 2849.*Gaudi::Units::mm, 2850.*Gaudi::Units::mm, 3490.*Gaudi::Units::mm};
237 
238  // Access source of detector parameters.
239  // VDetectorParameters* parameters = VDetectorParameters::GetInstance();
240 
241  // Get the z-Shift from the detector parameters routine.
242  // double zShift = parameters->GetValue("LArEMECZshift");
243 
244  // Adjust mother volume size.
245  // int lastPlaneCryo = ( sizeof(cryoMotherZplan) / sizeof(double) );
246  // cryoMotherZplan[lastPlaneCryo-1] += zShift;
247  // cryoMotherZplan[0] -= zShift;
248 
249  double dphi_all = 2.*M_PI;
250 
251  GeoPcon* cryoMotherShape =
252  new GeoPcon(0., // starting phi
253  dphi_all ); // total phi
254 
255  for(unsigned int ind=0; ind<cryoMotherPlanes.size(); ind++)
256  {
257  iter = cryoMotherPlanes.find(ind);
258 
259  if(iter==cryoMotherPlanes.end()) {
260  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in CryoMother");
261  }
262  else {
263  currentRecord = (*cryoPcons)[(*iter).second];
264 
265  cryoMotherShape->addPlane(currentRecord->getDouble("ZPLANE"),
266  currentRecord->getDouble("RMIN"),
267  currentRecord->getDouble("RMAX"));
268  }
269  }
270 
271  // for ( int i = 0; i != lastPlaneCryo; ++i )
272  // {
273  // cryoMotherShape->addPlane(
274  // cryoMotherZplan[i], // position of z planes
275  // cryoMotherRin[i], // tangent distance to inner surface
276  // cryoMotherRout[i]); // tangent distance to outer surface
277  // }
278 
279  const GeoLogVol* cryoMotherLogical =
280  new GeoLogVol(cryoMotherName, cryoMotherShape, Air);
281 
282  m_cryoMotherPhysical = new GeoFullPhysVol(cryoMotherLogical);
283  //tag this volume as one that can be used as an envelope volume to add other volumes inside later
284  //(e.g. ITk and HGTD services built by other tools)
285  GeoVolumeTagCatalog::VolumeTagCatalog()->addTaggedVolume("Envelope","LArBarrel",m_cryoMotherPhysical);
286 
287  // //
288  //--------------------------------------------------------------------------------------------------//
289 
290  //--------------------------------------------------------------------------------------------------//
291  // Cylindrical layers for the cryo mother: //
292  //
293  for (unsigned int ind=0; ind < cryoCylinders->size(); ind++)
294  {
295  currentRecord = (*cryoCylinders)[ind];
296 
297  if(currentRecord->getString("CYL_LOCATION")=="Barrel::CryoMother")
298  {
299 
300  const GeoMaterial *material = materialManager->getMaterial(currentRecord->getString("MATERIAL"));
301 
302  if (!material)
303  {
304  std::ostringstream errorMessage;
305  errorMessage << "Error in BarrelCrysostat Construction" << std::endl;
306  errorMessage << "Material " << currentRecord->getString("MATERIAL") << " is not found" << std::endl;
307  throw std::runtime_error(errorMessage.str().c_str());
308  }
309 
310 
311  std::ostringstream cylStream;
312  int cylID = currentRecord->getInt("CYL_ID");
313  cylStream << "LAr::Barrel::Cryostat::Cylinder::#" << cylID;
314  std::string cylName= cylStream.str();
315 
316  int cylNumber = currentRecord->getInt("CYL_NUMBER");
317  double zMin = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm;
318  double dZ = currentRecord->getDouble("DZ")*Gaudi::Units::cm;
319  double zInCryostat = zMin + dZ / 2.;
320 
321  if(m_fullGeo){
322  if ((*cryoEars).size()>0 && cylID==1) {
323  const IRDBRecord * record = (*cryoEars)[0];
324  double rmin = record->getDouble("EARRMIN");
325  double rmax = record->getDouble("EARRMAX");
326  double zthick = record->getDouble("EARZTHICKNESS");
327  double yvert = record->getDouble("EARVERTICALEXTENT");
328  GeoTubs *tubs = new GeoTubs(rmin,
329  rmax,
330  zthick/ 2.,
331  (double) 0.,
332  dphi_all);
333 
334  GeoBox *box = new GeoBox( rmax, yvert/2, rmax);
335 
336  const GeoShape & shape = tubs->intersect(*box);
337  const GeoLogVol *logVol = new GeoLogVol ("LAr::Barrel::Cryostat::Sector::Ear",&shape, material);
338  GeoIntrusivePtr<GeoPhysVol>earPhysVol = new GeoPhysVol(logVol);
339 
340  m_cryoMotherPhysical->add(new GeoNameTag(std::string("CryostatEarForward")));
341  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
342  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
343  m_cryoMotherPhysical->add(earPhysVol);
344 
345  m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("CryostatEarBackward")));
346  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
347  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat)));
348  m_cryoMotherPhysical->add(earPhysVol);
349  }
350 
351  if ((*cryoEars).size() > 0 && cylID==6) {
352  const IRDBRecord * record = (*cryoEars)[0];
353  double rmin = record->getDouble("LEGRMIN");
354  double rmax = record->getDouble("LEGRMAX");
355  double zthick = record->getDouble("LEGZTHICKNESS");
356  double yvert = record->getDouble("LEGYMAX");
357  double angle = record->getDouble("LEGANGLE");
358 
359  GeoTubs *tubs = new GeoTubs(rmin,
360  rmax,
361  zthick/ 2.,
362  -angle*(M_PI/180.0),
363  M_PI + 2*angle*(M_PI/180));
364 
365  GeoTrf::TranslateY3D offset(rmax-yvert);
366  GeoBox * box = new GeoBox(rmax,rmax, rmax);
367  const GeoShape & shape = tubs->subtract((*box)<<offset);
368 
369  const GeoLogVol *logVol = new GeoLogVol ("LAr::Barrel::Cryostat::Sector::Leg",&shape, material);
370  GeoIntrusivePtr<GeoPhysVol>legPhysVol = new GeoPhysVol(logVol);
371 
372  m_cryoMotherPhysical->add(new GeoNameTag(std::string("CryostatLegForward")));
373  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
374  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat+zthick)));
375  m_cryoMotherPhysical->add(legPhysVol);
376 
377  m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("CryostatLegBackward")));
378  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
379  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat-zthick)));
380  m_cryoMotherPhysical->add(legPhysVol);
381  }
382  }
383 
384  const GeoShape* solidBarrelCylinder = nullptr;
385  const GeoLogVol* logicBarrelCylinder = nullptr;
386 
387  // For Reco Geometry construct only solenoid cylinders
388  if(m_fullGeo || (10<=cylID && cylID<=14)) {
389  solidBarrelCylinder
390  = new GeoTubs(currentRecord->getDouble("RMIN")*Gaudi::Units::cm,
391  currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm,
392  currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.,
393  (double) 0.,
394  dphi_all);
395  if(m_activateFT){
396  if(cylID == 7){ // Cut holes for feedthroughs in warm wall
397  ATH_MSG_DEBUG("Cut holes for feedthroughs in warm wall " << cylName);
398  const double rmin = currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
399  const double rmax = currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
400  const double bellow_Router = 0.5*299.*Gaudi::Units::mm; // from DMconstruction
401  const double warmhole_radius = bellow_Router;
402  const double warmhole_pos = 4.*Gaudi::Units::cm;
403  GeoTube *warmhole = new GeoTube(0., warmhole_radius, (rmax - rmin) * 2);
404  const GeoShapeShift &h1 = (*warmhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
405  const double r = (rmin + rmax) * 0.5;
406  const GeoShape *warmwall = solidBarrelCylinder;
407  const double dphi = 4.*Gaudi::Units::deg;
408  const int NCrates = 16;
409  auto put = [&warmwall, &warmhole_pos, &r, &h1](double pos){
410  const double x = r*cos(pos);
411  const double y = r*sin(pos);
412  warmwall = &(warmwall->subtract(
413  h1 << GeoTrf::Translate3D(x, y, warmhole_pos)
414  *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
415  ));
416  };
417  for(int i = 0; i < NCrates; ++ i){
418  const double phi = 360.*Gaudi::Units::deg * i / NCrates;
419  put(phi - dphi);
420  put(phi + dphi);
421  }
422  solidBarrelCylinder = warmwall;
423  } else if(cylID == 2){ // Cut holes for feedthroughs in cold wall
424  ATH_MSG_DEBUG("Cut holes for feedthroughs in cold wall " << cylName);
425  const double rmin = currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
426  const double rmax = currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
427  const double coldhole_radius = 0.5*150.*Gaudi::Units::mm; // see DMconstruction
428  const double coldhole_pos = 27.5*Gaudi::Units::mm;
429  GeoTube *coldhole = new GeoTube(0., coldhole_radius, (rmax - rmin) * 2);
430  const GeoShapeShift &h1 = (*coldhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
431  const double r = (rmin + rmax) * 0.5;
432  const GeoShape *coldwall = solidBarrelCylinder;
433  const double dphi = 4.*Gaudi::Units::deg;
434  const int NCrates = 16;
435  for(int i = 0; i < NCrates; ++ i){
436  const double phi = 360.*Gaudi::Units::deg * i / NCrates;
437  auto put = [&coldwall, &coldhole_pos, &r, &h1](double pos){
438  const double x = r*cos(pos);
439  const double 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  put(phi - dphi);
446  put(phi + dphi);
447  }
448  solidBarrelCylinder = coldwall;
449  }
450  }
451 
452  logicBarrelCylinder = new GeoLogVol(cylName,solidBarrelCylinder,material);
453  }
454 
455  if(logicBarrelCylinder) {
456  // If ZMIN < 0 place the cylinder onse
457  // If ZMIN >=0 place each cylinder twice, at +z and -z.
458  if(zMin<0) {
459  GeoIntrusivePtr<GeoFullPhysVol> physBarrelCylinder = new GeoFullPhysVol(logicBarrelCylinder);
460 
461  m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("Phys")));
462  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
463 
464  // put alignamble transform for cryostat cylinders 10<=cylID<=14
465  if(10<=cylID && cylID<=14)
466  m_cryoMotherPhysical->add(xfSolenoid);
467 
468  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
469  m_cryoMotherPhysical->add(physBarrelCylinder);
470 
471 
472  // NOTE: there are 5 volumes for solenoid with NO common direct parent
473  // I'm storing the first one #10. (FIXME)
474  // NOTE: Pretty soon there will
475  // be no need at all to store physical volumes in the manager or in storegate!
476  if(cylID==10) {
477  StoredPhysVol *sPhysVol = new StoredPhysVol(physBarrelCylinder);
478  StatusCode status=detStore->record(sPhysVol,"SOLENOID");
479  if(!status.isSuccess()) throw std::runtime_error ("Cannot store SOLENOID");
480  }
481 
482  }else{
483  GeoIntrusivePtr<GeoPhysVol> physBarrelCylinder = new GeoPhysVol(logicBarrelCylinder);
484 
485  m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("PhysForward")));
486  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
487  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
488  m_cryoMotherPhysical->add(physBarrelCylinder);
489 
490  m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("PhysBackward")));
491  m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
492  if(m_activateFT && (cylID == 2 || cylID == 7)){
493  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::RotateY3D(180.*Gaudi::Units::deg)));
494  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
495  } else {
496  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat)));
497  }
498  m_cryoMotherPhysical->add(physBarrelCylinder);
499  }
500  }
501  }
502  } //
503  //--------------------------------------------------------------------------------------------------//
504 
505  if(m_fullGeo) {
506  // Make a Polycon for the outer wall:
507  GeoPcon *outerWallPcon = new GeoPcon(0,dphi_all);
508 
509  for(unsigned int ind=0; ind<outerWallPlanes.size(); ind++) {
510  iter = outerWallPlanes.find(ind);
511 
512  if(iter==outerWallPlanes.end())
513  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in OuterWall");
514  else {
515  currentRecord = (*cryoPcons)[(*iter).second];
516  outerWallPcon->addPlane(currentRecord->getDouble("ZPLANE"),
517  currentRecord->getDouble("RMIN"),
518  currentRecord->getDouble("RMAX"));
519  }
520  }
521 
522  const GeoLogVol *outerWallLog = new GeoLogVol("LAr::Barrel::Cryostat::OuterWall", outerWallPcon, Aluminium);
523  m_cryoMotherPhysical->add(new GeoNameTag(std::string("Barrel Cryo OuterWall Phys")));
524  GeoIntrusivePtr<GeoPhysVol>outerWallPhys = new GeoPhysVol(outerWallLog);
525  m_cryoMotherPhysical->add(outerWallPhys);
526 
527  // Make a Polycon for the inner wall:
528  GeoPcon *innerWallPcon = new GeoPcon(0,dphi_all);
529 
530  for(unsigned int ind=0; ind<innerWallPlanes.size(); ind++) {
531  iter = innerWallPlanes.find(ind);
532 
533  if(iter==innerWallPlanes.end())
534  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerWall");
535  else {
536  currentRecord = (*cryoPcons)[(*iter).second];
537  innerWallPcon->addPlane(currentRecord->getDouble("ZPLANE"),
538  currentRecord->getDouble("RMIN"),
539  currentRecord->getDouble("RMAX"));
540  }
541  }
542 
543  const GeoLogVol *innerWallLog = new GeoLogVol("LAr::Barrel::Cryostat::InnerWall", innerWallPcon, Aluminium);
544  m_cryoMotherPhysical->add(new GeoNameTag(std::string("Barrel Cryo InnerWall Phys")));
545  GeoIntrusivePtr<GeoPhysVol>innerWallPhys = new GeoPhysVol(innerWallLog);
546  m_cryoMotherPhysical->add(innerWallPhys);
547 
548  // Vis a la fin du cryostat
549 
550  IRDBRecordset_ptr cryoBolts = rdbAccess->getRecordsetPtr("LArBarrelCryoBolts",
551  larVersionKey.tag(),
552  larVersionKey.node());
553  if (cryoBolts->size() >0) {
554  ATH_MSG_INFO(" new description with barrel croystat bolts");
555  const IRDBRecord * cryoBoltsRecord = (*cryoBolts) [0];
556  double rmax_vis = cryoBoltsRecord->getDouble("RBOLT");
557  int Nvis = cryoBoltsRecord->getInt("NBOLT");
558  double PhiPos0 = cryoBoltsRecord->getDouble("PHI0");
559  double RhoPosB = cryoBoltsRecord->getDouble("RADIUS");
560  int index1 = cryoBoltsRecord->getInt("INDEXWALL1");
561  int index2 = cryoBoltsRecord->getInt("INDEXWALL2");
562  const GeoMaterial *bolt_material = materialManager->getMaterial(cryoBoltsRecord->getString("MATERIAL"));
563  if (!bolt_material) {
564  throw std::runtime_error("Error in BarrelCryostatConstruction, material for bolt not found");
565  }
566 
567 
568  double z1=-1.;
569  double z2=-1.;
570  if ((iter = innerWallPlanes.find(index1))!= innerWallPlanes.end()) {
571  const IRDBRecord * pconsRecord = (*cryoPcons) [(*iter).second];
572  z1 = pconsRecord->getDouble("ZPLANE");
573  }
574  if ((iter = innerWallPlanes.find(index2))!= innerWallPlanes.end()) {
575  const IRDBRecord * pconsRecord = (*cryoPcons) [(*iter).second];
576  z2 = pconsRecord->getDouble("ZPLANE");
577  }
578  if (z1>0. && z2>0.) {
579  double zthick_vis=(z2-z1)-0.1;
580 
581  GeoTubs *tub_vis = new GeoTubs(0.,rmax_vis,zthick_vis/2., (double) 0., dphi_all);
582  const GeoLogVol * log_vis = new GeoLogVol("LAr::Barrel::Cryostat::InnerWall::Vis",tub_vis,bolt_material);
583  GeoIntrusivePtr<GeoPhysVol> phys_vis = new GeoPhysVol(log_vis);
584 
585  double xxVis=((double)(Nvis));
586  double ZposB=0.5*(z1+z2);
587  double twopi128 = 2.*M_PI/xxVis;
588  GeoGenfun::Variable i;
589  GeoGenfun::Mod Mod1(1.0),Mod128(xxVis),Mod2(2.0);
590  GeoGenfun::GENFUNCTION PhiPos = PhiPos0 + twopi128*Mod128(i);
591  GeoGenfun::GENFUNCTION Int = i - Mod1;
592  GeoGenfun::Cos Cos;
593  GeoGenfun::Sin Sin;
594  GeoXF::TRANSFUNCTION TX =
595  GeoXF::Pow(GeoTrf::TranslateX3D(1.0),RhoPosB*Cos(PhiPos))*
596  GeoXF::Pow(GeoTrf::TranslateY3D(1.0),RhoPosB*Sin(PhiPos))*
597  GeoXF::Pow(GeoTrf::TranslateZ3D(2*ZposB),Int(i/128))*
598  GeoTrf::TranslateZ3D(-ZposB);
599  GeoSerialTransformer *st = new GeoSerialTransformer(phys_vis, &TX, 2*Nvis);
600  innerWallPhys->add(st);
601  }
602  } // bolts found in the geometry database
603  else {
604  ATH_MSG_INFO(" old description withut bold in the geometry database ");
605  }
606 
607 
608  // extra Cone for systematics in upstream matter
609  IRDBRecordset_ptr extraCones = rdbAccess->getRecordsetPtr("LArCones",
610  larVersionKey.tag(),
611  larVersionKey.node());
612  if (extraCones->size() > 0 ) {
613  int nextra=0;
614  for(const IRDBRecord_ptr& cone : *extraCones) {
615  const std::string& conName = cone->getString("CONE");
616  if (conName.find("ExtraInCryo") != std::string::npos) {
617  nextra++;
618  double extra_dz = 0.5*( cone->getDouble("DZ") );
619  double extra_rmin1 = cone->getDouble("RMIN1");
620  double extra_rmin2 = cone->getDouble("RMIN2");
621  double extra_rmax1 = cone->getDouble("RMAX1");
622  double extra_rmax2 = cone->getDouble("RMAX2");
623  double extra_phi0 = cone->getDouble("PHI0");
624  double extra_dphi = cone->getDouble("DPHI");
625  double extra_zpos = cone->getDouble("ZPOS");
626  // GU 20-feb-06
627  // if extra_dphi is close to 2pi (6.283185) it seems safer for G4 navigation
628  // to impose exactly same dphi as mother volume instead of a sligthly smaller dphi
629  if (extra_dphi>6.2831) extra_dphi = dphi_all;
630  // std::cout << " rmin1,rmin2,rmax1,rmax2,dz,phi0,dphi,zpos " << extra_rmin1 << " " << extra_rmin2 << " "
631  // << extra_rmax1 << " " << extra_rmax2 << " " << extra_dz << " " << extra_phi0 << " "
632  // << extra_dphi << " " << extra_zpos << std::endl;
633  GeoCons* extraCons
634  = new GeoCons(extra_rmin1,extra_rmin2,extra_rmax1,extra_rmax2,extra_dz,extra_phi0,extra_dphi);
635 
636  std::ostringstream extraStream;
637  extraStream << "LAr::Barrel::Cryostat::ExtraMat" << nextra;
638  std::string extraName= extraStream.str();
639  // std::cout << " extraName " << extraName << std::endl;
640 
641  GeoLogVol* extraLog = new GeoLogVol(extraName,extraCons,Aluminium);
642  GeoIntrusivePtr<GeoPhysVol> extraPhys = new GeoPhysVol(extraLog);
643  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(extra_zpos)));
644  m_cryoMotherPhysical->add(extraPhys);
645  }
646  }
647  }
648 
649  // Throw in coil support block
650  {
651  const GeoMaterial* myMaterial;
652  double length,height,width,pairSeparation,distFromRidge;
653  int nPairTot,indexWall;
654  IRDBRecordset_ptr newBlocks = rdbAccess->getRecordsetPtr("LArBarBumperBlocks", larVersionKey.tag(),larVersionKey.node());
655  if (newBlocks->size() >0 ) {
656  ATH_MSG_INFO(" new coil bumper description ");
657  const IRDBRecord * newBlocksRecord = (*newBlocks) [0];
658  length = newBlocksRecord->getDouble("LENGTH"); // deltaX
659  height = newBlocksRecord->getDouble("HEIGHT"); // delta Y
660  width = newBlocksRecord->getDouble("WIDTH"); // lenght in Z
661  pairSeparation = newBlocksRecord->getDouble("PAIRSEP");
662  distFromRidge = newBlocksRecord->getDouble("DISTANCEFROMRIDGE");
663  nPairTot = newBlocksRecord->getInt("NPAIRTOT");
664  indexWall = newBlocksRecord->getInt("INDEXWALL");
665  myMaterial = materialManager->getMaterial(newBlocksRecord->getString("MATERIAL"));
666  if (!myMaterial) {
667  throw std::runtime_error("Error in BarrelCryostatConstruction, material for coil bumpber not found");
668  }
669  }
670  else {
671  ATH_MSG_INFO(" old coil bumper description ");
672  IRDBRecordset_ptr tiBlocks = rdbAccess->getRecordsetPtr("TiBlocks", larVersionKey.tag(),larVersionKey.node());
673  const IRDBRecord * tiBlocksRecord = (*tiBlocks) [0];
674  length = tiBlocksRecord->getDouble("LENGTH"); // delta X
675  height = tiBlocksRecord->getDouble("HEIGHT"); // delta Y
676  width = tiBlocksRecord->getDouble("WIDTH"); // lenght in Z
677  pairSeparation = tiBlocksRecord->getDouble("PAIRSEP");
678  distFromRidge = tiBlocksRecord->getDouble("DISTANCEFROMRIDGE");
679  nPairTot = tiBlocksRecord->getInt("NPAIRTOT");
680  indexWall=8;
681  myMaterial=Titanium;
682  }
683 
684  double r=-1.;
685  double z=-1.;
686  if ((iter = innerWallPlanes.find(indexWall))!= innerWallPlanes.end()) {
687  const IRDBRecord * pconsRecord = (*cryoPcons) [(*iter).second];
688  r = pconsRecord->getDouble("RMAX");
689  z = pconsRecord->getDouble("ZPLANE");
690  }
691 
692  if (r>0.) {
693 
694 
695  // Make one block:
696  GeoBox *box = new GeoBox(length/2.0, height/2.0, width/2.0);
697  GeoLogVol *logVol = new GeoLogVol("LAr::Barrel::Cryostat::Sector::TitaniumBlock", box,myMaterial);
698  GeoIntrusivePtr<GeoPhysVol>physVol = new GeoPhysVol(logVol);
699 
700  double angle=pairSeparation/r;
701  double pos = -z+width/2 + distFromRidge;
702 // position of bumpers in new description
703  if (newBlocks->size() >0) {
704  GeoGenfun::Variable i; //
705  GeoGenfun::Mod Mod1(1.0),Mod2(2.0); //
706  GeoGenfun::GENFUNCTION Truncate = i - Mod1(i); //
707  GeoGenfun::GENFUNCTION AngleZ = -angle/2.+angle*Truncate(Mod2(i/2))+ 2.*M_PI/(1.0*nPairTot)*Truncate(i/4) + 2*M_PI/(2.*nPairTot);
708  GeoGenfun::GENFUNCTION TransZ = -pos + 2.*pos*Mod2(i);
709 
710  TRANSFUNCTION tx =
711  GeoXF::Pow(GeoTrf::TranslateZ3D(1.0),TransZ)*
712  GeoXF::Pow(GeoTrf::RotateZ3D(1.0),AngleZ)*
713  GeoTrf::Translate3D(0.,r+height/2,0.);
714  GeoSerialTransformer *t = new GeoSerialTransformer(physVol, &tx, nPairTot*4);
715  m_cryoMotherPhysical->add(t);
716  }
717 // position of bumper in old description
718  else {
719  GeoGenfun::Variable i; //
720  GeoGenfun::Mod Mod1(1.0),Mod2(2.0); //
721  GeoGenfun::GENFUNCTION Truncate = i - Mod1(i); //
722 
723  TRANSFUNCTION tx =
724  Pow(GeoTrf::RotateZ3D(2*M_PI/nPairTot),Truncate(i/4))*
725  Pow(GeoTrf::RotateZ3D(angle),Mod2(i/2))*
726  GeoTrf::RotateZ3D(-angle/2)*
727  Pow(GeoTrf::TranslateZ3D(2*pos),Mod2(i))*
728  GeoTrf::Translate3D(0,r+height/2, -pos);
729  GeoSerialTransformer *t = new GeoSerialTransformer(physVol, &tx, nPairTot*4);
730  m_cryoMotherPhysical->add(t);
731  }
732 
733  } // r>0.
734  else {
735  ATH_MSG_WARNING(" could not find wall index plane => no coil bumper description ");
736  }
737 
738  } // end of coil supports
739 
740 
741  // Make a Polycon for the inner endwall:
742  if(!innerEndWallPlanes.empty()) {
743  GeoPcon *innerEndWallPcon = new GeoPcon(0,dphi_all);
744 
745  for(unsigned int ind=0; ind<innerEndWallPlanes.size(); ind++) {
746  iter = innerEndWallPlanes.find(ind);
747 
748  if(iter==innerEndWallPlanes.end())
749  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerEndWall");
750  else {
751  currentRecord = (*cryoPcons)[(*iter).second];
752  innerEndWallPcon->addPlane(currentRecord->getDouble("ZPLANE"),
753  currentRecord->getDouble("RMIN"),
754  currentRecord->getDouble("RMAX"));
755  }
756  }
757 
758  const GeoLogVol *innerEndWallLog = new GeoLogVol("LAr::Barrel::Cryostat::InnerEndWall", innerEndWallPcon, Aluminium);
759  m_cryoMotherPhysical->add(new GeoNameTag(std::string("Barrel Cryo InnerEndWall Phys")));
760  GeoIntrusivePtr<GeoPhysVol>innerEndWallPhys = new GeoPhysVol(innerEndWallLog);
761  m_cryoMotherPhysical->add(innerEndWallPhys);
762  m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::RotateY3D(M_PI)));
763  m_cryoMotherPhysical->add(innerEndWallPhys);
764  }
765 
766  //------------------------------------------------------------------------------------------------//
767  /*if ((*idSupportRails).size()>0 && railrec->size() >0) {
768  } this part of code is moved into SupportRailFactory.cxx (InDetServMatGeoModel package) --- Adam Agocs */
769  } // if(m_fullGeo)
770  //--------------------------------------------------------------------------------------------------//
771 
772  //--------------------------------------------------------------------------------------------------//
773  // The total liquid argon volume inside the cryostat. This will be
774  // sub-divided into sensitive-detector regions in the detector
775  // routine.
776 
777  // double totalLArRin[] = { 1565.5*Gaudi::Units::mm, 1385.*Gaudi::Units::mm, 1385.*Gaudi::Units::mm, 1565.5*Gaudi::Units::mm };
778  // double totalLArRout[] = { 2140. *Gaudi::Units::mm, 2140.*Gaudi::Units::mm, 2140.*Gaudi::Units::mm, 2140. *Gaudi::Units::mm };
779  // double totalLArZplan[] = {-3267. *Gaudi::Units::mm,-3101.*Gaudi::Units::mm, 3101.*Gaudi::Units::mm, 3267. *Gaudi::Units::mm };
780 
781  GeoPcon* totalLArShape =
782  new GeoPcon(0., // starting phi
783  dphi_all); // total phi
784 
785  for(unsigned int ind=0; ind<totalLarPlanes.size(); ind++)
786  {
787  iter = totalLarPlanes.find(ind);
788 
789  if(iter==totalLarPlanes.end())
790  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in CryoMother");
791  else
792  {
793  currentRecord = (*cryoPcons)[(*iter).second];
794  totalLArShape->addPlane(currentRecord->getDouble("ZPLANE"),
795  currentRecord->getDouble("RMIN"),
796  currentRecord->getDouble("RMAX"));
797  }
798  }
799 
800  std::string totalLArName = "LAr::Barrel::Cryostat::TotalLAr";
801  const GeoLogVol* totalLArLogical = new GeoLogVol(totalLArName, totalLArShape, LAr);
802 
803  // When you place a polycone inside another polycone, the z=0
804  // co-ordinates will be the same. (Let's hope this is still true
805  // in GeoModel.)
806  m_cryoMotherPhysical->add(new GeoNameTag("Total LAR Volume"));
807  GeoIntrusivePtr<GeoPhysVol> totalLArPhysical = new GeoPhysVol(totalLArLogical);
808  m_cryoMotherPhysical->add(totalLArPhysical);
809  // //
810 
811  // 19-Feb-2003 ML: mother volumes for halfBarrels
812 
813  // To allow for mis-alignments, provide a 3mm gap at low z. (This
814  // is just a first pass; we may want to introduce other adjustments
815  // to this shape to allow for mis-alignments in other dimensions.)
816 
817  // increase internal radius to allow misalignments
818  // ----------------------------------------------- double rInShift = 0.*Gaudi::Units::mm;
819 
820  // double halfLArZplan[] = { 3.0 *Gaudi::Units::mm, 3101.*Gaudi::Units::mm, 3267. *Gaudi::Units::mm };
821  // double halfLArRin[] = {1385.*Gaudi::Units::mm + rInShift, 1385.*Gaudi::Units::mm + rInShift, 1565.5*Gaudi::Units::mm + rInShift};
822  // double halfLArRout[] = {2140.*Gaudi::Units::mm, 2140.*Gaudi::Units::mm, 2140. *Gaudi::Units::mm };
823 
824  std::string halfLArName = "LAr::Barrel::Cryostat::HalfLAr";
825  GeoPcon* halfLArShape =
826  new GeoPcon(
827  0., // starting phi
828  dphi_all // total phi
829  );
830 
831  for(unsigned int ind=0; ind<halfLarPlanes.size(); ind++)
832  {
833  iter = halfLarPlanes.find(ind);
834 
835  if(iter==halfLarPlanes.end())
836  throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in CryoMother");
837  else
838  {
839  currentRecord = (*cryoPcons)[(*iter).second];
840  halfLArShape->addPlane(currentRecord->getDouble("ZPLANE"),
841  currentRecord->getDouble("RMIN"),
842  currentRecord->getDouble("RMAX"));
843  }
844  }
845 
846  // Define logical volumes for both halves of the barrel.
847  const GeoLogVol* halfLArLogicalPos =
848  new GeoLogVol(halfLArName + "::Pos", halfLArShape, LAr);
849  GeoIntrusivePtr<GeoPhysVol> halfLArPhysicalPos = new GeoPhysVol(halfLArLogicalPos);
850 
851  const GeoLogVol* halfLArLogicalNeg =
852  new GeoLogVol(halfLArName + "::Neg", halfLArShape, LAr);
853  GeoIntrusivePtr<GeoPhysVol> halfLArPhysicalNeg = new GeoPhysVol(halfLArLogicalNeg);
854 
855  totalLArPhysical->add(new GeoNameTag(halfLArName + "::PosPhysical"));
856 
857  // add alignable transform
858  totalLArPhysical->add(xfHalfLArPos);
859  totalLArPhysical->add(halfLArPhysicalPos);
860 
861  totalLArPhysical->add(new GeoNameTag(halfLArName + "::NegPhysical"));
862 
863  // add alignable transform
864  totalLArPhysical->add(xfHalfLArNeg);
865  totalLArPhysical->add( new GeoTransform(GeoTrf::RotateY3D(180.*Gaudi::Units::deg)) );
866  totalLArPhysical->add(halfLArPhysicalNeg);
867 
868  {
869 
870  // 27-Nov-2001 WGS: Place the barrel LAr and detector inside the cryostat.
871  // There are two placements: one for the z>0 section, one for the z<0 section.
872 
873 
874  BarrelConstruction barrelConstruction(m_fullGeo, params);
875  barrelConstruction.setBarrelSagging(m_barrelSagging);
876  barrelConstruction.setBarrelCellVisLimit(m_barrelVisLimit);
877 
878 
879  // The "envelope" determined by the EMB should be a GeoFullPhysVol.
880  GeoIntrusivePtr<GeoFullPhysVol> barrelPosEnvelope = barrelConstruction.GetPositiveEnvelope();
881  if ( barrelPosEnvelope)
882  halfLArPhysicalPos->add(barrelPosEnvelope);
883 
884  // The "envelope" determined by the EMB should be a GeoFullPhysVol.
885  GeoIntrusivePtr<GeoFullPhysVol> barrelNegEnvelope = barrelConstruction.GetNegativeEnvelope();
886  if ( barrelNegEnvelope)
887  halfLArPhysicalNeg->add(barrelNegEnvelope);
888 
889  if(m_fullGeo) {
890  //--------------------------------------------------------------------------------------------------//
891  // Cylindrical layers for half LAr
892  //
893  for (unsigned int ind=0; ind < cryoCylinders->size(); ind++) {
894  currentRecord = (*cryoCylinders)[ind];
895 
896  if(currentRecord->getString("CYL_LOCATION")=="Barrel::HalfLAr"||
897  currentRecord->getString("CYL_LOCATION")=="Barrel::TotalLAr") {
898  bool isHalfLar = currentRecord->getString("CYL_LOCATION")=="Barrel::HalfLAr";
899 
900  const GeoMaterial *material = materialManager->getMaterial(currentRecord->getString("MATERIAL"));
901 
902  if (!material) {
903  std::ostringstream errorMessage;
904  errorMessage << "Error in BarrelCrysostat Construction" << std::endl;
905  errorMessage << "Material " << currentRecord->getString("MATERIAL") << " is not found" << std::endl;
906  throw std::runtime_error(errorMessage.str().c_str());
907  }
908 
909  std::ostringstream cylStream;
910  cylStream << "LAr::Barrel::Cryostat::";
911 
912  if (!currentRecord->isFieldNull("QUALIFIER")) {
913  const std::string& qualifier = currentRecord->getString("QUALIFIER");
914  if (!qualifier.empty()) cylStream << qualifier << "::";
915  }
916  cylStream << "Cylinder::#" << currentRecord->getInt("CYL_ID");
917  std::string cylName= cylStream.str();
918 
919  GeoTubs* solidBarrelCylinder
920  = new GeoTubs(currentRecord->getDouble("RMIN")*Gaudi::Units::cm,
921  currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm,
922  currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.,
923  (double) 0.,
924  dphi_all);
925 
926  const GeoLogVol* logicBarrelCylinder
927  = new GeoLogVol(cylName,solidBarrelCylinder,material);
928 
929  GeoIntrusivePtr<GeoPhysVol> physBarrelCylinder = new GeoPhysVol(logicBarrelCylinder);
930 
931  double zInCryostat = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm + currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
932 
933  int cylNumber = currentRecord->getInt("CYL_NUMBER");
934 
935 
936  if(isHalfLar) {
937  // Place each cylinder twice, once in each half-barrel:
938  halfLArPhysicalPos->add(new GeoNameTag(cylName+std::string("PhysForward")));
939  halfLArPhysicalPos->add(new GeoIdentifierTag(cylNumber));
940  // halfLArPhysicalPos->add(xfPos);
941  halfLArPhysicalPos->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
942  halfLArPhysicalPos->add(physBarrelCylinder);
943 
944  halfLArPhysicalNeg->add(new GeoNameTag(cylName+std::string("PhysBackward")));
945  halfLArPhysicalNeg->add(new GeoIdentifierTag(cylNumber));
946  // halfLArPhysicalNeg->add(xfNeg);
947  halfLArPhysicalNeg->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
948  halfLArPhysicalNeg->add(physBarrelCylinder);
949  } else {
950  totalLArPhysical->add(new GeoNameTag(cylName+std::string("PhysForward")));
951  totalLArPhysical->add(new GeoIdentifierTag(cylNumber));
952  totalLArPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
953  totalLArPhysical->add(physBarrelCylinder);
954 
955  totalLArPhysical->add(new GeoNameTag(cylName+std::string("PhysBackward")));
956  totalLArPhysical->add(new GeoIdentifierTag(cylNumber));
957  totalLArPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat)));
958  totalLArPhysical->add(physBarrelCylinder);
959  }
960  }
961  } //
962  //--------------------------------------------------------------------------------------------------//
963  }
964 
965  }
966  {
967  // ----- Presampler ------
968  double PresamplerMother_length = 1549.0*Gaudi::Units::mm; // Copied from PresParameterDef.icc
969  double presamplerShift = 3.*Gaudi::Units::mm;
970  BarrelPresamplerConstruction barrelPSConstruction(m_fullGeo, params);
971 
972  // The "envelope" determined by the EMB should be a GeoFullPhysVol.
973  GeoIntrusivePtr<GeoFullPhysVol> barrelPSPosEnvelope = barrelPSConstruction.GetPositiveEnvelope();
974  GeoTransform *xfPos = new GeoTransform(GeoTrf::Transform3D(GeoTrf::TranslateZ3D(PresamplerMother_length+presamplerShift)));
975  {
976  halfLArPhysicalPos->add(xfPos);
977  //halfLArPhysicalPos->add(new GeoNameTag("PositivePSBarrel"));
978  halfLArPhysicalPos->add(barrelPSPosEnvelope);
979 
980  StoredPhysVol *sPhysVol = new StoredPhysVol(barrelPSPosEnvelope);
981  StatusCode status=detStore->record(sPhysVol,"PRESAMPLER_B_POS");
982  if(!status.isSuccess()) throw std::runtime_error ("Cannot store PRESAMPLER_B_POS");
983  }
984  // The "envelope" determined by the EMB should be a GeoFullPhysVol.
985  GeoIntrusivePtr<GeoFullPhysVol> barrelPSNegEnvelope = barrelPSConstruction.GetNegativeEnvelope();
986  GeoTransform *xfNeg = new GeoTransform(GeoTrf::Transform3D(GeoTrf::TranslateZ3D(PresamplerMother_length+presamplerShift)));
987  {
988  halfLArPhysicalNeg->add(xfNeg);
989  //halfLArPhysicalPos->add(new GeoNameTag("NegativePSBarrel"));
990  halfLArPhysicalNeg->add(barrelPSNegEnvelope);
991 
992  StoredPhysVol *sPhysVol = new StoredPhysVol(barrelPSNegEnvelope);
993  StatusCode status=detStore->record(sPhysVol,"PRESAMPLER_B_NEG");
994  if(!status.isSuccess()) throw std::runtime_error ("Cannot store PRESAMPLER_B_NEG");
995  }
996 
997  }
998 
999  // SCT-EC Cooling
1000  IRDBRecordset_ptr cryoPconPhiSect = rdbAccess->getRecordsetPtr("CryoPconPhiSect", larVersionKey.tag(),larVersionKey.node());
1001  if ((*cryoPconPhiSect).size()!=0){
1002  for(unsigned i=0; i<cryoPconPhiSect->size(); ++i) {
1003  double startPhi = (*cryoPconPhiSect)[i]->getDouble("STARTPHI");
1004  double dPhi = (*cryoPconPhiSect)[i]->getDouble("DPHI");
1005  double centerPhi = startPhi + 0.5*dPhi;
1006 
1007  const GeoMaterial* material = materialManager->getMaterial((*cryoPconPhiSect)[i]->getString("MATERIAL"));
1008  if (!material) {
1009  std::string message = std::string("Error in BarrelCryostatConstruction! ") + (*cryoPconPhiSect)[i]->getString("MATERIAL") + std::string(" is not found.");
1010  throw std::runtime_error(message.c_str());
1011  }
1012 
1013  GeoPcon* pcon = new GeoPcon(startPhi*Gaudi::Units::deg,dPhi*Gaudi::Units::deg);
1014 
1015  for(unsigned int ii=0; ii<sctEcCoolingPlanes.size(); ii++) {
1016  iter = sctEcCoolingPlanes.find(ii);
1017 
1018  if(iter==sctEcCoolingPlanes.end()) {
1019  std::ostringstream stream;
1020  stream << "Error in BarrelCryostatConstruction, missing plane " << ii <<" in SCT-EC cooling";
1021  throw std::runtime_error(stream.str().c_str());
1022  }
1023  else {
1024  currentRecord = (*cryoPcons)[(*iter).second];
1025  pcon->addPlane(currentRecord->getDouble("ZPLANE"),
1026  currentRecord->getDouble("RMIN"),
1027  currentRecord->getDouble("RMAX"));
1028  }
1029  } // iterate over planes
1030 
1031  const GeoLogVol* sctCiCoolingLog = new GeoLogVol("LAr::Barrel::Cryostat::SctCiCooling",pcon,material);
1032  GeoIntrusivePtr<GeoPhysVol> sctCiCoolingPhys = new GeoPhysVol(sctCiCoolingLog);
1033 
1034  GeoTransform* xfPos1 = new GeoTransform(GeoTrf::Transform3D::Identity());
1035  GeoTransform* xfPos2 = new GeoTransform(GeoTrf::RotateZ3D(180*Gaudi::Units::deg));
1036  GeoTransform* xfNeg1 = new GeoTransform(GeoTrf::RotateZ3D((180+2*centerPhi)*Gaudi::Units::deg)*GeoTrf::RotateY3D(180*Gaudi::Units::deg));
1037  GeoTransform* xfNeg2 = new GeoTransform(GeoTrf::RotateZ3D(2*centerPhi*Gaudi::Units::deg)*GeoTrf::RotateY3D(180*Gaudi::Units::deg));
1038 
1039  m_cryoMotherPhysical->add(xfPos1);
1040  m_cryoMotherPhysical->add(sctCiCoolingPhys);
1041  m_cryoMotherPhysical->add(xfPos2);
1042  m_cryoMotherPhysical->add(sctCiCoolingPhys);
1043  m_cryoMotherPhysical->add(xfNeg1);
1044  m_cryoMotherPhysical->add(sctCiCoolingPhys);
1045  m_cryoMotherPhysical->add(xfNeg2);
1046  m_cryoMotherPhysical->add(sctCiCoolingPhys);
1047  } // iterate over Phi Sections
1048  }
1049  else {
1050  ATH_MSG_DEBUG("CryoPconPhiSect table not found - not building SCT cooling ");
1051  }
1052 
1053 
1054  if(!rdbAccess->getChildTag("LArBarrelDM",larVersionKey.tag(),larVersionKey.node()).empty() && m_fullGeo) {
1055  // Dead material in barrel
1056  CrackDMConstruction crackDMConstruction(rdbAccess,geoModel,materialManager,m_activateFT);
1057  crackDMConstruction.create(m_cryoMotherPhysical);
1058  }
1059 
1060  return m_cryoMotherPhysical;
1061 }
IRDBRecord::getInt
virtual int getInt(const std::string &fieldName) const =0
Get int field value.
LArGeo::BarrelConstruction::GetNegativeEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetNegativeEnvelope()
Definition: BarrelConstruction.cxx:124
beamspotman.r
def r
Definition: beamspotman.py:676
BarrelCryostatConstruction.h
Declaration of BarrelCryostatConstruction class.
PlotCalibFromCool.ft
ft
Definition: PlotCalibFromCool.py:329
LArGeo::BarrelPresamplerConstruction
GeoModel description of the LAr Barrel Presampler.
Definition: BarrelPresamplerConstruction.h:26
LArGeo::VDetectorParameters
Definition: VDetectorParameters.h:29
CrackDMConstruction
Definition: CrackDMConstruction.h:16
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
GeoDBUtils::getTransformRecord
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition: GeoDBUtils.h:23
LAr
Definition: LArVolumeBuilder.h:36
IRDBRecord::getString
virtual const std::string & getString(const std::string &fieldName) const =0
Get string field value.
StoredAlignX
Definition: StoredAlignX.h:23
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
StoredAlignX.h
DecodeVersionKey::node
const std::string & node() const
Return the version node.
Definition: DecodeVersionKey.cxx:97
LArGeo::BarrelCryostatConstruction::BarrelCryostatConstruction
BarrelCryostatConstruction(bool fullGeo, bool activateFT=false)
Definition: BarrelCryostatConstruction.cxx:75
LArGeo::BarrelConstruction::GetPositiveEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetPositiveEnvelope()
Definition: BarrelConstruction.cxx:119
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
read_hist_ntuple.h1
h1
Definition: read_hist_ntuple.py:21
x
#define x
ReweightUtils.message
message
Definition: ReweightUtils.py:15
BarrelPresamplerConstruction.h
Declaration of BarrelPresamplerConstruction class.
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
GeoDBUtils::getTransform
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
Definition: GeoDBUtils.h:33
StoredPhysVol
Definition: StoredPhysVol.h:27
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
LArGeo::BarrelPresamplerConstruction::GetPositiveEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetPositiveEnvelope()
Definition: BarrelPresamplerConstruction.cxx:504
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
Trk::index1
@ index1
Definition: BoundarySurfaceFace.h:48
lumiFormat.i
int i
Definition: lumiFormat.py:85
GeoDBUtils.h
z
#define z
CrackDMConstruction::create
void create(GeoFullPhysVol *envelope)
Definition: CrackDMConstruction.cxx:860
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
python.subdetectors.mmg.names
names
Definition: mmg.py:8
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:538
DecodeVersionKey
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
Definition: DecodeVersionKey.h:18
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
DecodeVersionKey::tag
const std::string & tag() const
Return version tag.
Definition: DecodeVersionKey.cxx:91
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
BarrelConstruction.h
LArGeo::BarrelCryostatConstruction::GetEnvelope
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
Definition: BarrelCryostatConstruction.cxx:87
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
CrackDMConstruction.h
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
Trk::index2
@ index2
Definition: BoundarySurfaceFace.h:49
LArGeo::BarrelPresamplerConstruction::GetNegativeEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetNegativeEnvelope()
Definition: BarrelPresamplerConstruction.cxx:508
StoredMaterialManager.h
LArGeo::BarrelConstruction
Definition: BarrelConstruction.h:22
DecodeVersionKey.h
planeIndMap
std::map< int, unsigned int, std::less< int > > planeIndMap
Definition: BarrelCryostatConstruction.cxx:73
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
LArGeo::BarrelConstruction::setBarrelSagging
void setBarrelSagging(bool flag)
Definition: BarrelConstruction.h:36
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
y
#define y
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
GeoGenfun
Definition: ArrayFunction.cxx:7
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
IRDBRecord
IRDBRecord is one record in the IRDBRecordset object.
Definition: IRDBRecord.h:27
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
StoredMaterialManager::getMaterial
virtual const GeoMaterial * getMaterial(const std::string &name)=0
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
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
LArGeo::BarrelCryostatConstruction::~BarrelCryostatConstruction
virtual ~BarrelCryostatConstruction()
IRDBRecord::getDouble
virtual double getDouble(const std::string &fieldName) const =0
Get double field value.
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
IGeoModelSvc.h
StoreGateSvc.h
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
TileDCSDataPlotter.tx
tx
Definition: TileDCSDataPlotter.py:878
checkFileSG.ind
list ind
Definition: checkFileSG.py:118
StoredPhysVol.h
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
LArGeo::BarrelConstruction::setBarrelCellVisLimit
void setBarrelCellVisLimit(int maxCell)
Definition: BarrelConstruction.h:37