ATLAS Offline Software
Public Member Functions | Private Attributes | List of all members
LArGeo::HECModuleConstruction Class Reference

GeoModel description of LAr HECModule. More...

#include <HECModuleConstruction.h>

Collaboration diagram for LArGeo::HECModuleConstruction:

Public Member Functions

 HECModuleConstruction (bool threeBoards=false, bool frontWheel=true, bool tb=false, int tbyear=2002)
 
virtual ~HECModuleConstruction ()
 
GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope ()
 

Private Attributes

GeoIntrusivePtr< GeoFullPhysVol > m_physiHECModule
 
bool m_threeBoards
 
bool m_frontWheel
 
bool m_tb
 
int m_tbyear
 

Detailed Description

GeoModel description of LAr HECModule.

The geometry is built and placed within HECModule envelope which is implemented by LArGeoEndcap.

Definition at line 26 of file HECModuleConstruction.h.

Constructor & Destructor Documentation

◆ HECModuleConstruction()

LArGeo::HECModuleConstruction::HECModuleConstruction ( bool  threeBoards = false,
bool  frontWheel = true,
bool  tb = false,
int  tbyear = 2002 
)

Definition at line 52 of file HECModuleConstruction.cxx.

52  :
53  m_physiHECModule(nullptr)
54 {
55  m_threeBoards = threeBoards; // If true, build 3 boards in gap. Else just one thick board.
56  m_frontWheel = frontWheel; // If true, build a front Module. Else build a rear Module.
57  m_tb = tb; // If true, build a Module for testbeam.
58  m_tbyear = tbyear; // If testbeam, specify the testbeam year.
59 
60 // if (tb && ( tbyear!=2002 && tbyear!=2004 )) {
61 // throw std::runtime_error ("TESTBEAM HEC: Asking for an unsupported HEC testbeam year!!!!! ");
62 // }
63 
64 }

◆ ~HECModuleConstruction()

LArGeo::HECModuleConstruction::~HECModuleConstruction ( )
virtual

Definition at line 67 of file HECModuleConstruction.cxx.

68 {;}

Member Function Documentation

◆ GetEnvelope()

GeoIntrusivePtr< GeoFullPhysVol > LArGeo::HECModuleConstruction::GetEnvelope ( )

Definition at line 71 of file HECModuleConstruction.cxx.

72 {
73  if(m_physiHECModule) return m_physiHECModule->clone();
74 
75 
76 
77  ISvcLocator *svcLocator = Gaudi::svcLocator();
78 
79  MsgStream log(Athena::getMessageSvc(),"HECModuleConstruction " );
80 
81  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endmsg;
82  log << MSG::DEBUG << "+ +" << endmsg;
83  log << MSG::DEBUG << "+ Start of HECModule GeoModel definition +" << endmsg;
84  log << MSG::DEBUG << "+ +" << endmsg;
85  log << MSG::DEBUG << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endmsg;
86 
87 
89  if (svcLocator->service("DetectorStore", detStore, false )==StatusCode::FAILURE) {
90  throw std::runtime_error("Error in HECModuleConstruction, cannot access DetectorStore");
91  }
92 
93 
94  StoredMaterialManager* materialManager = nullptr;
95  if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) {
96  throw std::runtime_error("Error in HECModuleConstruction, cannot access Material Manager");
97  }
98 
99  const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
100  if (!LAr) throw std::runtime_error("Error in HECModuleConstruction, std::LiquidArgon is not found.");
101 
102  const GeoMaterial *Iron = materialManager->getMaterial("std::Iron");
103  if (!Iron) throw std::runtime_error("Error in HECModuleConstruction, std::Iron is not found.");
104 
105  const GeoMaterial *Copper = materialManager->getMaterial("std::Copper");
106  if (!Copper) throw std::runtime_error("Error in HECModuleConstruction, std::Copper is not found.");
107 
108  const GeoMaterial *Kapton = materialManager->getMaterial("std::Kapton");
109  if (!Kapton) throw std::runtime_error("Error in HECModuleConstruction, std::Kapton is not found.");
110 
111 
112 
113  StatusCode sc;
114  IRDBAccessSvc *pAccessSvc;
115  sc=svcLocator->service("RDBAccessSvc",pAccessSvc);
116  if (sc != StatusCode::SUCCESS) {
117  throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
118  }
119 
120 
121  IGeoModelSvc *geoModel;
122  sc = svcLocator->service ("GeoModelSvc",geoModel);
123  if (sc != StatusCode::SUCCESS) {
124  throw std::runtime_error ("Cannot locate GeoModelSvc!!");
125  }
126 
127  std::string AtlasVersion = geoModel->atlasVersion();
128  std::string LArVersion = geoModel->LAr_VersionOverride();
129 
130  std::string detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion;
131  std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
132 
133  IRDBRecordset_ptr hadronicEndcap = pAccessSvc->getRecordsetPtr("HadronicEndcap",detectorKey, detectorNode);
134  if(hadronicEndcap->size()>0)
135  log << MSG::DEBUG << "Using numbers from HadronicEndcap tag: " << hadronicEndcap->tagName() << endmsg;
136  else
137  throw std::runtime_error("Error in HECConstruction: hadronicEendcap not found");
138 
139  IRDBRecordset_ptr hecLongitudinalBlock = pAccessSvc->getRecordsetPtr("HecLongitudinalBlock",detectorKey, detectorNode);
140  if(hecLongitudinalBlock->size()>0)
141  log << MSG::DEBUG << "Using numbers from HecLongitudinalBlock tag: " << hecLongitudinalBlock->tagName() << endmsg;
142  else
143  throw std::runtime_error("Error in HECConstruction: hecLongitudinalBlock not found");
144 
145  //----------------------------------------------------------------
146  // Collect all the numbers we need from the database:
147  //----------------------------------------------------------------
148 
149  double shrinkCold = 1.0; //thermal expansion factor: 1.0 = warm geometry
150  //kapton is treated the same at Cu and Fe at the moment
151 
152  int moduleNumber = (*hadronicEndcap)[0]->getInt("NSCT");
153  double moduleRinner1 = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMN")*cm;
154  double moduleRinner2 = shrinkCold * (*hecLongitudinalBlock)[1]->getDouble("BLRMN")*cm;
155  double moduleRouter = shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("BLRMX")*cm;
156  if (m_tbyear==2004) moduleRouter = moduleRinner1 + 787*mm; // Mini Modules for 2004 testbeam CAUTION! Hard-coded number!!!
157  double copperPad = shrinkCold * (*hadronicEndcap)[0]->getDouble("COPPER")*cm;
158  double gapSize = shrinkCold * (*hadronicEndcap)[0]->getDouble("LARG")*cm;
159  double drModOverlap = shrinkCold * (*hadronicEndcap)[0]->getDouble("DRMODOVERLAP")*cm;
160  double kaptonWidth[2];
161  kaptonWidth[0] = shrinkCold * (*hadronicEndcap)[0]->getDouble("ESTPL")*cm;
162  kaptonWidth[1] = shrinkCold * (*hadronicEndcap)[0]->getDouble("PADPL")*cm;
163  int gapN[7];
164  for(int id=0;id<7;id++) gapN[id] = (int) (*hecLongitudinalBlock)[id]->getDouble("BLMOD");
165  double firstFrontAbsThickness= shrinkCold * (*hecLongitudinalBlock)[0]->getDouble("PLATE0")*cm;
166  double firstRearAbsThickness = shrinkCold * (*hecLongitudinalBlock)[3]->getDouble("PLATE0")*cm;
167  double frontAbsThickness = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_0")*cm;
168  double rearAbsThickness = shrinkCold * (*hadronicEndcap)[0]->getDouble("PLATE_1")*cm;
169  double tieRodPositionX[4];
170  double tieRodPositionY[4];
171  tieRodPositionX[0] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_0")*cm;
172  tieRodPositionY[0] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_0")*cm;
173  tieRodPositionX[1] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_1")*cm;
174  tieRodPositionY[1] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_1")*cm;
175  tieRodPositionX[2] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_2")*cm;
176  tieRodPositionY[2] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_2")*cm;
177  tieRodPositionX[3] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSX_3")*cm;
178  tieRodPositionY[3] = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODPOSR_3")*cm;
179  double tieRodDiameter = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODDIM_0")*cm;
180  double spacerDiameter = shrinkCold * (*hadronicEndcap)[0]->getDouble("SPCDIM_0")*cm;
181  double spacerDeadZone = shrinkCold * 3.0*mm;
182  if (!m_frontWheel)
183  {
184  tieRodDiameter = shrinkCold * (*hadronicEndcap)[0]->getDouble("RODDIM_1")*cm;
185  spacerDiameter = shrinkCold * (*hadronicEndcap)[0]->getDouble("SPCDIM_1")*cm;
186  }
187 
188 
189  //--- Get the right Absorber thickness and Depth number depending on Front or Rear Wheel (and TB)
190  // (2002 and 2004 testbeam have only 1/2 rear depth)
191  int depthNumber = 3;
192  int depthOffset = depthNumber; // need this to start rear wheel depth-number at 3
193  double absThickness = frontAbsThickness;
194  double firstAbsThickness = firstFrontAbsThickness;
195  if (!m_frontWheel) {
196  depthNumber = 4;
197  if (m_tb) depthNumber= 2;
198  absThickness = rearAbsThickness;
199  firstAbsThickness = firstRearAbsThickness;
200  }
201 
202 
203  //---- Calculate the sizes of the 7 longitudinal Depths -------------------------------------
204  double depthS[7];
205  depthS[0] = firstFrontAbsThickness + gapN[0]*(frontAbsThickness+gapSize);
206  depthS[1] = gapN[1]*(frontAbsThickness+gapSize);
207  depthS[2] = gapN[2]*(frontAbsThickness+gapSize);
208  depthS[3] = firstRearAbsThickness + gapN[3]*(rearAbsThickness+gapSize);
209  depthS[4] = gapN[4]*(rearAbsThickness+gapSize);
210  depthS[5] = gapN[5]*(rearAbsThickness+gapSize);
211  depthS[6] = gapN[6]*(rearAbsThickness+gapSize);
212 
213  //--- From the depth Size, calculate the boundary planes of the Module Mother volume ---------
214  // (Add 0.1 mm to avoid clashes)
215  double zCoordinate[4];
216  double depthSize[4];
217  int gapNumber[4];
218  int gaptally[4];
219  double g4allow = shrinkCold * 0.1*mm ;
220  double g4allowS = 0.001*mm ;
221  if (m_frontWheel){
222  zCoordinate[0] = shrinkCold * 0.0*cm;
223  zCoordinate[1] = depthS[0];
224  zCoordinate[2] = depthS[0] + g4allow;
225  zCoordinate[3] = depthS[0]+depthS[1]+depthS[2] + g4allow; // End of front Module
226  gaptally[0]=0;
227  for (int i=0; i<3; i++) {
228  if (i>0) gaptally[i] = gaptally[i-1] + gapN[i-1];
229  gapNumber[i] = gapN[i];
230  depthSize[i] = depthS[i];
231  }
232  }
233  else{
234  zCoordinate[0] = shrinkCold * 0.0*cm;
235  zCoordinate[1] = depthS[3]+depthS[4]+depthS[5]+depthS[6]+g4allow; // End of rear Atlas Module
236  if(m_tb) zCoordinate[1]= depthS[3]+depthS[4]+g4allow; // For TB only 1/2 rear depth
237  gaptally[0] = 0;
238  for (int i=0; i<4; i++) { // Re-number the rear wheel
239  if (i>0) gaptally[i] =gaptally[i-1] + gapN[i+3-1];
240  gapNumber[i] = gapN[i+3]; // gaps and depths to have
241  depthSize[i] = depthS[i+3]; // their index start at Zero.
242  }
243  }
244 
245  //--- Calculate where to put the tie-rod spacers into the available LAr gap.
246  // This depends on the configuration of the boards.
247 
248  // +/-ztie are the center z-coordinates of the LAr sub-gaps
249  // rodSize is the length of spacer to be fit into the LAr that is not occupied by boards
250  // Small tolerance to fit G4 volumes into one another
251  double ztie[2];
252  double rodSize;
253 
254  //-- For Three-board approach:
255  if (m_threeBoards) {
256  double halfGap = gapSize/2.;
257  double halfGapLAr = (gapSize - kaptonWidth[1])/2.;
258  double restLAr = (halfGapLAr-kaptonWidth[0])/2. ;
259  ztie[0] = restLAr/2 + kaptonWidth[1]/2.;
260  ztie[1] = halfGap - restLAr/2.;
261  rodSize = restLAr - g4allowS;
262  }
263  else{
264  //-- For One-board approach:
265  double halfGap = gapSize/2.;
266  double halfGapLAr = (gapSize - kaptonWidth[1])/2. - kaptonWidth[0];
267  ztie[0] = (halfGap-halfGapLAr/2.);
268  ztie[1] = 0.0; // fix complilation warning
269  rodSize = halfGapLAr-g4allowS;
270  }
271 
272 
273  //---- And here we have some more (yikes!) hard-coded values: ------------------------
274  int nZplane = 4;
275  if (!m_frontWheel) nZplane = 2;
276  int nRods = 4;
277  if (m_tbyear==2004) nRods = 2;
278  double modulePhistart = 264.375*deg; // (270.-11.25/2.)*deg
279  double moduleDeltaPhi = 2*M_PI/moduleNumber; //11.25*deg;
280  int sectMax = 2;
281  if(!m_frontWheel) sectMax = 1;
282  int rearOffset = 24; // The rear wheel slice numbering starts at 24
283  // This complies with the old HECConstruction.
284 
285  //--- A dead-zone in the LAr gap of depth deadZone all around the module
286  // requires a radial shift of size larshift
287  double deadZone = shrinkCold * 3.*mm;
288  double larShift = deadZone / sin(moduleDeltaPhi/2.);
289 
290  //--- To create a (dead) inter-module gap of 2mm (i.e. 1mm on either side of each module)
291  // between the absorbers, use a radial shift of -1.02*cm.
292  // This does that:
293  double deadGap = shrinkCold * 1.*mm;
294  double radialShift = deadGap / sin(moduleDeltaPhi/2.);
295 
296 
297 
298 
299 
300  //-------------------------------------------------------------------//
301  //-------------------------------------------------------------------//
302  // Now start building the Module geometry //
303  // First create all the little bits so that they are //
304  // ready to be inserted into the bigger pieces when they get //
305  // are created. //
306  //-------------------------------------------------------------------//
307  //-------------------------------------------------------------------//
308 
309  std::string moduleName = "LAr::HEC::Module";
310  std::string depthName = moduleName + "::Depth";
311  std::string sliceName = depthName + "::Slice";
312  std::string electrodeName = sliceName + "::Electrode";
313  std::string copperName = electrodeName + "::Copper";
314  std::string tieRodName = sliceName + "::TieRod";
315  std::string deadTieName = sliceName + "::TieRodDead";
316  std::string absorberName = depthName + "::Absorber";
317  std::string firstAbsorberName = depthName + "::FirstAbsorber";
318  std::string absTieRodName = absorberName + "::TieRod";
319  std::string firstabsTieRodName = firstAbsorberName + "::TieRod";
320 
321  //---- Tie rods to go into Absorbers --------------------------------------
322 
323  GeoIntrusivePtr<GeoTubs>solidAbsorberTieRod = new GeoTubs(0.*cm,tieRodDiameter/2.,absThickness/2.,0.*deg,360.*deg);
324  GeoIntrusivePtr<GeoLogVol> logiAbsorberTieRod = new GeoLogVol(absTieRodName,solidAbsorberTieRod,Iron); //,0,0,0);
325  GeoIntrusivePtr<GeoPhysVol> physiAbsorberTieRod = new GeoPhysVol(logiAbsorberTieRod);
326 
327  GeoIntrusivePtr<GeoTubs> solidFirstAbsorberTieRod = new GeoTubs(0.*cm,tieRodDiameter/2.,firstAbsThickness/2.,0.*deg,360.*deg);
328  GeoIntrusivePtr<GeoLogVol> logiFirstAbsorberTieRod = new GeoLogVol(firstabsTieRodName,solidFirstAbsorberTieRod,Iron); //,0,0,0);
329  GeoIntrusivePtr<GeoPhysVol> physiFirstAbsorberTieRod = new GeoPhysVol(logiFirstAbsorberTieRod);
330 
331 
332  //---- Tie rods to go into Slices (i.e. sensitive LAr gaps) -----------------
333 
334  GeoIntrusivePtr<GeoTubs> solidTieRod = new GeoTubs(0.*cm,spacerDiameter/2.,rodSize/2.,0.*deg,360.*deg);
335  GeoIntrusivePtr<GeoLogVol> logiTieRod = new GeoLogVol(tieRodName, solidTieRod, Iron);
336  GeoIntrusivePtr<GeoPhysVol> physiTieRod = new GeoPhysVol(logiTieRod);
337 
338 
339  GeoIntrusivePtr<GeoTubs> solidDeadTie = new GeoTubs(g4allowS+spacerDiameter/2.,
340  spacerDeadZone+spacerDiameter/2.,
341  rodSize/2.,
342  0.*deg,360.*deg);
343  GeoIntrusivePtr<GeoLogVol> logiDeadTie = new GeoLogVol(deadTieName, solidDeadTie, LAr);
344  GeoIntrusivePtr<GeoPhysVol> physiDeadTie = new GeoPhysVol(logiDeadTie);
345 
346 
347  //---- Create PAD board and EST boards, then also Slices (ie. LAr gaps) and put the boards into Slices ------------
348  // This requires a loop, because the frontWheel has two sections (iSect) of different radial size.
349  // The same goes for the Absorbers - create them in this loop, too.
350  // (NB: Each wheel has only one "firstAbsorber"; Create that ahead of everything else.)
351  // And finally equip the LAr Slices as well as the Absorbers with their respective tie-rods.
352 
353 
354  std::array<GeoIntrusivePtr<GeoTubs>, 2> solidPadBoard{};
355  std::array<GeoIntrusivePtr<GeoLogVol>, 2> logiPadBoard{};
356  std::array<GeoIntrusivePtr<GeoPhysVol>, 2> physiPadBoard{};
357 
358  std::array<GeoIntrusivePtr<GeoTubs>, 2> solidCopperPad{};
359  std::array<GeoIntrusivePtr<GeoLogVol>, 2> logiCopperPad{};
360  std::array<GeoIntrusivePtr<GeoPhysVol>, 2> physiCopperPad{};
361 
362  std::array<GeoIntrusivePtr<GeoTubs>, 2> solidEstBoard{};
363  std::array<GeoIntrusivePtr<GeoLogVol>, 2> logiEstBoard{};
364  std::array<GeoIntrusivePtr<GeoPhysVol>, 2> physiEstBoard{};
365 
366  std::array<GeoIntrusivePtr<GeoTubs>, 2> solidSlice{};
367  std::array<GeoIntrusivePtr<GeoLogVol>, 2> logiSlice{};
368  std::array<GeoIntrusivePtr<GeoPhysVol>,2> physiSlice{};
369 
370  std::array<GeoIntrusivePtr<GeoTubs>,2> solidAbsorber{};
371  std::array<GeoIntrusivePtr<GeoLogVol>,2> logiAbsorber{};
372  std::array<GeoIntrusivePtr<GeoPhysVol>,2> physiAbsorber{};
373 
374  // First Absorbers in front of first and third samplings (need only one type in each wheel)
375  double rOuterF = moduleRouter-radialShift;
376  double rInnerF = moduleRinner2-radialShift;
377  if (m_frontWheel) rInnerF= moduleRinner1-radialShift;
378  GeoIntrusivePtr<GeoTubs> solidFirstAbsorber = new GeoTubs(rInnerF,rOuterF,
379  firstAbsThickness/2.,
380  modulePhistart,moduleDeltaPhi);
381  GeoIntrusivePtr<GeoLogVol> logiFirstAbsorber = new GeoLogVol(firstAbsorberName, solidFirstAbsorber, Copper);
382  GeoIntrusivePtr<GeoPhysVol> physiFirstAbsorber = new GeoPhysVol(logiFirstAbsorber);
383 
384 
385  for(int iSect=0; iSect<sectMax; iSect++)
386  {
387  //-------- First make the slice: ------------------
388  // NB: larShift produces the inter-module gap,
389  // but the actual radial size of the board or slice also has to be
390  // made smaller by the value of deadZone.
391 
392  double rOuter = moduleRouter - larShift - deadZone;
393  double rInner = moduleRinner2 - larShift + deadZone;
394  if (iSect<1 && m_frontWheel) rInner = moduleRinner1 - larShift + deadZone;
395  solidSlice[iSect] = new GeoTubs(rInner, rOuter, gapSize/2., modulePhistart, moduleDeltaPhi);
396  logiSlice[iSect] = new GeoLogVol(sliceName, solidSlice[iSect], LAr);
397  physiSlice[iSect] = new GeoPhysVol(logiSlice[iSect]);
398 
399  //-------- Now make the boards: --------
400  rOuter = moduleRouter - larShift - deadZone -g4allowS;
401  rInner = moduleRinner2 - larShift + deadZone +g4allowS;
402  if (m_frontWheel && iSect==0) rInner = moduleRinner1 - larShift + deadZone +g4allowS ;
403 
404  // First, make a central PAD Board: Copper encased in Kapton
405  // In case of the one-board approach, that's the only board (just thicker)
406  if (m_threeBoards){
407  solidPadBoard[iSect] = new GeoTubs(rInner,rOuter,
408  kaptonWidth[1]/2.,
409  modulePhistart,moduleDeltaPhi);
410  }
411  else{
412  solidPadBoard[iSect] = new GeoTubs(rInner,rOuter,
413  (kaptonWidth[1]/2.+ kaptonWidth[0]),
414  modulePhistart,moduleDeltaPhi);
415  }
416  logiPadBoard[iSect] = new GeoLogVol(electrodeName, solidPadBoard[iSect], Kapton );
417  physiPadBoard[iSect] = new GeoPhysVol(logiPadBoard[iSect]);
418 
419  // The central board contains copper pads for readout
420  solidCopperPad[iSect] = new GeoTubs(rInner,rOuter,copperPad/2.,
421  modulePhistart,moduleDeltaPhi);
422  logiCopperPad[iSect] = new GeoLogVol(copperName, solidCopperPad[iSect], Copper);
423  physiCopperPad[iSect] = new GeoPhysVol(logiCopperPad[iSect]);
424  physiPadBoard[iSect]->add(physiCopperPad[iSect]);
425 
426  // For the three-board approach, make an individual EST board and place it twice in the LAr gap
427  if(m_threeBoards){
428  solidEstBoard[iSect] = new GeoTubs(rInner,rOuter,kaptonWidth[0]/2.,
429  modulePhistart,moduleDeltaPhi);
430  logiEstBoard[iSect] = new GeoLogVol(electrodeName, solidEstBoard[iSect], Kapton );
431  physiEstBoard[iSect] = new GeoPhysVol(logiEstBoard[iSect]);
432  }
433 
434  //--- Insert the Boards into the Slice ---------
435 
436  physiSlice[iSect]->add(new GeoIdentifierTag(1));
437  physiSlice[iSect]->add(physiPadBoard[iSect]);
438 
439 
440  // For the three-board approach, make an individual EST board and place it twice in the LAr gap
441  if(m_threeBoards){
442  double halfGapLAr = (gapSize - kaptonWidth[1])/2.;
443  double ESTPos = (kaptonWidth[1]+halfGapLAr)/2.;
444  physiSlice[iSect]->add(new GeoIdentifierTag(0));
445  physiSlice[iSect]->add(new GeoTransform(Translate3D(0,0,(-ESTPos))));
446  physiSlice[iSect]->add(physiEstBoard[iSect]);
447  physiSlice[iSect]->add(new GeoIdentifierTag(2));
448  physiSlice[iSect]->add(new GeoTransform(Translate3D(0,0,ESTPos)));
449  physiSlice[iSect]->add(physiEstBoard[iSect]);
450  }
451 
452 
453 
454 
455  //--- Create the absorbers -----
456 
457  rOuter = moduleRouter - radialShift;
458  rInner = moduleRinner2 - radialShift;
459  if (iSect<1 && m_frontWheel) rInner = moduleRinner1 - radialShift;
460  solidAbsorber[iSect] = new GeoTubs(rInner,rOuter,absThickness/2., modulePhistart,moduleDeltaPhi);
461  logiAbsorber[iSect] = new GeoLogVol(absorberName, solidAbsorber[iSect], Copper);
462  physiAbsorber[iSect] = new GeoPhysVol(logiAbsorber[iSect]);
463 
464 
465 
466  //--- Insert tie rods into the Absorbers and Slices -----
467  // There are three pairs (left/right symmetric-> handled by loop over isignX)
468  // and they need to be placed in z on either side of the board(s) (loop over isign)
469  // (Note; we did the radial shift for the absorber(and slice); have to compensate for that now in Y position)
470 
471 
472  for(int indexRod=1; indexRod<nRods; indexRod++) {
473  for(double isignX=-1;isignX<2;isignX=isignX+2.){
474 
475  physiAbsorber[iSect]->add(new GeoIdentifierTag(indexRod));
476  physiAbsorber[iSect]->add(new GeoTransform(Translate3D(isignX*tieRodPositionX[indexRod],
477  -tieRodPositionY[indexRod]+radialShift, 0)));
478  physiAbsorber[iSect]->add(physiAbsorberTieRod);
479  if (iSect==0){ // fill the FirstAbsorber with tie-rods at the same time)
480  physiFirstAbsorber->add(new GeoIdentifierTag(indexRod));
481  physiFirstAbsorber->add(new GeoTransform(Translate3D(isignX*tieRodPositionX[indexRod],
482  -tieRodPositionY[indexRod]+radialShift, 0)));
483  physiFirstAbsorber->add(physiFirstAbsorberTieRod);
484  }
485 
486  // For the LAr slices, we have to insert the spacers around the boards (in Z):
487 
488  for(int itie=0; itie<2; itie++ ){ // itie=0 inserts spacers, itie=1 inserts spacer dead-zone
489  for(double isignZ=-1;isignZ<2;isignZ=isignZ+2.){
490  physiSlice[iSect]->add(new GeoIdentifierTag(indexRod));
491  physiSlice[iSect]->add(new GeoTransform
492  (Translate3D(isignX*tieRodPositionX[indexRod],
493  -tieRodPositionY[indexRod]+larShift,
494  isignZ*ztie[0])));
495  if (itie==0) { physiSlice[iSect]->add(physiTieRod); }
496  else { physiSlice[iSect]->add(physiDeadTie);}
497 
498  if (m_threeBoards) {
499  physiSlice[iSect]->add(new GeoIdentifierTag(indexRod));
500  physiSlice[iSect]->add(new GeoTransform
501  (Translate3D(isignX*tieRodPositionX[indexRod],
502  -tieRodPositionY[indexRod]+larShift,
503  isignZ*ztie[1])));
504  if (itie==0) { physiSlice[iSect]->add(physiTieRod); }
505  else { physiSlice[iSect]->add(physiDeadTie);}
506  }
507  }
508  }
509 
510 
511 
512  }
513  }
514 
515  //--- This is for the lonely un-paired tie-rod at the narrow end of the module (Absorber):
516  physiAbsorber[iSect]->add(new GeoIdentifierTag(0));
517  physiAbsorber[iSect]->add(new GeoTransform(Translate3D(tieRodPositionX[0],
518  -tieRodPositionY[0]+radialShift,0)));
519  physiAbsorber[iSect]->add(physiAbsorberTieRod);
520  if (iSect==0){
521  physiFirstAbsorber->add(new GeoIdentifierTag(0));
522  physiFirstAbsorber->add(new GeoTransform(Translate3D(tieRodPositionX[0],
523  -tieRodPositionY[0]+radialShift,0)));
524  physiFirstAbsorber->add(physiFirstAbsorberTieRod);
525  }
526 
527  //--- And the lonely Slice tie-rods: -------------
528  for(int itie=0; itie<2; itie++ ){ // tie=0 inserts spacers, itie=1 inserts spacer dead-zone
529  for(double isignZ=-1;isignZ<2;isignZ=isignZ+2){
530  physiSlice[iSect]->add(new GeoIdentifierTag(0));
531  physiSlice[iSect]->add(new GeoTransform(Translate3D(tieRodPositionX[0],
532  -tieRodPositionY[0]+larShift,
533  isignZ*ztie[0])));
534  if (itie==0) { physiSlice[iSect]->add(physiTieRod); }
535  else { physiSlice[iSect]->add(physiDeadTie);}
536 
537  if (m_threeBoards) {
538  physiSlice[iSect]->add(new GeoIdentifierTag(0));
539  physiSlice[iSect]->add(new GeoTransform(Translate3D(tieRodPositionX[0],
540  -tieRodPositionY[0]+larShift,
541  isignZ*ztie[1])));
542  if (itie==0) { physiSlice[iSect]->add(physiTieRod); }
543  else { physiSlice[iSect]->add(physiDeadTie);}
544  }
545  }
546  }
547 
548  }//for iSect
549 
550 
551 
552  // Now that Slices and Absorbers are filled with their components,
553  // create the Depths and place the slices and absorbers into them
554 
555 
556  //----------------------------------------------------------------
557  // Depths
558  //----------------------------------------------------------------
559  // There are 3 depths in the front wheel, and 4 in the rear wheel.
560  // Create them and equip them with fully assembled slices and absorbers.
561 
562  std::array<GeoIntrusivePtr<GeoTubs>, 4> solidDepth{};
563  std::array<GeoIntrusivePtr<GeoLogVol>, 4> logiDepth{};
564  std::array<GeoIntrusivePtr<GeoPhysVol>, 4> physiDepth{};
565 
566  for(int iDepth=0; iDepth<depthNumber; iDepth++)
567  {
568  double rOuter = moduleRouter;
569  double rInner = moduleRinner2;
570  if (iDepth<1 && m_frontWheel) rInner= moduleRinner1;
571  solidDepth[iDepth] = new GeoTubs(rInner-drModOverlap,rOuter,
572  depthSize[iDepth]/2.,modulePhistart,moduleDeltaPhi);
573  logiDepth[iDepth] = new GeoLogVol(depthName, solidDepth[iDepth], LAr);
574  physiDepth[iDepth] = new GeoPhysVol(logiDepth[iDepth]);
575 
576 
577  // Position the sensitive LAr Slice-gaps and absorbers into the just created Depth:
578  // Absorber size and position
579  double firstAbs = 0.;
580  if (iDepth==0) firstAbs = firstAbsThickness;
581  double slicePositionZ = firstAbs + gapSize/2.0 -depthSize[iDepth]/2.0;
582  double absorberPositionZ = firstAbs + gapSize + absThickness/2.0 - depthSize[iDepth]/2.0;
583 
584  // sliceCopyNo is the copy number of the slice and runs consecutively from
585  // front to back throughout the module.
586  // The first gap in the rear Wheel has number 24 (=rearOffset).
587  // sliceNo refers to how many slice types there are (0,1 in Front ; 0 in Rear)
588  // gapNumber is the number of gaps in a given Depth
589  int sliceNo = 0;
590  int sliceCopyNo = 0;
591  if(!m_frontWheel) sliceCopyNo = rearOffset ;
592 
593  if (iDepth>0)
594  {
595  sliceCopyNo += gaptally[iDepth];
596  if(m_frontWheel) sliceNo=1;
597  }
598 
599  // Serially install all slices and _regular_ absorbers into the depths
600  GeoGenfun::Variable Index;
601  GeoXF::TRANSFUNCTION TS =
602  TranslateY3D(-larShift)*GeoXF::Pow(TranslateZ3D(1.0),slicePositionZ + (absThickness+gapSize)*Index);
603  GeoXF::TRANSFUNCTION TA =
604  TranslateY3D(-radialShift)*GeoXF::Pow(TranslateZ3D(1.0),absorberPositionZ + (absThickness+gapSize)*Index);
605 
606  GeoSerialIdentifier *sI = new GeoSerialIdentifier(sliceCopyNo);
607  GeoSerialTransformer *sTS = new GeoSerialTransformer(physiSlice[sliceNo], &TS, gapNumber[iDepth]);
608  GeoSerialTransformer *sTAF = new GeoSerialTransformer(physiAbsorber[sliceNo], &TA, gapNumber[iDepth]);
609  physiDepth[iDepth]->add(sI);
610  physiDepth[iDepth]->add(sTS);
611  physiDepth[iDepth]->add(sI);
612  physiDepth[iDepth]->add(sTAF);
613 
614  } //for iDepth
615 
616 
617  // The first absorber is special (1/2 thickness) install that now
618  double firstAbsorberPositionZ = firstAbsThickness/2.- depthSize[0]/2.0;
619  if(m_frontWheel) physiDepth[0]->add(new GeoIdentifierTag(0));
620  else physiDepth[0]->add(new GeoIdentifierTag(1));
621  physiDepth[0]->add(new GeoTransform(Translate3D(0,-radialShift,firstAbsorberPositionZ)));
622  physiDepth[0]->add(physiFirstAbsorber);
623 
624 
625  //----------------------------------------------------------------
626  // HEC Module
627  //----------------------------------------------------------------
628 
629 
630  GeoPcon* solidHECModule = new GeoPcon(modulePhistart, moduleDeltaPhi);
631  for (int i=0; i< nZplane; i++)
632  {
633  double innerRadius = moduleRinner2;
634  if (i<2 && m_frontWheel) innerRadius=moduleRinner1;
635  solidHECModule->addPlane(zCoordinate[i],innerRadius-drModOverlap,moduleRouter);
636  }
637  GeoIntrusivePtr<GeoLogVol> logicHECModule = new GeoLogVol(moduleName, solidHECModule , LAr);
638  GeoIntrusivePtr<GeoFullPhysVol> physiHECModule = new GeoFullPhysVol(logicHECModule);
639 
640 
641  //--- Place the fully instrumented depths into the Module: ----
642 
643  double depthPositionZ = 0.;
644 
645  for(int iDepth=0; iDepth<depthNumber; iDepth++)
646  {
647  depthPositionZ +=depthSize[iDepth]/2.;
648  if(!m_frontWheel) physiHECModule->add(new GeoIdentifierTag(iDepth+depthOffset));
649  else physiHECModule->add(new GeoIdentifierTag(iDepth));
650  physiHECModule->add(new GeoTransform(Translate3D(0,0,depthPositionZ)));
651  physiHECModule->add(physiDepth[iDepth]);
652  depthPositionZ +=depthSize[iDepth]/2.;
653  } //for iDepth
654 
655 
656 
657  // Return the physical volume that contains everything we've placed.
658  return physiHECModule;
659 }

Member Data Documentation

◆ m_frontWheel

bool LArGeo::HECModuleConstruction::m_frontWheel
private

Definition at line 37 of file HECModuleConstruction.h.

◆ m_physiHECModule

GeoIntrusivePtr<GeoFullPhysVol> LArGeo::HECModuleConstruction::m_physiHECModule
private

Definition at line 35 of file HECModuleConstruction.h.

◆ m_tb

bool LArGeo::HECModuleConstruction::m_tb
private

Definition at line 38 of file HECModuleConstruction.h.

◆ m_tbyear

int LArGeo::HECModuleConstruction::m_tbyear
private

Definition at line 39 of file HECModuleConstruction.h.

◆ m_threeBoards

bool LArGeo::HECModuleConstruction::m_threeBoards
private

Definition at line 36 of file HECModuleConstruction.h.


The documentation for this class was generated from the following files:
JTC::TS
TS
Definition: IJetTileCorrectionTool.h:27
LArGeo::HECModuleConstruction::m_physiHECModule
GeoIntrusivePtr< GeoFullPhysVol > m_physiHECModule
Definition: HECModuleConstruction.h:35
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
LAr
Definition: LArVolumeBuilder.h:36
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
LArGeo::HECModuleConstruction::m_frontWheel
bool m_frontWheel
Definition: HECModuleConstruction.h:37
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
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
Execution.tb
tb
Definition: Execution.py:15
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
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
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
LArGeo::HECModuleConstruction::m_tb
bool m_tb
Definition: HECModuleConstruction.h:38
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:194
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
LArGeo::HECModuleConstruction::m_tbyear
int m_tbyear
Definition: HECModuleConstruction.h:39
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
LArGeo::HECModuleConstruction::m_threeBoards
bool m_threeBoards
Definition: HECModuleConstruction.h:36
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
IGeoModelSvc::atlasVersion
virtual const std::string & atlasVersion() const =0
jet::CombMassComp::TA
@ TA
Definition: UncertaintyEnum.h:198