ATLAS Offline Software
HECWheelConstruction.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // HECWheelConstruction.cxx 1.0.0
6 //
7 // This provides a mother volume for the ATLAS Front HEC or Rear HEC,
8 // gets the modules from the HECModuleConstruction and arranges
9 // them into a FrontWheel or RearWheel respectively.
10 // The LAr gaps can be equipped with either one thick PAD+EST board
11 // or with 3 individual boards (1 PAD + 2 EST).
12 //
13 // M. Fincke-Keeler
14 //
15 //====================================================================
19 
20 #include "GeoModelKernel/GeoElement.h"
21 #include "GeoModelKernel/GeoMaterial.h"
22 #include "GeoModelKernel/GeoFullPhysVol.h"
23 #include "GeoModelKernel/GeoPhysVol.h"
24 #include "GeoModelKernel/GeoVPhysVol.h"
25 #include "GeoModelKernel/GeoLogVol.h"
26 #include "GeoModelKernel/GeoPcon.h"
27 #include "GeoModelKernel/GeoTubs.h"
28 #include "GeoModelKernel/GeoNameTag.h"
29 #include "GeoModelKernel/GeoTransform.h"
30 #include "GeoModelKernel/GeoAlignableTransform.h"
31 #include "GeoModelKernel/GeoIdentifierTag.h"
32 #include "GeoModelKernel/GeoSerialTransformer.h"
33 #include "GeoModelKernel/GeoSerialIdentifier.h"
34 #include "GeoModelKernel/GeoXF.h"
35 #include "GeoModelKernel/GeoDefinitions.h"
36 #include "GeoGenericFunctions/Variable.h"
37 #include "StoreGate/StoreGateSvc.h"
39 #include "GaudiKernel/MsgStream.h"
40 #include "GaudiKernel/Bootstrap.h"
41 #include "GaudiKernel/SystemOfUnits.h"
43 
44 
49 
50 #include <string>
51 #include <cmath>
52 #include <iostream>
53 
54 
55 using Gaudi::Units::cm;
56 using Gaudi::Units::mm;
57 using Gaudi::Units::deg;
58 using GeoTrf::RotateZ3D;
59 
60 
61 //Constructor
62 LArGeo::HECWheelConstruction::HECWheelConstruction(bool fullGeo, const std::string& wheelType, bool threeBoards, bool posZSide):
63  m_posZSide(posZSide),
64  m_threeBoards(threeBoards),
65  m_wheelType(wheelType),
66  m_fullGeo(fullGeo)
67 {
68  m_frontWheel = m_wheelType=="front";
69 }
70 
71 //~Destructor
73 
74 
75 GeoIntrusivePtr<GeoFullPhysVol> LArGeo::HECWheelConstruction::GetEnvelope() {
76 
77  // Get access to the material manager:
78 
79  ISvcLocator *svcLocator = Gaudi::svcLocator();
80 
81  MsgStream log(Athena::getMessageSvc(),"HECWheelConstruction " );
82 
83  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endmsg;
84  log << MSG::DEBUG << "+ +" << endmsg;
85  log << MSG::DEBUG << "+ Start of HECWheel GeoModel definition +" << endmsg;
86  log << MSG::DEBUG << "+ +" << endmsg;
87  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endmsg;
88 
89 
91  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
92  throw std::runtime_error("Error in HECWheelConstruction, cannot access DetectorStore");
93  }
94 
95 
96  StoredMaterialManager* materialManager = nullptr;
97  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
98  throw std::runtime_error("Error in HECWheelConstruction, cannot access Material Manager");
99  }
100 
101  const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
102  if (!LAr) throw std::runtime_error("Error in HECWheelConstruction, std::LiquidArgon is not found.");
103 
104  const GeoMaterial *Iron = materialManager->getMaterial("std::Iron");
105  if (!Iron) throw std::runtime_error("Error in HECWheelConstruction, std::Iron is not found.");
106 
107 
108 
109  StatusCode sc;
110  IRDBAccessSvc *pAccessSvc;
111  sc=svcLocator->service("RDBAccessSvc",pAccessSvc);
112  if (sc != StatusCode::SUCCESS) {
113  throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
114  }
115 
116 
117  IGeoModelSvc *geoModel;
118  sc = svcLocator->service ("GeoModelSvc",geoModel);
119  if (sc != StatusCode::SUCCESS) {
120  throw std::runtime_error ("Cannot locate GeoModelSvc!!");
121  }
122 
123  std::string AtlasVersion = geoModel->atlasVersion();
124  std::string LArVersion = geoModel->LAr_VersionOverride();
125 
126  std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion;
127  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
128 
129  IRDBRecordset_ptr hadronicEndcap = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode);
130  if(hadronicEndcap->size()>0)
131  log << MSG::DEBUG << "Using numbers from HadronicEndcap tag: " << hadronicEndcap->tagName() << endmsg;
132  else
133  throw std::runtime_error("Error in HECConstruction: hadronicEendcap not found");
134 
135  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode);
136  if(hecLongitudinalBlock->size()>0)
137  log << MSG::DEBUG << "Using numbers from HecLongitudinalBlock tag: " << hecLongitudinalBlock->tagName() << endmsg;
138  else
139  throw std::runtime_error("Error in HECConstruction: hecLongitudinalBlock not found");
140 
141  IRDBRecordset_ptr coldContraction = pAccessSvc->getRecordsetPtr("ColdContraction",detectorKey, detectorNode);
142  if(coldContraction->size()>0)
143  log << MSG::DEBUG << "Numbers from ColdContraction db (not used yet) tag: " << coldContraction->tagName() << endmsg;
144  else
145  throw std::runtime_error("Error in HECConstruction: ColdContraction not found");
146 
147  //----------------------------------------------------------------
148  // Collect all the numbers we need from the database:
149  //----------------------------------------------------------------
150 
151  // This will have to come into action once we are all ready to go cold:
152  // (what's still missing right now are the proper densities to go with it)
153  //double shrinkCold = (*coldContraction)[0]->getDouble("ABSORBERCONTRACTION");
154 
155  double shrinkCold = 1.0; // thermal expansion factor: 1.0 = warm geometry
156 
157  int moduleNumber = (*hadronicEndcap)[0]->getInt("NSCT");
158  double drModOverlap = shrinkCold * (*hadronicEndcap)[0]->getDouble("DRMODOVERLAP")*cm;
159  double rOuter = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
160  if (rOuter<2100.*mm) rOuter = shrinkCold * 2130*mm; // Needs fixing in database to make room for HEC Clamping bars!
161  // Caution: We'll need 2 Routers - One for Wheel, one for Module!
162  double rInner1 = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMN")*cm;
163  double rInner2 = shrinkCold * (*hecLongitudinalBlock)[1]->getDouble("BLRMN")*cm;
164  double firstFrontAbsThickness= shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("PLATE0")*cm;
165  double firstRearAbsThickness = shrinkCold * (*hecLongitudinalBlock)[3]->getDouble("PLATE0")*cm;
166  double frontAbsThickness = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_0")*cm;
167  double rearAbsThickness = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_1")*cm;
168  double gapSize = shrinkCold * (*hadronicEndcap)[0]->getDouble("LARG")*cm;
169  int gapNumber[7];
170  for (int id=0; id<7;id++) gapNumber[id] = (int) (*hecLongitudinalBlock)[id]->getDouble("BLMOD");
171 
172 
173  //---- Calculate the sizes of the 7 longitudinal Depths -------------------------------------
174  double depthSize[7];
175  depthSize[0] = firstFrontAbsThickness + gapNumber[0]*(frontAbsThickness+gapSize);
176  depthSize[1] = gapNumber[1]*(frontAbsThickness+gapSize);
177  depthSize[2] = gapNumber[2]*(frontAbsThickness+gapSize);
178  depthSize[3] = firstRearAbsThickness + gapNumber[3]*(rearAbsThickness+gapSize);
179  depthSize[4] = gapNumber[4]*(rearAbsThickness+gapSize);
180  depthSize[5] = gapNumber[5]*(rearAbsThickness+gapSize);
181  depthSize[6] = gapNumber[6]*(rearAbsThickness+gapSize);
182 
183  //--- From the depth Size, calculate the boundary planes of the Wheel Mother volume ---------
184  // (Add 0.2 mm to avoid clashes)
185  double g4allow = shrinkCold * 0.2*mm;
186  double zCoordinate[4];
187  if (m_frontWheel){
188  zCoordinate[0] = shrinkCold * 0.0*cm;
189  zCoordinate[1] = depthSize[0]; //280.5*mm; (end of the section with the long plates)
190  zCoordinate[2] = depthSize[0] + g4allow; //280.6*mm;
191  zCoordinate[3] = depthSize[0] + depthSize[1] + depthSize[2] + g4allow; // End of front Module
192  }
193  else{
194  zCoordinate[0] = shrinkCold * 0.0*cm;
195  zCoordinate[1] = depthSize[3] + depthSize[4] + depthSize[5] + depthSize[6] + g4allow; // End of rear
196  }
197 
198  //---- And here we have some (yikes!) hard-coded values: -------------------------------------
199  // The somewhat odd looking phistart arranges that the y-axis lines up
200  // with the (radial) symmetry axis of of the module.
201  // This is important for the calculator.
202  //
203  double modulePhistart = 264.375*deg; // (270.-11.25/2.)*deg
204  double moduleDeltaPhi = 2*M_PI/moduleNumber; //11.25*deg;
205 
206  int nZplane = 4;
207  if (!m_frontWheel) nZplane = 2;
208 
209 
210 
211  //----------------------------------------------------------------
212  // HECWheel
213  //----------------------------------------------------------------
214  GeoPcon* solidHECWheel = new GeoPcon(0., 2.*M_PI);
215  for (int i=0; i< nZplane; i++)
216  {
217  double innerRadius = rInner2;
218  if (i<2 && m_frontWheel) innerRadius=rInner1;
219  solidHECWheel->addPlane(zCoordinate[i],innerRadius-drModOverlap,rOuter);
220  }
221  std::string hecFrontName = "LAr::HEC::LiquidArgon";
222  const GeoLogVol* logicHECWheel = new GeoLogVol(hecFrontName, solidHECWheel , LAr);
223  GeoIntrusivePtr<GeoFullPhysVol> physiHECWheel{new GeoFullPhysVol(logicHECWheel)};
224 
225 
226  if(m_fullGeo) {
227 
228  //----------------------------------------------------------------
229  // Get HEC Modules
230  //----------------------------------------------------------------
231  // NB: HECModuleConstruction( threeBoards, frontWheel, TB,TByear) ;
232 
233  HECModuleConstruction HECModule(m_threeBoards,m_frontWheel,false,0) ;
234  PVLink moduleEnvelope = HECModule.GetEnvelope();
235 
236  //----------------------------------------------------------------
237  // Place Modules into HEC Wheel
238  //----------------------------------------------------------------
239  // Rotation angle is: 11.25/2 + Index * 11.25*deg
240  // Modules are numbered mirror-symmetric in pos/neg z-side!
241 
242  GeoSerialIdentifier *sIF = new GeoSerialIdentifier(0);
243  GeoGenfun::Variable Index;
244 
245  if (m_posZSide) {
246  GeoGenfun::GENFUNCTION ModuleRotationAngle = -modulePhistart + moduleDeltaPhi*Index;
247  GeoXF::TRANSFUNCTION t = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngle);
248  GeoSerialTransformer *sTF = new GeoSerialTransformer (moduleEnvelope,&t,moduleNumber);
249  physiHECWheel->add(sIF);
250  physiHECWheel->add(sTF);
251  } else {
252  //For the neg z-side have to build everything in the opposite sense from pos-z wheel.
253  GeoGenfun::GENFUNCTION ModuleRotationAngle1 = -modulePhistart+180*deg-moduleDeltaPhi - moduleDeltaPhi*Index;
254  GeoXF::TRANSFUNCTION t1 = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngle1);
255  GeoSerialTransformer *sTF1 = new GeoSerialTransformer (moduleEnvelope,&t1,moduleNumber);
256  physiHECWheel->add(sIF);
257  physiHECWheel->add(sTF1);
258  }
259 
260  //----------------------------------------------------------------
261  // Add Outer Connecting Bars to HEC Wheel
262  //----------------------------------------------------------------
263 
264  HECClampConstruction HECClamp (m_frontWheel,m_posZSide);
265  HECClamp.AddClamps(physiHECWheel);
266  }
267 
268  return physiHECWheel;
269 }
270 
LArGeo::HECWheelConstruction::GetEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope()
Definition: HECWheelConstruction.cxx:75
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
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
LArGeo::HECClampConstruction::AddClamps
void AddClamps(GeoIntrusivePtr< GeoFullPhysVol > physiHECWheel)
Definition: HECClampConstruction.cxx:334
LAr
Definition: LArVolumeBuilder.h:36
LArGeo::HECModuleConstruction
GeoModel description of LAr HECModule.
Definition: HECModuleConstruction.h:27
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
HECWheelConstruction.h
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
IGeoModelSvc::LAr_VersionOverride
virtual const std::string & LAr_VersionOverride() const =0
LArGeo::HECWheelConstruction::m_frontWheel
bool m_frontWheel
Definition: HECWheelConstruction.h:36
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:128
Index
IndexedConstituentUserInfo::Index Index
Definition: IndexedConstituentUserInfo.cxx:12
EventInfoWrite.AtlasVersion
AtlasVersion
Definition: EventInfoWrite.py:17
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
lumiFormat.i
int i
Definition: lumiFormat.py:92
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
HECClampConstruction.h
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
LArGeo::HECClampConstruction
Definition: HECClampConstruction.h:23
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:194
StoredMaterialManager.h
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
HECModuleConstruction.h
Declaration of HECModuleConstruction class.
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
LArGeo::HECWheelConstruction::~HECWheelConstruction
virtual ~HECWheelConstruction()
LArGeo::HECModuleConstruction::GetEnvelope
GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope()
Definition: HECModuleConstruction.cxx:71
DEBUG
#define DEBUG
Definition: page_access.h:11
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
StoredMaterialManager::getMaterial
virtual const GeoMaterial * getMaterial(const std::string &name)=0
LArGeo::HECWheelConstruction::m_wheelType
std::string m_wheelType
Definition: HECWheelConstruction.h:37
StoredMaterialManager
This class holds one or more material managers and makes them storeable, under StoreGate.
Definition: StoredMaterialManager.h:28
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
LArGeo::HECWheelConstruction::HECWheelConstruction
HECWheelConstruction(bool fullGeo, const std::string &wheelType="front", bool threeBoards=false, bool posZSide=true)
Definition: HECWheelConstruction.cxx:62
IGeoModelSvc::atlasVersion
virtual const std::string & atlasVersion() const =0
IGeoModelSvc.h
StoreGateSvc.h