13#include <TGeoCompositeShape.h>
17#include <TGeoSphere.h>
18#include <TGeoVolume.h>
19#include <TMCManagerStack.h>
20#include "TGeoManager.h"
25#include "TVirtualMC.h"
29#include <fairlogger/Logger.h>
49 :
o2::base::DetImpl<
Detector>(
"FT0", Active), mIdSens1(0), mPMTeff(nullptr), mHits(
o2::
utils::createSimVector<
o2::ft0::
HitType>()), mTrackIdTop(-1), mTrackIdMCPtop(-1)
57 :
o2::base::DetImpl<
Detector>(rhs), mIdSens1(rhs.mIdSens1), mPMTeff(rhs.mPMTeff), mHits(
o2::
utils::createSimVector<
o2::ft0::
HitType>()), mTrackIdTop(-1), mTrackIdMCPtop(-1)
60 std::copy(std::begin(rhs.mSim2LUT), std::end(rhs.mSim2LUT), mSim2LUT);
72 TGeoVolume*
v = gGeoManager->GetVolume(
"0REG");
74 LOG(warn) <<
"@@@@ Sensitive volume 0REG not found!!!!!!!!";
77 mREGVolID =
fMC->VolId(
"0REG");
79 TGeoVolume* vrad = gGeoManager->GetVolume(
"0TOP");
80 if (vrad ==
nullptr) {
81 LOG(warn) <<
"@@@@ Sensitive radiator not found!!!!!!!!";
84 mTOPVolID =
fMC->VolId(
"0TOP");
86 TGeoVolume* vmcp = gGeoManager->GetVolume(
"0MTO");
87 if (vmcp ==
nullptr) {
88 LOG(warn) <<
"@@@@ Sensitive MCP glass not found!!!!!!!!";
91 mMTOVolID =
fMC->VolId(
"0MTO");
97 LOG(
debug) <<
"Creating FT0 geometry\n";
100 TGeoVolumeAssembly* stlinA =
new TGeoVolumeAssembly(
"FT0A");
101 TGeoVolumeAssembly* stlinC =
new TGeoVolumeAssembly(
"FT0C");
106 int nCellsA = geometry.
NCellsA;
107 int nCellsC = geometry.
NCellsC;
109 for (
int ipos = 0; ipos < nCellsA; ipos++) {
110 mPosModuleAx[ipos] = geometry.
centerMCP(ipos).X();
111 mPosModuleAy[ipos] = geometry.
centerMCP(ipos).Y();
115 TVirtualMC::GetMC()->Gsvolu(
"0MOD",
"BOX",
getMediumID(
kAir), mInStart, 3);
116 TGeoVolume* ins = gGeoManager->GetVolume(
"0MOD");
118 TGeoTranslation* tr[nCellsA + nCellsC];
122 nameTr = Form(
"0TR%i", itr + 1);
123 float z = -mStartA[2] + mInStart[2];
124 tr[itr] =
new TGeoTranslation(nameTr.Data(), mPosModuleAx[itr], mPosModuleAy[itr],
z);
125 tr[itr]->RegisterYourself();
126 stlinA->AddNode(ins, itr, tr[itr]);
127 LOG(
debug) <<
" A geom " << itr <<
" " << mPosModuleAx[itr] <<
" " << mPosModuleAy[itr];
132 stlinA->AddNode(constructFrameAGeometry(), 1,
new TGeoTranslation(0, 0, -mStartA[2] + mInStart[2]));
135 TGeoRotation* rot[nCellsC];
137 TGeoCombiTrans* com[nCellsC];
138 TGeoCombiTrans* comCable[nCellsC];
142 TGeoCombiTrans* plateCom[nCellsC];
143 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
144 TGeoCompositeShape* plateCompositeShape =
new TGeoCompositeShape(
"plateCompositeShape", cPlateShapeString().c_str());
145 TGeoVolume* plateVol =
new TGeoVolume(
"plateVol", plateCompositeShape, Al);
148 nameTr = Form(
"0TR%i", itr + 1);
149 nameRot = Form(
"0Rot%i", itr + 1);
151 float ac1 = geometry.
tiltMCP(ic).X();
152 float bc1 = geometry.
tiltMCP(ic).Y();
153 float gc1 = geometry.
tiltMCP(ic).Z();
154 rot[ic] =
new TGeoRotation(nameRot.Data(), ac1, bc1, gc1);
155 LOG(
debug) <<
" rot geom " << ic <<
" " << ac1 <<
" " << bc1 <<
" " << gc1;
156 rot[ic]->RegisterYourself();
157 mPosModuleCx[ic] = geometry.
centerMCP(ic + nCellsA).X();
158 mPosModuleCy[ic] = geometry.
centerMCP(ic + nCellsA).Y();
159 mPosModuleCz[ic] = geometry.
centerMCP(ic + nCellsA).Z() - 80;
160 com[ic] =
new TGeoCombiTrans(mPosModuleCx[ic], mPosModuleCy[ic], mPosModuleCz[ic], rot[ic]);
161 TGeoHMatrix hm = *com[ic];
162 TGeoHMatrix* ph =
new TGeoHMatrix(hm);
163 stlinC->AddNode(ins, itr, ph);
166 LOG(
debug) <<
" C " << mPosModuleCx[ic] <<
" " << mPosModuleCy[ic];
169 comCable[ic] =
new TGeoCombiTrans(mPosModuleCx[ic], mPosModuleCy[ic], mPosModuleCz[ic] + mInStart[2] + 0.2 + 0.1, rot[ic]);
170 TGeoHMatrix hmCable = *comCable[ic];
171 TGeoHMatrix* phCable =
new TGeoHMatrix(hmCable);
172 stlinC->AddNode(cables, itr, comCable[ic]);
175 plateCom[ic] =
new TGeoCombiTrans(mPosModuleCx[ic], mPosModuleCy[ic], (mPosModuleCz[ic] - 3), rot[ic]);
176 TGeoHMatrix hmPlate = *plateCom[ic];
177 TGeoHMatrix* phPlate =
new TGeoHMatrix(hmPlate);
178 stlinC->AddNode(plateVol, itr, phPlate);
181 stlinC->AddNode(constructFrameCGeometry(), nCellsA + nCellsC + 1);
183 TGeoVolume* alice = gGeoManager->GetVolume(
"barrel");
185 alice->AddNode(stlinA, 1,
new TGeoTranslation(0, 30., zdetA + 0.63));
188 TGeoRotation* rotC =
new TGeoRotation(
"rotC", 90., 0., 90., 90., 180., 0.);
189 alice->AddNode(stlinC, 1,
new TGeoCombiTrans(0., 30., -zdetC, rotC));
198 LOG(
debug) <<
"Creating FIT optical geometry properties";
210 Float_t ptop[3] = {1.324, 1.324, 1.};
211 Double_t prfv[3] = {0.0002, 1.323, 1.};
212 Double_t prfh[3] = {1.323, 0.0002, 1.};
218 const double kWrapClearance = 1.e-4;
219 Float_t ptopref[3] = {
static_cast<Float_t>(ptop[0] + 2 * prfv[0] + kWrapClearance),
220 static_cast<Float_t>(ptop[1] + 2 * prfh[1] + kWrapClearance), 1.};
221 Float_t pmcp[3] = {2.949, 2.949, 0.66};
222 Float_t pmcpinner[3] = {2.749, 2.749, 0.1};
223 Float_t pmcpbase[3] = {2.949, 2.949, 0.675};
224 Float_t pmcpside[3] = {0.15, 2.949, 0.65};
225 Float_t pmcptopglass[3] = {2.949, 2.949, 0.1};
226 Float_t preg[3] = {1.324, 1.324, 0.005};
229 TGeoVolume*
top = gGeoManager->GetVolume(
"0TOP");
230 TVirtualMC::GetMC()->Gsvolu(
"0TRE",
"BOX",
getMediumID(
kAir), ptopref, 3);
231 TGeoVolume* topref = gGeoManager->GetVolume(
"0TRE");
233 TGeoVolume* rfv = gGeoManager->GetVolume(
"0RFV");
235 TGeoVolume* rfh = gGeoManager->GetVolume(
"0RFH");
238 TGeoVolume* cat = gGeoManager->GetVolume(
"0REG");
242 Int_t ntops = 0, nrfvs = 0, nrfhs = 0;
244 topref->AddNode(
top, 1,
new TGeoTranslation(0, 0, 0));
249 auto seat = [](
Float_t half, Double_t strip) {
return double(
half) + strip; };
250 double xinv = -seat(ptop[0], prfv[0]);
251 topref->AddNode(rfv, 1,
new TGeoTranslation(xinv, 0, 0));
252 xinv = seat(ptop[0], prfv[0]);
253 topref->AddNode(rfv, 2,
new TGeoTranslation(xinv, 0, 0));
254 double yinv = -seat(ptop[1], prfh[1]);
255 topref->AddNode(rfh, 1,
new TGeoTranslation(0, yinv, 0));
256 yinv = seat(ptop[1], prfh[1]);
257 topref->AddNode(rfh, 2,
new TGeoTranslation(0, yinv, 0));
264 const double zRadiatorCentre = -mInStart[2] + double(ptopref[2]);
265 const double zRadiatorBack = zRadiatorCentre + double(ptopref[2]);
266 const double zTopGlassCentre = zRadiatorBack + double(pmcptopglass[2]);
267 const double zTopGlassBack = zTopGlassCentre + double(pmcptopglass[2]);
268 const double zCathodeCentre = zTopGlassBack + double(preg[2]);
269 const double zCathodeBack = zCathodeCentre + double(preg[2]);
272 for (Int_t ix = 0; ix < 2; ix++) {
273 float xin = -mInStart[0] + 0.3 + (ix + 0.5) * 2 * ptopref[0];
274 for (Int_t iy = 0; iy < 2; iy++) {
275 float yin = -mInStart[1] + 0.3 + (iy + 0.5) * 2 * ptopref[1];
277 ins->AddNode(topref, ntops,
new TGeoTranslation(xin, yin, zRadiatorCentre));
278 LOG(
debug) <<
" n " << ntops <<
" x " << xin <<
" y " << yin <<
" z radiator " << zRadiatorCentre;
279 ins->AddNode(cat, ntops,
new TGeoTranslation(xin, yin, zCathodeCentre));
280 LOG(
debug) <<
" n " << ntops <<
" x " << xin <<
" y " << yin <<
" z cathod " << zCathodeCentre;
285 TGeoVolume* mcptop = gGeoManager->GetVolume(
"0MTO");
286 ins->AddNode(mcptop, 1,
new TGeoTranslation(0, 0, zTopGlassCentre));
288 TVirtualMC::GetMC()->Gsvolu(
"0MCP",
"BOX",
getMediumID(
kAir), pmcp, 3);
289 TGeoVolume* mcp = gGeoManager->GetVolume(
"0MCP");
290 ins->AddNode(mcp, 1,
new TGeoTranslation(0, 0, zCathodeBack +
double(pmcp[2])));
293 TGeoVolume* mcpside = gGeoManager->GetVolume(
"0MSI");
294 x = -pmcp[0] + pmcpside[0];
295 y = -pmcp[1] + pmcpside[1];
296 mcp->AddNode(mcpside, 1,
new TGeoTranslation(
x,
y, 0));
297 x = pmcp[0] - pmcpside[0];
298 y = pmcp[1] - pmcpside[1];
299 mcp->AddNode(mcpside, 2,
new TGeoTranslation(
x,
y, 0));
300 x = -pmcp[1] + pmcpside[1];
301 y = -pmcp[0] + pmcpside[0];
302 mcp->AddNode(mcpside, 3,
new TGeoCombiTrans(
x,
y, 0,
new TGeoRotation(
"R2", 90, 0, 0)));
303 x = pmcp[1] - pmcpside[1];
304 y = pmcp[0] - pmcpside[0];
305 mcp->AddNode(mcpside, 4,
new TGeoCombiTrans(
x,
y, 0,
new TGeoRotation(
"R2", 90, 0, 0)));
308 TGeoVolume* mcpbase = gGeoManager->GetVolume(
"0MBA");
309 z = -mInStart[2] + 2 * ptopref[2] + pmcptopglass[2] + 2 * pmcp[2] + pmcpbase[2];
310 ins->AddNode(mcpbase, 1,
new TGeoTranslation(0, 0,
z));
317 float pcableplane[3] = {20, 20, 0.25};
319 TVirtualMC::GetMC()->Gsvolu(
"0CAA",
"BOX",
getMediumID(
kAir), pcableplane, 3);
320 TGeoVolume* cableplane = gGeoManager->GetVolume(
"0CAA");
324 const float kBeamPipeHoleRadius = 3.;
325 new TGeoBBox(
"0CAAbox", pcableplane[0], pcableplane[1], pcableplane[2]);
326 new TGeoTube(
"0CAAhole", 0., kBeamPipeHoleRadius, pcableplane[2] + 0.1);
327 cableplane->SetShape(
new TGeoCompositeShape(
"0CAAshape",
"0CAAbox-0CAAhole"));
330 double xcell[24], ycell[24];
331 for (
int imcp = 0; imcp < 24; imcp++) {
332 xcell[na] = mPosModuleAx[imcp];
333 ycell[na] = mPosModuleAy[imcp];
335 cableplane->AddNode(vol, na,
new TGeoTranslation(xcell[na], ycell[na], 0));
340 Float_t pcablesextend[3] = {2, 15, 0.245};
341 Float_t pcablesextendsmall[3] = {3, 2, 0.245};
342 Float_t* ppcablesextend[] = {pcablesextend, pcablesextend, pcablesextendsmall, pcablesextendsmall};
344 double xcell_side[] = {-mStartA[0] + pcablesextend[0], mStartA[0] - pcablesextend[0], 0, 0};
345 double ycell_side[] = {0, 0, -mStartA[1] + pcablesextendsmall[1], mStartA[1] - pcablesextendsmall[1]};
347 for (
int icab = 0; icab < 4; icab++) {
348 const std::string volName = Form(
"CAB%2.i", 52 + icab);
349 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
" BOX",
getMediumID(
kCable), ppcablesextend[icab], 3);
350 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
351 cableplane->AddNode(vol, 1,
new TGeoTranslation(xcell_side[icab], ycell_side[icab], 0));
353 float zcableplane = mStartA[2] - pcableplane[2] - 3;
354 stl->AddNode(cableplane, 1,
new TGeoTranslation(0, 0, zcableplane));
363 int mcpcables[52] = {2, 1, 2, 1, 2,
379 double xcell[ncells], ycell[ncells], zcell[ncells];
380 float xsize[3] = {1.8, 1.8, 2.6};
381 float ysize[3] = {0.6, 1.7, 2.};
382 float zsize[3] = {0.1, 0.1, 0.1};
384 int ic = mcpcables[mod];
386 calblesize[0] = xsize[ic - 1];
387 calblesize[1] = ysize[ic - 1];
388 calblesize[2] = zsize[ic - 1];
389 const std::string volName = Form(
"CAB%2.i", mod);
390 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
"BOX",
getMediumID(
kCable), calblesize, 3);
391 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
392 LOG(
debug) <<
"C cables " << mod <<
" " << volName <<
" " << ic;
405 LOG(info) <<
"Add FT0 alignable volumes";
408 LOG(fatal) <<
"TGeoManager doesn't exist !";
412 TString volPath = Form(
"/cave_1/barrel_1");
414 TString volPathA = volPath + Form(
"/FT0A_1");
415 TString symNameA =
"FT0A";
416 LOG(info) << symNameA <<
" <-> " << volPathA;
417 if (!gGeoManager->SetAlignableEntry(symNameA.Data(), volPathA.Data())) {
418 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
421 TString volPathC = volPath + Form(
"/FT0C_1");
422 TString symNameC =
"FT0C";
423 LOG(info) << symNameC <<
" <-> " << volPathC;
424 if (!gGeoManager->SetAlignableEntry(symNameC.Data(), volPathC.Data())) {
425 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
427 TString volPathMod, symNameMod;
430 volPathMod = volPath + Form(
"/0MOD_%d", imod);
431 symNameMod = Form(
"0MOD_%d", imod);
432 if (!gGeoManager->SetAlignableEntry(symNameMod.Data(), volPathMod.Data())) {
433 LOG(fatal) << (Form(
"Alignable entry %s not created. Volume path %s not valid", symNameMod.Data(), volPathMod.Data()));
450TGeoVolume* Detector::constructFrameAGeometry()
453 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
454 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
457 TGeoVolumeAssembly* FT0_Frame =
new TGeoVolumeAssembly(
"FT0_Frame");
460 Double_t blockdX = 37.1;
461 Double_t blockdY = 36.85;
462 Double_t blockdZ = 6.95;
463 TGeoBBox* block =
new TGeoBBox(
"block", blockdX / 2, blockdY / 2, blockdZ / 2);
469 Double_t box1dX = 1.57;
470 Double_t box1dY = 6.55;
471 Double_t box1PosX = -(blockdX / 2 - box1dX / 2);
472 Double_t box1PosY = 0;
474 TGeoTranslation* box1Tr1 =
new TGeoTranslation(
"box1Tr1", box1PosX, box1PosY, 0);
475 box1Tr1->RegisterYourself();
476 TGeoTranslation* box1Tr2 =
new TGeoTranslation(
"box1Tr2", -box1PosX, -box1PosY, 0);
477 box1Tr2->RegisterYourself();
479 Double_t box2dX = 2.9;
480 Double_t box2dY = 15.1;
481 Double_t box2PosX = -(blockdX / 2 - box2dX / 2);
482 Double_t box2PosY = blockdY / 2 - box2dY / 2;
484 TGeoTranslation* box2Tr1 =
new TGeoTranslation(
"box2Tr1", box2PosX, box2PosY, 0);
485 box2Tr1->RegisterYourself();
486 TGeoTranslation* box2Tr2 =
new TGeoTranslation(
"box2Tr2", -box2PosX, -box2PosY, 0);
487 box2Tr2->RegisterYourself();
491 Double_t box3dX = 12.7;
493 Double_t box3dZ = 5.45;
494 Double_t box3PosX = -(blockdX / 2 - box2dX - box3dZ / 2);
495 Double_t box3PosY = blockdY / 2 - box3dY / 2;
496 Double_t box3PosZ = blockdZ / 2 - box3dZ / 2;
498 TGeoTranslation* box3Tr1 =
new TGeoTranslation(
"box3Tr1", box3PosX, box3PosY, box3PosZ);
499 box3Tr1->RegisterYourself();
500 TGeoTranslation* box3Tr2 =
new TGeoTranslation(
"box3Tr2", -box3PosX, -box3PosY, box3PosZ);
501 box3Tr2->RegisterYourself();
503 Double_t box4dX = 6.6;
504 Double_t box4dY = 1.67;
505 Double_t box4PosX = 0;
506 Double_t box4PosY = blockdY / 2 - box4dY / 2;
508 TGeoTranslation* box4Tr1 =
new TGeoTranslation(
"box4Tr1", box4PosX, box4PosY, 0);
509 box4Tr1->RegisterYourself();
510 TGeoTranslation* box4Tr2 =
new TGeoTranslation(
"box4Tr2", -box4PosX, -box4PosY, 0);
511 box4Tr2->RegisterYourself();
513 Double_t box5dX = 15;
515 Double_t box5PosX = blockdX / 2 - box5dX / 2;
516 Double_t box5PosY = blockdY / 2 - box5dY / 2;
518 TGeoTranslation* box5Tr1 =
new TGeoTranslation(
"box5Tr1", box5PosX, box5PosY, 0);
519 box5Tr1->RegisterYourself();
520 TGeoTranslation* box5Tr2 =
new TGeoTranslation(
"box5Tr2", -box5PosX, -box5PosY, 0);
521 box5Tr2->RegisterYourself();
525 Double_t box6dX = 2.9;
526 Double_t box6dY = 12.2;
527 Double_t box6dZ = 5.45;
528 Double_t box6PosX = blockdX / 2 - box6dX / 2;
529 Double_t box6PosY = blockdY / 2 - box5dY - box6dY / 2;
530 Double_t box6PosZ = blockdZ / 2 - box6dZ / 2;
532 TGeoTranslation* box6Tr1 =
new TGeoTranslation(
"box6Tr1", box6PosX, box6PosY, box6PosZ);
533 box6Tr1->RegisterYourself();
534 TGeoTranslation* box6Tr2 =
new TGeoTranslation(
"box6Tr2", -box6PosX, -box6PosY, box6PosZ);
535 box6Tr2->RegisterYourself();
541 Double_t cbox1dX = 7.175;
542 Double_t cbox1dY = 5.5;
543 Double_t cbox1Xoffset = 14.425;
544 Double_t cbox1PosX = -(blockdX / 2 - cbox1Xoffset - cbox1dX / 2);
545 Double_t cbox1PosY = 0;
546 TGeoBBox* cbox1 =
new TGeoBBox(
"cbox1", cbox1dX / 2, cbox1dY / 2, blockdZ / 2);
547 TGeoTranslation* cbox1Tr1 =
new TGeoTranslation(
"cbox1Tr1", cbox1PosX, cbox1PosY, 0);
548 cbox1Tr1->RegisterYourself();
549 TGeoTranslation* cbox1Tr2 =
new TGeoTranslation(
"cbox1Tr2", -cbox1PosX, -cbox1PosY, 0);
550 cbox1Tr2->RegisterYourself();
552 Double_t cbox2dX = 5.75;
554 Double_t cbox2dY = 6.575;
555 Double_t cbox2Yoffset = 14.425;
556 Double_t cbox2PosX = 0;
557 Double_t cbox2PosY = blockdY / 2 - cbox2Yoffset - cbox2dY / 2;
558 TGeoBBox* cbox2 =
new TGeoBBox(
"cbox2", cbox2dX / 2, cbox2dY / 2, blockdZ / 2);
559 TGeoTranslation* cbox2Tr1 =
new TGeoTranslation(
"cbox2Tr1", cbox2PosX, cbox2PosY, 0);
560 cbox2Tr1->RegisterYourself();
561 TGeoTranslation* cbox2Tr2 =
new TGeoTranslation(
"cbox2Tr2", -cbox2PosX, -cbox2PosY, 0);
562 cbox2Tr2->RegisterYourself();
569 Double_t gapBoxdX = 0.1;
570 Double_t gapBoxdY = blockdY / 2;
571 Double_t gapPosX = -(sPmtSide / 2 + sEps + gapBoxdX / 2);
572 Double_t gapPosY = blockdY / 4;
573 TGeoBBox* gapBox =
new TGeoBBox(
"gapBox", gapBoxdX / 2, gapBoxdY / 2, blockdZ / 2);
574 TGeoTranslation* gapBoxTr1 =
new TGeoTranslation(
"gapBoxTr1", gapPosX, gapPosY, 0);
575 gapBoxTr1->RegisterYourself();
576 TGeoTranslation* gapBoxTr2 =
new TGeoTranslation(
"gapBoxTr2", -gapPosX, -gapPosY, 0);
577 gapBoxTr2->RegisterYourself();
581 std::string frameACompositeString =
"block ";
582 frameACompositeString +=
"- box1:box1Tr1 - box1:box1Tr2 ";
583 frameACompositeString +=
"- box2:box2Tr1 - box2:box2Tr2 ";
584 frameACompositeString +=
"- box3:box3Tr1 - box3:box3Tr2 ";
585 frameACompositeString +=
"- box4:box4Tr1 - box4:box4Tr2 ";
586 frameACompositeString +=
"- box5:box5Tr1 - box5:box5Tr2 ";
587 frameACompositeString +=
"- box6:box6Tr1 - box6:box6Tr2 ";
588 frameACompositeString +=
"- cbox1:cbox1Tr1 - cbox1:cbox1Tr2 ";
589 frameACompositeString +=
"- cbox2:cbox2Tr1 - cbox2:cbox2Tr2 ";
590 frameACompositeString +=
"- gapBox:gapBoxTr1 - gapBox:gapBoxTr2";
600 Double_t coverPlatedZ = 0.2;
601 Double_t fiberPlatedZ = 0.5;
604 Double_t opticalFiberHeaddY = 0.52;
605 Double_t opticalFiberHeaddX = 1.142;
611 Double_t fh1TopPosX = -1.6;
612 Double_t fh1TopPosY = 1.325;
613 Double_t fh1BotPosX = 1.555;
614 Double_t fh1BotPosY = 1.249;
615 Double_t fh1BotAngle = 16;
619 Double_t fh2TopPosX = -1.563;
620 Double_t fh2TopPosY = 1.4625;
621 Double_t fh2TopAngle = 60;
623 Double_t fh2BotPosX = 1.084;
624 Double_t fh2BotPosY = 1.186;
625 Double_t fh2BotAngle = -30;
628 TGeoBBox* coverPlate =
new TGeoBBox(
"coverPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, coverPlatedZ / 2);
629 TGeoBBox* fiberPlate =
new TGeoBBox(
"fiberPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, fiberPlatedZ / 2);
630 TGeoBBox* opticalFiberHead =
new TGeoBBox(
"opticalFiberHead", opticalFiberHeaddX / 2, opticalFiberHeaddY / 2, fiberPlatedZ / 2);
633 TGeoTranslation* coverPlateTr =
new TGeoTranslation(
"coverPlateTr", 0, 0, fiberPlatedZ / 2 + coverPlatedZ / 2);
634 coverPlateTr->RegisterYourself();
635 TGeoTranslation* fh1TopTr1 =
new TGeoTranslation(
"fh1TopTr1", fh1TopPosX, fh1TopPosY, 0);
636 fh1TopTr1->RegisterYourself();
637 TGeoTranslation* fh1TopTr2 =
new TGeoTranslation(
"fh1TopTr2", fh1TopPosX, -fh1TopPosY, 0);
638 fh1TopTr2->RegisterYourself();
639 TGeoCombiTrans* fh1BotTr1 =
new TGeoCombiTrans(
"fh1BotTr1", fh1BotPosX, fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot1", fh1BotAngle, 0, 0));
640 fh1BotTr1->RegisterYourself();
641 TGeoCombiTrans* fh1BotTr2 =
new TGeoCombiTrans(
"fh1BotTr2", fh1BotPosX, -fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot2", -fh1BotAngle, 0, 0));
642 fh1BotTr2->RegisterYourself();
643 TGeoCombiTrans* fh2TopTr1 =
new TGeoCombiTrans(
"fh2TopTr1", fh2TopPosX, fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot1", fh2TopAngle + 90, 0, 0));
644 fh2TopTr1->RegisterYourself();
645 TGeoCombiTrans* fh2TopTr2 =
new TGeoCombiTrans(
"fh2TopTr2", fh2TopPosX, -fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot2", -fh2TopAngle - 90, 0, 0));
646 fh2TopTr2->RegisterYourself();
647 TGeoCombiTrans* fh2BotTr1 =
new TGeoCombiTrans(
"fh2BotTr1", fh2BotPosX, fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot1", -fh2BotAngle, 0, 0));
648 fh2BotTr1->RegisterYourself();
649 TGeoCombiTrans* fh2BotTr2 =
new TGeoCombiTrans(
"fh2BotTr2", fh2BotPosX, -fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot2", fh2BotAngle, 0, 0));
650 fh2BotTr2->RegisterYourself();
653 std::string outerPlateGroupString =
"fiberPlate ";
654 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr1 ";
655 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr2 ";
656 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr1 ";
657 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr2 ";
658 outerPlateGroupString +=
"+ coverPlate:coverPlateTr";
661 TGeoCompositeShape* outerPlateGroup =
new TGeoCompositeShape(
"outerPlateGroup", outerPlateGroupString.c_str());
664 std::string innerPlateGroupString =
"fiberPlate ";
665 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr1 ";
666 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr2 ";
667 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr1 ";
668 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr2 ";
669 innerPlateGroupString +=
"+ coverPlate:coverPlateTr";
672 TGeoCompositeShape* innerPlateGroup =
new TGeoCompositeShape(
"innerPlateGroup", innerPlateGroupString.c_str());
677 Double_t backPlanedZ = 0.25;
678 Double_t socketdZ = blockdZ - backPlanedZ;
681 TGeoVolume* socket = gGeoManager->MakeBox(
"Socket", Vacuum, sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, socketdZ / 2);
685 Double_t rotAngle[
Geometry::NCellsA] = {0, 0, -90, -90, -90, 0, 0, -90, -90, -90, 0, 0, 180, 180, 90, 90, 90, 180, 180, 90, 90, 90, 180, 180};
688 TString nameTrSocket;
690 TString nameTrPlateGroup;
697 nameTrSocket = Form(
"trSocket%i", itr + 1);
698 float z = -backPlanedZ / 4.0;
699 trSocket[itr] =
new TGeoTranslation(nameTrSocket.Data(), mPosModuleAx[itr], mPosModuleAy[itr],
z);
700 trSocket[itr]->RegisterYourself();
701 frameACompositeString +=
"- Socket:";
702 frameACompositeString += nameTrSocket.Data();
704 nameTrPlateGroup = Form(
"trPlateGroup%i", itr + 1);
705 namePGRot = Form(
"pgRot%i", itr + 1);
706 float z2 = -blockdZ / 2 + (coverPlatedZ + fiberPlatedZ) / 2;
707 trPlateGroup[itr] =
new TGeoCombiTrans(nameTrPlateGroup.Data(), mPosModuleAx[itr], mPosModuleAy[itr], z2,
new TGeoRotation(namePGRot.Data(), rotAngle[itr], 0, 0));
708 trPlateGroup[itr]->RegisterYourself();
710 if (itr == 0 || itr == 2 || itr == 3 || itr == 4 || itr == 5 || itr == 10 || itr == 13 || itr == 18 || itr == 19 || itr == 20 || itr == 21 || itr == 23) {
711 frameACompositeString +=
" + outerPlateGroup:";
712 frameACompositeString += nameTrPlateGroup.Data();
713 frameACompositeString +=
" ";
715 frameACompositeString +=
" + innerPlateGroup:";
716 frameACompositeString += nameTrPlateGroup.Data();
717 frameACompositeString +=
" ";
722 TGeoVolume* frameA =
new TGeoVolume(
"frameA",
new TGeoCompositeShape(
"frameA", frameACompositeString.c_str()), Al);
725 FT0_Frame->AddNode(frameA, 1);
734TGeoVolume* Detector::constructFrameCGeometry()
738 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
739 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
740 static constexpr Double_t sFrameZC = 5.5632;
741 static constexpr Double_t frameHeightC = 2.5;
744 static constexpr Double_t sensShift = 0.5;
745 static constexpr Double_t sQuartzRadiatorZC = 1.94360;
746 static constexpr Double_t sQuartzHeightC = (-sFrameZC / 2 + sQuartzRadiatorZC / 2);
747 static constexpr Double_t sPmtZC = 3.600;
748 static constexpr Double_t sPmtHeightC = (sFrameZC / 2 - sPmtZC / 2);
756 Float_t rMax = rMin + sFrameZC;
761 Float_t pinstart[3] = {2.9491, 2.9491, 2.5};
762 Float_t pstartC[3] = {20., 20, 5};
765 Double_t xCorn = multCorn * (-14.75272569);
766 Double_t yCorn = multCorn * (14.9043284);
767 Double_t zCorn = 79.27306024;
769 Double_t xCorn2 = -xCorn;
770 Double_t yCorn2 = yCorn;
771 Double_t zCorn2 = zCorn;
773 Double_t acCorn = TMath::ATan(yCorn / xCorn) - TMath::Pi() / 2 + 2 * TMath::Pi();
774 Double_t bcCorn = TMath::ACos(zCorn / crad);
775 Double_t gcCorn = -1 * acCorn;
779 Double_t flopsErr = 0.00001;
783 Double_t errPMTZ = 10 * sEps;
784 Double_t errPMTXY = 0.02;
785 Double_t errQrdZ = 0.143 + 0.22;
786 Double_t errQrdXY = 0.35;
793 TGeoSphere* sphere1 =
new TGeoSphere(
"sphere1", rMin, rMax, tMin, tMax, pMin, pMax);
794 TGeoSphere* sphere2 =
new TGeoSphere(
"sphere2", rMin - sweep, rMax + sweep, tMin, tMax, pMin, pMax);
795 TGeoSphere* sphere3 =
new TGeoSphere(
"sphere3", rMin, rMin + backPlateZ, tMin, tMax, pMin, pMax);
796 TGeoSphere* sphere4 =
new TGeoSphere(
"sphere4", rMin - sweep, rMax + backPlateZ + sweep, tMin, tMax, pMin, pMax);
798 TGeoBBox* insSeat =
new TGeoBBox(
"insSeat", pinstart[0] * 2, pinstart[1] * 2, pinstart[2] * 2);
801 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
802 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
803 sQuartzRadiatorZC / 2 + sEps + errQrdZ);
806 sPmtSide / 2 + sEps + errPMTXY,
807 sPmtSide / 2 + sEps + errPMTXY,
808 sPmtZ / 2 + sEps + errPMTZ);
810 sCornerRadius / 2 - flopsErr,
811 sCornerRadius / 2 - flopsErr,
817 TGeoRotation* rot1 =
new TGeoRotation(
"rot1", 90, 0, 0);
818 rot1->RegisterYourself();
819 TGeoCombiTrans* rotTr1 =
new TGeoCombiTrans(
"rotTr1", -20, -1, -5, rot1);
820 rotTr1->RegisterYourself();
822 TGeoRotation* rot2 =
new TGeoRotation(
"rot2", -90, 0, 0);
823 rot2->RegisterYourself();
824 TGeoCombiTrans* rotTr2 =
new TGeoCombiTrans(
"rotTr2", 20, -1, -5, rot2);
825 rotTr2->RegisterYourself();
827 TGeoRotation* rot3 =
new TGeoRotation(
"rot3", 0, 0, 0);
828 rot3->RegisterYourself();
829 TGeoCombiTrans* rotTr3 =
new TGeoCombiTrans(
"rotTr3", 0, 20, -5, rot3);
830 rotTr3->RegisterYourself();
832 TGeoTranslation* centerTrans =
new TGeoTranslation(
"centerTrans", 0, 0, 85);
833 centerTrans->RegisterYourself();
835 TGeoRotation* reflectC1 =
new TGeoRotation(
"reflectC1", 0, 0, 0);
836 reflectC1->ReflectX(
true);
837 reflectC1->ReflectY(
true);
838 reflectC1->RegisterYourself();
840 TGeoRotation* rotCorners =
new TGeoRotation(
"rotCorners", acCorn, bcCorn, gcCorn);
841 rotCorners->RegisterYourself();
843 TGeoCombiTrans* comCorners =
new TGeoCombiTrans(
"comCorners", xCorn, yCorn, zCorn, rotCorners);
844 comCorners->RegisterYourself();
846 TGeoCombiTrans* comCorners2 =
new TGeoCombiTrans(
"comCorners2", xCorn2, yCorn2, zCorn2, rotCorners);
847 comCorners2->RegisterYourself();
850 std::string shellString =
"";
851 shellString +=
"sphere1";
852 shellString +=
"- sphere2:rotTr1";
853 shellString +=
"- sphere2:rotTr2";
854 shellString +=
"- sphere2:rotTr3";
855 shellString +=
"- insSeat:centerTrans";
856 shellString +=
"- framecornerBox:comCorners";
857 shellString +=
"- framecornerBox:comCorners2";
860 std::string backPlateString =
"";
861 backPlateString +=
"sphere3";
862 backPlateString +=
"- sphere4:rotTr1";
863 backPlateString +=
"- sphere4:rotTr2";
864 backPlateString +=
"- sphere4:rotTr3";
865 backPlateString +=
"- insSeat:centerTrans";
866 backPlateString +=
"- framecornerBox:comCorners";
867 backPlateString +=
"- framecornerBox:comCorners2";
871 static constexpr Double_t xi[NCellsC] = {-15.038271418735729, 15.038271418735729, -15.003757581112167, 15.003757581112167, -9.02690018974363, 9.02690018974363, -9.026897413747076, 9.026897413747076, -9.026896531935773, 9.026896531935773, -3.0004568618531313, 3.0004568618531313, -3.0270795197907225, 3.0270795197907225, 3.0003978432927543, -3.0003978432927543, 3.0270569670429572, -3.0270569670429572, 9.026750365564254, -9.026750365564254, 9.026837450695885, -9.026837450695885, 9.026849243816981, -9.026849243816981, 15.038129472387304, -15.038129472387304, 15.003621961057961, -15.003621961057961};
872 static constexpr Double_t yi[NCellsC] = {3.1599494336464455, -3.1599494336464455, 9.165191680982874, -9.165191680982874, 3.1383331772537426, -3.1383331772537426, 9.165226363918643, -9.165226363918643, 15.141616002932361, -15.141616002932361, 9.16517861649866, -9.16517861649866, 15.188854859073416, -15.188854859073416, 9.165053319552113, -9.165053319552113, 15.188703787345304, -15.188703787345304, 3.138263189805292, -3.138263189805292, 9.165104089644917, -9.165104089644917, 15.141494417823818, -15.141494417823818, 3.1599158563428644, -3.1599158563428644, 9.165116302773846, -9.165116302773846};
874 Double_t zi[NCellsC];
875 for (Int_t ic = 0; ic < NCellsC; ic++) {
876 zi[ic] = TMath::Sqrt(TMath::Power(crad, 2) - TMath::Power(xi[ic], 2) - TMath::Power(yi[ic], 2));
880 Double_t ac[NCellsC],
bc[NCellsC], gc[NCellsC];
881 for (Int_t
i = 0;
i < NCellsC;
i++) {
882 ac[
i] = TMath::ATan(yi[
i] / xi[
i]) - TMath::Pi() / 2 + 2 * TMath::Pi();
884 bc[
i] = TMath::ACos(zi[
i] / crad);
886 bc[
i] = -1 * TMath::ACos(zi[
i] / crad);
890 Double_t xc2[NCellsC], yc2[NCellsC], zc2[NCellsC];
894 Double_t rcomp = crad + pstartC[2] / 2.0;
895 for (Int_t
i = 0;
i < NCellsC;
i++) {
897 xc2[
i] = rcomp * TMath::Cos(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
898 yc2[
i] = rcomp * TMath::Sin(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
899 zc2[
i] = rcomp * TMath::Cos(
bc[
i]);
902 ac[
i] *= 180 / TMath::Pi();
903 bc[
i] *= 180 / TMath::Pi();
907 Double_t rmag = sqrt(xc2[0] * xc2[0] + yc2[0] * yc2[0] + zc2[0] * zc2[0]);
909 Double_t scalePMT = (rmag + (frameHeightC / 2.0) - (sPmtHeightC / 2)) / rmag;
910 Double_t scaleQrad = (rmag + (frameHeightC / 2.0) - sPmtHeightC - (sQuartzRadiatorZC / 2.0)) / rmag;
912 Double_t xPMT[NCellsC];
913 Double_t yPMT[NCellsC];
914 Double_t zPMT[NCellsC];
916 Double_t xQrad[NCellsC];
917 Double_t yQrad[NCellsC];
918 Double_t zQrad[NCellsC];
920 Double_t rotC[NCellsC];
921 Double_t comC[NCellsC];
923 for (Int_t
i = 0;
i < NCellsC;
i++) {
925 xPMT[
i] = scalePMT * xc2[
i];
926 yPMT[
i] = scalePMT * yc2[
i];
927 zPMT[
i] = scalePMT * zc2[
i];
930 xQrad[
i] = scaleQrad * xc2[
i];
931 yQrad[
i] = scaleQrad * yc2[
i];
932 zQrad[
i] = scaleQrad * zc2[
i];
937 TString nameComQuartz;
938 TString nameComPlates;
941 for (Int_t itr = NCellsA; itr < NCellsA + NCellsC; itr++) {
942 nameRot = Form(
"0Rot%i", itr + 1);
943 int ic = itr - NCellsA;
944 nameComPMT = Form(
"0ComPMT%i", ic + 1);
945 nameComQuartz = Form(
"0ComQuartz%i", ic + 1);
950 TGeoRotation* rotC =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
951 rotC->RegisterYourself();
953 TGeoCombiTrans* comC =
new TGeoCombiTrans(nameComC.Data(), xc2[ic], yc2[ic], zc2[ic], rotC);
954 comC->RegisterYourself();
956 TGeoRotation* rotPMT =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
957 rotPMT->RegisterYourself();
959 TGeoCombiTrans* comPMT =
new TGeoCombiTrans(nameComPMT.Data(),
962 comPMT->RegisterYourself();
964 TGeoRotation* rotQuartz =
new TGeoRotation(nameRot.Data(),
965 ac[ic],
bc[ic], gc[ic]);
966 rotQuartz->RegisterYourself();
968 TGeoCombiTrans* comQuartz =
new TGeoCombiTrans(nameComQuartz.Data(),
969 xQrad[ic], yQrad[ic],
970 zQrad[ic] - (sQuartzRadiatorZC / 2 + 3 * sEps),
972 comQuartz->RegisterYourself();
974 TGeoRotation* rotPlates =
new TGeoRotation(nameRot.Data(),
975 ac[ic],
bc[ic], gc[ic]);
976 rotPlates->RegisterYourself();
977 TGeoCombiTrans* comPlates =
new TGeoCombiTrans(nameComPlates.Data(),
978 xQrad[ic], yQrad[ic],
981 comPlates->RegisterYourself();
984 std::string pmtCombiString =
"";
985 pmtCombiString +=
"- ";
986 pmtCombiString +=
"pmtBoxSeat:";
987 pmtCombiString += nameComPMT.Data();
988 shellString += pmtCombiString;
991 std::string quartzCombiString =
"";
992 quartzCombiString +=
"- ";
993 quartzCombiString +=
"quartzRadiatorSeat:";
994 quartzCombiString += nameComQuartz.Data();
995 shellString += quartzCombiString;
1000 TGeoCompositeShape* shellCompShape =
new TGeoCompositeShape(
"shellCompShape", shellString.c_str());
1002 TGeoVolume* shellVol =
new TGeoVolume(
"shellVol", shellCompShape, Al);
1005 TGeoVolumeAssembly* FT0_C_Frame =
new TGeoVolumeAssembly(
"FT0_C_Frame");
1008 TGeoTranslation* shellTr1 =
new TGeoTranslation(
"shellTr1", 0, 0, -80);
1009 shellTr1->RegisterYourself();
1011 TGeoCombiTrans* shellTr2 =
new TGeoCombiTrans(
"shellTr2", 0, 0, -80, reflectC1);
1012 shellTr2->RegisterYourself();
1014 FT0_C_Frame->AddNode(shellVol, 1, shellTr1);
1015 FT0_C_Frame->AddNode(shellVol, 2, shellTr2);
1017 TGeoTranslation* backPlateTr1 =
new TGeoTranslation(
"backPlateTr1", 0, 0, -74);
1018 backPlateTr1->RegisterYourself();
1020 TGeoCombiTrans* backPlateTr2 =
new TGeoCombiTrans(
"backPlateTr2", 0, 0, -74, reflectC1);
1021 backPlateTr2->RegisterYourself();
1023 TGeoCompositeShape* backPlateShape =
new TGeoCompositeShape(
"backPlateShape", backPlateString.c_str());
1024 TGeoVolume* backPlateVol =
new TGeoVolume(
"backPlateVol", backPlateShape, Al);
1026 FT0_C_Frame->AddNode(backPlateVol, 3, backPlateTr1);
1027 FT0_C_Frame->AddNode(backPlateVol, 4, backPlateTr2);
1032std::string Detector::cPlateShapeString()
1034 Double_t prismHeight = 0.3895;
1035 Double_t prismSide = 5.9;
1036 Double_t radCurve = 81.9469;
1037 Double_t delHeight = radCurve * (1.0 - TMath::Sqrt(1.0 - 0.5 * TMath::Power(prismSide / radCurve, 2.0)));
1040 Double_t heightBase = prismHeight + delHeight;
1041 Double_t sliceSide = 5.3;
1042 Double_t heightBaseBox = 2 * heightBase;
1043 Double_t totalHeight = 0.5;
1044 Double_t sliceHeight = 0.5 - heightBase;
1047 Double_t cableHoleWidth = 0.3503;
1048 Double_t cableHoleLength = 0.9003;
1049 Double_t cableHoleDepth = 1;
1054 Double_t sHolesBottomEdge = 1.585;
1055 Double_t sHolesTopEdge = 0.515;
1056 Double_t sHolesAvgTopBottom = (sHolesBottomEdge + sHolesTopEdge) / 2.0;
1057 Double_t sHolesUpFromCenter = ((sliceSide / 2.0) - sHolesAvgTopBottom);
1059 Double_t sHolesFarEdge = 1.585;
1060 Double_t sHolesNearEdge = 1.065;
1061 Double_t sHolesAvgNearFar = (sHolesFarEdge + sHolesNearEdge) / 2.0;
1062 Double_t sHolesLateralFromCenter = ((sliceSide / 2.0) - sHolesAvgNearFar);
1065 TGeoBBox*
box =
new TGeoBBox(
"BASE", prismSide / 2.0, heightBaseBox / 2.0, prismSide / 2.0);
1068 TGeoBBox* slice =
new TGeoBBox(
"SLICE", sliceSide / 2.0, heightBaseBox / 2.0, sliceSide / 2.0);
1069 TGeoBBox* cableHole =
new TGeoBBox(
"CABLE", cableHoleLength / 2.0, cableHoleDepth / 2.0, cableHoleWidth / 2.0);
1070 TGeoBBox* cableHole2 =
new TGeoBBox(
"CABLE2", cableHoleWidth / 2.0, cableHoleLength / 2.0, cableHoleDepth / 2.0);
1072 TGeoSphere* baseShape =
new TGeoSphere(
"BASE_SUBTRACTION", radCurve, radCurve + 5.0, 80, 100, 80, 100);
1074 TGeoTranslation* rTrans =
new TGeoTranslation(
"rTrans", 0, radCurve, 0);
1075 rTrans->RegisterYourself();
1077 TGeoTranslation* rBackTrans =
new TGeoTranslation(
"rBackTrans", 0, -1.0 * radCurve, 0);
1078 rBackTrans->RegisterYourself();
1080 TGeoTranslation* subSliceTrans =
new TGeoTranslation(
"subSliceTrans", 0, (heightBaseBox / 2.0) + sliceHeight, 0);
1081 subSliceTrans->RegisterYourself();
1083 TGeoTranslation* sHolesTopLeftTrans =
new TGeoTranslation(
"sHolesTopLeftTrans", sHolesUpFromCenter, 0, sHolesLateralFromCenter);
1084 sHolesTopLeftTrans->RegisterYourself();
1086 TGeoTranslation* sHolesTopRightTrans =
new TGeoTranslation(
"sHolesTopRightTrans", sHolesUpFromCenter, 0, -1.0 * sHolesLateralFromCenter);
1087 sHolesTopRightTrans->RegisterYourself();
1089 TGeoTranslation* testTrans =
new TGeoTranslation(
"testTrans", 0.1, 0.1, 0);
1090 testTrans->RegisterYourself();
1092 TGeoRotation* switchToZ =
new TGeoRotation(
"switchToZ", 90, 90, 0);
1093 switchToZ->RegisterYourself();
1095 TGeoRotation* rotateHolesLeft =
new TGeoRotation(
"rotateHolesLeft", 345, 0, 0);
1096 rotateHolesLeft->RegisterYourself();
1098 TGeoRotation* rotateHolesRight =
new TGeoRotation(
"rotatetHolesRight", 15, 0, 0);
1099 rotateHolesRight->RegisterYourself();
1102 TGeoCombiTrans* rHolesBottomLeftTrans =
new TGeoCombiTrans(
"rHolesBottomLeftTrans", -1.0 * sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesLeft);
1103 rHolesBottomLeftTrans->RegisterYourself();
1105 TGeoCombiTrans* rHolesBottomRightTrans =
new TGeoCombiTrans(
"rHolesBottomRightTrans", sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesRight);
1106 rHolesBottomRightTrans->RegisterYourself();
1108 std::string plateString =
" ";
1109 plateString +=
"(((BASE:rTrans";
1110 plateString +=
"- BASE_SUBTRACTION)";
1111 plateString +=
"+ (SLICE:rTrans))";
1112 plateString +=
":rBackTrans";
1113 plateString +=
"- BASE:subSliceTrans";
1114 plateString +=
"- (CABLE:sHolesTopLeftTrans)";
1115 plateString +=
"- (CABLE:sHolesTopRightTrans))";
1116 plateString +=
":switchToZ";
1117 plateString +=
"- (CABLE2:rHolesBottomLeftTrans)";
1118 plateString +=
"- (CABLE2:rHolesBottomRightTrans)";
1129 Int_t volID =
fMC->CurrentVolID(copy);
1130 if (
fMC->IsTrackEntering() && !
fMC->IsNewTrack() &&
fMC->TrackCharge() != 0 && volID == mTOPVolID) {
1132 if (o2stack->GetCurrentTrackNumber() != mTrackRefLastTrackID) {
1133 mTrackRefLastTrackID = o2stack->GetCurrentTrackNumber();
1139 Int_t quadrant, mcp;
1140 if (
fMC->IsTrackEntering()) {
1142 fMC->TrackPosition(
x,
y,
z);
1143 fMC->CurrentVolID(quadrant);
1144 fMC->CurrentVolOffID(1, mcp);
1145 float time =
fMC->TrackTime() * 1.0e9;
1146 int trackID =
stack->GetCurrentTrackNumber();
1147 int detID = mSim2LUT[4 * mcp + quadrant - 1];
1148 int iPart =
fMC->TrackPid();
1149 if (
fMC->TrackCharge() && volID == mREGVolID) {
1152 if (iPart == 50000050) {
1153 float etot =
fMC->Etot();
1154 float enDep =
fMC->Edep();
1155 Int_t parentID =
stack->GetCurrentTrack()->GetMother(0);
1156 if (volID == mTOPVolID) {
1161 mTrackIdTop = trackID;
1164 if (volID == mMTOVolID) {
1165 if (trackID != mTrackIdTop) {
1170 mTrackIdMCPtop = trackID;
1174 if (volID == mREGVolID) {
1175 if (trackID != mTrackIdTop && trackID != mTrackIdMCPtop) {
1180 if (trackID == mTrackIdTop || trackID == mTrackIdMCPtop) {
1193 mHits->emplace_back(
x,
y,
z,
time, energy, trackId, detId);
1201 return &(mHits->back());
1220 mTrackRefLastTrackID = -1;
1222 mTrackIdMCPtop = -1;
1235 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
1236 Float_t zAir[4] = {6., 7., 8., 18.};
1237 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
1241 Float_t aglass[2] = {28.0855, 15.9994};
1242 Float_t zglass[2] = {14., 8.};
1255 Float_t aCeramic[2] = {26.981539, 15.9994};
1256 Float_t zCeramic[2] = {13., 8.};
1257 Float_t wCeramic[2] = {2., 3.};
1261 const Int_t nCeramicNice = 3;
1262 Float_t aCeramicNicel[3] = {26.981539, 15.9994, 58.6934};
1263 Float_t zCeramicNicel[3] = {13., 8., 28};
1264 Float_t wCeramicNicel[3] = {0.2, 0.3, 0.5};
1265 Float_t denscerCeramicNickel = 5.6;
1269 const Int_t nPlast = 4;
1270 Float_t aPlast[nPlast] = {1.00784, 12.0107, 15.999, 63.54};
1271 Float_t zPlast[nPlast] = {1, 6, 8, 29};
1272 Float_t wPlast[nPlast] = {0.08, 0.53, 0.22, 0.17};
1273 const Float_t denCable = 3.66;
1281 Material(11,
"Aliminium$", 26.98, 13.0, 2.7, 8.9, 999);
1282 Mixture(1,
"Vacuum$", aAir, zAir, dAir1, 4, wAir);
1283 Mixture(2,
"Air$", aAir, zAir, dAir, 4, wAir);
1284 Mixture(4,
"MCP glass $", aglass, zglass, dglass_mcp, -2, wglass);
1285 Mixture(24,
"Radiator Optical glass$", aglass, zglass, dglass, -2, wglass);
1286 Mixture(3,
"Ceramic$", aCeramic, zCeramic, denscer, -2, wCeramic);
1287 Mixture(23,
"CablePlasticCooper$", aPlast, zPlast, denCable, 4, wPlast);
1288 Mixture(25,
"MCPwalls $", aCeramicNicel, zCeramicNicel, denscerCeramicNickel, 3, wCeramicNicel);
1290 Medium(1,
"Air$", 2, 0, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1291 Medium(3,
"Vacuum$", 1, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1292 Medium(4,
"Ceramic$", 3, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1293 Medium(6,
"Glass$", 4, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1294 Medium(15,
"Aluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1295 Medium(17,
"OptAluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1296 Medium(16,
"OpticalGlass$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .01);
1297 Medium(19,
"OpticalGlassCathode$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1299 Medium(23,
"Cables$", 23, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1300 Medium(25,
"MCPWalls", 25, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1308 const char* aliceO2env = std::getenv(
"O2_ROOT");
1310 inputDir = aliceO2env;
1312 inputDir +=
"/share/Detectors/FT0/files/";
1314 TString optPropPath = inputDir +
"quartzOptProperties.txt";
1315 gSystem->ExpandPathName(optPropPath);
1320 LOG(
error) <<
"Could not read FIT optical properties " <<
result <<
" " << optPropPath.Data();
1323 Int_t nBins = mPhotonEnergyD.size();
1325 mPMTeff =
new TGraph(nBins, &(mPhotonEnergyD[0]), &(mQuantumEfficiency[0]));
1331 TVirtualMC::GetMC()->SetCerenkov(
getMediumID(
kOpGlass), nBins, &(mPhotonEnergyD[0]), &(mAbsorptionLength[0]),
1332 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1334 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1337 TVirtualMC::GetMC()->DefineOpSurface(
"surfRd", kUnified, kDielectric_dielectric, kPolishedbackpainted, 0.);
1338 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEfficMet[0]));
1339 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflMet[0]));
1340 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder0",
"0TOP", 1,
"0RFV", 1,
"surfRd");
1341 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder1",
"0TOP", 1,
"0RFH", 1,
"surfRd");
1342 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder2",
"0TOP", 1,
"0RFV", 2,
"surfRd");
1343 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder3",
"0TOP", 1,
"0RFH", 2,
"surfRd");
1345 TVirtualMC::GetMC()->DefineOpSurface(
"surFrontBWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1346 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1347 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1348 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderFrontBWindow",
"0REG", 1,
"0MTO", 1,
"surFrontBWindow");
1350 TVirtualMC::GetMC()->DefineOpSurface(
"surBackFrontWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1351 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1352 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1353 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderBackFrontWindow",
"0TOP", 1,
"0MTO", 1,
"surBackFrontWindow");
1358 for (Int_t
i = 0;
i < mPhotonEnergyD.size();
i++) {
1359 mReflBlackPaper.push_back(0.);
1360 mEffBlackPaper.push_back(0);
1361 mAbsBlackPaper.push_back(1);
1363 mReflFrontWindow.push_back(0.01);
1364 mEffFrontWindow.push_back(1);
1365 mRindexFrontWindow.push_back(1);
1367 mRindexAir.push_back(1.);
1368 mAbsorAir.push_back(0.3);
1369 mRindexCathodeNext.push_back(1);
1371 mAbsorbCathodeNext.push_back(1);
1372 mEfficMet.push_back(0);
1373 mRindexMet.push_back(1);
1374 mReflMet.push_back(1);
1381 float eff = mPMTeff->Eval(energy);
1392 std::ifstream infile;
1393 infile.open(filePath.c_str());
1394 LOG(info) <<
" file " << filePath.c_str();
1396 if (infile.fail() ==
true) {
1401 std::string comment;
1402 if (!getline(infile, comment)) {
1403 LOG(
error) <<
"Error opening ascii file (it is probably a folder!): " << filePath.c_str();
1406 getline(infile, comment);
1411 if (nLines < 0 || nLines > 1e4) {
1415 getline(infile, comment);
1416 getline(infile, comment);
1421 getline(infile, sLine);
1422 while (!infile.eof()) {
1423 if (iLine >= nLines) {
1427 std::stringstream ssLine(sLine);
1432 mPhotonEnergyD.push_back(energy);
1434 Double_t absorption;
1435 ssLine >> absorption;
1436 mAbsorptionLength.push_back(absorption);
1438 Double_t refraction;
1439 ssLine >> refraction;
1440 mRefractionIndex.push_back(refraction);
1442 Double_t efficiency;
1443 ssLine >> efficiency;
1444 mQuantumEfficiency.push_back(efficiency);
1445 if (!(ssLine.good() || ssLine.eof())) {
1450 getline(infile, sLine);
1453 if (iLine != mPhotonEnergyD.size()) {
1459 LOG(info) <<
"Optical properties taken from the file: " << filePath.c_str() <<
" Number of lines read: " << iLine;
1466 std::string inputDir;
1467 const char* aliceO2env = std::getenv(
"O2_ROOT");
1469 inputDir = aliceO2env;
1471 inputDir +=
"/share/Detectors/FT0/files/";
1473 TString indPath = inputDir +
"Sim2DataChannels.txt";
1474 gSystem->ExpandPathName(indPath);
1476 std::ifstream infile;
1477 infile.open(indPath.Data());
1478 LOG(info) <<
" file open " << indPath.Data();
1480 if (infile.fail() ==
true) {
1481 LOG(
error) <<
"Error opening ascii file (it is probably a folder!): " << indPath;
1486 mSim2LUT[iind] = fromfile;
Definition of the Stack class.
Definition of the Detector class.
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
char error[CURL_ERROR_SIZE]
void AddSensitiveVolume(TGeoVolume *v)
TVirtualMC * fMC
flag for initialisation
void RegisterAny(const char *name, T *&obj, Bool_t toFile)
static FairRootManager * Instance()
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
int getMediumID(int imed) const
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
std::string addNameTo(const char *ext) const
void SetOneMCP(TGeoVolume *stl)
TGeoVolume * SetCablesSize(int mod)
Int_t ReadOptProperties(const std::string inputFilePath)
void DefineSim2LUTindex()
~Detector() override
Destructor.
void DefineOpticalProperties()
void InitializeO2Detector() override
Initialization of the detector is done here.
Bool_t ProcessHits(FairVolume *v) override
This method is called for each step during simulation (see FairMCApplication::Stepping())
void FillOtherOptProperties()
void ConstructGeometry() override
void addAlignableVolumes() const override
Add alignable volumes.
void CreateMaterials()
Base class to create the detector geometry.
void SetCablesA(TGeoVolume *stl)
void ConstructOpGeometry() override
o2::ft0::HitType * AddHit(float x, float y, float z, float time, float energy, Int_t trackId, Int_t detId)
Detector()=default
Default constructor.
Bool_t RegisterPhotoE(float energy)
TVector3 centerMCP(int imcp)
static constexpr float ZdetC
static constexpr float ZdetA
static constexpr int NCellsA
static constexpr int Nchannels
static constexpr int NCellsC
TVector3 tiltMCP(int imcp)
static ShmManager & Instance()
GLdouble GLdouble GLdouble GLdouble top
GLsizei const GLint * box
GLdouble GLdouble GLdouble z
std::vector< VerticalEdge< T > > sweep(Node< T > *segmentTree, const std::vector< VerticalEdge< T > > &polygonVerticalEdges)
void freeSimVector(std::vector< T > *ptr)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Common utility functions.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"