ATLAS Offline Software
Loading...
Searching...
No Matches
LArDetectorFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
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
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)
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.
67void 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
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
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") ;
163 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
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(std::move(larPosition), "LARCRYO_EC_NEG");
178 if (!negRec) throw std::runtime_error("Error, no lar position record in the database") ;
179 GeoTrf::Transform3D xfNeg = GeoDBUtils::getTransform(negRec);
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(std::move(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") ;
226 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
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(std::move(larPosition), "LARCRYO_EC_NEG");
241 if (!negRec) throw std::runtime_error("Error, no lar position record in the database") ;
242 GeoTrf::Transform3D xfNeg = GeoDBUtils::getTransform(negRec);
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
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
310
311std::unique_ptr<LArGeo::VDetectorParameters> LArGeo::LArDetectorFactory::moveParameters()
312{
313 return std::move (m_parameters);
314}
315
#define ATH_MSG_DEBUG(x)
Declaration of BarrelCryostatConstruction class.
Declaration of EndcapCryostatConstruction class.
Definition of the abstract IRDBAccessSvc interface.
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition of the abstract IRDBRecord interface.
Definition of the abstract IRDBRecordset interface.
std::tuple< EMBDetectorManager *, EMECDetectorManager *, HECDetectorManager *, FCALDetectorManager * > buildLArReadoutGeometry(StoreGateSvc *detStore, const LArHVManager *hvManager, IMessageSvc *msgSvc, int testbeam, double projectivityDisplacement)
Helper function for building readout geometries of all LAr subsystems.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
const std::string & tag() const
Return version tag.
const std::string & node() const
Return the version node.
A manager class providing access to readout geometry information for the electromagnetic barrel calor...
A manager class providing access to readout geometry information for the electromagnetic endcap calor...
A manager class providing access to readout geometry information for the forward calorimeter.
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition GeoDBUtils.h:23
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
Definition GeoDBUtils.h:33
A manager class providing access to readout geometry information for the hadronic endcap calorimeter.
IRDBRecord is one record in the IRDBRecordset object.
Definition IRDBRecord.h:27
virtual unsigned int size() const =0
Stored in storegate.
Builds GeoModel description of the LAr Electromagnetic Barrel.
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
Description of the LAr End Cap cryostat, including MBTS description.
GeoIntrusivePtr< GeoFullPhysVol > createEnvelope(bool bPos)
LArDetectorManager * m_detectorManager
std::unique_ptr< VDetectorParameters > m_parameters
std::unique_ptr< LArGeo::VDetectorParameters > moveParameters()
LArDetectorFactory(StoreGateSvc *detStore, const LArHVManager *hvManager, int testbeam, bool fullGeo)
virtual void create(GeoPhysVol *world) override
const LArHVManager * m_hvManager
virtual const LArDetectorManager * getDetectorManager() const override
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
This class provides access to the High Voltage throughout the LAr.
The Athena Transient Store API.
This class holds one or more material managers and makes them storeable, under StoreGate.
IMessageSvc * getMessageSvc(bool quiet=false)