ATLAS Offline Software
LArDetectorFactory.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 #include "LArDetectorFactory.h"
7 
9 #include "LArGeoRAL/RAL.h"
10 
14 
15 #include "GeoModelKernel/GeoPhysVol.h"
16 #include "GeoModelKernel/GeoTransform.h"
17 #include "GeoModelKernel/GeoAlignableTransform.h"
18 #include "GeoModelKernel/GeoNameTag.h"
19 #include "GeoModelKernel/GeoShapeUnion.h"
20 #include "GeoModelKernel/GeoDefinitions.h"
21 #include "GaudiKernel/SystemOfUnits.h"
22 
26 
27 #include "StoreGate/StoreGateSvc.h"
28 #include "GaudiKernel/Bootstrap.h"
35 
40 #include "GeoModelKernel/CellBinning.h"
41 
43  , const LArHVManager* hvManager
44  , int testbeam
45  , bool fullGeo)
46  : AthMessaging("LArDetectorFactory")
47  , m_detectorManager(nullptr)
48  , m_detStore(detStore)
49  , m_hvManager(hvManager)
50  , m_barrelSagging(false)
51  , m_barrelVisLimit(-1)
52  , m_fcalVisLimit(-1)
53  , m_buildBarrel(true)
54  , m_buildEndcap(true)
55  , m_testbeam(testbeam)
56  , m_fullGeo(fullGeo)
57  , m_activateFT(false)
58  , m_enableMBTS(true)
59 {}
60 
61 
63 = default;
64 
65 
66 // Place the cryostats into a container physical volume.
67 void LArGeo::LArDetectorFactory::create(GeoPhysVol* a_container )
68 {
69  // Tree Tops:
70  GeoIntrusivePtr<GeoFullPhysVol> barrelEnvelope{nullptr}, endcapEnvelopePos{nullptr}, endcapEnvelopeNeg{nullptr};
71 
72  double projectivityDisplacement(0.);
73 
74  if(m_testbeam==0 || m_testbeam==1) {
75  m_parameters = std::make_unique<LArGeo::RAL>();
76 
77  // Get access to the material manager:
78  StoredMaterialManager* materialManager = nullptr;
79  if (StatusCode::SUCCESS != m_detStore->retrieve(materialManager, std::string("MATERIALS"))) {
80  throw std::runtime_error("Error in LArDetectorFactory, cannot access Material Manager");
81  }
82 
83  SmartIF<IRDBAccessSvc> rdbAccess{Gaudi::svcLocator()->service("RDBAccessSvc")};
84 
85  if(!rdbAccess.isValid())
86  throw std::runtime_error("Error in BarrelCryostatConstruction, cannot access RDBAccessSvc");
87 
88  DecodeVersionKey larVersionKey("LAr");
89  ATH_MSG_DEBUG("Getting primary numbers for " << larVersionKey.node() << ", " << larVersionKey.tag());
90 
91  IRDBRecordset_ptr larPosition = rdbAccess->getRecordsetPtr("LArPosition",larVersionKey.tag(),larVersionKey.node());
92 
93  if(larPosition->size()==0) {
94  larPosition = rdbAccess->getRecordsetPtr("LArPosition", "LArPosition-00");
95  if (larPosition->size()==0)
96  throw std::runtime_error("Error, no lar position table in database!");
97  }
98 
99  IRDBRecordset_ptr emecGeometry = rdbAccess->getRecordsetPtr("EmecGeometry",larVersionKey.tag(),larVersionKey.node());
100  projectivityDisplacement = (*emecGeometry)[0]->getDouble("ZSHIFT");
101 
102  //
103  // Patch the materials list by adding special materials. These
104  // cannot be added for the moment to the standard list because they
105  // are blended materials and to do the blending requires access to
106  // LAr Geometry.
107  //
108 
109  LArMaterialManager lArMaterialManager(m_detStore);
110  lArMaterialManager.buildMaterials();
111 
112  if (m_testbeam==0) {
113 
114  BarrelCryostatConstruction barrelCryostatConstruction(m_fullGeo, m_activateFT);
115  barrelCryostatConstruction.setBarrelSagging(m_barrelSagging);
116  barrelCryostatConstruction.setBarrelCellVisLimit(m_barrelVisLimit);
117 
118  EndcapCryostatConstruction endcapCryostatConstruction(m_fullGeo, m_EMECVariantInner, m_EMECVariantOuter, m_activateFT, m_enableMBTS);
119  endcapCryostatConstruction.setFCALVisLimit(m_fcalVisLimit);
120 
121  if(m_buildBarrel) {
122  barrelEnvelope = barrelCryostatConstruction.GetEnvelope(m_parameters.get());
123  }
124 
125  if(m_buildEndcap) {
126  endcapEnvelopePos = endcapCryostatConstruction.createEnvelope(true);
127  endcapEnvelopeNeg = endcapCryostatConstruction.createEnvelope(false);
128  }
129 
130  // Offset of endcaps from nominal position.
131  a_container->add(new GeoNameTag("LAr"));
132 
133  if(m_buildBarrel && m_buildEndcap) {
134 
135  // Typical scenario for each of the Tree Tops:
136  // 1. Construct Alignable Transform from LArPositions
137  // 2. Store FullPV in SG
138  // 3. Store Alignable XF in SG
139 
140  // --- Barrel
141  const IRDBRecord *barrelRec = GeoDBUtils::getTransformRecord(larPosition,"LARCRYO_B");
142  if(!barrelRec) throw std::runtime_error("Error, no lar position record in the database");
143  GeoTrf::Transform3D xfBarrel = GeoDBUtils::getTransform(barrelRec);
144  GeoAlignableTransform* barrelAlXf = new GeoAlignableTransform(xfBarrel);
145 
146  {
147  StoredPhysVol *sPhysVol = new StoredPhysVol(barrelEnvelope);
148  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_B");
149  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B PhysVol");
150 
151  StoredAlignX *sAlignX = new StoredAlignX(barrelAlXf);
152  status=m_detStore->record(sAlignX,"LARCRYO_B");
153  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B Alignable XF");
154  }
155 
156  a_container->add(new GeoNameTag("LArBarrel"));
157  a_container->add(barrelAlXf);
158  a_container->add(barrelEnvelope);
159 
160  // --- Endcap Pos
161  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_POS");
162  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
164  GeoAlignableTransform *xfEndcapPos = new GeoAlignableTransform(xfPos);
165 
166  {
167  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopePos);
168  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_POS");
169  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_POS PhysVol");
170 
171  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapPos);
172  status=m_detStore->record(sAlignX,"LARCRYO_EC_POS");
173  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_POS");
174  }
175 
176  // --- Endcap Neg
177  const IRDBRecord *negRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_NEG");
178  if (!negRec) throw std::runtime_error("Error, no lar position record in the database") ;
180  GeoAlignableTransform *xfEndcapNeg = new GeoAlignableTransform(xfNeg);
181 
182  {
183  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopeNeg);
184  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_NEG");
185  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_NEG PhysVol");
186 
187  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapNeg);
188  status=m_detStore->record(sAlignX,"LARCRYO_EC_NEG");
189  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_NEG");
190  }
191 
192  a_container->add( new GeoNameTag("LArEndcapPos"));
193  a_container->add(xfEndcapPos);
194  a_container->add(endcapEnvelopePos);
195  a_container->add( new GeoNameTag("LArEndcapNeg"));
196  a_container->add(xfEndcapNeg);
197  a_container->add( new GeoTransform(GeoTrf::RotateY3D(180.0*Gaudi::Units::deg)));
198  a_container->add(endcapEnvelopeNeg);
199  }
200  else if(!m_buildEndcap) {
201  // -- Build the Barrel only
202  const IRDBRecord *barrelRec = GeoDBUtils::getTransformRecord(larPosition,"LARCRYO_B");
203  if(!barrelRec) throw std::runtime_error("Error, no lar position record in the database");
204  GeoTrf::Transform3D xfBarrel = GeoDBUtils::getTransform(barrelRec);
205  GeoAlignableTransform* barrelAlXf = new GeoAlignableTransform(xfBarrel);
206 
207  {
208  StoredPhysVol *sPhysVol = new StoredPhysVol(barrelEnvelope);
209  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_B");
210  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B PhysVol");
211 
212  StoredAlignX *sAlignX = new StoredAlignX(barrelAlXf);
213  status=m_detStore->record(sAlignX,"LARCRYO_B");
214  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B Alignable XF");
215  }
216 
217  a_container->add(new GeoNameTag("LArBarrel"));
218  a_container->add(barrelAlXf);
219  a_container->add(barrelEnvelope);
220 
221  }
222  else if(!m_buildBarrel) {
223  // --- Endcap Pos
224  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_POS");
225  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
227  GeoAlignableTransform *xfEndcapPos = new GeoAlignableTransform(xfPos);
228 
229  {
230  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopePos);
231  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_POS");
232  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_POS PhysVol");
233 
234  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapPos);
235  status=m_detStore->record(sAlignX,"LARCRYO_EC_POS");
236  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_POS");
237  }
238 
239  // --- Endcap Neg
240  const IRDBRecord *negRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_NEG");
241  if (!negRec) throw std::runtime_error("Error, no lar position record in the database") ;
243  GeoAlignableTransform *xfEndcapNeg = new GeoAlignableTransform(xfNeg);
244 
245  {
246  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopeNeg);
247  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_NEG");
248  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_NEG PhysVol");
249 
250  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapNeg);
251  status=m_detStore->record(sAlignX,"LARCRYO_EC_NEG");
252  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_NEG");
253  }
254 
255  a_container->add( new GeoNameTag("LArEndcapPos"));
256  a_container->add(xfEndcapPos);
257  a_container->add(endcapEnvelopePos);
258  a_container->add( new GeoNameTag("LArEndcapNeg"));
259  a_container->add(xfEndcapNeg);
260  a_container->add( new GeoTransform(GeoTrf::RotateY3D(180.0*Gaudi::Units::deg)));
261  a_container->add(endcapEnvelopeNeg);
262 
263  }
264  }
265  else {
266  TBBarrelCryostatConstruction tbbarrelCryostatConstruction;
267  tbbarrelCryostatConstruction.setBarrelSagging(m_barrelSagging);
268  tbbarrelCryostatConstruction.setBarrelCellVisLimit(m_barrelVisLimit);
269 
270  barrelEnvelope = tbbarrelCryostatConstruction.GetEnvelope(m_parameters.get());
271 
272  a_container->add(new GeoNameTag("LAr"));
273  a_container->add(barrelEnvelope);
274 
275  }
276  }
277 
278  auto subDetManagers = buildLArReadoutGeometry(m_detStore
279  , m_hvManager
281  , m_testbeam
282  , projectivityDisplacement);
283 
284  EMBDetectorManager* embDetectorManager{std::get<0>(subDetManagers)};
285  EMECDetectorManager* emecDetectorManager{std::get<1>(subDetManagers)};
286  HECDetectorManager* hecDetectorManager{std::get<2>(subDetManagers)};
287  FCALDetectorManager* fcalDetectorManager{std::get<3>(subDetManagers)};
288 
289  if(!embDetectorManager
290  || !emecDetectorManager
291  || !hecDetectorManager
292  || !fcalDetectorManager) {
293  std::string errorMessage="Failed to build LAr Readout Geometry description";
294  throw std::runtime_error(errorMessage);
295  }
296 
297  m_detectorManager = new LArDetectorManager(embDetectorManager,emecDetectorManager,hecDetectorManager,fcalDetectorManager);
298  m_detectorManager->isTestBeam(false);
299  if (barrelEnvelope) m_detectorManager->addTreeTop(barrelEnvelope);
300  if (endcapEnvelopePos) m_detectorManager->addTreeTop(endcapEnvelopePos);
301  if (endcapEnvelopeNeg) m_detectorManager->addTreeTop(endcapEnvelopeNeg);
302 }
303 
304 
305 
307 {
308  return m_detectorManager;
309 }
310 
311 std::unique_ptr<LArGeo::VDetectorParameters> LArGeo::LArDetectorFactory::moveParameters()
312 {
313  return std::move (m_parameters);
314 }
315 
LArMaterialManager.h
LArGeo::BarrelCryostatConstruction
Builds GeoModel description of the LAr Electromagnetic Barrel. Descriptions of the presampler and dea...
Definition: BarrelCryostatConstruction.h:33
BarrelCryostatConstruction.h
Declaration of BarrelCryostatConstruction class.
LArGeo::LArDetectorFactory::LArDetectorFactory
LArDetectorFactory(StoreGateSvc *detStore, const LArHVManager *hvManager, int testbeam, bool fullGeo)
Definition: LArDetectorFactory.cxx:42
FCALDetectorManager
A manager class providing access to readout geometry information for the forward calorimeter.
Definition: FCALDetectorManager.h:29
LArMaterialManager::buildMaterials
void buildMaterials()
Definition: LArMaterialManager.cxx:28
GeoDBUtils::getTransformRecord
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition: GeoDBUtils.h:23
EMECDetectorManager
A manager class providing access to readout geometry information for the electromagnetic endcap calor...
Definition: EMECDetectorManager.h:31
LArGeo::LArDetectorFactory::getDetectorManager
virtual const LArDetectorManager * getDetectorManager() const override
Definition: LArDetectorFactory.cxx:306
EndcapCryostatConstruction.h
Declaration of EndcapCryostatConstruction class.
StoredAlignX
Definition: StoredAlignX.h:23
LArGeo::EndcapCryostatConstruction::setFCALVisLimit
void setFCALVisLimit(int limit)
Definition: EndcapCryostatConstruction.h:54
LArGeo::EndcapCryostatConstruction
Description of the LAr End Cap cryostat, including MBTS description.
Definition: EndcapCryostatConstruction.h:32
deg
#define deg
Definition: SbPolyhedron.cxx:17
StoredAlignX.h
LArGeo::BarrelCryostatConstruction::setBarrelCellVisLimit
void setBarrelCellVisLimit(int maxCell)
Definition: BarrelCryostatConstruction.h:44
DecodeVersionKey::node
const std::string & node() const
Return the version node.
Definition: DecodeVersionKey.cxx:97
HECDetectorRegion.h
LArGeo::LArDetectorFactory::moveParameters
std::unique_ptr< LArGeo::VDetectorParameters > moveParameters()
Definition: LArDetectorFactory.cxx:311
GeoDBUtils::getTransform
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
Definition: GeoDBUtils.h:33
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
LArGeo::LArDetectorFactory::~LArDetectorFactory
virtual ~LArDetectorFactory()
LArReadoutGeometryBuilder.h
Helper function for building readout geometries of all LAr subsystems.
RAL.h
StoredPhysVol
Definition: StoredPhysVol.h:27
HECLongBlock.h
TBBarrelCryostatConstruction.h
EMBDetectorManager
A manager class providing access to readout geometry information for the electromagnetic barrel calor...
Definition: EMBDetectorManager.h:32
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:125
LArMaterialManager
Definition: LArMaterialManager.h:38
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
GeoDBUtils.h
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
DecodeVersionKey
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
Definition: DecodeVersionKey.h:18
LArDetectorFactory.h
LArGeo::LArDetectorFactory::create
virtual void create(GeoPhysVol *world) override
Definition: LArDetectorFactory.cxx:67
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
LArGeo::BarrelCryostatConstruction::GetEnvelope
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
Definition: BarrelCryostatConstruction.cxx:87
LArDetectorManager
Stored in storegate. Provides access to EMB, EMEC, HEC and FCAL Detector Managers....
Definition: LArDetectorManager.h:26
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
HECDetectorManager
A manager class providing access to readout geometry information for the hadronic endcap calorimeter.
Definition: HECDetectorManager.h:28
LArGeo::TBBarrelCryostatConstruction::setBarrelSagging
void setBarrelSagging(bool flag)
Definition: TBBarrelCryostatConstruction.h:27
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
LArGeo::TBBarrelCryostatConstruction::GetEnvelope
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
Definition: TBBarrelCryostatConstruction.cxx:59
VDetectorParameters.h
StoredMaterialManager.h
LArGeo::BarrelCryostatConstruction::setBarrelSagging
void setBarrelSagging(bool flag)
Definition: BarrelCryostatConstruction.h:43
DecodeVersionKey.h
LArGeo::TBBarrelCryostatConstruction
Definition: TBBarrelCryostatConstruction.h:19
LArGeo::TBBarrelCryostatConstruction::setBarrelCellVisLimit
void setBarrelCellVisLimit(int maxCell)
Definition: TBBarrelCryostatConstruction.h:28
LArHVManager
This class provides access to the High Voltage throughout the LAr. High voltage conditions can also b...
Definition: LArHVManager.h:24
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
HECDetDescr.h
IRDBRecord
IRDBRecord is one record in the IRDBRecordset object.
Definition: IRDBRecord.h:27
buildLArReadoutGeometry
std::tuple< EMBDetectorManager *,EMECDetectorManager *,HECDetectorManager *,FCALDetectorManager * > buildLArReadoutGeometry(StoreGateSvc *detStore, const LArHVManager *hvManager, IMessageSvc *msgSvc, int testbeam, double projectivityDisplacement)
Definition: LArReadoutGeometryBuilder.cxx:37
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
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
StoreGateSvc.h
HECDetectorManager.h
StoredPhysVol.h
LArGeo::EndcapCryostatConstruction::createEnvelope
GeoIntrusivePtr< GeoFullPhysVol > createEnvelope(bool bPos)
Definition: EndcapCryostatConstruction.cxx:89