22#include <fairlogger/Logger.h>
25#include <TGeoCompositeShape.h>
27#include <TGeoManager.h>
28#include <TGeoMatrix.h>
29#include <TGeoMedium.h>
31#include <TGeoVolume.h>
39 initializeCellCenters();
40 initializeReadoutCenters();
41 if (initType != eUninitialized) {
46Geometry::Geometry(
const Geometry& geometry) : mGeometryType(geometry.mGeometryType), mLeftTransformation(nullptr), mRightTransformation(nullptr)
48 this->mEnabledComponents = geometry.mEnabledComponents;
53 if (mRightTransformation) {
54 delete mRightTransformation;
56 if (mLeftTransformation) {
57 delete mLeftTransformation;
63 int detectorHalfID = -1;
67 fMC->CurrentVolOffID(2, detectorHalfID);
68 fMC->CurrentVolOffID(1, sectorID);
69 fMC->CurrentVolOffID(0, ringID);
71 sectorID += detectorHalfID * sNumberOfCellSectors;
73 LOG(
debug) <<
"FV0 Geometry::getCurrentCellId(): \n"
74 <<
"Half id: " << detectorHalfID <<
"\n"
75 <<
"Half name: " << fMC->CurrentVolOffName(2) <<
"\n"
76 <<
"Sector id: " << sectorID <<
"\n"
77 <<
"Sector name: " << fMC->CurrentVolOffName(1) <<
"\n"
78 <<
"Ring id: " << ringID <<
"\n"
79 <<
"Ring name: " << fMC->CurrentVolOffName(0) <<
"\n"
80 <<
"Cell id : " << sectorID + 8 * ringID <<
"\n";
82 return sectorID + 8 * ringID;
87 if (mEnabledComponents.find(component) == mEnabledComponents.end()) {
88 LOG(
debug) <<
"FV0 Geometry::enableComponent(): Component not initialized and cannot be enabled/disabled!";
92 return mEnabledComponents[component] =
enable;
97 TGeoVolume* vALIC = gGeoManager->GetVolume(
"barrel");
99 LOG(fatal) <<
"FV0: Could not find the top volume";
103 TGeoVolumeAssembly* vFV0 =
new TGeoVolumeAssembly(sDetectorName.c_str());
104 LOG(info) <<
"FV0: Building geometry. FV0 volume name is '" << vFV0->GetName() <<
"'";
106 TGeoVolumeAssembly* vFV0Right =
new TGeoVolumeAssembly((sDetectorName +
"RIGHT").c_str());
107 TGeoVolumeAssembly* vFV0Left =
new TGeoVolumeAssembly((sDetectorName +
"LEFT").c_str());
109 vFV0->AddNode(vFV0Right, 0, mRightTransformation);
110 vFV0->AddNode(vFV0Left, 1, mLeftTransformation);
112 assembleSensVols(vFV0Right, vFV0Left);
113 assembleNonSensVols(vFV0Right, vFV0Left);
115 vALIC->AddNode(vFV0, 1,
new TGeoTranslation(sXGlobal, sYGlobal + 30., sZGlobal));
127 return mCellCenter.at(cellId);
132 return mReadoutCenter.at(cellId);
137 return cellId >= (sNumberOfCellRings - 1) * sNumberOfCellSectors * 2;
140void Geometry::initializeGeometry()
144 initializeTransformations();
145 initializeSensVols();
146 initializeNonSensVols();
149void Geometry::initializeMaps()
151 const bool isFull = mGeometryType ==
eFull;
152 const bool isRough = isFull || mGeometryType ==
eRough;
154 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
eScintillator, hasScint));
155 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
ePlastics, isRough));
156 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
ePmts, isFull));
157 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
eFibers, isFull));
158 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
eScrews, isFull));
159 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
eRods, isFull));
160 mEnabledComponents.insert(std::pair<EGeoComponent, bool>(
eContainer, isRough));
163void Geometry::initializeVectors()
165 initializeCellRingRadii();
166 initializeSectorTransformations();
167 initializeFiberVolumeRadii();
168 initializeFiberMedium();
169 initializeScrewAndRodRadii();
170 initializeScrewTypeMedium();
171 initializeRodTypeMedium();
172 initializeScrewAndRodPositionsAndDimensions();
175void Geometry::initializeCellRingRadii()
178 mRAvgRing.assign(sCellRingRadii, sCellRingRadii + sNumberOfCellRings + 1);
181 for (
int i = 0;
i < mRAvgRing.size() - 1; ++
i) {
182 mRMinScintillator.push_back(mRAvgRing[
i] + sDrSeparationScint);
183 mRMaxScintillator.push_back(mRAvgRing[
i + 1] - sDrSeparationScint);
188void Geometry::initializeSectorTransformations()
190 for (
int iSector = 0; iSector < sNumberOfCellSectors; ++iSector) {
194 TGeoRotation* trans = createAndRegisterRot(sDetectorName + sSectorName +
std::to_string(iSector) +
"TRANS");
196 if (iSector == 2 || iSector == 3) {
199 trans->ReflectY(
true);
202 mSectorTrans.push_back(trans);
206void Geometry::initializeFiberVolumeRadii()
208 for (
int i = 0;
i < sNumberOfCellRings;
i++) {
209 mRMinFiber.push_back(sCellRingRadii[
i] + sEpsilon / 2);
210 mRMaxFiber.push_back(sCellRingRadii[
i + 1] - sEpsilon / 2);
214void Geometry::initializeFiberMedium()
220 for (
int i = 0;
i < mRMinFiber.size();
i++) {
221 mediumName = Form(
"FV0_FiberRing%i$",
i + 1);
222 medium = gGeoManager->GetMedium(mediumName);
224 LOG(warning) << Form(
"FV0 geometry: Fiber medium for ring no. %i (%s) not found!",
i + 1, mediumName.Data());
226 mMediumFiberRings.push_back(medium);
230 for (
int i = 0;
i < sNumberOfPMTFiberVolumes;
i++) {
231 mediumName = Form(
"FV0_FiberPMT%i$",
i + 1);
232 medium = gGeoManager->GetMedium(mediumName);
234 LOG(warning) << Form(
"FV0 geometry: PMT fiber medium from cell no. %i (%s) not found!",
i + 1, mediumName.Data());
236 mMediumFiberPMTs.push_back(medium);
240void Geometry::initializeScrewAndRodRadii()
242 mRScrewAndRod.push_back(mRAvgRing[1]);
243 mRScrewAndRod.push_back(mRAvgRing[2]);
244 mRScrewAndRod.push_back(mRAvgRing[3]);
245 mRScrewAndRod.push_back(mRAvgRing[4]);
246 mRScrewAndRod.push_back((mRAvgRing[4] + mRAvgRing[5]) / 2);
247 mRScrewAndRod.push_back(mRAvgRing[5]);
250void Geometry::initializeScrewTypeMedium()
253 TGeoMedium* medium = gGeoManager->GetMedium(
"FV0_Titanium$");
254 for (
int i = 0;
i < sNumberOfScrewTypes; ++
i) {
255 mMediumScrewTypes.push_back(medium);
259void Geometry::initializeRodTypeMedium()
262 TGeoMedium* medium = gGeoManager->GetMedium(
"FV0_Aluminium$");
263 for (
int i = 0;
i < sNumberOfRodTypes; ++
i) {
264 mMediumRodTypes.push_back(medium);
268void Geometry::addScrewProperties(
const int screwTypeID,
const int iRing,
const float phi)
270 float r = mRScrewAndRod[iRing];
271 mScrewTypeIDs.push_back(screwTypeID);
272 mScrewPos.push_back(std::vector<float>{cosf(phi * M_PI / 180) *
r,
273 sinf(phi * M_PI / 180) *
r,
274 sZScintillator - sDzScintillator / 2 + sZShiftScrew + sDzMaxScrewTypes[screwTypeID] / 2});
275 mDrMinScrews.push_back(sDrMinScrewTypes[screwTypeID]);
276 mDrMaxScrews.push_back(sDrMaxScrewTypes[screwTypeID]);
277 mDzMaxScrews.push_back(sDzMaxScrewTypes[screwTypeID]);
278 mDzMinScrews.push_back(sDzMinScrewTypes[screwTypeID]);
281void Geometry::addRodProperties(
const int rodTypeID,
const int iRing)
283 mRodTypeIDs.push_back(rodTypeID);
284 mRodPos.push_back(std::vector<float>{sDxMinRodTypes[rodTypeID] / 2,
285 mRScrewAndRod[iRing],
286 sZScintillator - sDzScintillator / 2 + sZShiftRod + sDzMaxRodTypes[rodTypeID] / 2});
287 mDxMinRods.push_back(sDxMinRodTypes[rodTypeID]);
288 mDzMaxRods.push_back(sDxMaxRodTypes[rodTypeID]);
289 mDyMinRods.push_back(sDyMinRodTypes[rodTypeID]);
290 mDyMaxRods.push_back(sDyMaxRodTypes[rodTypeID]);
291 mDzMaxRods.push_back(sDzMaxRodTypes[rodTypeID]);
292 mDzMinRods.push_back(sDzMinRodTypes[rodTypeID]);
294 mRodTypeIDs.push_back(rodTypeID);
295 mRodPos.push_back(std::vector<float>{sDxMinRodTypes[rodTypeID] / 2,
296 -mRScrewAndRod[iRing],
297 sZScintillator - sDzScintillator / 2 + sZShiftRod + sDzMaxRodTypes[rodTypeID] / 2});
298 mDxMinRods.push_back(sDxMinRodTypes[rodTypeID]);
299 mDzMaxRods.push_back(sDxMaxRodTypes[rodTypeID]);
300 mDyMinRods.push_back(sDyMinRodTypes[rodTypeID]);
301 mDyMaxRods.push_back(sDyMaxRodTypes[rodTypeID]);
302 mDzMaxRods.push_back(sDzMaxRodTypes[rodTypeID]);
303 mDzMinRods.push_back(sDzMinRodTypes[rodTypeID]);
306void Geometry::initializeScrewAndRodPositionsAndDimensions()
308 for (
int iRing = 0; iRing < mRScrewAndRod.size(); ++iRing) {
311 addRodProperties(0, iRing);
312 for (
float phi = 45;
phi >= -45;
phi -= 45) {
313 addScrewProperties(0, iRing, phi);
317 addRodProperties(0, iRing);
318 for (
float phi = 45;
phi >= -45;
phi -= 45) {
319 addScrewProperties(1, iRing, phi);
323 addRodProperties(1, iRing);
324 for (
float phi = 67.5;
phi >= -67.5;
phi -= 22.5) {
325 addScrewProperties(2, iRing, phi);
329 addRodProperties(2, iRing);
330 for (
float phi = 67.5;
phi >= -67.5;
phi -= 22.5) {
331 addScrewProperties(3, iRing, phi);
335 addRodProperties(3, iRing);
336 for (
float phi = 45;
phi >= -45;
phi -= 45) {
337 addScrewProperties(4, iRing, phi);
341 addRodProperties(3, iRing);
342 for (
float phi = 67.5;
phi >= -67.5;
phi -= 22.5) {
343 addScrewProperties(5, iRing, phi);
352void Geometry::initializeTransformations()
354 TGeoTranslation leftTranslation(-sDxHalvesSeparation / 2, 0, 0);
355 TGeoRotation leftRotation;
356 leftRotation.ReflectX(
true);
357 TGeoHMatrix leftTotalTransformation = leftTranslation * leftRotation;
359 mLeftTransformation =
new TGeoHMatrix(leftTotalTransformation);
360 mRightTransformation =
new TGeoTranslation(sDxHalvesSeparation / 2, sDyHalvesSeparation, sDzHalvesSeparation);
363void Geometry::initializeSensVols()
365 initializeScintCells();
368void Geometry::initializeNonSensVols()
370 initializeScrewHoles();
371 initializeRodHoles();
372 initializePlasticCells();
377 initializeMetalContainer();
380void Geometry::initializeScrewHoles()
382 std::string boolFormula =
"";
384 for (
int i = 0;
i < mScrewPos.size(); ++
i) {
385 std::string holeShapeName = sDetectorName + sScrewName +
"HOLE" +
std::to_string(
i);
386 std::string holeTransName = sDetectorName + sScrewName +
"HOLETRANS" +
std::to_string(
i);
388 createScrewShape(holeShapeName, mScrewTypeIDs[
i], sEpsilon, sEpsilon);
389 createAndRegisterTrans(holeTransName, mScrewPos[
i][0] + sXShiftScrews, mScrewPos[
i][1], mScrewPos[
i][2]);
391 boolFormula += ((
i != 0) ?
"+" :
"") + holeShapeName +
":" + holeTransName;
394 new TGeoCompositeShape(sScrewHolesCSName.c_str(), boolFormula.c_str());
397void Geometry::initializeRodHoles()
399 std::string boolFormula =
"";
401 for (
int i = 0;
i < mRodPos.size(); ++
i) {
402 std::string holeShapeName = sDetectorName + sRodName +
"HOLE" +
std::to_string(
i);
403 std::string holeTransName = sDetectorName + sRodName +
"HOLETRANS" +
std::to_string(
i);
405 createRodShape(holeShapeName, mRodTypeIDs[
i], sEpsilon, sEpsilon);
406 createAndRegisterTrans(holeTransName, mRodPos[
i][0] + sXShiftScrews, mRodPos[
i][1], mRodPos[
i][2]);
408 boolFormula += ((
i != 0) ?
"+" :
"") + holeShapeName +
":" + holeTransName;
411 new TGeoCompositeShape(sRodHolesCSName.c_str(), boolFormula.c_str());
414void Geometry::initializeCells(
const std::string& cellType,
const float zThickness,
const TGeoMedium* medium,
415 const bool isSensitive)
422 const float dxHoleCut = sDxHoleExtensionScintillator;
423 const float xHole = sDrSeparationScint + dxHoleCut;
426 const std::string secSepShapeName =
"FV0_" + cellType +
"SectorSeparation";
427 new TGeoBBox(secSepShapeName.c_str(), mRMaxScintillator.back() + sEpsilon, sDrSeparationScint, zThickness / 2);
430 const std::string secSepRot45Name =
"FV0_" + cellType +
"SecSepRot45";
431 const std::string secSepRot90Name =
"FV0_" + cellType +
"SecSepRot90";
433 createAndRegisterRot(secSepRot45Name, 45, 0, 0);
434 createAndRegisterRot(secSepRot90Name, 90, 0, 0);
437 const std::string holeSmallName =
"FV0_" + cellType +
"HoleSmall";
438 const std::string holeLargeName =
"FV0_" + cellType +
"HoleLarge";
439 const std::string holeSmallCutName =
"FV0_" + cellType +
"HoleSmallCut";
440 const std::string holeLargeCutName =
"FV0_" + cellType +
"HoleLargeCut";
442 new TGeoTube(holeSmallName.c_str(), 0, sDrHoleSmallScintillator, zThickness / 2);
443 new TGeoTube(holeLargeName.c_str(), 0, sDrHoleLargeScintillator, zThickness / 2);
444 new TGeoBBox(holeSmallCutName.c_str(), dxHoleCut, sDrHoleSmallScintillator, zThickness / 2);
445 new TGeoBBox(holeLargeCutName.c_str(), dxHoleCut, sDrHoleLargeScintillator, zThickness / 2);
447 for (
int ir = 0;
ir < sNumberOfCellRings; ++
ir) {
449 const float rMin = mRAvgRing[
ir];
450 const float rMax = mRAvgRing[
ir + 1];
451 const float rMid = rMin + (rMax - rMin) / 2;
476 const std::string aCellName = createVolumeName(cellType + sCellName +
"a",
ir);
479 const std::string aCellShapeName = aCellName +
"Shape";
484 const std::string a1CellShapeFullName = aCellShapeName +
"Full";
485 const std::string a1CellShapeHoleCutName = aCellShapeName +
"HoleCut";
486 const std::string a1CellShapeHoleCutTransName = a1CellShapeHoleCutName +
"Trans";
488 new TGeoTubeSeg(a1CellShapeFullName.c_str(), 0, mRMaxScintillator[
ir], zThickness / 2 - sEpsilon, 45, 90);
489 new TGeoTube(a1CellShapeHoleCutName.c_str(), 0, mRMinScintillator[
ir], zThickness);
491 createAndRegisterTrans(a1CellShapeHoleCutTransName, sXShiftInnerRadiusScintillator, 0, 0);
493 const std::string a1BoolFormula = a1CellShapeFullName +
"-" + a1CellShapeHoleCutName +
":" + a1CellShapeHoleCutTransName;
494 new TGeoCompositeShape(aCellShapeName.c_str(), a1BoolFormula.c_str());
497 new TGeoTubeSeg(aCellShapeName.c_str(), mRMinScintillator[
ir], mRMaxScintillator[
ir], zThickness / 2, 45, 90);
513 const std::string aHole1TransName = aCellName +
"Hole1Trans";
514 const std::string aHole2TransName = aCellName +
"Hole2Trans";
515 const std::string aHole3TransName = aCellName +
"Hole3Trans";
516 const std::string aHole4TransName = aCellName +
"Hole4Trans";
517 const std::string aHole5TransName = aCellName +
"Hole5Trans";
518 const std::string aHole6TransName = aCellName +
"Hole6Trans";
519 const std::string aHole7TransName = aCellName +
"Hole7Trans";
520 const std::string aHole8TransName = aCellName +
"Hole8Trans";
521 const std::string aHole1CutTransName = aCellName +
"Hole1CutTrans";
522 const std::string aHole2CutTransName = aCellName +
"Hole2CutTrans";
523 const std::string aHole7CutTransName = aCellName +
"Hole7CutTrans";
525 createAndRegisterTrans(aHole1TransName, xHole, cos(asin(xHole / rMax)) * rMax, 0);
526 createAndRegisterTrans(aHole2TransName, xHole, cos(asin(xHole / rMin)) * rMin, 0);
527 createAndRegisterTrans(aHole3TransName, sin(45 * M_PI / 180) * rMax, cos(45 * M_PI / 180) * rMax, 0);
528 createAndRegisterTrans(aHole4TransName, sin(45 * M_PI / 180) * rMin, cos(45 * M_PI / 180) * rMin, 0);
529 createAndRegisterTrans(aHole5TransName, sin(22.5 * M_PI / 180) * rMax, cos(22.5 * M_PI / 180) * rMax, 0);
530 createAndRegisterTrans(aHole6TransName, sin(22.5 * M_PI / 180) * rMin, cos(22.5 * M_PI / 180) * rMin, 0);
531 createAndRegisterTrans(aHole7TransName, xHole, cos(asin(xHole / rMid)) * rMid, 0);
532 createAndRegisterTrans(aHole8TransName, sin(45 * M_PI / 180) * rMid, cos(45 * M_PI / 180) * rMid, 0);
533 createAndRegisterTrans(aHole1CutTransName, 0, cos(asin(xHole / rMax)) * rMax, 0);
534 createAndRegisterTrans(aHole2CutTransName, 0, cos(asin(xHole / rMin)) * rMin, 0);
535 createAndRegisterTrans(aHole7CutTransName, 0, cos(asin(xHole / rMid)) * rMid, 0);
538 std::string aBoolFormula = aCellShapeName;
541 aBoolFormula +=
"-" + secSepShapeName +
":" + secSepRot45Name;
542 aBoolFormula +=
"-" + secSepShapeName +
":" + secSepRot90Name;
545 aBoolFormula +=
"-" + ((
ir < 2) ? holeSmallName : holeLargeName) +
":" + aHole1TransName;
546 aBoolFormula +=
"-" + ((
ir < 2) ? holeSmallCutName : holeLargeCutName) +
":" + aHole1CutTransName;
547 aBoolFormula +=
"-" + ((
ir < 2) ? holeSmallName : holeLargeName) +
":" + aHole3TransName;
551 const std::string screwHoleName = (
ir < 3) ? holeSmallName : holeLargeName;
552 const std::string screwHoleCutName = (
ir < 3) ? holeSmallCutName : holeLargeCutName;
554 aBoolFormula +=
"-" + screwHoleName +
":" + aHole2TransName;
555 aBoolFormula +=
"-" + screwHoleCutName +
":" + aHole2CutTransName;
556 aBoolFormula +=
"-" + screwHoleName +
":" + aHole4TransName;
561 aBoolFormula +=
"-" + holeLargeName +
":" + aHole5TransName;
566 aBoolFormula +=
"-" + holeLargeName +
":" + aHole6TransName;
571 aBoolFormula +=
"-" + holeLargeName +
":" + aHole7TransName;
572 aBoolFormula +=
"-" + holeLargeCutName +
":" + aHole7CutTransName;
573 aBoolFormula +=
"-" + holeLargeName +
":" + aHole8TransName;
576 const std::string aCellCSName = aCellName +
"CS";
577 const TGeoCompositeShape* aCellCs =
new TGeoCompositeShape(aCellCSName.c_str(), aBoolFormula.c_str());
580 const TGeoVolume* aCell =
new TGeoVolume(aCellName.c_str(), aCellCs, medium);
604 const std::string bCellName = createVolumeName(cellType + sCellName +
"b",
ir);
607 const std::string bCellShapeName = bCellName +
"Shape";
612 const std::string b1CellShapeFullName = bCellShapeName +
"Full";
613 const std::string b1CellShapeHoleCutName = bCellShapeName +
"Cut";
614 const std::string b1CellShapeHoleCutTransName = b1CellShapeHoleCutName +
"Trans";
616 new TGeoTubeSeg(b1CellShapeFullName.c_str(), 0, mRMaxScintillator[
ir], zThickness / 2 - sEpsilon, 0, 45);
617 new TGeoTube(b1CellShapeHoleCutName.c_str(), 0, mRMinScintillator[
ir], zThickness);
619 createAndRegisterTrans(b1CellShapeHoleCutTransName, sXShiftInnerRadiusScintillator, 0, 0);
621 const std::string b1BoolFormula = b1CellShapeFullName +
"-" + b1CellShapeHoleCutName +
":" + b1CellShapeHoleCutTransName;
622 new TGeoCompositeShape(bCellShapeName.c_str(), b1BoolFormula.c_str());
625 new TGeoTubeSeg(bCellShapeName.c_str(), mRMinScintillator[
ir], mRMaxScintillator[
ir], zThickness / 2, 0, 45);
639 const std::string bHole1TransName = bCellName +
"Hole1Trans";
640 const std::string bHole2TransName = bCellName +
"Hole2Trans";
641 const std::string bHole3TransName = bCellName +
"Hole3Trans";
642 const std::string bHole4TransName = bCellName +
"Hole4Trans";
643 const std::string bHole5TransName = bCellName +
"Hole5Trans";
644 const std::string bHole6TransName = bCellName +
"Hole6Trans";
645 const std::string bHole7TransName = bCellName +
"Hole7Trans";
646 const std::string bHole8TransName = bCellName +
"Hole8Trans";
648 createAndRegisterTrans(bHole1TransName, sin(45 * M_PI / 180) * rMax, cos(45 * M_PI / 180) * rMax, 0);
649 createAndRegisterTrans(bHole2TransName, sin(45 * M_PI / 180) * rMin, cos(45 * M_PI / 180) * rMin, 0);
650 createAndRegisterTrans(bHole3TransName, rMax, 0, 0);
651 createAndRegisterTrans(bHole4TransName, rMin, 0, 0);
652 createAndRegisterTrans(bHole5TransName, cos(22.5 * M_PI / 180) * rMax, sin(22.5 * M_PI / 180) * rMax, 0);
653 createAndRegisterTrans(bHole6TransName, cos(22.5 * M_PI / 180) * rMin, sin(22.5 * M_PI / 180) * rMin, 0);
654 createAndRegisterTrans(bHole7TransName, sin(45 * M_PI / 180) * rMid, cos(45 * M_PI / 180) * rMid, 0);
655 createAndRegisterTrans(bHole8TransName, rMid, 0, 0);
658 std::string bBoolFormula = bCellShapeName;
661 bBoolFormula +=
"-" + secSepShapeName;
662 bBoolFormula +=
"-" + secSepShapeName +
":" + secSepRot45Name;
665 bBoolFormula +=
"-" + ((
ir < 2) ? holeSmallName : holeLargeName) +
":" + bHole1TransName;
666 bBoolFormula +=
"-" + ((
ir < 2) ? holeSmallName : holeLargeName) +
":" + bHole3TransName;
670 const std::string holeName = (
ir < 3) ? holeSmallName : holeLargeName;
672 bBoolFormula +=
"-" + holeName +
":" + bHole2TransName;
673 bBoolFormula +=
"-" + holeName +
":" + bHole4TransName;
678 bBoolFormula +=
"-" + holeLargeName +
":" + bHole5TransName;
683 bBoolFormula +=
"-" + holeLargeName +
":" + bHole6TransName;
688 bBoolFormula +=
"-" + holeLargeName +
":" + bHole7TransName;
689 bBoolFormula +=
"-" + holeLargeName +
":" + bHole8TransName;
692 const std::string bCellCSName = bCellName +
"CS";
693 const TGeoCompositeShape* bCellCs =
new TGeoCompositeShape(bCellCSName.c_str(), bBoolFormula.c_str());
696 const TGeoVolume* bCell =
new TGeoVolume(bCellName.c_str(), bCellCs, medium);
699 mSensitiveVolumeNames.push_back(aCell->GetName());
700 mSensitiveVolumeNames.push_back(bCell->GetName());
705void Geometry::initializeScintCells()
707 const TGeoMedium* medium = gGeoManager->GetMedium(
"FV0_Scintillator$");
708 initializeCells(sScintillatorName, sDzScintillator, medium,
true);
711void Geometry::initializePlasticCells()
713 const TGeoMedium* medium = gGeoManager->GetMedium(
"FV0_Plastic$");
714 initializeCells(sPlasticName, sDzPlastic, medium,
false);
717void Geometry::initializePmts()
719 const TGeoMedium* medium = gGeoManager->GetMedium(
"FV0_PMT$");
720 new TGeoVolume(createVolumeName(sPmtName).c_str(),
new TGeoTube(createVolumeName(sPmtName +
"Shape").c_str(), 0, sDrPmt, sDzPmt / 2), medium);
723void Geometry::initializeFibers()
726 const float dzFibers = sDzContainer - sDzContainerBack - sDzContainerFront - sDzScintillator - sDzPlastic - 2 * sEpsilon;
728 const std::string fiberName = sDetectorName +
"Fibers";
730 const std::string fiberSepCutName = fiberName +
"SepCut";
731 const std::string fiberConeCutName = fiberName +
"ConeCut";
732 const std::string fiberHoleCutName = fiberName +
"HoleCut";
734 const std::string fiberTransName = fiberName +
"Trans";
735 const std::string fiberConeCutTransName = fiberConeCutName +
"Trans";
736 const std::string fiberHoleCutTransName = fiberHoleCutName +
"Trans";
738 new TGeoBBox(fiberSepCutName.c_str(), sDrSeparationScint, mRMaxFiber.back() + sEpsilon, dzFibers / 2 + sEpsilon);
739 new TGeoConeSeg(fiberConeCutName.c_str(), sDzContainerCone / 2 + sEpsilon, 0,
740 sDrMinContainerCone + sXYThicknessContainerCone + sEpsilon, 0, sDrMinContainerFront + sEpsilon, -90, 90);
741 new TGeoTube(fiberHoleCutName.c_str(), 0, mRMinScintillator.front(), dzFibers / 2 + sEpsilon);
743 createAndRegisterTrans(fiberTransName, sXScintillator, 0, sZFiber);
744 createAndRegisterTrans(fiberConeCutTransName, sXScintillator, 0, sZCone);
745 createAndRegisterTrans(fiberHoleCutTransName, sXScintillator + sXShiftInnerRadiusScintillator, 0, sZFiber);
747 for (
int i = 0;
i < mRMinFiber.size(); ++
i) {
749 new TGeoTubeSeg(fiberShapeName.c_str(), mRMinFiber[
i], mRMaxFiber[
i] - sEpsilon, dzFibers / 2, -90, 90);
752 std::string boolFormula =
"";
753 boolFormula += fiberShapeName +
":" + fiberTransName;
754 boolFormula +=
"-" + fiberSepCutName +
":" + fiberTransName;
755 boolFormula +=
"-" + fiberConeCutName +
":" + fiberConeCutTransName;
759 boolFormula +=
"-" + fiberHoleCutName +
":" + fiberHoleCutTransName;
763 boolFormula +=
"-" + sScrewHolesCSName;
764 boolFormula +=
"-" + sRodHolesCSName;
766 const TGeoCompositeShape* fiberCS =
new TGeoCompositeShape((fiberShapeName +
"CS").c_str(), boolFormula.c_str());
768 new TGeoVolume(createVolumeName(sFiberName,
i + 1).c_str(), fiberCS, mMediumFiberRings[
i]);
772 for (
int i = 0;
i < sNumberOfPMTFiberVolumes;
i++) {
773 new TGeoVolume(createVolumeName(sFiberName + sPmtName,
i + 1).c_str(),
774 new TGeoTube(createVolumeName(sFiberName + sPmtName +
"Shape",
i + 1).c_str(), 0, sDrPmt / 2, sDzPmt / 2),
775 mMediumFiberPMTs[
i]);
779void Geometry::initializeScrews()
781 for (
int i = 0;
i < sNumberOfScrewTypes; ++
i) {
782 const std::string screwName = createVolumeName(sScrewName,
i);
783 const TGeoShape* screwShape = createScrewShape(screwName +
"Shape",
i, 0, 0, 0);
786 new TGeoVolume(screwName.c_str(), screwShape, mMediumScrewTypes[
i]);
790void Geometry::initializeRods()
792 for (
int i = 0;
i < sNumberOfRodTypes; ++
i) {
793 const std::string rodName = createVolumeName(sRodName,
i);
794 const TGeoShape* rodShape = createRodShape(rodName +
"Shape",
i, -sEpsilon, -sEpsilon);
797 new TGeoVolume(rodName.c_str(), rodShape, mMediumRodTypes[
i]);
801void Geometry::initializeMetalContainer()
810 const std::string backPlateName =
"FV0_BackPlate";
811 const std::string backPlateStandName = backPlateName +
"Stand";
812 const std::string backPlateHoleName = backPlateName +
"Hole";
813 const std::string backPlateHoleCutName = backPlateHoleName +
"Cut";
814 const std::string backPlateStandTransName = backPlateStandName +
"Trans";
815 const std::string backPlateHoleTransName = backPlateHoleName +
"Trans";
817 new TGeoTubeSeg(backPlateName.c_str(), 0, sDrMaxContainerBack, sDzContainerBack / 2, -90, 90);
818 new TGeoBBox(backPlateStandName.c_str(), sDxContainerStand / 2, (sDrMaxContainerBack + sDyContainerStand) / 2,
819 sDzContainerBack / 2);
820 new TGeoTubeSeg(backPlateHoleName.c_str(), 0, sDrContainerHole, sDzContainerBack / 2, -90, 90);
821 new TGeoBBox(backPlateHoleCutName.c_str(), -sXShiftContainerHole, sDrContainerHole, sDzContainerBack);
823 createAndRegisterTrans(backPlateStandTransName, sDxContainerStand / 2,
824 -(sDrMaxContainerBack + sDyContainerStand) / 2, 0);
825 createAndRegisterTrans(backPlateHoleTransName, sXShiftContainerHole, 0, 0);
828 std::string backPlateBoolFormula =
"";
829 backPlateBoolFormula += backPlateName;
830 backPlateBoolFormula +=
"+" + backPlateStandName +
":" + backPlateStandTransName;
831 backPlateBoolFormula +=
"-" + backPlateHoleName +
":" + backPlateHoleTransName;
832 backPlateBoolFormula +=
"-" + backPlateHoleCutName;
834 const std::string backPlateCSName = backPlateName +
"CS";
835 const std::string backPlateCSTransName = backPlateCSName +
"Trans";
837 new TGeoCompositeShape(backPlateCSName.c_str(), backPlateBoolFormula.c_str());
838 createAndRegisterTrans(backPlateCSTransName, 0, 0, sZContainerBack);
843 const float zPosFrontPlate = sZContainerFront;
845 const float dyFrontPlateStand = sDyContainerStand + (sDrMaxContainerFront - sDrMinContainerFront) / 2;
847 const float yPosFrontPlateStand = -sDrMaxContainerFront - sDyContainerStand + dyFrontPlateStand / 2;
849 const std::string frontPlateName =
"FV0_FrontPlate";
850 const std::string frontPlateStandName = frontPlateName +
"Stand";
851 const std::string frontPlateTransName = frontPlateName +
"Trans";
852 const std::string frontPlateStandTransName = frontPlateStandName +
"Trans";
854 new TGeoTubeSeg(frontPlateName.c_str(), sDrMinContainerFront, sDrMaxContainerFront, sDzContainerFront / 2, -90, 90);
855 new TGeoBBox(frontPlateStandName.c_str(), sDxContainerStand / 2, dyFrontPlateStand / 2, sDzContainerBack / 2);
857 createAndRegisterTrans(frontPlateTransName, 0, 0, zPosFrontPlate);
858 createAndRegisterTrans(frontPlateStandTransName, sDxContainerStand / 2, yPosFrontPlateStand, 0);
861 std::string frontPlateBoolFormula =
"";
862 frontPlateBoolFormula += frontPlateName;
863 frontPlateBoolFormula +=
"+" + frontPlateStandName +
":" + frontPlateStandTransName;
865 const std::string frontPlateCSName = frontPlateName +
"CS";
867 new TGeoCompositeShape(frontPlateCSName.c_str(), frontPlateBoolFormula.c_str());
872 const float thicknessFrontPlateCone = sXYThicknessContainerCone;
874 const float zPosCone = sDzContainerFront / 2 - sDzContainerCone / 2;
876 const std::string frontPlateConeName =
"FV0_FrontPlateCone";
877 const std::string frontPlateConeShieldName = frontPlateConeName +
"Shield";
878 const std::string frontPlateConeShieldTransName = frontPlateConeShieldName +
"Trans";
880 new TGeoConeSeg(frontPlateConeShieldName.c_str(), sDzContainerCone / 2, sDrMinContainerCone,
881 sDrMinContainerCone + thicknessFrontPlateCone, sDrMinContainerFront - thicknessFrontPlateCone,
882 sDrMinContainerFront,
884 createAndRegisterTrans(frontPlateConeShieldTransName, 0, 0, zPosCone);
889 const float zPosConePlate = sDzContainerFront / 2 - sDzContainerCone + thicknessFrontPlateCone / 2;
891 const std::string frontPlateConePlateName = frontPlateConeName +
"Plate";
893 new TGeoTubeSeg(frontPlateConePlateName.c_str(), 0, sDrMinContainerCone + thicknessFrontPlateCone,
894 thicknessFrontPlateCone / 2, -90, 90);
897 std::string frontPlateConePlateCSBoolFormula;
898 frontPlateConePlateCSBoolFormula += frontPlateConePlateName;
899 frontPlateConePlateCSBoolFormula +=
"-" + backPlateHoleName +
":" + backPlateHoleTransName;
901 const std::string frontPlateConePlateCSName = frontPlateConePlateName +
"CS";
902 const std::string frontPlateConePlateCSTransName = frontPlateConePlateCSName +
"Trans";
903 new TGeoCompositeShape(frontPlateConePlateCSName.c_str(), frontPlateConePlateCSBoolFormula.c_str());
904 createAndRegisterTrans(frontPlateConePlateCSTransName, 0, 0, zPosConePlate);
907 std::string frontPlateConeCSBoolFormula =
"";
908 frontPlateConeCSBoolFormula += frontPlateConeShieldName +
":" + frontPlateConeShieldTransName;
909 frontPlateConeCSBoolFormula +=
"+" + frontPlateConePlateCSName +
":" + frontPlateConePlateCSTransName;
911 const std::string frontPlateConeCSName = frontPlateConeName +
"CS";
912 new TGeoCompositeShape(frontPlateConeCSName.c_str(), frontPlateConeCSBoolFormula.c_str());
915 const float dzShieldGap = 0.7;
916 const float dzShield = sDzContainer - 2 * dzShieldGap;
919 const float zPosOuterShield = (sZContainerBack + sZContainerFront) / 2;
921 const std::string outerShieldName =
"FV0_OuterShield";
922 const std::string outerShieldTransName = outerShieldName +
"Trans";
924 new TGeoTubeSeg(outerShieldName.c_str(), sDrMinContainerOuterShield, sDrMaxContainerOuterShield, dzShield / 2, -90,
926 createAndRegisterTrans(outerShieldTransName, 0, 0, zPosOuterShield);
929 const float dzInnerShield = sDzContainer - sDzContainerCone - dzShieldGap;
930 const float zPosInnerShield = sZContainerBack - sDzContainerBack / 2 + dzShieldGap + dzInnerShield / 2;
932 const std::string innerShieldName =
"FV0_InnerShield";
933 const std::string innerShieldCutName = innerShieldName +
"Cut";
935 new TGeoTubeSeg(innerShieldName.c_str(), sDrMinContainerInnerShield, sDrMaxContainerInnerShield, dzInnerShield / 2, -90, 90);
936 new TGeoBBox(innerShieldCutName.c_str(), fabs(sXShiftContainerHole), sDrMaxContainerInnerShield, dzInnerShield / 2);
939 std::string innerShieldCSBoolFormula;
940 innerShieldCSBoolFormula = innerShieldName;
941 innerShieldCSBoolFormula +=
"-" + innerShieldCutName;
943 const std::string innerShieldCSName = innerShieldName +
"CS";
944 const std::string innerShieldCSTransName = innerShieldCSName +
"Trans";
945 new TGeoCompositeShape(innerShieldCSName.c_str(), innerShieldCSBoolFormula.c_str());
946 createAndRegisterTrans(innerShieldCSTransName, sXShiftContainerHole, 0, zPosInnerShield);
949 const float dzCover = sDzContainer;
950 const float zPosCoverConeCut = zPosFrontPlate + zPosCone;
952 const std::string coverName =
"FV0_Cover";
953 const std::string coverConeCutName = coverName +
"ConeCut";
954 const std::string coverHoleCutName = coverName +
"HoleCut";
956 new TGeoBBox(coverName.c_str(), sDxContainerCover / 2, sDrMaxContainerOuterShield, dzCover / 2);
957 new TGeoCone(coverConeCutName.c_str(), sDzContainerCone / 2, 0, sDrMinContainerCone + thicknessFrontPlateCone, 0,
958 sDrMinContainerFront);
959 new TGeoTubeSeg(coverHoleCutName.c_str(), 0, sDrMinContainerInnerShield, dzCover / 2, 0, 360);
961 const std::string coverTransName = coverName +
"Trans";
962 const std::string coverConeCutTransName = coverConeCutName +
"Trans";
963 const std::string coverHoleCutTransName = coverHoleCutName +
"Trans";
965 createAndRegisterTrans(coverTransName, sDxContainerCover / 2, 0, zPosOuterShield);
966 createAndRegisterTrans(coverConeCutTransName, 0, 0, zPosCoverConeCut);
967 createAndRegisterTrans(coverHoleCutTransName.c_str(), sXShiftContainerHole, 0, zPosOuterShield);
970 std::string coverCSBoolFormula =
"";
971 coverCSBoolFormula += coverName +
":" + coverTransName;
972 coverCSBoolFormula +=
"-" + coverConeCutName +
":" + coverConeCutTransName;
973 coverCSBoolFormula +=
"-" + coverHoleCutName +
":" + coverHoleCutTransName;
975 const std::string coverCSName = coverName +
"CS";
976 new TGeoCompositeShape(coverCSName.c_str(), coverCSBoolFormula.c_str());
979 const float dzStandBottom = sDzContainer - sDzContainerBack - sDzContainerFront;
980 const float dyStandBottomGap = 0.5;
981 const float dxStandBottomHole = 9.4;
982 const float dzStandBottomHole = 20.4;
983 const float dxStandBottomHoleSpacing = 3.1;
985 const std::string standName =
"FV0_StandBottom";
986 const std::string standHoleName = standName +
"Hole";
988 new TGeoBBox(standName.c_str(), sDxContainerStandBottom / 2, sDyContainerStandBottom / 2, dzStandBottom / 2);
989 new TGeoBBox(standHoleName.c_str(), dxStandBottomHole / 2, sDyContainerStandBottom / 2 + sEpsilon,
990 dzStandBottomHole / 2);
992 const std::string standHoleTrans1Name = standHoleName +
"Trans1";
993 const std::string standHoleTrans2Name = standHoleName +
"Trans2";
994 const std::string standHoleTrans3Name = standHoleName +
"Trans3";
996 createAndRegisterTrans(standHoleTrans1Name, -dxStandBottomHoleSpacing - dxStandBottomHole, 0, 0);
997 createAndRegisterTrans(standHoleTrans2Name, 0, 0, 0);
998 createAndRegisterTrans(standHoleTrans3Name, dxStandBottomHoleSpacing + dxStandBottomHole, 0, 0);
1001 const std::string standCSName = standName +
"CS";
1003 std::string standBoolFormula =
"";
1004 standBoolFormula += standName;
1005 standBoolFormula +=
"-" + standHoleName +
":" + standHoleTrans1Name;
1006 standBoolFormula +=
"-" + standHoleName +
":" + standHoleTrans2Name;
1007 standBoolFormula +=
"-" + standHoleName +
":" + standHoleTrans3Name;
1009 new TGeoCompositeShape(standCSName.c_str(), standBoolFormula.c_str());
1011 const std::string standCSTransName = standCSName +
"Trans";
1013 createAndRegisterTrans(standCSTransName.c_str(),
1014 sDxContainerStand - sDxContainerStandBottom / 2,
1015 -(sDrMaxContainerBack + sDyContainerStand) + sDyContainerStandBottom / 2 + dyStandBottomGap,
1019 std::string boolFormula =
"";
1020 boolFormula += backPlateCSName +
":" + backPlateCSTransName;
1021 boolFormula +=
"+" + frontPlateCSName +
":" + frontPlateTransName;
1022 boolFormula +=
"+" + frontPlateConeCSName +
":" + frontPlateTransName;
1023 boolFormula +=
"+" + outerShieldName +
":" + outerShieldTransName;
1024 boolFormula +=
"+" + innerShieldCSName +
":" + innerShieldCSTransName;
1025 boolFormula +=
"+" + coverCSName;
1026 boolFormula +=
"+" + standCSName +
":" + standCSTransName;
1027 boolFormula +=
"-" + sScrewHolesCSName;
1028 boolFormula +=
"-" + sRodHolesCSName;
1030 const std::string aluContCSName =
"FV0_AluContCS";
1031 const TGeoCompositeShape* aluContCS =
new TGeoCompositeShape(aluContCSName.c_str(), boolFormula.c_str());
1034 const std::string aluContName = createVolumeName(sContainerName);
1035 const TGeoMedium* medium = gGeoManager->GetMedium(
"FV0_Aluminium$");
1036 new TGeoVolume(aluContName.c_str(), aluContCS, medium);
1039void Geometry::assembleSensVols(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1042 assembleScintSectors(vFV0Right, vFV0Left);
1046void Geometry::assembleNonSensVols(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1049 assemblePlasticSectors(vFV0Right, vFV0Left);
1051 if (mEnabledComponents.at(
ePmts)) {
1052 assemblePmts(vFV0Right, vFV0Left);
1054 if (mEnabledComponents.at(
eFibers)) {
1055 assembleFibers(vFV0Right, vFV0Left);
1057 if (mEnabledComponents.at(
eScrews)) {
1058 assembleScrews(vFV0Right, vFV0Left);
1060 if (mEnabledComponents.at(
eRods)) {
1061 assembleRods(vFV0Right, vFV0Left);
1064 assembleMetalContainer(vFV0Right, vFV0Left);
1068void Geometry::assembleScintSectors(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1070 TGeoVolumeAssembly* sectors = buildSectorAssembly(sScintillatorName);
1073 vFV0Right->AddNode(sectors, 0);
1074 vFV0Left->AddNode(sectors, 1);
1077void Geometry::assemblePlasticSectors(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1079 TGeoVolumeAssembly* sectors = buildSectorAssembly(sPlasticName);
1082 TGeoTranslation* trans =
new TGeoTranslation(0, 0, sZPlastic);
1084 vFV0Right->AddNode(sectors, 0, trans);
1085 vFV0Left->AddNode(sectors, 1, trans);
1088void Geometry::assemblePmts(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1090 TGeoVolumeAssembly* pmts =
new TGeoVolumeAssembly(createVolumeName(
"PMTS").c_str());
1091 TGeoVolume* pmt = gGeoManager->GetVolume(createVolumeName(sPmtName).c_str());
1093 LOG(warning) <<
"FV0 Geometry::assemblePmts(): PMT volume not found.";
1095 for (
int i = 0;
i < sNumberOfPMTs;
i++) {
1096 pmts->AddNode(pmt,
i,
new TGeoTranslation(sXPmt[
i], sYPmt[
i], sZPmt));
1100 vFV0Right->AddNode(pmts, 0);
1101 vFV0Left->AddNode(pmts, 1);
1104void Geometry::assembleFibers(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1106 TGeoVolumeAssembly* fibersRight =
new TGeoVolumeAssembly(createVolumeName(
"FIBERSRIGHT").c_str());
1107 TGeoVolumeAssembly* fibersLeft =
new TGeoVolumeAssembly(createVolumeName(
"FIBERSLEFT").c_str());
1111 for (
int i = 0;
i < mRMinFiber.size(); ++
i) {
1112 volumeName = createVolumeName(sFiberName,
i + 1);
1113 fiber = gGeoManager->GetVolume(volumeName);
1115 LOG(warning) << Form(
"FV0 geometry: Fiber volume no. %i (%s) not found!",
i + 1, volumeName.Data());
1117 fibersRight->AddNode(fiber,
i);
1118 fibersLeft->AddNode(fiber,
i);
1122 int iPMTFiberCell = 0;
1123 for (
int i = 0;
i < sNumberOfPMTs;
i++) {
1124 if (iPMTFiberCell == sNumberOfPMTsPerSector) {
1128 volumeName = createVolumeName(sFiberName + sPmtName, sPMTFiberCellOrder[iPMTFiberCell]);
1129 fiber = gGeoManager->GetVolume(volumeName);
1132 LOG(warning) << Form(
"FV0 geometry: Volume of fibers from cell %i (%s) not found!", iPMTFiberCell, volumeName.Data());
1134 fibersRight->AddNode(fiber,
i,
new TGeoTranslation(sXPmt[
i], sYPmt[
i], sZPmt + sDzPmt));
1138 volumeName = createVolumeName(sFiberName + sPmtName, sPMTFiberCellOrder[abs(iPMTFiberCell - sNumberOfPMTsPerSector) - 1]);
1139 fiber = gGeoManager->GetVolume(volumeName);
1142 LOG(warning) << Form(
"FV0 geometry: Volume of fibers from cell %i (%s) not found!", iPMTFiberCell, volumeName.Data());
1144 fibersLeft->AddNode(fiber,
i,
new TGeoTranslation(sXPmt[
i], sYPmt[
i], sZPmt + sDzPmt));
1150 LOG(
debug) << Form(
"FV0 geometry: total weight of fibers = %.4f kg", fibersRight->Weight(1e-5) + fibersLeft->Weight(1e-5));
1152 vFV0Right->AddNode(fibersRight, 0);
1153 vFV0Left->AddNode(fibersLeft, 1);
1156void Geometry::assembleScrews(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1158 TGeoVolumeAssembly* screws =
new TGeoVolumeAssembly(createVolumeName(
"SCREWS").c_str());
1161 for (
int i = 0;
i < mScrewPos.size(); ++
i) {
1162 TGeoVolume* screw = gGeoManager->GetVolume(createVolumeName(sScrewName, mScrewTypeIDs[
i]).c_str());
1164 LOG(warning) <<
"FV0 Geometry::assembleScrews(): Screw no. " <<
i <<
" not found";
1166 screws->AddNode(screw,
i,
new TGeoTranslation(mScrewPos[
i][0] + sXShiftScrews, mScrewPos[
i][1], mScrewPos[
i][2]));
1170 vFV0Right->AddNode(screws, 0);
1171 vFV0Left->AddNode(screws, 1);
1174void Geometry::assembleRods(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1176 TGeoVolumeAssembly* rods =
new TGeoVolumeAssembly(createVolumeName(
"RODS").c_str());
1179 for (
int i = 0;
i < mRodPos.size(); ++
i) {
1180 TGeoVolume* rod = gGeoManager->GetVolume(createVolumeName(sRodName, mRodTypeIDs[
i]).c_str());
1183 LOG(info) <<
"FV0 Geometry::assembleRods(): Rod no. " <<
i <<
" not found";
1185 rods->AddNode(rod,
i,
new TGeoTranslation(mRodPos[
i][0] + sXShiftScrews, mRodPos[
i][1], mRodPos[
i][2]));
1189 vFV0Right->AddNode(rods, 0);
1190 vFV0Left->AddNode(rods, 1);
1193void Geometry::assembleMetalContainer(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
const
1195 TGeoVolume* container = gGeoManager->GetVolume(createVolumeName(sContainerName).c_str());
1197 LOG(warning) <<
"FV0: Could not find container volume";
1199 vFV0Right->AddNode(container, 0);
1200 vFV0Left->AddNode(container, 1);
1204TGeoVolumeAssembly* Geometry::buildSectorAssembly(
const std::string& cellName)
const
1206 TGeoVolumeAssembly* assembly =
new TGeoVolumeAssembly(createVolumeName(cellName).c_str());
1208 for (
int iSector = 0; iSector < mSectorTrans.size(); ++iSector) {
1209 TGeoVolumeAssembly* sector = buildSector(cellName, iSector);
1210 assembly->AddNode(sector, iSector, mSectorTrans[iSector]);
1216TGeoVolumeAssembly* Geometry::buildSector(
const std::string& cellType,
const int iSector)
const
1218 TGeoVolumeAssembly* sector =
new TGeoVolumeAssembly(createVolumeName(cellType + sSectorName, iSector).c_str());
1220 for (
int i = 0;
i < sNumberOfCellRings; ++
i) {
1221 TGeoVolume* cell = gGeoManager->GetVolume(createVolumeName(cellType + sCellName + sCellTypes[iSector],
i).c_str());
1224 LOG(warning) <<
"FV0 Geometry::buildSector(): Couldn't find cell volume no. " <<
i;
1226 sector->AddNode(cell,
i,
new TGeoTranslation(sXScintillator, 0, 0));
1233TGeoShape* Geometry::createScrewShape(
const std::string& shapeName,
const int screwTypeID,
const float xEpsilon,
1234 const float yEpsilon,
const float zEpsilon)
const
1236 const float xyEpsilon = (fabs(xEpsilon) > fabs(yEpsilon)) ? xEpsilon : yEpsilon;
1237 const float dzMax = sDzMaxScrewTypes[screwTypeID] / 2 + zEpsilon;
1238 const float dzMin = sDzMinScrewTypes[screwTypeID] / 2 + zEpsilon;
1240 const std::string thinPartName = shapeName +
"Thin";
1241 const std::string thickPartName = shapeName +
"Thick";
1242 const std::string thickPartTransName = thickPartName +
"Trans";
1244 if ((screwTypeID == 0) || (screwTypeID == 5)) {
1245 return new TGeoTube(shapeName.c_str(), 0, sDrMinScrewTypes[screwTypeID] + xyEpsilon, dzMax);
1247 new TGeoTube(thinPartName.c_str(), 0, sDrMinScrewTypes[screwTypeID] + xyEpsilon, dzMax);
1248 new TGeoTube(thickPartName.c_str(), 0, sDrMaxScrewTypes[screwTypeID] + xyEpsilon, dzMin);
1249 createAndRegisterTrans(thickPartTransName, 0, 0, -dzMax - sZShiftScrew + sDzScintillator + sDzPlastic + dzMin);
1250 std::string boolFormula = thinPartName;
1251 boolFormula +=
"+" + thickPartName +
":" + thickPartTransName;
1252 return new TGeoCompositeShape(shapeName.c_str(), boolFormula.c_str());
1256TGeoShape* Geometry::createRodShape(
const std::string& shapeName,
const int rodTypeID,
const float xEpsilon,
1257 const float yEpsilon,
const float zEpsilon)
const
1259 const float dxMin = sDxMinRodTypes[rodTypeID] / 2 + xEpsilon;
1260 const float dxMax = sDxMaxRodTypes[rodTypeID] / 2 + xEpsilon;
1261 const float dyMin = sDyMinRodTypes[rodTypeID] / 2 + yEpsilon;
1262 const float dyMax = sDyMaxRodTypes[rodTypeID] / 2 + yEpsilon;
1263 const float dzMax = sDzMaxRodTypes[rodTypeID] / 2 + zEpsilon;
1264 const float dzMin = sDzMinRodTypes[rodTypeID] / 2 + zEpsilon;
1266 const std::string thinPartName = shapeName +
"Thin";
1267 const std::string thickPartName = shapeName +
"Thick";
1268 const std::string thickPartTransName = thickPartName +
"Trans";
1270 new TGeoBBox(thinPartName.c_str(), dxMin, dyMin, dzMax);
1271 new TGeoBBox(thickPartName.c_str(), dxMax, dyMax, dzMin);
1272 createAndRegisterTrans(thickPartTransName, dxMax - dxMin, 0,
1273 -dzMax - sZShiftRod + sDzScintillator + sDzPlastic + dzMin);
1275 std::string boolFormula = thinPartName;
1276 boolFormula +=
"+" + thickPartName +
":" + thickPartTransName;
1278 TGeoCompositeShape* rodShape =
new TGeoCompositeShape(shapeName.c_str(), boolFormula.c_str());
1282TGeoTranslation* Geometry::createAndRegisterTrans(
const std::string&
name,
const double dx,
const double dy,
1283 const double dz)
const
1285 TGeoTranslation* trans =
new TGeoTranslation(
name.c_str(), dx, dy, dz);
1286 trans->RegisterYourself();
1290TGeoRotation* Geometry::createAndRegisterRot(
const std::string&
name,
const double phi,
const double theta,
1291 const double psi)
const
1293 TGeoRotation* rot =
new TGeoRotation(
name.c_str(), phi, theta, psi);
1294 rot->RegisterYourself();
1298const std::string Geometry::createVolumeName(
const std::string& volumeType,
const int number)
const
1300 return sDetectorName + volumeType + ((number >= 0) ?
std::to_string(number) :
"");
1303void Geometry::initializeCellCenters()
1305 const float phi0 = 67.5 * TMath::DegToRad();
1306 const float dphi = 45. * TMath::DegToRad();
1307 const float lutSect2Phi[sNumberOfCellSectors * 2] = {phi0, phi0 - dphi, phi0 - 2 * dphi, phi0 - 3 * dphi, phi0 + dphi, phi0 + 2 * dphi, phi0 + 3 * dphi, phi0 + 4 * dphi};
1308 for (
int cellId = 0; cellId < sNumberOfCells; cellId++) {
1309 float r = 0.5 * (sCellRingRadii[sCellToRing[cellId]] + sCellRingRadii[sCellToRing[cellId] + 1]);
1310 double x = sXGlobal +
r * TMath::Cos(lutSect2Phi[sCellToSector[cellId]]);
1311 double y = sYGlobal +
r * TMath::Sin(lutSect2Phi[sCellToSector[cellId]]);
1318void Geometry::initializeReadoutCenters()
1320 for (
int channelId = 0; channelId < sNumberOfReadoutChannels; channelId++) {
1325 const int numberOfSectorsR5 = sNumberOfCellSectors * 4;
1326 const float phi0 = 78.75 * TMath::DegToRad();
1327 const float dphi = 22.5 * TMath::DegToRad();
1328 const float lutReadoutSect2Phi[numberOfSectorsR5] =
1329 {phi0 - 0 * dphi, phi0 - 1 * dphi, phi0 - 2 * dphi, phi0 - 3 * dphi,
1330 phi0 - 4 * dphi, phi0 - 5 * dphi, phi0 - 6 * dphi, phi0 - 7 * dphi,
1331 phi0 + 1 * dphi, phi0 + 2 * dphi, phi0 + 3 * dphi, phi0 + 4 * dphi,
1332 phi0 + 5 * dphi, phi0 + 6 * dphi, phi0 + 7 * dphi, phi0 + 8 * dphi};
1334 int iReadoutSector = channelId - ((sNumberOfCellRings - 1) * sNumberOfCellSectors * 2);
1335 float r = 0.5 * (sCellRingRadii[4] + sCellRingRadii[5]);
1336 double x = sXGlobal +
r * TMath::Cos(lutReadoutSect2Phi[iReadoutSector]);
1337 double y = sYGlobal +
r * TMath::Sin(lutReadoutSect2Phi[iReadoutSector]);
1343Geometry* Geometry::sInstance =
nullptr;
1349 LOG(info) <<
"FV0 geometry instance created";
1351 sInstance =
new Geometry(initType);
Base definition of FV0 geometry.
ClassImp(o2::fv0::Geometry)
void buildGeometry() const
Build the geometry.
Point3Dsimple & getReadoutCenter(UInt_t cellId)
int getCurrentCellId(const TVirtualMC *fMC) const
static Geometry * instance(EGeoType initType=eUninitialized)
bool enableComponent(EGeoComponent component, bool enable=true)
Point3Dsimple & getCellCenter(UInt_t cellId)
bool isRing5(UInt_t cellId)
EGeoComponent
Geometry components possible to be enabled/disabled. Only enabled components will be created.
void getGlobalPosition(float &x, float &y, float &z)
Utility functions to be accessed externally.
GLuint const GLchar * name
GLdouble GLdouble GLdouble z
std::string to_string(gsl::span< T, Size > span)
void SetCoordinates(float x, float y, float z)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)