5 #include "LArReadoutGeometry/FCAL_ChannelMap.h"
8 #include "GeoModelKernel/GeoElement.h"
9 #include "GeoModelKernel/GeoMaterial.h"
10 #include "GeoModelKernel/GeoFullPhysVol.h"
11 #include "GeoModelKernel/GeoPhysVol.h"
12 #include "GeoModelKernel/GeoVPhysVol.h"
13 #include "GeoModelKernel/GeoLogVol.h"
14 #include "GeoModelKernel/GeoTransform.h"
15 #include "GeoModelKernel/GeoAlignableTransform.h"
16 #include "GeoModelKernel/GeoIdentifierTag.h"
17 #include "GeoModelKernel/GeoNameTag.h"
18 #include "GeoModelKernel/GeoSerialIdentifier.h"
19 #include "GeoModelKernel/GeoSerialTransformer.h"
20 #include "GeoModelKernel/GeoXF.h"
21 #include "GeoModelKernel/GeoPerfUtils.h"
22 #include "GeoModelKernel/GeoDefinitions.h"
23 #include "GeoModelKernel/Units.h"
26 #include "GeoModelKernel/GeoPcon.h"
27 #include "GeoModelKernel/GeoTubs.h"
28 #include "GeoModelKernel/GeoCons.h"
29 #include "GeoModelKernel/GeoBox.h"
30 #include "GeoModelKernel/GeoTrap.h"
39 #include "GeoGenericFunctions/Abs.h"
40 #include "GeoGenericFunctions/Sin.h"
41 #include "GeoGenericFunctions/Cos.h"
42 #include "GeoGenericFunctions/Sqrt.h"
43 #include "GeoGenericFunctions/ATan.h"
44 #include "GeoGenericFunctions/Rectangular.h"
45 #include "GeoGenericFunctions/Mod.h"
46 #include "GeoGenericFunctions/Variable.h"
47 #include "GeoGenericFunctions/FixedConstant.h"
48 #include "GeoGenericFunctions/ArrayFunction.h"
55 #include "GaudiKernel/MsgStream.h"
56 #include "GaudiKernel/Bootstrap.h"
57 #include "GaudiKernel/SystemOfUnits.h"
65 #include "GaudiKernel/ISvcLocator.h"
70 m_absPhysical1(nullptr),
71 m_absPhysical2(nullptr),
72 m_absPhysical3(nullptr),
78 if(
m_svcLocator->service (
"RDBAccessSvc",rdbAccess) == StatusCode::FAILURE)
79 throw std::runtime_error(
"Error in FCALConstructionH62004, cannot access RDBAccessSvc");
84 throw std::runtime_error(
"Error getting FCAL electrode from database");
90 throw std::runtime_error(
"Error getting FCAL Module parameters from database");
108 const bool F1=
true,F2=
true,F3=
true;
122 double innerModuleRadius;
123 double outerModuleRadius;
124 double fullModuleDepth;
125 double innerGapRadius;
126 double outerGapRadius;
133 if (m_svcLocator->service(
"MessageSvc",
msgSvc,
true )==StatusCode::FAILURE) {
134 throw std::runtime_error(
"Error in FCALConstructionH62004, cannot access MessageSvc");
136 MsgStream
log(
msgSvc,
"FCALConstructionH62004");
140 log <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
141 log <<
"+ +" << std::endl;
142 log <<
"+ Start of FCAL GeoModel definition +" << std::endl;
143 log <<
"+ +" << std::endl;
144 log <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
147 if (m_svcLocator->service(
"DetectorStore",
detStore,
false )==StatusCode::FAILURE) {
148 throw std::runtime_error(
"Error in FCALConstructionH62004, cannot access DetectorStore");
155 if (StatusCode::SUCCESS !=
detStore->retrieve(materialManager, std::string(
"MATERIALS")))
return nullptr;
157 const GeoMaterial *Copper = materialManager->
getMaterial(
"std::Copper");
158 if (!Copper)
throw std::runtime_error(
"Error in FCALConstructionH62004, std::Copper is not found.");
160 const GeoMaterial *Iron = materialManager->
getMaterial(
"std::Iron");
161 if (!Iron)
throw std::runtime_error(
"Error in FCALConstructionH62004, std::Iron is not found.");
163 const GeoMaterial *Lead = materialManager->
getMaterial(
"std::Lead");
164 if (!Lead)
throw std::runtime_error(
"Error in FCALConstructionH62004, std::Lead is not found.");
166 const GeoMaterial *
LAr = materialManager->
getMaterial(
"std::LiquidArgon");
167 if (!
LAr)
throw std::runtime_error(
"Error in FCALConstructionH62004, std::LiquidArgon is not found.");
169 const GeoMaterial *Air = materialManager->
getMaterial(
"std::Air");
170 if (!Air)
throw std::runtime_error(
"Error in FCALConstructionH62004, std::Air is not found.");
172 const GeoMaterial *Kapton = materialManager->
getMaterial(
"std::Kapton");
173 if (!Kapton)
throw std::runtime_error(
"Error in FCALConstructionH62004, std::Kapton is not found.");
175 const GeoMaterial *Glue = materialManager->
getMaterial(
"LAr::Glue");
176 if (!Glue)
throw std::runtime_error(
"Error in FCALConstructionH62004, LAr::Glue is not found.");
178 const GeoMaterial *G10 = materialManager->
getMaterial(
"LAr::G10");
179 if (!G10)
throw std::runtime_error(
"Error in FCALConstructionH62004, LAr::G10 is not found.");
182 const GeoMaterial *FCal1Absorber = materialManager->
getMaterial(
"LAr::FCal1Absorber");
183 if (!FCal1Absorber)
throw std::runtime_error(
"Error in FCALConstructionH62004, LAr::FCal1Absorber is not found.");
185 const GeoMaterial *FCal23Absorber = materialManager->
getMaterial(
"LAr::FCal23Absorber");
186 if (!FCal23Absorber)
throw std::runtime_error(
"Error in FCALConstructionH62004, LAr::FCal23Absorber is not found.");
188 const GeoMaterial *FCalCableHarness = materialManager->
getMaterial(
"LAr::FCalCableHarness");
189 if (!FCalCableHarness)
throw std::runtime_error(
"Error in FCALConstructionH62004, LAr::FCalCableHarness is not found.");
191 const GeoMaterial *FCal23Slugs = materialManager->
getMaterial(
"LAr::FCal23Slugs");
192 if (!FCal23Slugs)
throw std::runtime_error(
"Error in FCALConstructionH62004, LAr::FCal23Slugs is not found.");
195 FCALData_t fcalData[3];
196 for(
int i=0;
i<3; ++
i) {
197 fcalData[
i].innerModuleRadius = (*m_fcalMod)[
i]->getDouble(
"INNERMODULERADIUS");
198 fcalData[
i].outerModuleRadius = (*m_fcalMod)[
i]->getDouble(
"OUTERMODULERADIUS");
199 fcalData[
i].fullModuleDepth = (*m_fcalMod)[
i]->getDouble(
"FULLMODULEDEPTH");
200 fcalData[
i].innerGapRadius = (*m_fcalMod)[
i]->getDouble(
"INNERGAPRADIUS");
201 fcalData[
i].outerGapRadius = (*m_fcalMod)[
i]->getDouble(
"OUTERGAPRADIUS");
202 fcalData[
i].fullGapDepth = (*m_fcalMod)[
i]->getDouble(
"FULLGAPDEPTH");
203 fcalData[
i].FCalSampling = (*m_fcalMod)[
i]->getInt(
"FCALSAMPLING");
208 GeoIntrusivePtr<GeoFullPhysVol>fcalPhysical(
nullptr);
210 std::string baseName =
"LAr::FCAL::";
212 double fcalHalfDepth=0;
213 double startZFCal1 = (*m_fcalMod)[0]->getDouble(
"STARTPOSITION");
214 double startZFCal2 = (*m_fcalMod)[1]->getDouble(
"STARTPOSITION");
215 double startZFCal3 = (*m_fcalMod)[2]->getDouble(
"STARTPOSITION");
223 double outerRadius =
std::max(fcalData[0].outerModuleRadius,
std::max(fcalData[1].outerModuleRadius,fcalData[2].outerModuleRadius));
224 double innerRadius =
std::min(fcalData[0].innerModuleRadius,
std::min(fcalData[1].innerModuleRadius,fcalData[2].innerModuleRadius));
225 double depthZFCal3 = fcalData[2].fullModuleDepth;
226 double stopZFCal3 = startZFCal3 + depthZFCal3;
228 double totalDepth = stopZFCal3 - startZFCal1;
229 double halfDepth = totalDepth/2.;
231 std::string
name = baseName +
"LiquidArgonC";
232 GeoTubs *tubs =
new GeoTubs(innerRadius,outerRadius,halfDepth, 0.99*fcalstartPhi, 1.01*fcaldeltaPhi);
233 GeoLogVol *logVol=
new GeoLogVol(
name, tubs,
LAr);
234 fcalPhysical =
new GeoFullPhysVol(logVol);
236 fcalHalfDepth = halfDepth;
243 GeoIntrusivePtr<GeoFullPhysVol>modPhysical =
nullptr;
245 double halfDepth = fcalData[0].fullModuleDepth/2;
246 double innerRadius = fcalData[0].innerModuleRadius;
247 double outerRadius = fcalData[0].outerModuleRadius;
248 GeoIntrusivePtr<GeoFullPhysVol>physVol;
251 physVol = m_absPhysical1->clone();
254 GeoTubs *tubs =
new GeoTubs( innerRadius, outerRadius, halfDepth, fcalstartPhi, fcaldeltaPhi);
255 GeoLogVol *logVol =
new GeoLogVol(baseName +
"Module1::Absorber", tubs, FCal1Absorber);
256 physVol =
new GeoFullPhysVol(logVol);
259 fcalPhysical->add(
new GeoTransform(GeoTrf::Translate3D(0.,0.,-(fcalHalfDepth-halfDepth))));
260 fcalPhysical->add(physVol);
261 modPhysical = physVol;
263 std::string
tag = std::string(
"FCAL1") ;
268 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
272 if(m_absPhysical1==
nullptr)
275 double outerRadius = fcalData[0].outerModuleRadius;
276 double innerRadius = outerRadius - troughDepth;
277 double halfLength = fcalData[0].fullModuleDepth/ 2.0;
280 GeoTubs * tubs =
new GeoTubs(innerRadius,outerRadius,halfLength,startPhi,
deltaPhi );
281 GeoLogVol *logVol =
new GeoLogVol(baseName+
"Module1::CableTrough",tubs,FCalCableHarness);
282 GeoIntrusivePtr<GeoPhysVol>physVol =
new GeoPhysVol(logVol);
283 GeoGenfun::Variable
i;
285 GeoXF::TRANSFUNCTION xf = GeoXF::Pow(GeoTrf::RotateZ3D(1.0),rotationAngle);
286 GeoSerialTransformer *st =
new GeoSerialTransformer(physVol,&xf,4);
287 modPhysical->add(st);
290 if (m_absPhysical1==
nullptr)
292 double halfDepth = fcalData[0].fullGapDepth/2.0;
293 double innerRadius = fcalData[0].innerGapRadius;
294 double outerRadius = fcalData[0].outerGapRadius;
296 GeoLogVol *logVol =
new GeoLogVol(baseName +
"Module1::Gap",tubs,
LAr);
297 GeoIntrusivePtr<GeoPhysVol>physVol =
new GeoPhysVol(logVol);
300 modPhysical->add(
new GeoSerialIdentifier(0));
305 if ((*m_fcalElectrode).size()>0) {
306 for (
unsigned int i=0;
i<(*m_fcalElectrode).size();
i++) {
309 int thisGroup=record->
getInt(
"MODNUMBER");
310 if (thisGroup!=myGroup)
continue;
311 double thisTubeX= record->
getDouble(
"X");
312 double thisTubeY= record->
getDouble(
"Y");
313 if (thisTubeX>=0. || thisTubeY<=0.)
continue;
315 std::string thisTileStr=record->
getString(
"TILENAME");
316 int thisTubeI=record->
getInt(
"I");
317 int thisTubeJ= record->
getInt(
"J");
318 int thisTubeID = record->
getInt(
"ID");
319 int thisTubeMod = record->
getInt(
"MODNUMBER");
321 cmap->
add_tube(thisTileStr, thisTubeMod, thisTubeID, thisTubeI,thisTubeJ, thisTubeX, thisTubeY);
323 if (m_VisLimit != -1 && (
counter++ > m_VisLimit))
continue;
327 modPhysical->add(xf);
328 modPhysical->add(physVol);
333 m_absPhysical1 = modPhysical;
339 GeoIntrusivePtr<GeoFullPhysVol>modPhysical =
nullptr;
341 double halfDepth = fcalData[1].fullModuleDepth/2;
342 double innerRadius = fcalData[1].innerModuleRadius;
343 double outerRadius = fcalData[1].outerModuleRadius;
344 GeoIntrusivePtr<GeoFullPhysVol>physVol;
347 physVol = m_absPhysical2->clone();
350 GeoTubs *tubs =
new GeoTubs( innerRadius, outerRadius, halfDepth, fcalstartPhi, fcaldeltaPhi);
351 GeoLogVol *logVol =
new GeoLogVol(baseName +
"Module2::Absorber", tubs, FCal23Absorber);
352 physVol =
new GeoFullPhysVol(logVol);
355 fcalPhysical->add(
new GeoTransform(GeoTrf::Translate3D(0.,0.,-(fcalHalfDepth-(startZFCal2-startZFCal1)-halfDepth))));
356 fcalPhysical->add(physVol);
357 modPhysical = physVol;
359 std::string
tag = std::string(
"FCAL2");
364 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
368 if(m_absPhysical2==
nullptr)
371 double outerRadius = fcalData[1].outerModuleRadius;
372 double innerRadius = outerRadius - troughDepth;
373 double halfLength = fcalData[1].fullModuleDepth/ 2.0;
376 GeoTubs * tubs =
new GeoTubs(innerRadius,outerRadius,halfLength,startPhi,
deltaPhi );
377 GeoLogVol *logVol =
new GeoLogVol(baseName+
"Module2::CableTrough",tubs,FCalCableHarness);
378 GeoIntrusivePtr<GeoPhysVol>physVol =
new GeoPhysVol(logVol);
379 GeoGenfun::Variable
i;
381 GeoXF::TRANSFUNCTION xf = GeoXF::Pow(GeoTrf::RotateZ3D(1.0),rotationAngle);
382 GeoSerialTransformer *st =
new GeoSerialTransformer(physVol,&xf,4);
383 modPhysical->add(st);
387 if(m_absPhysical2==
nullptr)
390 double halfDepth = fcalData[1].fullGapDepth/2.0;
391 double innerRadius = fcalData[1].innerGapRadius;
392 double outerRadius = fcalData[1].outerGapRadius;
394 GeoTubs *gapTubs =
new GeoTubs(0,outerRadius,halfDepth, fcalstartPhi, fcaldeltaPhi);
395 GeoLogVol *gapLog =
new GeoLogVol(baseName +
"Module2::Gap",gapTubs,
LAr);
396 GeoIntrusivePtr<GeoPhysVol>gapPhys =
new GeoPhysVol(gapLog);
398 GeoTubs *rodTubs =
new GeoTubs(0,innerRadius,halfDepth, fcalstartPhi, fcaldeltaPhi);
399 GeoLogVol *rodLog =
new GeoLogVol(baseName +
"Module2::Rod",rodTubs, FCal23Slugs);
400 GeoIntrusivePtr<GeoPhysVol>rodPhys =
new GeoPhysVol(rodLog);
402 gapPhys->add(rodPhys);
405 modPhysical->add(
new GeoSerialIdentifier(0));
408 if ((*m_fcalElectrode).size()>0) {
409 for (
unsigned int i=0;
i<(*m_fcalElectrode).size();
i++) {
412 int thisGroup=record->
getInt(
"MODNUMBER");
413 if (thisGroup!=myGroup)
continue;
415 double thisTubeX= record->
getDouble(
"X");
416 double thisTubeY= record->
getDouble(
"Y");
418 if (thisTubeX>=0. || thisTubeY<=0.)
continue;
420 std::string thisTileStr=record->
getString(
"TILENAME");
421 int thisTubeI=record->
getInt(
"I");
422 int thisTubeJ= record->
getInt(
"J");
423 int thisTubeID = record->
getInt(
"ID");
424 int thisTubeMod = record->
getInt(
"MODNUMBER");
426 cmap->
add_tube(thisTileStr, thisTubeMod, thisTubeID, thisTubeI,thisTubeJ, thisTubeX, thisTubeY);
428 if (m_VisLimit!=-1 && (
counter++ > m_VisLimit))
continue;
431 modPhysical->add(xf);
432 modPhysical->add(gapPhys);
435 m_absPhysical2 = modPhysical;
442 GeoIntrusivePtr<GeoFullPhysVol>modPhysical =
nullptr;
444 double halfDepth = fcalData[2].fullModuleDepth/2;
445 double innerRadius = fcalData[2].innerModuleRadius;
446 double outerRadius = fcalData[2].outerModuleRadius;
447 GeoIntrusivePtr<GeoFullPhysVol>physVol;
452 thisAbsorber->add(Copper,0.994);
453 thisAbsorber->add(
LAr,0.006);
454 thisAbsorber->lock();
458 physVol = m_absPhysical3->clone();
461 GeoTubs *tubs =
new GeoTubs( innerRadius, outerRadius, halfDepth, 0.999*fcalstartPhi, 1.001*fcaldeltaPhi);
462 GeoLogVol *logVol =
new GeoLogVol(baseName +
"ColdTC::Absorber", tubs, thisAbsorber);
463 physVol =
new GeoFullPhysVol(logVol);
467 fcalPhysical->add(
new GeoTransform(GeoTrf::Translate3D(0.,0.,fcalHalfDepth-halfDepth)));
468 fcalPhysical->add(physVol);
469 modPhysical = physVol;
471 std::string
tag = std::string(
"ColdTC");
476 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+
tag).c_str());
480 if(m_absPhysical3==
nullptr){
481 double halfDepth = fcalData[2].fullGapDepth/2;
482 double innerRadius = fcalData[2].innerGapRadius;
483 double outerRadius = fcalData[2].outerGapRadius;
490 GeoTubs *gapSolid =
new GeoTubs(innerRadius,outerRadius,halfDepth, fcalstartPhi, fcaldeltaPhi);
491 GeoLogVol *gapLV =
new GeoLogVol(baseName +
"ColdTC::Gap", gapSolid,
LAr);
493 GeoTubs *electrodeSolid =
new GeoTubs(innerRadius,outerRadius,ElectrodeDepth/2.,1.00001*fcalstartPhi, 0.99999*fcaldeltaPhi);
494 GeoLogVol *electrodeLV =
new GeoLogVol(baseName +
"ColdTC::Electrode", electrodeSolid, G10);
496 GeoTubs *activeSolid =
new GeoTubs(innerRadius,outerRadius,ActiveDepth/2.,1.0001*fcalstartPhi, 0.9999*fcaldeltaPhi);
497 GeoLogVol *activeLV =
new GeoLogVol(baseName +
"ColdTC::Active", activeSolid,
LAr);
499 GeoIntrusivePtr<GeoPhysVol>activePhys =
new GeoPhysVol(activeLV);
500 GeoIntrusivePtr<GeoPhysVol>electrodePhys =
new GeoPhysVol(electrodeLV);
501 GeoIntrusivePtr<GeoPhysVol>gapPhys =
new GeoPhysVol(gapLV);
506 GeoTransform *
t1 =
new GeoTransform(GeoTrf::Translate3D(0.,0.,zPos));
507 electrodePhys->add(
new GeoSerialIdentifier(iCopy));
508 electrodePhys->add(
t1);
509 electrodePhys->add(activePhys);
512 electrodePhys->add(
new GeoSerialIdentifier(iCopy));
513 electrodePhys->add(
t1);
514 electrodePhys->add(activePhys);
516 zPos = -halfDepth + ElectrodeDepth/2.;
517 GeoTransform *
t2 =
new GeoTransform(GeoTrf::Translate3D(0.,0.,zPos));
518 gapPhys->add(
new GeoSerialIdentifier(1));
520 gapPhys->add(electrodePhys);
522 zPos = -fcalData[2].fullModuleDepth/2. + 2.2 *
Gaudi::Units::cm + halfDepth;
523 for ( iCopy = 1; iCopy < 9; ++iCopy ){
524 modPhysical->add(
new GeoSerialIdentifier(iCopy));
525 modPhysical->add(
new GeoTransform(GeoTrf::Translate3D(0.,0.,zPos)));
526 modPhysical->add(gapPhys);
529 m_absPhysical3 = modPhysical;
538 if(!
status.isSuccess())
throw std::runtime_error (
"Cannot store FCAL_ChannelMap");