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