ATLAS Offline Software
HECClampConstruction.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 // HECClampConstruction.cxx 1.0.0
6 //
7 // GetClampingBar:
8 // Construct Outer Connecting Bars and Support Rails for the
9 // HEC Wheels (Front or Rear)
10 // AddClamps:
11 // Places the Bars and Rails on the HEC Wheel
12 //
13 // 25. Oct 2007 M. Fincke-Keeler
14 //
15 //====================================================================
18 
19 #include "GeoModelKernel/GeoElement.h"
20 #include "GeoModelKernel/GeoMaterial.h"
21 #include "GeoModelKernel/GeoFullPhysVol.h"
22 #include "GeoModelKernel/GeoPhysVol.h"
23 #include "GeoModelKernel/GeoVPhysVol.h"
24 #include "GeoModelKernel/GeoLogVol.h"
25 #include "GeoModelKernel/GeoPcon.h"
26 #include "GeoModelKernel/GeoTubs.h"
27 #include "GeoModelKernel/GeoNameTag.h"
28 #include "GeoModelKernel/GeoTransform.h"
29 #include "GeoModelKernel/GeoAlignableTransform.h"
30 #include "GeoModelKernel/GeoIdentifierTag.h"
31 #include "GeoModelKernel/GeoSerialTransformer.h"
32 #include "GeoModelKernel/GeoSerialIdentifier.h"
33 #include "GeoModelKernel/GeoXF.h"
34 #include "GeoModelKernel/GeoDefinitions.h"
35 #include "GeoGenericFunctions/Variable.h"
36 #include "StoreGate/StoreGateSvc.h"
38 #include "GaudiKernel/MsgStream.h"
39 #include "GaudiKernel/Bootstrap.h"
40 #include "GaudiKernel/SystemOfUnits.h"
42 
43 
48 
49 #include <string>
50 #include <cmath>
51 #include <iostream>
52 
53 using Gaudi::Units::cm;
54 using Gaudi::Units::mm;
55 using Gaudi::Units::deg;
56 using GeoTrf::RotateZ3D;
57 using GeoTrf::Translate3D;
58 using GeoTrf::TranslateZ3D;
59 
60 
61 //Constructor
63  : m_moduleNumber(0),
64  m_moduleRouter(0),
65  m_modulePhistart(0),
66  m_rOuter(0),
67  m_moduleDeltaPhi(0)
68 {
69  m_front = front;
70  m_posZSide = posZSide;
71 }
72 
73 //~Destructor
75 = default;
76 
78 {
79 
80  ISvcLocator *svcLocator = Gaudi::svcLocator();
81 
82  MsgStream log(Athena::getMessageSvc(),"HECClampConstruction " );
83  log << MSG::DEBUG << " In HECClampConstruction " << endmsg;
84 
85 
86  SmartIF<StoreGateSvc> detStore{svcLocator->service("DetectorStore")};
87  if(!detStore.isValid()) {
88  throw std::runtime_error("Error in HECModuleConstruction(ClampBar), cannot access DetectorStore");
89  }
90 
91 
92  // Get access to the material manager:
93  StoredMaterialManager* materialManager = nullptr;
94  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
95  throw std::runtime_error("Error in HECModuleConstruction(ClampBar), cannot access Material Manager");
96  }
97  const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
98  if (!LAr) throw std::runtime_error("Error in HECModuleConstruction(ClampBar), std::LiquidArgon is not found.");
99  const GeoMaterial *Iron = materialManager->getMaterial("std::Iron");
100  if (!Iron) throw std::runtime_error("Error in HECModuleConstruction(ClampBar), std::Iron is not found.");
101 
102 
103  SmartIF<IRDBAccessSvc> pAccessSvc{svcLocator->service("RDBAccessSvc")};
104  if(!pAccessSvc.isValid()) {
105  throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
106  }
107 
108  SmartIF<IGeoModelSvc> geoModel{svcLocator->service("GeoModelSvc")};
109  if(!geoModel.isValid()) {
110  throw std::runtime_error ("Cannot locate GeoModelSvc!!");
111  }
112 
113  std::string AtlasVersion = geoModel->atlasVersion();
114  std::string LArVersion = geoModel->LAr_VersionOverride();
115 
116  std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion;
117  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
118 
119  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode);
120  IRDBRecordset_ptr hadronicEndcap = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode);
121 
122 
123  //----------------------------------------------------------------
124  // Collect all the numbers we need from the database:
125  //----------------------------------------------------------------
126  //
127  // NOT READY YET
128  //
129 
130  //----------------------------------------------------------------
131  // Add outer clamping bars for Atlas wheels
132  //----------------------------------------------------------------
133  // NB.: The outer clamping bars have notches for the HEC cables.
134  // that sit at different levels for Front/Rear Wheel
135  //
136  double shrinkCold = 1.0; // thermal expansion factor: 1.0 = warm
137 
138  int moduleNumber = (*hadronicEndcap)[0]->getInt("NSCT");
139  double moduleRouter = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
140  double modulePhistart = 264.375*deg; // (270.-11.25/2.)*deg
141  double rOuter = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
142  double moduleDeltaPhi = 2*M_PI/moduleNumber; //11.25*deg;
143  m_moduleNumber = moduleNumber;
144  m_moduleRouter = moduleRouter;
145  m_modulePhistart= modulePhistart;
146  m_rOuter = rOuter;
147  m_moduleDeltaPhi= moduleDeltaPhi ;
148 
149  std::string clampName = "LAr::HEC::Clamp";
150  std::string larName = "LAr::HEC::Clamp::LiquidArgon";
151  double g4allow = 0.01 *mm;
152  double extThick = shrinkCold * 37.*mm;
153  double extLength = shrinkCold * 84.*mm;
154  double clampWidth = shrinkCold * 147.0 *mm;
155  double clampThick = shrinkCold * 50.*mm;
156  double notchLevel = shrinkCold * 25.*mm;
157  double notchHeight = shrinkCold * 15.*mm;
158  // cppcheck-suppress duplicateAssignExpression
159  double notchWidth = shrinkCold * 20.*mm;
160  double slotWidth = shrinkCold * 20.*mm;
161  double clampLength = shrinkCold * 815.*mm;
162  double clampAngle = 2.* asin(clampWidth/(2.*(moduleRouter+clampThick/2.)));
163  double slotAngle = 2.* asin(notchWidth/(2.*(moduleRouter+clampThick/2.)));
164 
165  std::vector<double> notchLocation;
166  if (m_front){
167  if (!rail){
168 // notchLocation.push_back(shrinkCold * 201.*mm);
169 // notchLocation.push_back(shrinkCold * 469.*mm);
170 // notchLocation.push_back(shrinkCold * 737.*mm);
171  notchLocation.push_back(shrinkCold * 200.*mm); // adjust for shortened clamp
172  notchLocation.push_back(shrinkCold * 468.*mm);
173  notchLocation.push_back(shrinkCold * 736.*mm);
174  }
175  else {
176 // notchLocation.push_back(shrinkCold * 206.*mm);
177 // notchLocation.push_back(shrinkCold * 474.*mm);
178 // notchLocation.push_back(shrinkCold * 742.*mm);
179  notchLocation.push_back(shrinkCold * 201.*mm); // adjust for shortened rail
180  notchLocation.push_back(shrinkCold * 469.*mm);
181  notchLocation.push_back(shrinkCold * 737.*mm);
182  clampWidth = shrinkCold * 148.5 *mm;
183  clampThick = shrinkCold * 98.*mm; // 98.*mm (this is the total overall rail thickness)
184  clampLength = shrinkCold * 815.*mm;
185  }
186  }
187  else {
188  if (!rail){
189 // notchLocation.push_back(shrinkCold * 364.0*mm);
190 // notchLocation.push_back(shrinkCold * 832.0*mm);
191  notchLocation.push_back(shrinkCold * 363.0*mm); // adjust for shortened clamp
192  notchLocation.push_back(shrinkCold * 831.0*mm);
193  clampLength = shrinkCold * 960.*mm;
194  }
195  else {
196 // notchLocation.push_back(shrinkCold * 372.5*mm);
197 // notchLocation.push_back(shrinkCold * 840.5*mm);
198  notchLocation.push_back(shrinkCold * 364.*mm); // adjust for shortened rail
199  notchLocation.push_back(shrinkCold * 832.*mm);
200  clampWidth = shrinkCold * 148.5 *mm;
201  clampThick = shrinkCold * 98.*mm;
202  clampLength = shrinkCold * 960.*mm;
203  extLength = shrinkCold * 132.*mm;
204  }
205  notchWidth = shrinkCold * 16.*mm;
206  notchHeight = shrinkCold * 16.*mm;
207  notchLevel = shrinkCold * 0.*mm;
208  }
209 
210 
211 
212 
213  // Construct the the slots and notches here. For the support rails, they have to be inserted
214  // into the physExt[0] volume. For the regular clamps they go into physClamp.
215  std::array<GeoIntrusivePtr<GeoTubs>, 3> clampExt;
216  std::array<GeoIntrusivePtr<GeoLogVol>, 3> logExt;
217  std::array<GeoIntrusivePtr<GeoPhysVol>, 3> physExt;
218 
219  GeoIntrusivePtr<GeoTubs> Notch{new GeoTubs(moduleRouter+notchLevel+g4allow, moduleRouter+notchLevel+notchHeight-g4allow,
220  notchWidth/2.,
221  modulePhistart-(clampAngle/2.) , clampAngle)};
222  GeoIntrusivePtr<GeoLogVol> logNotch {new GeoLogVol(larName, Notch, LAr)};
223  GeoIntrusivePtr<GeoPhysVol> physiNotch{new GeoPhysVol(logNotch)};
224 
225  GeoIntrusivePtr<GeoTubs> Slot {new GeoTubs(moduleRouter+g4allow, moduleRouter+notchLevel-g4allow, slotWidth/2. ,
226  modulePhistart-(slotAngle/2.) , slotAngle)};
227  GeoIntrusivePtr<GeoLogVol> logSlot{new GeoLogVol(larName, Slot, LAr)};
228  GeoIntrusivePtr<GeoPhysVol> physiSlot{new GeoPhysVol(logSlot)};
229 
230 
231 
232  GeoIntrusivePtr<GeoTubs> clampBar{};
233  GeoIntrusivePtr<GeoLogVol> logClamp{};
234  GeoIntrusivePtr<GeoPhysVol> physClamp{};
235 
236  if(!rail){
237  clampBar = new GeoTubs(moduleRouter, moduleRouter+clampThick, clampLength/2. ,
238  modulePhistart-(clampAngle/2.) , clampAngle);
239  logClamp = new GeoLogVol(clampName, clampBar, Iron);
240  physClamp= new GeoPhysVol(logClamp);
241  }
242  else{
243 
244  //For the support rails, make the mother LAr and the place the steel inside:
245 
246  clampBar = new GeoTubs(moduleRouter, moduleRouter+clampThick, clampLength/2. ,
247  modulePhistart-(clampAngle/2.) , clampAngle);
248  logClamp = new GeoLogVol(larName, clampBar, LAr);
249  physClamp= new GeoPhysVol(logClamp);
250 
251 
252  clampExt[0] = new GeoTubs(moduleRouter+g4allow, moduleRouter+clampThick-extThick,
253  clampLength/2. , modulePhistart-(clampAngle/2.), clampAngle);
254  clampExt[1] = new GeoTubs(moduleRouter+clampThick-extThick+g4allow, moduleRouter+clampThick-g4allow,
255  clampLength/2. , modulePhistart, clampAngle/2.);
256  clampExt[2] = new GeoTubs(moduleRouter+clampThick-extThick+g4allow, moduleRouter+clampThick-g4allow,
257  extLength/2. , modulePhistart, clampAngle/2.);
258 
259 
260 
261 
262  for (int iext=0; iext<3; iext++){
263 
264  logExt[iext] = new GeoLogVol(clampName, clampExt[iext], Iron);
265  physExt[iext]= new GeoPhysVol(logExt[iext]);
266 
267 
268  if (iext==0) {
269  for ( unsigned int i = 0; i < notchLocation.size(); i++ )
270  {
271  physExt[0]->add( new GeoIdentifierTag(i) );
272  physExt[0]->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );
273  physExt[0]->add( physiNotch );
274  if (m_front){
275  physExt[0]->add( new GeoIdentifierTag(i) );
276  physExt[0]->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );
277  physExt[0]->add( physiSlot );
278  }
279  }
280  }
281 
282 
283  if (iext==1 && !left) physClamp->add(new GeoTransform(RotateZ3D(-clampAngle/2.)));
284  else if(iext==2 && left) physClamp->add(new GeoTransform(TranslateZ3D((clampLength-extLength)/2.)
285  *RotateZ3D(-clampAngle/2.)));
286  else if(iext==2) physClamp->add(new GeoTransform(TranslateZ3D((clampLength-extLength)/2.)
287  *RotateZ3D( 0.)));
288 
289  if (left) physClamp->add( new GeoIdentifierTag(16) );
290  else physClamp->add( new GeoIdentifierTag(32) );
291 
292 
293  physClamp->add(physExt[iext]);
294 
295  }
296 
297 
298  }
299 
300 
301  for ( unsigned int i = 0; i < notchLocation.size(); i++ )
302  {
303  if(!rail){
304  physClamp->add( new GeoIdentifierTag(i) );
305  physClamp->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );
306  physClamp->add( physiNotch );
307  }
308  }
309 
310  if(m_front)
311  {
312  for ( unsigned int i = 0; i < notchLocation.size(); i++ )
313  {
314  if(!rail){
315  physClamp->add( new GeoIdentifierTag(i) );
316  physClamp->add( new GeoTransform(Translate3D(0,0,-clampLength/2.+notchLocation[i])) );
317  physClamp->add( physiSlot );
318  }
319  }
320 
321  }
322 
323 
324  return physClamp;
325 }
326 
327 
328 
329 void LArGeo::HECClampConstruction::AddClamps(GeoIntrusivePtr<GeoFullPhysVol> physiHECWheel)
330 {
331  //----------------------------------------------------------------
332  // Add Outer Connecting Bars to HEC Wheel
333  //----------------------------------------------------------------
334 
335  double shrinkCold = 1.0 ; // thermal expansion factor: 1.0 = warm
336 
337  std::string clampName = "LAr::HEC::Clamp";
338  std::string larName = "LAr::HEC::Clamp::LiquidArgon";
339  // cppcheck-suppress duplicateAssignExpression
340  double clampLength = shrinkCold * 815.*mm;
341  double railLength = shrinkCold * 815.*mm;
342  double railOffset = shrinkCold * 0.*mm;
343  if (!m_front) {
344  clampLength = shrinkCold * 960.*mm;
345  railLength = shrinkCold * 960.*mm;
346  railOffset = shrinkCold * 0.*mm;
347  }
348 
349  GeoIntrusivePtr<GeoVPhysVol> clampingBar = GetClampingBar(false,false);
350  GeoIntrusivePtr<GeoVPhysVol> clampingRailR = GetClampingBar(true,false);
351  GeoIntrusivePtr<GeoVPhysVol> clampingRailL = GetClampingBar(true,true);
352 
353 
354 
355  // In the below positioning sequence, the ORDER MATTERS!
356  //
357 
358  GeoIntrusivePtr<GeoTransform> xt{new GeoTransform(TranslateZ3D(clampLength/2.))};
359  physiHECWheel->add(xt);
360 
361  GeoIntrusivePtr<GeoSerialIdentifier> sIC{new GeoSerialIdentifier(0)};
362  GeoGenfun::Variable IndexC;
363 
364  if (m_posZSide)
365  {
366  GeoGenfun::GENFUNCTION ModuleRotationAngleC = -m_modulePhistart+m_moduleDeltaPhi + m_moduleDeltaPhi*IndexC;
367  GeoXF::TRANSFUNCTION tC = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC);
368  GeoIntrusivePtr<GeoSerialTransformer> sTC{new GeoSerialTransformer (clampingBar,&tC,((m_moduleNumber/2)-1))};
369  physiHECWheel->add(sIC);
370  physiHECWheel->add(sTC);
371  }
372  else
373  {
374  GeoGenfun::GENFUNCTION ModuleRotationAngleC = -m_modulePhistart-m_moduleDeltaPhi+180*deg - m_moduleDeltaPhi*IndexC;
375  GeoXF::TRANSFUNCTION tC = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC);
376  GeoIntrusivePtr<GeoSerialTransformer> sTC{new GeoSerialTransformer (clampingBar,&tC,((m_moduleNumber/2)-1))};
377  physiHECWheel->add(sIC);
378  physiHECWheel->add(sTC);
379  }
380 
381 
382  physiHECWheel->add(new GeoTransform(TranslateZ3D(railLength/2.-railOffset)*RotateZ3D(-m_modulePhistart-(180.*deg))));
383  //GeoSerialIdentifier *sIR = new GeoSerialIdentifier(15); // For the pos z-side this is the position of module no.15
384  //physiHECWheel->add(sIR); // No need to aplly it if we position clamps in this order
386  if (!m_posZSide)
387  {
388  GeoSerialIdentifier *sIR = new GeoSerialIdentifier(31);
389  physiHECWheel->add(sIR);
390  }
391  physiHECWheel->add(clampingRailL);
392 
393 
394  physiHECWheel->add(xt);
395  GeoGenfun::Variable IndexC2;
396 
397  if (m_posZSide)
398  {
399  GeoGenfun::GENFUNCTION ModuleRotationAngleC2 = -m_modulePhistart+m_moduleDeltaPhi-(180.*deg) + m_moduleDeltaPhi*IndexC2;
400  GeoXF::TRANSFUNCTION tC2 = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC2);
401  GeoIntrusivePtr<GeoSerialTransformer> sTC2{new GeoSerialTransformer (clampingBar,&tC2,((m_moduleNumber/2)-1))};
402  physiHECWheel->add(sTC2);
403  }
404  else
405  {
406  GeoGenfun::GENFUNCTION ModuleRotationAngleC2 = -m_modulePhistart-m_moduleDeltaPhi - m_moduleDeltaPhi*IndexC2;
407  GeoXF::TRANSFUNCTION tC2 = GeoXF::Pow(RotateZ3D(1.0),ModuleRotationAngleC2);
408  GeoIntrusivePtr<GeoSerialTransformer> sTC2{new GeoSerialTransformer (clampingBar,&tC2,((m_moduleNumber/2)-1))};
409  physiHECWheel->add(sTC2);
410  }
411 
412  physiHECWheel->add(new GeoTransform(TranslateZ3D(railLength/2.)*RotateZ3D(-m_modulePhistart)));
413  if (!m_posZSide)
414  {
415  GeoSerialIdentifier *sIR = new GeoSerialIdentifier(15);
416  physiHECWheel->add(sIR);
417  }
418  physiHECWheel->add(clampingRailR);
419 
420 }
421 
422 
423 
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
LArGeo::HECClampConstruction::AddClamps
void AddClamps(GeoIntrusivePtr< GeoFullPhysVol > physiHECWheel)
Definition: HECClampConstruction.cxx:329
LAr
Definition: LArVolumeBuilder.h:36
LArGeo::HECClampConstruction::~HECClampConstruction
virtual ~HECClampConstruction()
LArGeo::HECClampConstruction::HECClampConstruction
HECClampConstruction(bool front=true, bool posZSide=true)
Definition: HECClampConstruction.cxx:62
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
xt
#define xt
EventInfoWrite.AtlasVersion
AtlasVersion
Definition: EventInfoWrite.py:17
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
HECClampConstruction.h
LArGeo::HECClampConstruction::GetClampingBar
PVLink GetClampingBar(bool rail=false, bool left=false)
Definition: HECClampConstruction.cxx:77
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
LArGeo::HECClampConstruction::m_front
bool m_front
Definition: HECClampConstruction.h:32
StoredMaterialManager.h
LArGeo::HECClampConstruction::m_posZSide
bool m_posZSide
Definition: HECClampConstruction.h:35
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
HECModuleConstruction.h
Declaration of HECModuleConstruction class.
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
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
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.
IGeoModelSvc.h
StoreGateSvc.h