ATLAS Offline Software
Loading...
Searching...
No Matches
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)
 ~HECModuleConstruction ()=default
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 25 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}
GeoIntrusivePtr< GeoFullPhysVol > m_physiHECModule

◆ ~HECModuleConstruction()

LArGeo::HECModuleConstruction::~HECModuleConstruction ( )
default

Member Function Documentation

◆ GetEnvelope()

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

Definition at line 62 of file HECModuleConstruction.cxx.

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

Member Data Documentation

◆ m_frontWheel

bool LArGeo::HECModuleConstruction::m_frontWheel
private

Definition at line 36 of file HECModuleConstruction.h.

◆ m_physiHECModule

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

Definition at line 34 of file HECModuleConstruction.h.

◆ m_tb

bool LArGeo::HECModuleConstruction::m_tb
private

Definition at line 37 of file HECModuleConstruction.h.

◆ m_tbyear

int LArGeo::HECModuleConstruction::m_tbyear
private

Definition at line 38 of file HECModuleConstruction.h.

◆ m_threeBoards

bool LArGeo::HECModuleConstruction::m_threeBoards
private

Definition at line 35 of file HECModuleConstruction.h.


The documentation for this class was generated from the following files: