7 #include "GeoModelKernel/GeoMaterial.h"
8 #include "GeoModelKernel/GeoBox.h"
9 #include "GeoModelKernel/GeoPcon.h"
10 #include "GeoModelKernel/GeoTube.h"
11 #include "GeoModelKernel/GeoTubs.h"
12 #include "GeoModelKernel/GeoLogVol.h"
13 #include "GeoModelKernel/GeoNameTag.h"
14 #include "GeoModelKernel/GeoPhysVol.h"
15 #include "GeoModelKernel/GeoFullPhysVol.h"
16 #include "GeoModelKernel/GeoVFullPhysVol.h"
17 #include "GeoModelKernel/GeoTransform.h"
18 #include "GeoModelKernel/GeoSerialDenominator.h"
19 #include "GeoModelKernel/GeoSerialIdentifier.h"
20 #include "GeoModelKernel/GeoAlignableTransform.h"
21 #include "GeoModelKernel/GeoSerialTransformer.h"
22 #include "GeoModelKernel/GeoIdentifierTag.h"
23 #include "GeoModelKernel/GeoShapeUnion.h"
24 #include "GeoModelKernel/GeoDefinitions.h"
25 #include "GeoGenericFunctions/AbsFunction.h"
26 #include "GeoGenericFunctions/Variable.h"
27 #include "GeoGenericFunctions/Sin.h"
28 #include "GeoGenericFunctions/Cos.h"
35 #include "GaudiKernel/MsgStream.h"
36 #include "GaudiKernel/Bootstrap.h"
37 #include "GaudiKernel/SystemOfUnits.h"
49 using namespace GeoXF;
68 if (m_h6Phys)
return (m_h6Phys);
71 ISvcLocator *svcLocator = Gaudi::svcLocator();
73 if (svcLocator->service(
"MessageSvc",
msgSvc,
true )==StatusCode::FAILURE) {
74 throw std::runtime_error(
"Error in HECConstruction, cannot access MessageSvc");
78 log <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
79 log <<
"+ +" << std::endl;
80 log <<
"+ Start of HEC TB GeoModel definition +" << std::endl;
81 log <<
"+ +" << std::endl;
82 log <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
86 if (svcLocator->service(
"DetectorStore", detectorStore,
false )==StatusCode::FAILURE) {
87 throw std::runtime_error(
"Error in HECConstruction, cannot access DetectorStore");
93 sc=svcLocator->service(
"RDBAccessSvc",pAccessSvc);
94 if (
sc != StatusCode::SUCCESS) {
95 throw std::runtime_error (
"Cannot locate RDBAccessSvc!!");
100 if (StatusCode::SUCCESS != detectorStore->retrieve(materialManager, std::string(
"MATERIALS"))) {
112 const GeoMaterial *
LAr = materialManager->
getMaterial(
"std::LiquidArgon");
113 if (!
LAr)
throw std::runtime_error(
"Error in HECConstruction, std::LiquidArgon is not found.");
115 const GeoMaterial *Iron = materialManager->
getMaterial(
"std::Iron");
116 if (!Iron)
throw std::runtime_error(
"Error in HECConstruction, std::Iron is not found.");
118 const GeoMaterial *Copper = materialManager->
getMaterial(
"std::Copper");
119 if (!Copper)
throw std::runtime_error(
"Error in HECConstruction, std::Copper is not found.");
121 const GeoMaterial *Kapton = materialManager->
getMaterial(
"std::Kapton");
122 if (!Kapton)
throw std::runtime_error(
"Error in HECConstruction, std::Kapton is not found.");
126 const std::string& detectorKey = larVersion.
tag();
127 const std::string& detectorNode = larVersion.
node();
131 if(!hadronicEndcap)
throw std::runtime_error(
"Error in HECConstruction: hadronicEendcap not found");
132 if(!hecLongitudinalBlock)
throw std::runtime_error(
"Error in HECConstruction: hecLongitudinalBlock not found");
134 int numberZplane = 6;
137 double kaptonPosition[3];
138 double kaptonWidth[3];
139 double tieRodPositionX[4];
140 double tieRodPositionY[4];
141 double tieRodDiameter[2];
142 double spacerDiameter[2];
143 double firstAbsorber[7];
146 double zCoordinate[6],innerRadius[6],outerRadius[6];
151 const double moduleNumber = (*hadronicEndcap)[0]->getInt(
"NSCT");
152 unsigned int TBmoduleNumber = 8;
153 double moduleRinner1 = (*hecLongitudinalBlock)[0]->getDouble(
"BLRMN")*
Gaudi::Units::cm;
154 double moduleRinner2 = (*hecLongitudinalBlock)[1]->getDouble(
"BLRMN")*
Gaudi::Units::cm;
156 double copperPad = (*hadronicEndcap)[0]->getDouble(
"COPPER")*
Gaudi::Units::cm;
160 for (indexloop=0; indexloop < depthNumber; ++indexloop){
161 depthSize[indexloop] = (*hecLongitudinalBlock)[indexloop]->getDouble(
"BLDPTH")*
Gaudi::Units::cm;
162 firstAbsorber[indexloop]= (*hecLongitudinalBlock)[indexloop]->getDouble(
"PLATE0")*
Gaudi::Units::cm;
163 gapNumber[indexloop] = (
int) (*hecLongitudinalBlock)[indexloop]->getDouble(
"BLMOD");
166 std::string sidx[4]={
"_0",
"_1",
"_2",
"_3"};
168 for (indexloop=0; indexloop < 3; ++indexloop){
169 kaptonPosition[indexloop] = (*hadronicEndcap)[0]->getDouble(
"KPTPOS" + sidx[indexloop])*
Gaudi::Units::cm;
170 kaptonWidth[indexloop] = (*hadronicEndcap)[0]->getDouble(
"KPTWID" + sidx[indexloop])*
Gaudi::Units::cm;
173 for (indexloop=0; indexloop < 4; ++indexloop){
174 tieRodPositionX[indexloop] = (*hadronicEndcap)[0]->getDouble(
"RODPOSX" + sidx[indexloop])*
Gaudi::Units::cm;
175 tieRodPositionY[indexloop] = (*hadronicEndcap)[0]->getDouble(
"RODPOSR" + sidx[indexloop])*
Gaudi::Units::cm;
178 for (indexloop=0; indexloop < 2; ++indexloop){
179 tieRodDiameter[indexloop] = (*hadronicEndcap)[0]->getDouble(
"RODDIM" + sidx[indexloop])*
Gaudi::Units::cm;
180 spacerDiameter[indexloop] = (*hadronicEndcap)[0]->getDouble(
"SPCDIM" + sidx[indexloop])*
Gaudi::Units::cm;
183 double absorberZ1 = (*hadronicEndcap)[0]->getDouble(
"PLATE_0")*
Gaudi::Units::cm;
184 double absorberZ2 = (*hadronicEndcap)[0]->getDouble(
"PLATE_1")*
Gaudi::Units::cm;
186 const double moduleDeltaPhi = 2*
M_PI/moduleNumber;
187 double modulePhistart = -moduleDeltaPhi/2.;
190 zCoordinate[1]=depthSize[0];
192 zCoordinate[3]=zCoordinate[2]+depthSize[1]+depthSize[2]+betweenWheel/2;
193 zCoordinate[4]=zCoordinate[3]+depthSize[3]+depthSize[4]+betweenWheel/2;
195 innerRadius[0]=moduleRinner1;
196 innerRadius[1]=moduleRinner1;
206 std::string hecName =
"LAr::HEC::LiquidArgon";
207 GeoPcon* solidHEC =
new GeoPcon(
M_PI / 2., TBmoduleNumber*moduleDeltaPhi);
208 for (
int i = 0;
i < numberZplane - 1; ++
i) {
209 solidHEC->addPlane(zCoordinate[
i],innerRadius[
i]-PosYcorr,outerRadius[
i]);
211 const GeoLogVol *logicHEC =
new GeoLogVol(hecName, solidHEC ,
LAr);
213 m_h6Phys =
new GeoFullPhysVol(logicHEC);
215 std::string
tag = std::string(
"HEC_POS");
219 status=detectorStore->record(sPhysVol,
tag);
220 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
224 std::array<GeoIntrusivePtr<GeoTubs>, 7> solidDepth{};
225 std::array<GeoIntrusivePtr<GeoLogVol>, 7> logiDepth{};
226 std::array<GeoIntrusivePtr<GeoPhysVol>, 7> physiDepth{};
229 std::array<GeoIntrusivePtr<GeoTubs>, 3> solidSlice{};
230 std::array<GeoIntrusivePtr<GeoLogVol>, 3> logiSlice{};
231 std::array<GeoIntrusivePtr<GeoPhysVol>, 3> physiSlice{};
234 GeoIntrusivePtr<GeoTubs> solidEstBoard{};
235 GeoIntrusivePtr<GeoLogVol> logiEstBoard{};
236 GeoIntrusivePtr<GeoPhysVol> physiEstBoard{};
239 GeoIntrusivePtr<GeoTubs> solidPadBoard{};
240 GeoIntrusivePtr<GeoLogVol> logiPadBoard{};
241 GeoIntrusivePtr<GeoPhysVol> physiPadBoard{};
244 std::array<GeoIntrusivePtr<GeoTubs>, 2> solidTieRod{};
245 std::array<GeoIntrusivePtr<GeoLogVol>, 2> logiTieRod{};
246 std::array<GeoIntrusivePtr<GeoPhysVol>, 2> physiTieRod{};
248 std::array<GeoIntrusivePtr<GeoTubs>, 2> solidAbsorberTieRod{};
249 std::array<GeoIntrusivePtr<GeoLogVol>, 2> logiAbsorberTieRod{};
250 std::array<GeoIntrusivePtr<GeoPhysVol>, 2> physiAbsorberTieRod{};
252 std::array<GeoIntrusivePtr<GeoTubs>, 3> solidAbsorber{};
253 std::array<GeoIntrusivePtr<GeoLogVol>, 3> logiAbsorber{};
254 std::array<GeoIntrusivePtr<GeoPhysVol>, 3> physiAbsorber{};
256 GeoIntrusivePtr<GeoTubs> solidFirstAbsorber{};
257 GeoIntrusivePtr<GeoLogVol> logiFirstAbsorber{};
258 GeoIntrusivePtr<GeoPhysVol> physiFirstAbsorber{};
265 std::string moduleName =
"LAr::HEC::Module";
266 GeoPcon* solidModule =
new GeoPcon(modulePhistart, moduleDeltaPhi);
267 for (
int i=0;
i< numberZplane - 1; ++
i){
268 solidModule->addPlane(zCoordinate[
i],innerRadius[
i]-PosYcorr,outerRadius[
i]);
270 GeoLogVol* logicModule =
new GeoLogVol(moduleName, solidModule ,
LAr);
271 GeoIntrusivePtr<GeoPhysVol> physiModule =
new GeoPhysVol(logicModule);
276 GeoSerialIdentifier *sI =
new GeoSerialIdentifier(9);
277 GeoGenfun::Variable
Index;
278 GeoGenfun::GENFUNCTION ModuleRotationAngle =
M_PI/2. + moduleDeltaPhi/2. + moduleDeltaPhi*
Index;
279 GeoXF::TRANSFUNCTION
t = GeoXF::Pow(GeoTrf::RotateZ3D(1.0),ModuleRotationAngle);
280 GeoSerialTransformer *sT =
new GeoSerialTransformer (physiModule,&
t,TBmoduleNumber);
289 std::string depthName = moduleName +
"::Depth";
290 std::string sliceName = depthName +
"::Slice";
291 double moduleRinner= moduleRinner1 ;
293 for( sliceNo=0; sliceNo<3; sliceNo++){
294 if (sliceNo>0) moduleRinner = moduleRinner2;
295 solidSlice[sliceNo] =
new GeoTubs(moduleRinner-PosYcorr,outerRadius[0],gapSize/2.,modulePhistart,moduleDeltaPhi);
296 logiSlice[sliceNo] =
new GeoLogVol(sliceName, solidSlice[sliceNo],
LAr);
297 physiSlice[sliceNo] =
new GeoPhysVol(logiSlice[sliceNo]);
305 std::string absorberName = depthName +
"::Absorber";
306 double absorberRinner1 = moduleRinner1-absorberPosY;
307 double absorberRinner2 = moduleRinner2-absorberPosY;
308 double absorberRouter = outerRadius[0] - absorberPosY;
309 solidAbsorber[0] =
new GeoTubs(absorberRinner1,absorberRouter,absorberZ1/2.,
310 modulePhistart,moduleDeltaPhi);
311 solidAbsorber[1] =
new GeoTubs(absorberRinner2,absorberRouter,absorberZ1/2.,
312 modulePhistart,moduleDeltaPhi);
313 solidAbsorber[2] =
new GeoTubs(absorberRinner2,absorberRouter,absorberZ2/2.,
314 modulePhistart,moduleDeltaPhi);
316 for (absorberNo=0;absorberNo<3;absorberNo++){
317 logiAbsorber[absorberNo] =
new GeoLogVol(absorberName, solidAbsorber[absorberNo], Copper);
318 physiAbsorber[absorberNo] =
new GeoPhysVol(logiAbsorber[absorberNo]);
323 std::string firstAbsorberName = depthName +
"::FirstAbsorber";
324 solidFirstAbsorber =
new GeoTubs(moduleRinner1-absorberPosY,outerRadius[0]-absorberPosY,firstAbsorber[0]/2.,
325 modulePhistart,moduleDeltaPhi);
326 logiFirstAbsorber =
new GeoLogVol(firstAbsorberName, solidFirstAbsorber, Copper);
327 physiFirstAbsorber =
new GeoPhysVol(logiFirstAbsorber);
333 double depthPositionZ = 0.;
334 for(
int indexDepth=0; indexDepth<5; indexDepth++){
335 depthPositionZ +=depthSize[indexDepth]/2.;
337 moduleRinner = moduleRinner2;
338 if (indexDepth==0) moduleRinner = moduleRinner1;
340 double absorberSize = absorberZ2;
341 if (indexDepth < 3) {
342 absorberSize = absorberZ1;
344 double absorberPositionZ=firstAbsorber[indexDepth]+
345 gapSize+absorberSize/2.0-depthSize[indexDepth]/2.0;
347 solidDepth[indexDepth] =
new GeoTubs(moduleRinner-PosYcorr,outerRadius[0], depthSize[indexDepth]/2.,
348 modulePhistart,moduleDeltaPhi);
349 logiDepth[indexDepth] =
new GeoLogVol(depthName, solidDepth[indexDepth],
LAr);
350 physiDepth[indexDepth] =
new GeoPhysVol(logiDepth[indexDepth]);
352 physiModule->add(
new GeoIdentifierTag(100+indexDepth));
353 physiModule->add(
new GeoTransform(GeoTrf::Translate3D(0,0,depthPositionZ)));
354 physiModule->add(physiDepth[indexDepth]);
355 depthPositionZ +=depthSize[indexDepth]/2.;
356 if (indexDepth==2) depthPositionZ +=betweenWheel;
358 double slicePositionZ=firstAbsorber[indexDepth] + gapSize/2.0 - depthSize[indexDepth]/2.0;
359 if (indexDepth>0) sliceCopyNo += gapNumber[indexDepth-1];
372 GeoGenfun::Variable
Index;
373 GeoXF::TRANSFUNCTION
TS = GeoXF::Pow(GeoTrf::TranslateZ3D(1.0),slicePositionZ + (absorberSize+gapSize)*
Index);
374 GeoXF::TRANSFUNCTION TA = GeoTrf::TranslateX3D(absorberPosY) * GeoXF::Pow(GeoTrf::TranslateZ3D(1.0),absorberPositionZ + (absorberSize+gapSize)*
Index);
376 GeoSerialIdentifier *sI =
new GeoSerialIdentifier(sliceCopyNo);
377 GeoSerialTransformer *sTS =
new GeoSerialTransformer(physiSlice[sliceNo], &
TS, gapNumber[indexDepth]);
378 GeoSerialTransformer *sTA =
new GeoSerialTransformer(physiAbsorber[absorberNo],&TA, gapNumber[indexDepth]);
379 physiDepth[indexDepth]->add(sI);
380 physiDepth[indexDepth]->add(sTS);
381 physiDepth[indexDepth]->add(sI);
382 physiDepth[indexDepth]->add(sTA);
385 double firstAbsorberPositionZ = firstAbsorber[0]/2.- depthSize[0]/2.0;
386 physiDepth[0]->add(
new GeoIdentifierTag(50));
387 physiDepth[0]->add(
new GeoTransform(GeoTrf::Translate3D(absorberPosY,0,firstAbsorberPositionZ)));
388 physiDepth[0]->add(physiFirstAbsorber);
391 firstAbsorberPositionZ = firstAbsorber[3]/2.- depthSize[3]/2.0;
392 physiAbsorber[1] =
new GeoPhysVol(logiAbsorber[1]);
393 physiDepth[3]->add(
new GeoIdentifierTag(51));
394 physiDepth[3]->add(
new GeoTransform(GeoTrf::Translate3D(absorberPosY,0,firstAbsorberPositionZ)));
395 physiDepth[3]->add(physiAbsorber[1]);
402 std::string electrodeName = sliceName +
"::Electrode";
403 std::string copperName = electrodeName +
"::Copper";
404 for(
int indexBoard=0; indexBoard<3; indexBoard++){
405 if (indexBoard==0) moduleRinner = moduleRinner1;
406 else moduleRinner = moduleRinner2;
408 solidPadBoard =
new GeoTubs(moduleRinner,outerRadius[0],copperPad/2.,modulePhistart,moduleDeltaPhi);
409 logiPadBoard =
new GeoLogVol(copperName, solidPadBoard, Copper);
410 solidEstBoard =
new GeoTubs(moduleRinner,outerRadius[0],(kaptonWidth[indexKapton]/2.+kaptonWidth[0]),
411 modulePhistart,moduleDeltaPhi);
412 logiEstBoard =
new GeoLogVol(electrodeName, solidEstBoard, Kapton);
414 double kaptonPositionZ = kaptonPosition[indexKapton]-gapSize/2.;
416 physiEstBoard =
new GeoPhysVol(logiEstBoard);
417 physiSlice[indexBoard]->add(
new GeoIdentifierTag(indexKapton));
418 physiSlice[indexBoard]->add(
new GeoTransform(GeoTrf::Translate3D(0,0,kaptonPositionZ)));
419 physiSlice[indexBoard]->add(physiEstBoard);
422 physiPadBoard =
new GeoPhysVol(logiPadBoard);
423 physiEstBoard->add(
new GeoIdentifierTag(indexKapton));
424 physiEstBoard->add(
new GeoTransform(GeoTrf::Translate3D(0,0,0)));
425 physiEstBoard->add(physiPadBoard);
432 std::string tieRodName = sliceName +
"::TieRod";
437 for (
int indexWheel=0; indexWheel<2; indexWheel++) {
438 solidTieRod[indexWheel] =
new GeoTubs(0.*
Gaudi::Units::cm,spacerDiameter[indexWheel]/2.,rodSize/2.,
440 logiTieRod[indexWheel] =
new GeoLogVol(tieRodName,solidTieRod[indexWheel], Iron);
442 for(
int numberSlice=0; numberSlice<3; numberSlice++){
444 if(numberSlice==2) numberTie=1;
446 for(indexRod=1; indexRod<2; indexRod++){
447 for(
int iz=0;iz<2;iz++){
448 physiTieRod[numberTie] =
new GeoPhysVol(logiTieRod[numberTie]);
449 physiSlice[numberSlice]->add(
new GeoIdentifierTag(indexRod));
450 physiSlice[numberSlice]->add(
new GeoTransform(GeoTrf::Translate3D(tieRodPositionY[indexRod],
451 tieRodPositionX[indexRod],ztie[iz])));
452 physiSlice[numberSlice]->add(physiTieRod[numberTie]);
454 physiTieRod[numberTie] =
new GeoPhysVol(logiTieRod[numberTie]);
455 physiSlice[numberSlice]->add(
new GeoIdentifierTag(indexRod));
456 physiSlice[numberSlice]->add(
new GeoTransform(GeoTrf::Translate3D(tieRodPositionY[indexRod],
457 -tieRodPositionX[indexRod],ztie[iz])));
458 physiSlice[numberSlice]->add(physiTieRod[numberTie]);
461 for(
int iz1=0;iz1<2;iz1++){
462 physiTieRod[numberTie] =
new GeoPhysVol(logiTieRod[numberTie]);
463 physiSlice[numberSlice]->add(
new GeoIdentifierTag(indexRod));
464 physiSlice[numberSlice]->add(
new GeoTransform(GeoTrf::Translate3D(tieRodPositionY[0],tieRodPositionX[0],ztie[iz1])));
465 physiSlice[numberSlice]->add(physiTieRod[numberTie]);
475 logiAbsorberTieRod[0] =
new GeoLogVol(tieRodName, solidAbsorberTieRod[0], Iron);
476 logiAbsorberTieRod[1] =
new GeoLogVol(tieRodName, solidAbsorberTieRod[1], Iron);
477 for(
int indexA=0; indexA<3; indexA++){
479 if(indexA>1) indexR=1;
481 for(indexRod=1; indexRod<2; indexRod++){
482 physiAbsorberTieRod[indexR] =
new GeoPhysVol(logiAbsorberTieRod[indexR]);
483 physiAbsorber[indexA]->add(
new GeoIdentifierTag(indexRod));
484 physiAbsorber[indexA]->add(
new GeoTransform(GeoTrf::Translate3D(tieRodPositionY[indexRod]+absorberPosY,
485 tieRodPositionX[indexRod], 0)));
486 physiAbsorber[indexA]->add(physiAbsorberTieRod[indexR]);
488 physiAbsorberTieRod[indexR] =
new GeoPhysVol(logiAbsorberTieRod[indexR]);
489 physiAbsorber[indexA]->add(
new GeoIdentifierTag(indexRod));
490 physiAbsorber[indexA]->add(
new GeoTransform(GeoTrf::Translate3D(tieRodPositionY[indexRod]+absorberPosY,
491 -tieRodPositionX[indexRod], 0)));
492 physiAbsorber[indexA]->add(physiAbsorberTieRod[indexR]);
494 physiAbsorberTieRod[indexR] =
new GeoPhysVol(logiAbsorberTieRod[indexR]);
495 physiAbsorber[indexA]->add(
new GeoIdentifierTag(indexRod));
496 physiAbsorber[indexA]->add(
new GeoTransform(GeoTrf::Translate3D(tieRodPositionY[0]+absorberPosY,
497 tieRodPositionX[0],0)));
498 physiAbsorber[indexA]->add(physiAbsorberTieRod[indexR]);
502 std::cout <<
" In the H6 2004 HEC Constr. GetEnvelope - about to return m_h6Phys " << std::endl;