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/MsgStream.h"
29 #include "GaudiKernel/Bootstrap.h"
36 
41 #include "GeoModelKernel/CellBinning.h"
42 
44  , const LArHVManager* hvManager
45  , int testbeam
46  , bool fullGeo)
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 
79  ISvcLocator *svcLocator = Gaudi::svcLocator();
80  IMessageSvc * msgSvc;
81  if (svcLocator->service("MessageSvc", msgSvc, true )==StatusCode::FAILURE) {
82  throw std::runtime_error("Error in LAr::DetectorFactor, cannot access MessageSvc");
83  }
84 
85  MsgStream log(msgSvc, "LAr::DetectorFactory");
86 
87  StoredMaterialManager* materialManager = nullptr;
88  if (StatusCode::SUCCESS != m_detStore->retrieve(materialManager, std::string("MATERIALS"))) {
89  throw std::runtime_error("Error in LArDetectorFactory, cannot access Material Manager");
90  }
91 
92  IRDBAccessSvc* rdbAccess = nullptr;
93 
94  if(svcLocator->service ("RDBAccessSvc",rdbAccess) == StatusCode::FAILURE)
95  throw std::runtime_error("Error in BarrelCryostatConstruction, cannot access RDBAccessSvc");
96 
97  DecodeVersionKey larVersionKey("LAr");
98  log << MSG::DEBUG << "Getting primary numbers for " << larVersionKey.node() << ", " << larVersionKey.tag() << endmsg;
99 
100  IRDBRecordset_ptr larPosition = rdbAccess->getRecordsetPtr("LArPosition",larVersionKey.tag(),larVersionKey.node());
101 
102  if(larPosition->size()==0) {
103  larPosition = rdbAccess->getRecordsetPtr("LArPosition", "LArPosition-00");
104  if (larPosition->size()==0)
105  throw std::runtime_error("Error, no lar position table in database!");
106  }
107 
108  IRDBRecordset_ptr emecGeometry = rdbAccess->getRecordsetPtr("EmecGeometry",larVersionKey.tag(),larVersionKey.node());
109  projectivityDisplacement = (*emecGeometry)[0]->getDouble("ZSHIFT");
110 
111  //
112  // Patch the materials list by adding special materials. These
113  // cannot be added for the moment to the standard list because they
114  // are blended materials and to do the blending requires access to
115  // LAr Geometry.
116  //
117 
118  LArMaterialManager lArMaterialManager(m_detStore);
119  lArMaterialManager.buildMaterials();
120 
121  if (m_testbeam==0) {
122 
123  BarrelCryostatConstruction barrelCryostatConstruction(m_fullGeo, m_activateFT);
124  barrelCryostatConstruction.setBarrelSagging(m_barrelSagging);
125  barrelCryostatConstruction.setBarrelCellVisLimit(m_barrelVisLimit);
126 
127  EndcapCryostatConstruction endcapCryostatConstruction(m_fullGeo, m_EMECVariantInner, m_EMECVariantOuter, m_activateFT, m_enableMBTS);
128  endcapCryostatConstruction.setFCALVisLimit(m_fcalVisLimit);
129 
130  if(m_buildBarrel) {
131  barrelEnvelope = barrelCryostatConstruction.GetEnvelope(m_parameters.get());
132  }
133 
134  if(m_buildEndcap) {
135  endcapEnvelopePos = endcapCryostatConstruction.createEnvelope(true);
136  endcapEnvelopeNeg = endcapCryostatConstruction.createEnvelope(false);
137  }
138 
139  // Offset of endcaps from nominal position.
140  a_container->add(new GeoNameTag("LAr"));
141 
142  if(m_buildBarrel && m_buildEndcap) {
143 
144  // Typical scenario for each of the Tree Tops:
145  // 1. Construct Alignable Transform from LArPositions
146  // 2. Store FullPV in SG
147  // 3. Store Alignable XF in SG
148 
149  // --- Barrel
150  const IRDBRecord *barrelRec = GeoDBUtils::getTransformRecord(larPosition,"LARCRYO_B");
151  if(!barrelRec) throw std::runtime_error("Error, no lar position record in the database");
152  GeoTrf::Transform3D xfBarrel = GeoDBUtils::getTransform(barrelRec);
153  GeoAlignableTransform* barrelAlXf = new GeoAlignableTransform(xfBarrel);
154 
155  {
156  StoredPhysVol *sPhysVol = new StoredPhysVol(barrelEnvelope);
157  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_B");
158  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B PhysVol");
159 
160  StoredAlignX *sAlignX = new StoredAlignX(barrelAlXf);
161  status=m_detStore->record(sAlignX,"LARCRYO_B");
162  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B Alignable XF");
163  }
164 
165  a_container->add(new GeoNameTag("LArBarrel"));
166  a_container->add(barrelAlXf);
167  a_container->add(barrelEnvelope);
168 
169  // --- Endcap Pos
170  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_POS");
171  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
173  GeoAlignableTransform *xfEndcapPos = new GeoAlignableTransform(xfPos);
174 
175  {
176  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopePos);
177  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_POS");
178  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_POS PhysVol");
179 
180  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapPos);
181  status=m_detStore->record(sAlignX,"LARCRYO_EC_POS");
182  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_POS");
183  }
184 
185  // --- Endcap Neg
186  const IRDBRecord *negRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_NEG");
187  if (!negRec) throw std::runtime_error("Error, no lar position record in the database") ;
189  GeoAlignableTransform *xfEndcapNeg = new GeoAlignableTransform(xfNeg);
190 
191  {
192  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopeNeg);
193  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_NEG");
194  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_NEG PhysVol");
195 
196  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapNeg);
197  status=m_detStore->record(sAlignX,"LARCRYO_EC_NEG");
198  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_NEG");
199  }
200 
201  a_container->add( new GeoNameTag("LArEndcapPos"));
202  a_container->add(xfEndcapPos);
203  a_container->add(endcapEnvelopePos);
204  a_container->add( new GeoNameTag("LArEndcapNeg"));
205  a_container->add(xfEndcapNeg);
206  a_container->add( new GeoTransform(GeoTrf::RotateY3D(180.0*Gaudi::Units::deg)));
207  a_container->add(endcapEnvelopeNeg);
208  }
209  else if(!m_buildEndcap) {
210  // -- Build the Barrel only
211  const IRDBRecord *barrelRec = GeoDBUtils::getTransformRecord(larPosition,"LARCRYO_B");
212  if(!barrelRec) throw std::runtime_error("Error, no lar position record in the database");
213  GeoTrf::Transform3D xfBarrel = GeoDBUtils::getTransform(barrelRec);
214  GeoAlignableTransform* barrelAlXf = new GeoAlignableTransform(xfBarrel);
215 
216  {
217  StoredPhysVol *sPhysVol = new StoredPhysVol(barrelEnvelope);
218  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_B");
219  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B PhysVol");
220 
221  StoredAlignX *sAlignX = new StoredAlignX(barrelAlXf);
222  status=m_detStore->record(sAlignX,"LARCRYO_B");
223  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_B Alignable XF");
224  }
225 
226  a_container->add(new GeoNameTag("LArBarrel"));
227  a_container->add(barrelAlXf);
228  a_container->add(barrelEnvelope);
229 
230  }
231  else if(!m_buildBarrel) {
232  // --- Endcap Pos
233  const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_POS");
234  if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
236  GeoAlignableTransform *xfEndcapPos = new GeoAlignableTransform(xfPos);
237 
238  {
239  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopePos);
240  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_POS");
241  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_POS PhysVol");
242 
243  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapPos);
244  status=m_detStore->record(sAlignX,"LARCRYO_EC_POS");
245  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_POS");
246  }
247 
248  // --- Endcap Neg
249  const IRDBRecord *negRec = GeoDBUtils::getTransformRecord(larPosition, "LARCRYO_EC_NEG");
250  if (!negRec) throw std::runtime_error("Error, no lar position record in the database") ;
252  GeoAlignableTransform *xfEndcapNeg = new GeoAlignableTransform(xfNeg);
253 
254  {
255  StoredPhysVol *sPhysVol = new StoredPhysVol(endcapEnvelopeNeg);
256  StatusCode status=m_detStore->record(sPhysVol,"LARCRYO_EC_NEG");
257  if(!status.isSuccess()) throw std::runtime_error("Cannot store LARCRYO_EC_NEG PhysVol");
258 
259  StoredAlignX *sAlignX = new StoredAlignX(xfEndcapNeg);
260  status=m_detStore->record(sAlignX,"LARCRYO_EC_NEG");
261  if(!status.isSuccess()) throw std::runtime_error ("Cannot store LARCRYO_EC_NEG");
262  }
263 
264  a_container->add( new GeoNameTag("LArEndcapPos"));
265  a_container->add(xfEndcapPos);
266  a_container->add(endcapEnvelopePos);
267  a_container->add( new GeoNameTag("LArEndcapNeg"));
268  a_container->add(xfEndcapNeg);
269  a_container->add( new GeoTransform(GeoTrf::RotateY3D(180.0*Gaudi::Units::deg)));
270  a_container->add(endcapEnvelopeNeg);
271 
272  }
273  }
274  else {
275  TBBarrelCryostatConstruction tbbarrelCryostatConstruction;
276  tbbarrelCryostatConstruction.setBarrelSagging(m_barrelSagging);
277  tbbarrelCryostatConstruction.setBarrelCellVisLimit(m_barrelVisLimit);
278 
279  barrelEnvelope = tbbarrelCryostatConstruction.GetEnvelope(m_parameters.get());
280 
281  a_container->add(new GeoNameTag("LAr"));
282  a_container->add(barrelEnvelope);
283 
284  }
285  }
286 
287  auto subDetManagers = buildLArReadoutGeometry(m_detStore
288  , m_hvManager
290  , m_testbeam
291  , projectivityDisplacement);
292 
293  EMBDetectorManager* embDetectorManager{std::get<0>(subDetManagers)};
294  EMECDetectorManager* emecDetectorManager{std::get<1>(subDetManagers)};
295  HECDetectorManager* hecDetectorManager{std::get<2>(subDetManagers)};
296  FCALDetectorManager* fcalDetectorManager{std::get<3>(subDetManagers)};
297 
298  if(!embDetectorManager
299  || !emecDetectorManager
300  || !hecDetectorManager
301  || !fcalDetectorManager) {
302  std::string errorMessage="Failed to build LAr Readout Geometry description";
303  throw std::runtime_error(errorMessage);
304  }
305 
306  m_detectorManager = new LArDetectorManager(embDetectorManager,emecDetectorManager,hecDetectorManager,fcalDetectorManager);
307  m_detectorManager->isTestBeam(false);
308  if (barrelEnvelope) m_detectorManager->addTreeTop(barrelEnvelope);
309  if (endcapEnvelopePos) m_detectorManager->addTreeTop(endcapEnvelopePos);
310  if (endcapEnvelopeNeg) m_detectorManager->addTreeTop(endcapEnvelopeNeg);
311 }
312 
313 
314 
316 {
317  return m_detectorManager;
318 }
319 
320 std::unique_ptr<LArGeo::VDetectorParameters> LArGeo::LArDetectorFactory::moveParameters()
321 {
322  return std::move (m_parameters);
323 }
324 
LArMaterialManager.h
LArGeo::BarrelCryostatConstruction
Builds GeoModel description of the LAr Electromagnetic Barrel. Descriptions of the presampler and dea...
Definition: BarrelCryostatConstruction.h:31
BarrelCryostatConstruction.h
Declaration of BarrelCryostatConstruction class.
LArGeo::LArDetectorFactory::LArDetectorFactory
LArDetectorFactory(StoreGateSvc *detStore, const LArHVManager *hvManager, int testbeam, bool fullGeo)
Definition: LArDetectorFactory.cxx:43
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:40
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.
EMECDetectorManager
A manager class providing access to readout geometry information for the electromagnetic endcap calor...
Definition: EMECDetectorManager.h:31
EndcapCryostatConstruction.h
Declaration of EndcapCryostatConstruction class.
StoredAlignX
Definition: StoredAlignX.h:23
LArGeo::EndcapCryostatConstruction::setFCALVisLimit
void setFCALVisLimit(int limit)
Definition: EndcapCryostatConstruction.h:56
LArGeo::EndcapCryostatConstruction
Description of the LAr End Cap cryostat, including MBTS description.
Definition: EndcapCryostatConstruction.h:34
deg
#define deg
Definition: SbPolyhedron.cxx:17
StoredAlignX.h
LArGeo::BarrelCryostatConstruction::setBarrelCellVisLimit
void setBarrelCellVisLimit(int maxCell)
Definition: BarrelCryostatConstruction.h:42
DecodeVersionKey::node
const std::string & node() const
Return the version node.
Definition: DecodeVersionKey.cxx:99
HECDetectorRegion.h
LArGeo::LArDetectorFactory::moveParameters
std::unique_ptr< LArGeo::VDetectorParameters > moveParameters()
Definition: LArDetectorFactory.cxx:320
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:128
LArMaterialManager
Definition: LArMaterialManager.h:36
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
GeoDBUtils.h
IRDBAccessSvc
IRDBAccessSvc is an abstract interface to the athena service that provides the following functionalit...
Definition: IRDBAccessSvc.h:45
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
LArGeo::LArDetectorFactory::create
virtual void create(GeoPhysVol *world)
Definition: LArDetectorFactory.cxx:67
LArGeo::LArDetectorFactory::getDetectorManager
virtual const LArDetectorManager * getDetectorManager() const
Definition: LArDetectorFactory.cxx:315
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
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
DecodeVersionKey::tag
const std::string & tag() const
Return version tag.
Definition: DecodeVersionKey.cxx:93
LArGeo::BarrelCryostatConstruction::GetEnvelope
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
Definition: BarrelCryostatConstruction.cxx:88
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:41
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
DEBUG
#define DEBUG
Definition: page_access.h:11
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
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:110