ATLAS Offline Software
Loading...
Searching...
No Matches
LArDetectorConstructionTBEC.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// LArDetectorConstructionTBEC
6
11
12#include "GeoModelKernel/GeoElement.h"
13#include "GeoModelKernel/GeoMaterial.h"
14#include "GeoModelKernel/GeoFullPhysVol.h"
15#include "GeoModelKernel/GeoPhysVol.h"
16#include "GeoModelKernel/GeoVPhysVol.h"
17#include "GeoModelKernel/GeoLogVol.h"
18#include "GeoModelKernel/GeoBox.h"
19#include "GeoModelKernel/GeoTube.h"
20#include "GeoModelKernel/GeoNameTag.h"
21#include "GeoModelKernel/GeoTransform.h"
22#include "GeoModelKernel/GeoAlignableTransform.h"
23#include "GeoModelKernel/GeoIdentifierTag.h"
24#include "GeoModelKernel/GeoDefinitions.h"
28#include "GeoModelKernel/GeoShapeUnion.h"
29#include "GeoModelKernel/GeoShapeShift.h"
30
31// For the database:
35
37#include "GaudiKernel/MsgStream.h"
38#include "GaudiKernel/Bootstrap.h"
39#include "GaudiKernel/SystemOfUnits.h"
40
42
43// For run options :
45
46#include <string>
47#include <cmath>
48
49// Handle Axis, for debug
50#define AXIS_ON 0
51
52// The "database record" types.
54 int cylNumber;
55 GeoMaterial* mat;
56 double Rmin;
57 double Dr;
58 double Zmin;
59 double Dz;
60};
61
62
64{
65 m_eta_cell = 12;
66 m_phi_cell = 16;
67
68 MsgStream log(Athena::getMessageSvc(),"LArGeo::LArDetectorConstructionTBEC");
69 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
70 if(!detStore.isValid()) throw std::runtime_error("LArDetectorConstructionTBEC: cannot initialize StoreGate interface");
71 const LArGeoTBGeometricOptions *largeotbgeometricoptions = nullptr;
72 StatusCode status = detStore->retrieve(largeotbgeometricoptions, "LArGeoTBGeometricOptions");
73 if(status.isFailure()){
74 log << MSG::WARNING << "Can't access LArGeoTBGeometricOptions, using default values" << endmsg;
75 }
76 else {
77 m_eta_cell = largeotbgeometricoptions->CryoEtaPosition();
78 m_phi_cell = largeotbgeometricoptions->CryoPhiPosition();
79 }
80
81 if ( m_eta_cell < 0.5 ) m_eta_pos = 0.05*( m_eta_cell + 0.5 ) + 1.375; // Cell 0 has double eta width
82 else if ( m_eta_cell > 43.5 ) m_eta_pos = 0.1*( m_eta_cell - 43.5 ) + 2.5; // Inner Wheel
83 else m_eta_pos = 0.025*( m_eta_cell - 0.5 ) + 1.425; // Outer Wheel
84
85 if ( m_eta_cell <= 43.5 ) m_phi_pos = -( ( m_phi_cell - 16. )*1.40625 + 0.46875 )*Gaudi::Units::deg; // Outer Wheel
86 else m_phi_pos = -( 4*( m_phi_cell - 4. )*1.40625 + 0.46875 )*Gaudi::Units::deg; // Inner Wheel
87
88}
89
91{
93
94 MsgStream log(Athena::getMessageSvc(),"LArGeo::LArDetectorConstructionTBEC");
95 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
96 if(!detStore.isValid()) {
97 throw std::runtime_error("LArDetectorConstructionTBEC: cannot initialize StoreGate interface");
98 }
99
100 StoredMaterialManager* materialManager = nullptr;
101 if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
102
103 const GeoMaterial *Air = materialManager->getMaterial("std::Air");
104 if (!Air) {
105 throw std::runtime_error("Error in LArDetectorConstructionTBEC, std::Air is not found.");
106 }
107
108 SmartIF<IRDBAccessSvc> accessSvc{Gaudi::svcLocator()->service("RDBAccessSvc")};
109 if(!accessSvc.isValid()) {
110 throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
111 }
112
113 DecodeVersionKey larVersion("LAr");
114 const std::string& detectorKey = larVersion.tag();
115 const std::string& detectorNode = larVersion.node();
116
117 // Default values....
118 m_hasLeadCompensator = false;
119 m_hasPresampler = false;
120 m_ModuleRotation = 0.*Gaudi::Units::deg;
121 m_YShift = 0.*Gaudi::Units::mm;
122
123 IRDBRecordset_ptr tbecGeometry = accessSvc->getRecordsetPtr("TBECGeometry",detectorKey, detectorNode);
124 if ((*tbecGeometry).size()!=0) {
125 m_hasLeadCompensator = (*tbecGeometry)[0]->getInt("LEADCOMPENSATOR");
126 m_hasPresampler = (*tbecGeometry)[0]->getInt("PRESAMPLER");
127 m_ModuleRotation = (*tbecGeometry)[0]->getDouble("MODULEROTATION");
128 m_YShift = (*tbecGeometry)[0]->getDouble("YSHIFT");
129 }
130
131 log << MSG::INFO << "LeadCompensator = ";
132 if(m_hasLeadCompensator) log << "true";
133 else log << "false";
134 log << endmsg;
135
136 log << MSG::INFO << "Presampler = ";
137 if(m_hasPresampler) log << "true";
138 else log << "false";
139 log << endmsg;
140
141 // Retrieve simulation parameters from Storegate
143
144 std::string baseName = "LAr::TBEC::MotherVolume";
145
146 GeoBox* tbecMotherShape = new GeoBox( 5.*Gaudi::Units::m, 5.*Gaudi::Units::m, 15.*Gaudi::Units::m );
147
148 const GeoLogVol* tbecMotherLogical =
149 new GeoLogVol(baseName, tbecMotherShape, Air);
150
151 m_tbecEnvelopePhysical = new GeoPhysVol(tbecMotherLogical);
152
153 m_tbecEnvelopePhysical->add( new GeoNameTag("LArEndcapPos") );
156}
157
159{
160 // Get access to the material manager:
161 MsgStream log(Athena::getMessageSvc(),"LArGeo::LArDetectorConstructionTBEC");
162 log << MSG::DEBUG << "createEnvelope() started" << endmsg;
163
164 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
165 if(!detStore.isValid()) {
166 throw std::runtime_error("Error in LArDetectorConstructionTBEC, cannot access DetectorStore");
167 }
168
169 // Get the materials from the material manager:-----------------------------------------------------//
170 // //
171 StoredMaterialManager* materialManager = nullptr;
172 if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
173
174 const GeoMaterial *Air = materialManager->getMaterial("std::Air");
175 if (!Air) throw std::runtime_error("Error in LArDetectorConstructionTBEC, std::Air is not found.");
176
177 const GeoMaterial *Lead = materialManager->getMaterial("std::Lead");
178 if (!Lead) throw std::runtime_error("Error in LArDetectorConstructionTBEC, std::Lead is not found.");
179
180
181 // //
182 //-------------------------------------------------------------------------------------------------//
183 DecodeVersionKey larVersion("LAr");
184
185
187 // Define geometry
189
190 // Set up strings for volume names.
191 std::string baseName = "LAr::TBEC";
192
193 // Define the mother volume for the endcap cryostat. Everything
194 // else in the endcap (cryostat walls, detectors, etc.) should be
195 // placed inside here.
196
197 // The position of this volume may change if the thickness of the
198 // cabling in front of the endcaps changes. Therefore, we must get
199 // the z-shift from the database and adjust the volume geometry
200 // accordingly.
201
202 std::string tbecMotherName = baseName + "::MotherVolume";
203 GeoBox* tbecMotherShape = new GeoBox( 5.*Gaudi::Units::m, 5.*Gaudi::Units::m, 15.*Gaudi::Units::m );
204 const GeoLogVol* tbecMotherLogical = new GeoLogVol( tbecMotherName, tbecMotherShape, Air );
205 GeoIntrusivePtr<GeoFullPhysVol> tbecMotherPhysical = new GeoFullPhysVol( tbecMotherLogical );
206
207 double xcent = -120.*Gaudi::Units::cm, zcent = 395.7*Gaudi::Units::cm;
208 double zfface = zcent - 60.09*Gaudi::Units::cm;
209 log << MSG::DEBUG << "eta = " << m_eta_pos;
210 if ( m_eta_pos > 5. ) m_eta_pos = 0.;
211 else m_eta_pos = 2*atan( exp( -m_eta_pos ) );
212 log << ", positioning cryostat with angle " << m_eta_pos*(1./Gaudi::Units::deg) << " Gaudi::Units::deg";
213 log << endmsg;
214
215 // Tubular axis, dummy
216
217 if ( AXIS_ON ) {
218
219 double axisZHalfLength = 5*Gaudi::Units::m;
220
221 GeoTube* axisShape = new GeoTube( 0.*Gaudi::Units::cm, 1.*Gaudi::Units::cm, axisZHalfLength );
222
223 // x-axis
224 std::string XAxisName = baseName + "::XAxis";
225 const GeoLogVol* XAxisLogical = new GeoLogVol( XAxisName, axisShape, Air );
226 GeoIntrusivePtr<GeoPhysVol> XAxisPhysVol = new GeoPhysVol( XAxisLogical );
227
228 tbecMotherPhysical->add( new GeoIdentifierTag( 1 ) );
229 tbecMotherPhysical->add( new GeoTransform( GeoTrf::Transform3D( GeoTrf::Translation3D( axisZHalfLength, 0.*Gaudi::Units::m, 0.*Gaudi::Units::m ) *GeoTrf::RotateY3D( 90.*Gaudi::Units::deg )) ) );
230 tbecMotherPhysical->add( XAxisPhysVol );
231
232 // y-axis
233 std::string YAxisName = baseName + "::YAxis";
234 const GeoLogVol* YAxisLogical = new GeoLogVol( YAxisName, axisShape, Air );
235 GeoIntrusivePtr<GeoPhysVol> YAxisPhysVol = new GeoPhysVol( YAxisLogical );
236
237 tbecMotherPhysical->add( new GeoIdentifierTag( 1 ) );
238 tbecMotherPhysical->add( new GeoTransform( GeoTrf::Transform3D( GeoTrf::Translation3D( 0.*Gaudi::Units::m, axisZHalfLength, 0.*Gaudi::Units::m )*GeoTrf::RotateX3D( -90.*Gaudi::Units::deg ) ) ) );
239 tbecMotherPhysical->add( YAxisPhysVol );
240
241 //z-axis
242 std::string ZAxisName = baseName + "::ZAxis";
243 const GeoLogVol* ZAxisLogical = new GeoLogVol( ZAxisName, axisShape, Air );
244 GeoIntrusivePtr<GeoPhysVol> ZAxisPhysVol = new GeoPhysVol( ZAxisLogical );
245
246 tbecMotherPhysical->add( new GeoIdentifierTag( 1 ) );
247 tbecMotherPhysical->add( new GeoTransform( GeoTrf::TranslateZ3D( axisZHalfLength ) ) );
248 tbecMotherPhysical->add( ZAxisPhysVol );
249 }
250
251 // Lead compensator, Optionnal
252
253 if ( m_hasLeadCompensator ) {
254 std::string CompensatorName = baseName + "::LeadCompensator";
255 GeoBox* CompensatorShape = new GeoBox( 152.*Gaudi::Units::cm, 195.*Gaudi::Units::cm, 0.56*Gaudi::Units::cm );
256 const GeoLogVol* CompensatorLogical = new GeoLogVol( CompensatorName, CompensatorShape, Lead );
257 GeoIntrusivePtr<GeoPhysVol> CompensatorPhysical = new GeoPhysVol( CompensatorLogical );
258
259 tbecMotherPhysical->add( new GeoIdentifierTag( 1 ) );
260
261 GeoTrf::Vector3D tmpvec1(xcent, 0., 300.*Gaudi::Units::cm);
262 GeoTrf::Vector3D tmpvec1Rotated = GeoTrf::RotateY3D(m_eta_pos)*tmpvec1;
263 GeoTrf::Translate3D tmpxf1(tmpvec1Rotated.x(),tmpvec1Rotated.y(),tmpvec1Rotated.z());
264 tbecMotherPhysical->add(new GeoTransform( tmpxf1 * GeoTrf::RotateY3D(m_eta_pos)));
265 tbecMotherPhysical->add( CompensatorPhysical );
266 }
267
268 // Cryostat
269
270 CryostatConstructionTBEC cryoConstruction;
271 GeoIntrusivePtr<GeoVFullPhysVol> cryoPhys = cryoConstruction.GetEnvelope();
272 GeoIntrusivePtr<GeoPhysVol> LArPhysical = cryoConstruction.GetLArPhysical();
273
274 tbecMotherPhysical->add( new GeoIdentifierTag( 1 ) );
275 GeoTrf::Vector3D tmpvec2(xcent, 0., zcent);
276 GeoTrf::Vector3D tmpvec2Rotated = GeoTrf::RotateY3D(m_eta_pos)*tmpvec2;
277 GeoTrf::Translate3D tmpxf2(tmpvec2Rotated.x(),tmpvec2Rotated.y(),tmpvec2Rotated.z());
278 tbecMotherPhysical->add(new GeoTransform( tmpxf2 * GeoTrf::RotateY3D(m_eta_pos)));
279 tbecMotherPhysical->add( cryoPhys );
280
281 // Beam chambers
282
283 log << MSG::VERBOSE << "Creating beam chambers ..." << std::endl;
284
285 const double beamCZ[ 4 ] = { 17.9*Gaudi::Units::m, 7.673*Gaudi::Units::m, 1.352*Gaudi::Units::m, .256*Gaudi::Units::m };
286 const double beamCSize = 11.*Gaudi::Units::cm, beamCTh = 28*Gaudi::Units::mm; // divided by 2, for half-length
287
288 GeoBox* BeamCShape = new GeoBox( beamCSize, beamCSize, beamCTh );
289 for ( int i = 0; i < 4; i++ ) {
290 std::string BeamCName = baseName + "::BeamChamber";
291 BeamCName+= char( i ) + '0';
292 GeoLogVol* BeamCLogical = new GeoLogVol( BeamCName, BeamCShape, Air );
293 GeoIntrusivePtr<GeoPhysVol> BeamCPhysical = new GeoPhysVol( BeamCLogical );
294
295 tbecMotherPhysical->add( new GeoIdentifierTag( 1 ) );
296 tbecMotherPhysical->add( new GeoTransform( GeoTrf::Translate3D( 0.*Gaudi::Units::cm, 0.*Gaudi::Units::cm, zfface - beamCZ[ i ] ) ) );
297 tbecMotherPhysical->add( BeamCPhysical );
298 }
299
300 // End cap module
301 log << MSG::DEBUG << std::endl
302 << "Module deviation: " << m_ModuleRotation * (1./Gaudi::Units::deg) << " Gaudi::Units::deg" << std::endl
303 << "Phi position: " << m_phi_pos * (1./Gaudi::Units::deg) << " Gaudi::Units::deg" << std::endl
304 << "Y shift: " << m_YShift * (1./Gaudi::Units::mm) << " Gaudi::Units::mm"
305 << endmsg;
306
307 // z = 0 in emecMother is at active region's front face
308
309 EMECConstruction emecModuleConstruction( true, true, true );
310 GeoIntrusivePtr<GeoFullPhysVol>emecEnvelope= (GeoIntrusivePtr<GeoFullPhysVol>) emecModuleConstruction.GetEnvelope();
311 StoredPhysVol *sPhysVol = new StoredPhysVol(emecEnvelope);
312 StatusCode status=detStore->record(sPhysVol,"EMEC_POS");
313 if(!status.isSuccess()) throw std::runtime_error ("Cannot store EMEC_POS");
314
315 GeoTrf::Transform3D Mrot(GeoTrf::RotateZ3D( m_phi_pos + 90*Gaudi::Units::deg)*GeoTrf::RotateY3D(m_ModuleRotation));
316 GeoTrf::Vector3D pos( -xcent, m_YShift, -51.4/2*Gaudi::Units::cm );
317
318 if ( LArPhysical ) {
319
320 LArPhysical->add( new GeoIdentifierTag( 1 ) );
321 LArPhysical->add( new GeoTransform( GeoTrf::Transform3D( GeoTrf::Translation3D(pos(0),pos(1),pos(2)))*Mrot ) );
322 LArPhysical->add( emecEnvelope );
323 }
324
325 pos-= GeoTrf::Vector3D( 0.*Gaudi::Units::mm, 0.*Gaudi::Units::mm, 61.*Gaudi::Units::mm +2.*Gaudi::Units::mm +13.5*Gaudi::Units::mm );
326
327 if ( m_hasPresampler ) {
328
329 EndcapPresamplerConstruction PresamplerConstruction( true );
330 GeoIntrusivePtr<GeoFullPhysVol> PresamplerEnvelope = PresamplerConstruction.Envelope();
331
332 StoredPhysVol *sPhysVol = new StoredPhysVol(PresamplerEnvelope);
333 StatusCode status=detStore->record(sPhysVol,"PRESAMPLER_EC_POS");
334 if(!status.isSuccess()) throw std::runtime_error ("Cannot store PRESAMPLER_EC_POS");
335
336 if ( LArPhysical ) {
337
338 LArPhysical->add( new GeoIdentifierTag( 1 ) );
339 LArPhysical->add( new GeoTransform( GeoTrf::Transform3D( GeoTrf::Translation3D(pos(0),pos(1),pos(2)))*Mrot ) );
340 LArPhysical->add( PresamplerEnvelope );
341 }
342 }
343
344return tbecMotherPhysical;
345}
#define endmsg
Declaration of EMECConstruction class.
Declaration of EndcapPresamplerConstruction 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.
struct { int cylNumber; GeoMaterial *mat; double Rmin; double Dr; double Zmin; double Dz;} cryoEndcapCylDBRecord_t
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.
GeoModel description of the LAr Endcap Presampler geometry.
GeoIntrusivePtr< GeoFullPhysVol > Envelope()
GeoIntrusivePtr< GeoVFullPhysVol > GetEnvelope()
GeoIntrusivePtr< GeoPhysVol > GetLArPhysical()
GeoModel description of the LAr EMEC envelope and the active part (custom shapes)
GeoIntrusivePtr< GeoFullPhysVol > createEnvelope()
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(const std::string &name)=0
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)