13#include <TGeoCompositeShape.h>
17#include <TGeoSphere.h>
18#include <TGeoVolume.h>
19#include <TMCManagerStack.h>
20#include "TGeoManager.h"
25#include "TVirtualMC.h"
28#include "FairRootManager.h"
29#include <fairlogger/Logger.h>
30#include "FairVolume.h"
32#include "FairRootManager.h"
33#include "FairVolume.h"
47 :
o2::base::DetImpl<
Detector>(
"FT0", Active), mIdSens1(0), mPMTeff(nullptr), mHits(
o2::
utils::createSimVector<
o2::ft0::
HitType>()), mTrackIdTop(-1), mTrackIdMCPtop(-1)
55 :
o2::base::DetImpl<
Detector>(rhs), mIdSens1(rhs.mIdSens1), mPMTeff(rhs.mPMTeff), mHits(
o2::
utils::createSimVector<
o2::ft0::
HitType>()), mTrackIdTop(-1), mTrackIdMCPtop(-1)
68 TGeoVolume*
v = gGeoManager->GetVolume(
"0REG");
70 LOG(warn) <<
"@@@@ Sensitive volume 0REG not found!!!!!!!!";
72 AddSensitiveVolume(
v);
73 mREGVolID = fMC->VolId(
"0REG");
75 TGeoVolume* vrad = gGeoManager->GetVolume(
"0TOP");
76 if (vrad ==
nullptr) {
77 LOG(warn) <<
"@@@@ Sensitive radiator not found!!!!!!!!";
79 AddSensitiveVolume(vrad);
80 mTOPVolID = fMC->VolId(
"0TOP");
82 TGeoVolume* vmcp = gGeoManager->GetVolume(
"0MTO");
83 if (vmcp ==
nullptr) {
84 LOG(warn) <<
"@@@@ Sensitive MCP glass not found!!!!!!!!";
86 AddSensitiveVolume(vmcp);
87 mMTOVolID = fMC->VolId(
"0MTO");
93 LOG(
debug) <<
"Creating FT0 geometry\n";
96 TGeoVolumeAssembly* stlinA =
new TGeoVolumeAssembly(
"FT0A");
97 TGeoVolumeAssembly* stlinC =
new TGeoVolumeAssembly(
"FT0C");
102 int nCellsA = geometry.
NCellsA;
103 int nCellsC = geometry.
NCellsC;
105 for (
int ipos = 0; ipos < nCellsA; ipos++) {
106 mPosModuleAx[ipos] = geometry.
centerMCP(ipos).X();
107 mPosModuleAy[ipos] = geometry.
centerMCP(ipos).Y();
111 TVirtualMC::GetMC()->Gsvolu(
"0MOD",
"BOX",
getMediumID(
kAir), mInStart, 3);
112 TGeoVolume* ins = gGeoManager->GetVolume(
"0MOD");
114 TGeoTranslation* tr[nCellsA + nCellsC];
118 nameTr = Form(
"0TR%i", itr + 1);
119 float z = -mStartA[2] + mInStart[2];
120 tr[itr] =
new TGeoTranslation(nameTr.Data(), mPosModuleAx[itr], mPosModuleAy[itr],
z);
121 tr[itr]->RegisterYourself();
122 stlinA->AddNode(ins, itr, tr[itr]);
123 LOG(
debug) <<
" A geom " << itr <<
" " << mPosModuleAx[itr] <<
" " << mPosModuleAy[itr];
128 stlinA->AddNode(constructFrameAGeometry(), 1,
new TGeoTranslation(0, 0, -mStartA[2] + mInStart[2]));
131 TGeoRotation* rot[nCellsC];
133 TGeoCombiTrans* com[nCellsC];
134 TGeoCombiTrans* comCable[nCellsC];
138 TGeoCombiTrans* plateCom[nCellsC];
139 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
140 TGeoCompositeShape* plateCompositeShape =
new TGeoCompositeShape(
"plateCompositeShape", cPlateShapeString().c_str());
141 TGeoVolume* plateVol =
new TGeoVolume(
"plateVol", plateCompositeShape, Al);
144 nameTr = Form(
"0TR%i", itr + 1);
145 nameRot = Form(
"0Rot%i", itr + 1);
147 float ac1 = geometry.
tiltMCP(ic).X();
148 float bc1 = geometry.
tiltMCP(ic).Y();
149 float gc1 = geometry.
tiltMCP(ic).Z();
150 rot[ic] =
new TGeoRotation(nameRot.Data(), ac1, bc1, gc1);
151 LOG(
debug) <<
" rot geom " << ic <<
" " << ac1 <<
" " << bc1 <<
" " << gc1;
152 rot[ic]->RegisterYourself();
153 mPosModuleCx[ic] = geometry.
centerMCP(ic + nCellsA).X();
154 mPosModuleCy[ic] = geometry.
centerMCP(ic + nCellsA).Y();
155 mPosModuleCz[ic] = geometry.
centerMCP(ic + nCellsA).Z() - 80;
156 com[ic] =
new TGeoCombiTrans(mPosModuleCx[ic], mPosModuleCy[ic], mPosModuleCz[ic], rot[ic]);
157 TGeoHMatrix hm = *com[ic];
158 TGeoHMatrix* ph =
new TGeoHMatrix(hm);
159 stlinC->AddNode(ins, itr, ph);
162 LOG(
debug) <<
" C " << mPosModuleCx[ic] <<
" " << mPosModuleCy[ic];
165 comCable[ic] =
new TGeoCombiTrans(mPosModuleCx[ic], mPosModuleCy[ic], mPosModuleCz[ic] + mInStart[2] + 0.2 + 0.1, rot[ic]);
166 TGeoHMatrix hmCable = *comCable[ic];
167 TGeoHMatrix* phCable =
new TGeoHMatrix(hmCable);
168 stlinC->AddNode(cables, itr, comCable[ic]);
171 plateCom[ic] =
new TGeoCombiTrans(mPosModuleCx[ic], mPosModuleCy[ic], (mPosModuleCz[ic] - 3), rot[ic]);
172 TGeoHMatrix hmPlate = *plateCom[ic];
173 TGeoHMatrix* phPlate =
new TGeoHMatrix(hmPlate);
174 stlinC->AddNode(plateVol, itr, phPlate);
177 stlinC->AddNode(constructFrameCGeometry(), nCellsA + nCellsC + 1);
179 TGeoVolume* alice = gGeoManager->GetVolume(
"barrel");
181 alice->AddNode(stlinA, 1,
new TGeoTranslation(0, 30., zdetA + 0.63));
184 TGeoRotation* rotC =
new TGeoRotation(
"rotC", 90., 0., 90., 90., 180., 0.);
185 alice->AddNode(stlinC, 1,
new TGeoCombiTrans(0., 30., -zdetC, rotC));
194 LOG(
debug) <<
"Creating FIT optical geometry properties";
206 Float_t ptop[3] = {1.324, 1.324, 1.};
207 Double_t prfv[3] = {0.0002, 1.323, 1.};
208 Double_t prfh[3] = {1.323, 0.0002, 1.};
214 const double kWrapClearance = 1.e-4;
215 Float_t ptopref[3] = {
static_cast<Float_t>(ptop[0] + 2 * prfv[0] + kWrapClearance),
216 static_cast<Float_t>(ptop[1] + 2 * prfh[1] + kWrapClearance), 1.};
217 Float_t pmcp[3] = {2.949, 2.949, 0.66};
218 Float_t pmcpinner[3] = {2.749, 2.749, 0.1};
219 Float_t pmcpbase[3] = {2.949, 2.949, 0.675};
220 Float_t pmcpside[3] = {0.15, 2.949, 0.65};
221 Float_t pmcptopglass[3] = {2.949, 2.949, 0.1};
222 Float_t preg[3] = {1.324, 1.324, 0.005};
225 TGeoVolume*
top = gGeoManager->GetVolume(
"0TOP");
226 TVirtualMC::GetMC()->Gsvolu(
"0TRE",
"BOX",
getMediumID(
kAir), ptopref, 3);
227 TGeoVolume* topref = gGeoManager->GetVolume(
"0TRE");
229 TGeoVolume* rfv = gGeoManager->GetVolume(
"0RFV");
231 TGeoVolume* rfh = gGeoManager->GetVolume(
"0RFH");
234 TGeoVolume* cat = gGeoManager->GetVolume(
"0REG");
238 Int_t ntops = 0, nrfvs = 0, nrfhs = 0;
240 topref->AddNode(
top, 1,
new TGeoTranslation(0, 0, 0));
245 auto seat = [](
Float_t half, Double_t strip) {
return double(
half) + strip; };
246 double xinv = -seat(ptop[0], prfv[0]);
247 topref->AddNode(rfv, 1,
new TGeoTranslation(xinv, 0, 0));
248 xinv = seat(ptop[0], prfv[0]);
249 topref->AddNode(rfv, 2,
new TGeoTranslation(xinv, 0, 0));
250 double yinv = -seat(ptop[1], prfh[1]);
251 topref->AddNode(rfh, 1,
new TGeoTranslation(0, yinv, 0));
252 yinv = seat(ptop[1], prfh[1]);
253 topref->AddNode(rfh, 2,
new TGeoTranslation(0, yinv, 0));
260 const double zRadiatorCentre = -mInStart[2] + double(ptopref[2]);
261 const double zRadiatorBack = zRadiatorCentre + double(ptopref[2]);
262 const double zTopGlassCentre = zRadiatorBack + double(pmcptopglass[2]);
263 const double zTopGlassBack = zTopGlassCentre + double(pmcptopglass[2]);
264 const double zCathodeCentre = zTopGlassBack + double(preg[2]);
265 const double zCathodeBack = zCathodeCentre + double(preg[2]);
268 for (Int_t ix = 0; ix < 2; ix++) {
269 float xin = -mInStart[0] + 0.3 + (ix + 0.5) * 2 * ptopref[0];
270 for (Int_t iy = 0; iy < 2; iy++) {
271 float yin = -mInStart[1] + 0.3 + (iy + 0.5) * 2 * ptopref[1];
273 ins->AddNode(topref, ntops,
new TGeoTranslation(xin, yin, zRadiatorCentre));
274 LOG(
debug) <<
" n " << ntops <<
" x " << xin <<
" y " << yin <<
" z radiator " << zRadiatorCentre;
275 ins->AddNode(cat, ntops,
new TGeoTranslation(xin, yin, zCathodeCentre));
276 LOG(
debug) <<
" n " << ntops <<
" x " << xin <<
" y " << yin <<
" z cathod " << zCathodeCentre;
281 TGeoVolume* mcptop = gGeoManager->GetVolume(
"0MTO");
282 ins->AddNode(mcptop, 1,
new TGeoTranslation(0, 0, zTopGlassCentre));
284 TVirtualMC::GetMC()->Gsvolu(
"0MCP",
"BOX",
getMediumID(
kAir), pmcp, 3);
285 TGeoVolume* mcp = gGeoManager->GetVolume(
"0MCP");
286 ins->AddNode(mcp, 1,
new TGeoTranslation(0, 0, zCathodeBack +
double(pmcp[2])));
289 TGeoVolume* mcpside = gGeoManager->GetVolume(
"0MSI");
290 x = -pmcp[0] + pmcpside[0];
291 y = -pmcp[1] + pmcpside[1];
292 mcp->AddNode(mcpside, 1,
new TGeoTranslation(
x,
y, 0));
293 x = pmcp[0] - pmcpside[0];
294 y = pmcp[1] - pmcpside[1];
295 mcp->AddNode(mcpside, 2,
new TGeoTranslation(
x,
y, 0));
296 x = -pmcp[1] + pmcpside[1];
297 y = -pmcp[0] + pmcpside[0];
298 mcp->AddNode(mcpside, 3,
new TGeoCombiTrans(
x,
y, 0,
new TGeoRotation(
"R2", 90, 0, 0)));
299 x = pmcp[1] - pmcpside[1];
300 y = pmcp[0] - pmcpside[0];
301 mcp->AddNode(mcpside, 4,
new TGeoCombiTrans(
x,
y, 0,
new TGeoRotation(
"R2", 90, 0, 0)));
304 TGeoVolume* mcpbase = gGeoManager->GetVolume(
"0MBA");
305 z = -mInStart[2] + 2 * ptopref[2] + pmcptopglass[2] + 2 * pmcp[2] + pmcpbase[2];
306 ins->AddNode(mcpbase, 1,
new TGeoTranslation(0, 0,
z));
313 float pcableplane[3] = {20, 20, 0.25};
315 TVirtualMC::GetMC()->Gsvolu(
"0CAA",
"BOX",
getMediumID(
kAir), pcableplane, 3);
316 TGeoVolume* cableplane = gGeoManager->GetVolume(
"0CAA");
320 const float kBeamPipeHoleRadius = 3.;
321 new TGeoBBox(
"0CAAbox", pcableplane[0], pcableplane[1], pcableplane[2]);
322 new TGeoTube(
"0CAAhole", 0., kBeamPipeHoleRadius, pcableplane[2] + 0.1);
323 cableplane->SetShape(
new TGeoCompositeShape(
"0CAAshape",
"0CAAbox-0CAAhole"));
326 double xcell[24], ycell[24];
327 for (
int imcp = 0; imcp < 24; imcp++) {
328 xcell[na] = mPosModuleAx[imcp];
329 ycell[na] = mPosModuleAy[imcp];
331 cableplane->AddNode(vol, na,
new TGeoTranslation(xcell[na], ycell[na], 0));
336 Float_t pcablesextend[3] = {2, 15, 0.245};
337 Float_t pcablesextendsmall[3] = {3, 2, 0.245};
338 Float_t* ppcablesextend[] = {pcablesextend, pcablesextend, pcablesextendsmall, pcablesextendsmall};
340 double xcell_side[] = {-mStartA[0] + pcablesextend[0], mStartA[0] - pcablesextend[0], 0, 0};
341 double ycell_side[] = {0, 0, -mStartA[1] + pcablesextendsmall[1], mStartA[1] - pcablesextendsmall[1]};
343 for (
int icab = 0; icab < 4; icab++) {
344 const std::string volName = Form(
"CAB%2.i", 52 + icab);
345 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
" BOX",
getMediumID(
kCable), ppcablesextend[icab], 3);
346 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
347 cableplane->AddNode(vol, 1,
new TGeoTranslation(xcell_side[icab], ycell_side[icab], 0));
349 float zcableplane = mStartA[2] - pcableplane[2] - 3;
350 stl->AddNode(cableplane, 1,
new TGeoTranslation(0, 0, zcableplane));
359 int mcpcables[52] = {2, 1, 2, 1, 2,
375 double xcell[ncells], ycell[ncells], zcell[ncells];
376 float xsize[3] = {1.8, 1.8, 2.6};
377 float ysize[3] = {0.6, 1.7, 2.};
378 float zsize[3] = {0.1, 0.1, 0.1};
380 int ic = mcpcables[mod];
382 calblesize[0] = xsize[ic - 1];
383 calblesize[1] = ysize[ic - 1];
384 calblesize[2] = zsize[ic - 1];
385 const std::string volName = Form(
"CAB%2.i", mod);
386 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
"BOX",
getMediumID(
kCable), calblesize, 3);
387 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
388 LOG(
debug) <<
"C cables " << mod <<
" " << volName <<
" " << ic;
401 LOG(info) <<
"Add FT0 alignable volumes";
404 LOG(fatal) <<
"TGeoManager doesn't exist !";
408 TString volPath = Form(
"/cave_1/barrel_1");
410 TString volPathA = volPath + Form(
"/FT0A_1");
411 TString symNameA =
"FT0A";
412 LOG(info) << symNameA <<
" <-> " << volPathA;
413 if (!gGeoManager->SetAlignableEntry(symNameA.Data(), volPathA.Data())) {
414 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
417 TString volPathC = volPath + Form(
"/FT0C_1");
418 TString symNameC =
"FT0C";
419 LOG(info) << symNameC <<
" <-> " << volPathC;
420 if (!gGeoManager->SetAlignableEntry(symNameC.Data(), volPathC.Data())) {
421 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
423 TString volPathMod, symNameMod;
426 volPathMod = volPath + Form(
"/0MOD_%d", imod);
427 symNameMod = Form(
"0MOD_%d", imod);
428 if (!gGeoManager->SetAlignableEntry(symNameMod.Data(), volPathMod.Data())) {
429 LOG(fatal) << (Form(
"Alignable entry %s not created. Volume path %s not valid", symNameMod.Data(), volPathMod.Data()));
446TGeoVolume* Detector::constructFrameAGeometry()
449 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
450 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
453 TGeoVolumeAssembly* FT0_Frame =
new TGeoVolumeAssembly(
"FT0_Frame");
456 Double_t blockdX = 37.1;
457 Double_t blockdY = 36.85;
458 Double_t blockdZ = 6.95;
459 TGeoBBox* block =
new TGeoBBox(
"block", blockdX / 2, blockdY / 2, blockdZ / 2);
465 Double_t box1dX = 1.57;
466 Double_t box1dY = 6.55;
467 Double_t box1PosX = -(blockdX / 2 - box1dX / 2);
468 Double_t box1PosY = 0;
470 TGeoTranslation* box1Tr1 =
new TGeoTranslation(
"box1Tr1", box1PosX, box1PosY, 0);
471 box1Tr1->RegisterYourself();
472 TGeoTranslation* box1Tr2 =
new TGeoTranslation(
"box1Tr2", -box1PosX, -box1PosY, 0);
473 box1Tr2->RegisterYourself();
475 Double_t box2dX = 2.9;
476 Double_t box2dY = 15.1;
477 Double_t box2PosX = -(blockdX / 2 - box2dX / 2);
478 Double_t box2PosY = blockdY / 2 - box2dY / 2;
480 TGeoTranslation* box2Tr1 =
new TGeoTranslation(
"box2Tr1", box2PosX, box2PosY, 0);
481 box2Tr1->RegisterYourself();
482 TGeoTranslation* box2Tr2 =
new TGeoTranslation(
"box2Tr2", -box2PosX, -box2PosY, 0);
483 box2Tr2->RegisterYourself();
487 Double_t box3dX = 12.7;
489 Double_t box3dZ = 5.45;
490 Double_t box3PosX = -(blockdX / 2 - box2dX - box3dZ / 2);
491 Double_t box3PosY = blockdY / 2 - box3dY / 2;
492 Double_t box3PosZ = blockdZ / 2 - box3dZ / 2;
494 TGeoTranslation* box3Tr1 =
new TGeoTranslation(
"box3Tr1", box3PosX, box3PosY, box3PosZ);
495 box3Tr1->RegisterYourself();
496 TGeoTranslation* box3Tr2 =
new TGeoTranslation(
"box3Tr2", -box3PosX, -box3PosY, box3PosZ);
497 box3Tr2->RegisterYourself();
499 Double_t box4dX = 6.6;
500 Double_t box4dY = 1.67;
501 Double_t box4PosX = 0;
502 Double_t box4PosY = blockdY / 2 - box4dY / 2;
504 TGeoTranslation* box4Tr1 =
new TGeoTranslation(
"box4Tr1", box4PosX, box4PosY, 0);
505 box4Tr1->RegisterYourself();
506 TGeoTranslation* box4Tr2 =
new TGeoTranslation(
"box4Tr2", -box4PosX, -box4PosY, 0);
507 box4Tr2->RegisterYourself();
509 Double_t box5dX = 15;
511 Double_t box5PosX = blockdX / 2 - box5dX / 2;
512 Double_t box5PosY = blockdY / 2 - box5dY / 2;
514 TGeoTranslation* box5Tr1 =
new TGeoTranslation(
"box5Tr1", box5PosX, box5PosY, 0);
515 box5Tr1->RegisterYourself();
516 TGeoTranslation* box5Tr2 =
new TGeoTranslation(
"box5Tr2", -box5PosX, -box5PosY, 0);
517 box5Tr2->RegisterYourself();
521 Double_t box6dX = 2.9;
522 Double_t box6dY = 12.2;
523 Double_t box6dZ = 5.45;
524 Double_t box6PosX = blockdX / 2 - box6dX / 2;
525 Double_t box6PosY = blockdY / 2 - box5dY - box6dY / 2;
526 Double_t box6PosZ = blockdZ / 2 - box6dZ / 2;
528 TGeoTranslation* box6Tr1 =
new TGeoTranslation(
"box6Tr1", box6PosX, box6PosY, box6PosZ);
529 box6Tr1->RegisterYourself();
530 TGeoTranslation* box6Tr2 =
new TGeoTranslation(
"box6Tr2", -box6PosX, -box6PosY, box6PosZ);
531 box6Tr2->RegisterYourself();
537 Double_t cbox1dX = 7.175;
538 Double_t cbox1dY = 5.5;
539 Double_t cbox1Xoffset = 14.425;
540 Double_t cbox1PosX = -(blockdX / 2 - cbox1Xoffset - cbox1dX / 2);
541 Double_t cbox1PosY = 0;
542 TGeoBBox* cbox1 =
new TGeoBBox(
"cbox1", cbox1dX / 2, cbox1dY / 2, blockdZ / 2);
543 TGeoTranslation* cbox1Tr1 =
new TGeoTranslation(
"cbox1Tr1", cbox1PosX, cbox1PosY, 0);
544 cbox1Tr1->RegisterYourself();
545 TGeoTranslation* cbox1Tr2 =
new TGeoTranslation(
"cbox1Tr2", -cbox1PosX, -cbox1PosY, 0);
546 cbox1Tr2->RegisterYourself();
548 Double_t cbox2dX = 5.75;
550 Double_t cbox2dY = 6.575;
551 Double_t cbox2Yoffset = 14.425;
552 Double_t cbox2PosX = 0;
553 Double_t cbox2PosY = blockdY / 2 - cbox2Yoffset - cbox2dY / 2;
554 TGeoBBox* cbox2 =
new TGeoBBox(
"cbox2", cbox2dX / 2, cbox2dY / 2, blockdZ / 2);
555 TGeoTranslation* cbox2Tr1 =
new TGeoTranslation(
"cbox2Tr1", cbox2PosX, cbox2PosY, 0);
556 cbox2Tr1->RegisterYourself();
557 TGeoTranslation* cbox2Tr2 =
new TGeoTranslation(
"cbox2Tr2", -cbox2PosX, -cbox2PosY, 0);
558 cbox2Tr2->RegisterYourself();
565 Double_t gapBoxdX = 0.1;
566 Double_t gapBoxdY = blockdY / 2;
567 Double_t gapPosX = -(sPmtSide / 2 + sEps + gapBoxdX / 2);
568 Double_t gapPosY = blockdY / 4;
569 TGeoBBox* gapBox =
new TGeoBBox(
"gapBox", gapBoxdX / 2, gapBoxdY / 2, blockdZ / 2);
570 TGeoTranslation* gapBoxTr1 =
new TGeoTranslation(
"gapBoxTr1", gapPosX, gapPosY, 0);
571 gapBoxTr1->RegisterYourself();
572 TGeoTranslation* gapBoxTr2 =
new TGeoTranslation(
"gapBoxTr2", -gapPosX, -gapPosY, 0);
573 gapBoxTr2->RegisterYourself();
577 std::string frameACompositeString =
"block ";
578 frameACompositeString +=
"- box1:box1Tr1 - box1:box1Tr2 ";
579 frameACompositeString +=
"- box2:box2Tr1 - box2:box2Tr2 ";
580 frameACompositeString +=
"- box3:box3Tr1 - box3:box3Tr2 ";
581 frameACompositeString +=
"- box4:box4Tr1 - box4:box4Tr2 ";
582 frameACompositeString +=
"- box5:box5Tr1 - box5:box5Tr2 ";
583 frameACompositeString +=
"- box6:box6Tr1 - box6:box6Tr2 ";
584 frameACompositeString +=
"- cbox1:cbox1Tr1 - cbox1:cbox1Tr2 ";
585 frameACompositeString +=
"- cbox2:cbox2Tr1 - cbox2:cbox2Tr2 ";
586 frameACompositeString +=
"- gapBox:gapBoxTr1 - gapBox:gapBoxTr2";
596 Double_t coverPlatedZ = 0.2;
597 Double_t fiberPlatedZ = 0.5;
600 Double_t opticalFiberHeaddY = 0.52;
601 Double_t opticalFiberHeaddX = 1.142;
607 Double_t fh1TopPosX = -1.6;
608 Double_t fh1TopPosY = 1.325;
609 Double_t fh1BotPosX = 1.555;
610 Double_t fh1BotPosY = 1.249;
611 Double_t fh1BotAngle = 16;
615 Double_t fh2TopPosX = -1.563;
616 Double_t fh2TopPosY = 1.4625;
617 Double_t fh2TopAngle = 60;
619 Double_t fh2BotPosX = 1.084;
620 Double_t fh2BotPosY = 1.186;
621 Double_t fh2BotAngle = -30;
624 TGeoBBox* coverPlate =
new TGeoBBox(
"coverPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, coverPlatedZ / 2);
625 TGeoBBox* fiberPlate =
new TGeoBBox(
"fiberPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, fiberPlatedZ / 2);
626 TGeoBBox* opticalFiberHead =
new TGeoBBox(
"opticalFiberHead", opticalFiberHeaddX / 2, opticalFiberHeaddY / 2, fiberPlatedZ / 2);
629 TGeoTranslation* coverPlateTr =
new TGeoTranslation(
"coverPlateTr", 0, 0, fiberPlatedZ / 2 + coverPlatedZ / 2);
630 coverPlateTr->RegisterYourself();
631 TGeoTranslation* fh1TopTr1 =
new TGeoTranslation(
"fh1TopTr1", fh1TopPosX, fh1TopPosY, 0);
632 fh1TopTr1->RegisterYourself();
633 TGeoTranslation* fh1TopTr2 =
new TGeoTranslation(
"fh1TopTr2", fh1TopPosX, -fh1TopPosY, 0);
634 fh1TopTr2->RegisterYourself();
635 TGeoCombiTrans* fh1BotTr1 =
new TGeoCombiTrans(
"fh1BotTr1", fh1BotPosX, fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot1", fh1BotAngle, 0, 0));
636 fh1BotTr1->RegisterYourself();
637 TGeoCombiTrans* fh1BotTr2 =
new TGeoCombiTrans(
"fh1BotTr2", fh1BotPosX, -fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot2", -fh1BotAngle, 0, 0));
638 fh1BotTr2->RegisterYourself();
639 TGeoCombiTrans* fh2TopTr1 =
new TGeoCombiTrans(
"fh2TopTr1", fh2TopPosX, fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot1", fh2TopAngle + 90, 0, 0));
640 fh2TopTr1->RegisterYourself();
641 TGeoCombiTrans* fh2TopTr2 =
new TGeoCombiTrans(
"fh2TopTr2", fh2TopPosX, -fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot2", -fh2TopAngle - 90, 0, 0));
642 fh2TopTr2->RegisterYourself();
643 TGeoCombiTrans* fh2BotTr1 =
new TGeoCombiTrans(
"fh2BotTr1", fh2BotPosX, fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot1", -fh2BotAngle, 0, 0));
644 fh2BotTr1->RegisterYourself();
645 TGeoCombiTrans* fh2BotTr2 =
new TGeoCombiTrans(
"fh2BotTr2", fh2BotPosX, -fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot2", fh2BotAngle, 0, 0));
646 fh2BotTr2->RegisterYourself();
649 std::string outerPlateGroupString =
"fiberPlate ";
650 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr1 ";
651 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr2 ";
652 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr1 ";
653 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr2 ";
654 outerPlateGroupString +=
"+ coverPlate:coverPlateTr";
657 TGeoCompositeShape* outerPlateGroup =
new TGeoCompositeShape(
"outerPlateGroup", outerPlateGroupString.c_str());
660 std::string innerPlateGroupString =
"fiberPlate ";
661 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr1 ";
662 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr2 ";
663 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr1 ";
664 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr2 ";
665 innerPlateGroupString +=
"+ coverPlate:coverPlateTr";
668 TGeoCompositeShape* innerPlateGroup =
new TGeoCompositeShape(
"innerPlateGroup", innerPlateGroupString.c_str());
673 Double_t backPlanedZ = 0.25;
674 Double_t socketdZ = blockdZ - backPlanedZ;
677 TGeoVolume* socket = gGeoManager->MakeBox(
"Socket", Vacuum, sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, socketdZ / 2);
681 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};
684 TString nameTrSocket;
686 TString nameTrPlateGroup;
693 nameTrSocket = Form(
"trSocket%i", itr + 1);
694 float z = -backPlanedZ / 4.0;
695 trSocket[itr] =
new TGeoTranslation(nameTrSocket.Data(), mPosModuleAx[itr], mPosModuleAy[itr],
z);
696 trSocket[itr]->RegisterYourself();
697 frameACompositeString +=
"- Socket:";
698 frameACompositeString += nameTrSocket.Data();
700 nameTrPlateGroup = Form(
"trPlateGroup%i", itr + 1);
701 namePGRot = Form(
"pgRot%i", itr + 1);
702 float z2 = -blockdZ / 2 + (coverPlatedZ + fiberPlatedZ) / 2;
703 trPlateGroup[itr] =
new TGeoCombiTrans(nameTrPlateGroup.Data(), mPosModuleAx[itr], mPosModuleAy[itr], z2,
new TGeoRotation(namePGRot.Data(), rotAngle[itr], 0, 0));
704 trPlateGroup[itr]->RegisterYourself();
706 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) {
707 frameACompositeString +=
" + outerPlateGroup:";
708 frameACompositeString += nameTrPlateGroup.Data();
709 frameACompositeString +=
" ";
711 frameACompositeString +=
" + innerPlateGroup:";
712 frameACompositeString += nameTrPlateGroup.Data();
713 frameACompositeString +=
" ";
718 TGeoVolume* frameA =
new TGeoVolume(
"frameA",
new TGeoCompositeShape(
"frameA", frameACompositeString.c_str()), Al);
721 FT0_Frame->AddNode(frameA, 1);
730TGeoVolume* Detector::constructFrameCGeometry()
734 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
735 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
736 static constexpr Double_t sFrameZC = 5.5632;
737 static constexpr Double_t frameHeightC = 2.5;
740 static constexpr Double_t sensShift = 0.5;
741 static constexpr Double_t sQuartzRadiatorZC = 1.94360;
742 static constexpr Double_t sQuartzHeightC = (-sFrameZC / 2 + sQuartzRadiatorZC / 2);
743 static constexpr Double_t sPmtZC = 3.600;
744 static constexpr Double_t sPmtHeightC = (sFrameZC / 2 - sPmtZC / 2);
752 Float_t rMax = rMin + sFrameZC;
757 Float_t pinstart[3] = {2.9491, 2.9491, 2.5};
758 Float_t pstartC[3] = {20., 20, 5};
761 Double_t xCorn = multCorn * (-14.75272569);
762 Double_t yCorn = multCorn * (14.9043284);
763 Double_t zCorn = 79.27306024;
765 Double_t xCorn2 = -xCorn;
766 Double_t yCorn2 = yCorn;
767 Double_t zCorn2 = zCorn;
769 Double_t acCorn = TMath::ATan(yCorn / xCorn) - TMath::Pi() / 2 + 2 * TMath::Pi();
770 Double_t bcCorn = TMath::ACos(zCorn / crad);
771 Double_t gcCorn = -1 * acCorn;
775 Double_t flopsErr = 0.00001;
779 Double_t errPMTZ = 10 * sEps;
780 Double_t errPMTXY = 0.02;
781 Double_t errQrdZ = 0.143 + 0.22;
782 Double_t errQrdXY = 0.35;
789 TGeoSphere* sphere1 =
new TGeoSphere(
"sphere1", rMin, rMax, tMin, tMax, pMin, pMax);
790 TGeoSphere* sphere2 =
new TGeoSphere(
"sphere2", rMin - sweep, rMax + sweep, tMin, tMax, pMin, pMax);
791 TGeoSphere* sphere3 =
new TGeoSphere(
"sphere3", rMin, rMin + backPlateZ, tMin, tMax, pMin, pMax);
792 TGeoSphere* sphere4 =
new TGeoSphere(
"sphere4", rMin - sweep, rMax + backPlateZ + sweep, tMin, tMax, pMin, pMax);
794 TGeoBBox* insSeat =
new TGeoBBox(
"insSeat", pinstart[0] * 2, pinstart[1] * 2, pinstart[2] * 2);
797 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
798 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
799 sQuartzRadiatorZC / 2 + sEps + errQrdZ);
802 sPmtSide / 2 + sEps + errPMTXY,
803 sPmtSide / 2 + sEps + errPMTXY,
804 sPmtZ / 2 + sEps + errPMTZ);
806 sCornerRadius / 2 - flopsErr,
807 sCornerRadius / 2 - flopsErr,
813 TGeoRotation* rot1 =
new TGeoRotation(
"rot1", 90, 0, 0);
814 rot1->RegisterYourself();
815 TGeoCombiTrans* rotTr1 =
new TGeoCombiTrans(
"rotTr1", -20, -1, -5, rot1);
816 rotTr1->RegisterYourself();
818 TGeoRotation* rot2 =
new TGeoRotation(
"rot2", -90, 0, 0);
819 rot2->RegisterYourself();
820 TGeoCombiTrans* rotTr2 =
new TGeoCombiTrans(
"rotTr2", 20, -1, -5, rot2);
821 rotTr2->RegisterYourself();
823 TGeoRotation* rot3 =
new TGeoRotation(
"rot3", 0, 0, 0);
824 rot3->RegisterYourself();
825 TGeoCombiTrans* rotTr3 =
new TGeoCombiTrans(
"rotTr3", 0, 20, -5, rot3);
826 rotTr3->RegisterYourself();
828 TGeoTranslation* centerTrans =
new TGeoTranslation(
"centerTrans", 0, 0, 85);
829 centerTrans->RegisterYourself();
831 TGeoRotation* reflectC1 =
new TGeoRotation(
"reflectC1", 0, 0, 0);
832 reflectC1->ReflectX(
true);
833 reflectC1->ReflectY(
true);
834 reflectC1->RegisterYourself();
836 TGeoRotation* rotCorners =
new TGeoRotation(
"rotCorners", acCorn, bcCorn, gcCorn);
837 rotCorners->RegisterYourself();
839 TGeoCombiTrans* comCorners =
new TGeoCombiTrans(
"comCorners", xCorn, yCorn, zCorn, rotCorners);
840 comCorners->RegisterYourself();
842 TGeoCombiTrans* comCorners2 =
new TGeoCombiTrans(
"comCorners2", xCorn2, yCorn2, zCorn2, rotCorners);
843 comCorners2->RegisterYourself();
846 std::string shellString =
"";
847 shellString +=
"sphere1";
848 shellString +=
"- sphere2:rotTr1";
849 shellString +=
"- sphere2:rotTr2";
850 shellString +=
"- sphere2:rotTr3";
851 shellString +=
"- insSeat:centerTrans";
852 shellString +=
"- framecornerBox:comCorners";
853 shellString +=
"- framecornerBox:comCorners2";
856 std::string backPlateString =
"";
857 backPlateString +=
"sphere3";
858 backPlateString +=
"- sphere4:rotTr1";
859 backPlateString +=
"- sphere4:rotTr2";
860 backPlateString +=
"- sphere4:rotTr3";
861 backPlateString +=
"- insSeat:centerTrans";
862 backPlateString +=
"- framecornerBox:comCorners";
863 backPlateString +=
"- framecornerBox:comCorners2";
867 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};
868 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};
870 Double_t zi[NCellsC];
871 for (Int_t ic = 0; ic < NCellsC; ic++) {
872 zi[ic] = TMath::Sqrt(TMath::Power(crad, 2) - TMath::Power(xi[ic], 2) - TMath::Power(yi[ic], 2));
876 Double_t ac[NCellsC],
bc[NCellsC], gc[NCellsC];
877 for (Int_t
i = 0;
i < NCellsC;
i++) {
878 ac[
i] = TMath::ATan(yi[
i] / xi[
i]) - TMath::Pi() / 2 + 2 * TMath::Pi();
880 bc[
i] = TMath::ACos(zi[
i] / crad);
882 bc[
i] = -1 * TMath::ACos(zi[
i] / crad);
886 Double_t xc2[NCellsC], yc2[NCellsC], zc2[NCellsC];
890 Double_t rcomp = crad + pstartC[2] / 2.0;
891 for (Int_t
i = 0;
i < NCellsC;
i++) {
893 xc2[
i] = rcomp * TMath::Cos(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
894 yc2[
i] = rcomp * TMath::Sin(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
895 zc2[
i] = rcomp * TMath::Cos(
bc[
i]);
898 ac[
i] *= 180 / TMath::Pi();
899 bc[
i] *= 180 / TMath::Pi();
903 Double_t rmag = sqrt(xc2[0] * xc2[0] + yc2[0] * yc2[0] + zc2[0] * zc2[0]);
905 Double_t scalePMT = (rmag + (frameHeightC / 2.0) - (sPmtHeightC / 2)) / rmag;
906 Double_t scaleQrad = (rmag + (frameHeightC / 2.0) - sPmtHeightC - (sQuartzRadiatorZC / 2.0)) / rmag;
908 Double_t xPMT[NCellsC];
909 Double_t yPMT[NCellsC];
910 Double_t zPMT[NCellsC];
912 Double_t xQrad[NCellsC];
913 Double_t yQrad[NCellsC];
914 Double_t zQrad[NCellsC];
916 Double_t rotC[NCellsC];
917 Double_t comC[NCellsC];
919 for (Int_t
i = 0;
i < NCellsC;
i++) {
921 xPMT[
i] = scalePMT * xc2[
i];
922 yPMT[
i] = scalePMT * yc2[
i];
923 zPMT[
i] = scalePMT * zc2[
i];
926 xQrad[
i] = scaleQrad * xc2[
i];
927 yQrad[
i] = scaleQrad * yc2[
i];
928 zQrad[
i] = scaleQrad * zc2[
i];
933 TString nameComQuartz;
934 TString nameComPlates;
937 for (Int_t itr = NCellsA; itr < NCellsA + NCellsC; itr++) {
938 nameRot = Form(
"0Rot%i", itr + 1);
939 int ic = itr - NCellsA;
940 nameComPMT = Form(
"0ComPMT%i", ic + 1);
941 nameComQuartz = Form(
"0ComQuartz%i", ic + 1);
946 TGeoRotation* rotC =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
947 rotC->RegisterYourself();
949 TGeoCombiTrans* comC =
new TGeoCombiTrans(nameComC.Data(), xc2[ic], yc2[ic], zc2[ic], rotC);
950 comC->RegisterYourself();
952 TGeoRotation* rotPMT =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
953 rotPMT->RegisterYourself();
955 TGeoCombiTrans* comPMT =
new TGeoCombiTrans(nameComPMT.Data(),
958 comPMT->RegisterYourself();
960 TGeoRotation* rotQuartz =
new TGeoRotation(nameRot.Data(),
961 ac[ic],
bc[ic], gc[ic]);
962 rotQuartz->RegisterYourself();
964 TGeoCombiTrans* comQuartz =
new TGeoCombiTrans(nameComQuartz.Data(),
965 xQrad[ic], yQrad[ic],
966 zQrad[ic] - (sQuartzRadiatorZC / 2 + 3 * sEps),
968 comQuartz->RegisterYourself();
970 TGeoRotation* rotPlates =
new TGeoRotation(nameRot.Data(),
971 ac[ic],
bc[ic], gc[ic]);
972 rotPlates->RegisterYourself();
973 TGeoCombiTrans* comPlates =
new TGeoCombiTrans(nameComPlates.Data(),
974 xQrad[ic], yQrad[ic],
977 comPlates->RegisterYourself();
980 std::string pmtCombiString =
"";
981 pmtCombiString +=
"- ";
982 pmtCombiString +=
"pmtBoxSeat:";
983 pmtCombiString += nameComPMT.Data();
984 shellString += pmtCombiString;
987 std::string quartzCombiString =
"";
988 quartzCombiString +=
"- ";
989 quartzCombiString +=
"quartzRadiatorSeat:";
990 quartzCombiString += nameComQuartz.Data();
991 shellString += quartzCombiString;
996 TGeoCompositeShape* shellCompShape =
new TGeoCompositeShape(
"shellCompShape", shellString.c_str());
998 TGeoVolume* shellVol =
new TGeoVolume(
"shellVol", shellCompShape, Al);
1001 TGeoVolumeAssembly* FT0_C_Frame =
new TGeoVolumeAssembly(
"FT0_C_Frame");
1004 TGeoTranslation* shellTr1 =
new TGeoTranslation(
"shellTr1", 0, 0, -80);
1005 shellTr1->RegisterYourself();
1007 TGeoCombiTrans* shellTr2 =
new TGeoCombiTrans(
"shellTr2", 0, 0, -80, reflectC1);
1008 shellTr2->RegisterYourself();
1010 FT0_C_Frame->AddNode(shellVol, 1, shellTr1);
1011 FT0_C_Frame->AddNode(shellVol, 2, shellTr2);
1013 TGeoTranslation* backPlateTr1 =
new TGeoTranslation(
"backPlateTr1", 0, 0, -74);
1014 backPlateTr1->RegisterYourself();
1016 TGeoCombiTrans* backPlateTr2 =
new TGeoCombiTrans(
"backPlateTr2", 0, 0, -74, reflectC1);
1017 backPlateTr2->RegisterYourself();
1019 TGeoCompositeShape* backPlateShape =
new TGeoCompositeShape(
"backPlateShape", backPlateString.c_str());
1020 TGeoVolume* backPlateVol =
new TGeoVolume(
"backPlateVol", backPlateShape, Al);
1022 FT0_C_Frame->AddNode(backPlateVol, 3, backPlateTr1);
1023 FT0_C_Frame->AddNode(backPlateVol, 4, backPlateTr2);
1028std::string Detector::cPlateShapeString()
1030 Double_t prismHeight = 0.3895;
1031 Double_t prismSide = 5.9;
1032 Double_t radCurve = 81.9469;
1033 Double_t delHeight = radCurve * (1.0 - TMath::Sqrt(1.0 - 0.5 * TMath::Power(prismSide / radCurve, 2.0)));
1036 Double_t heightBase = prismHeight + delHeight;
1037 Double_t sliceSide = 5.3;
1038 Double_t heightBaseBox = 2 * heightBase;
1039 Double_t totalHeight = 0.5;
1040 Double_t sliceHeight = 0.5 - heightBase;
1043 Double_t cableHoleWidth = 0.3503;
1044 Double_t cableHoleLength = 0.9003;
1045 Double_t cableHoleDepth = 1;
1050 Double_t sHolesBottomEdge = 1.585;
1051 Double_t sHolesTopEdge = 0.515;
1052 Double_t sHolesAvgTopBottom = (sHolesBottomEdge + sHolesTopEdge) / 2.0;
1053 Double_t sHolesUpFromCenter = ((sliceSide / 2.0) - sHolesAvgTopBottom);
1055 Double_t sHolesFarEdge = 1.585;
1056 Double_t sHolesNearEdge = 1.065;
1057 Double_t sHolesAvgNearFar = (sHolesFarEdge + sHolesNearEdge) / 2.0;
1058 Double_t sHolesLateralFromCenter = ((sliceSide / 2.0) - sHolesAvgNearFar);
1061 TGeoBBox*
box =
new TGeoBBox(
"BASE", prismSide / 2.0, heightBaseBox / 2.0, prismSide / 2.0);
1064 TGeoBBox* slice =
new TGeoBBox(
"SLICE", sliceSide / 2.0, heightBaseBox / 2.0, sliceSide / 2.0);
1065 TGeoBBox* cableHole =
new TGeoBBox(
"CABLE", cableHoleLength / 2.0, cableHoleDepth / 2.0, cableHoleWidth / 2.0);
1066 TGeoBBox* cableHole2 =
new TGeoBBox(
"CABLE2", cableHoleWidth / 2.0, cableHoleLength / 2.0, cableHoleDepth / 2.0);
1068 TGeoSphere* baseShape =
new TGeoSphere(
"BASE_SUBTRACTION", radCurve, radCurve + 5.0, 80, 100, 80, 100);
1070 TGeoTranslation* rTrans =
new TGeoTranslation(
"rTrans", 0, radCurve, 0);
1071 rTrans->RegisterYourself();
1073 TGeoTranslation* rBackTrans =
new TGeoTranslation(
"rBackTrans", 0, -1.0 * radCurve, 0);
1074 rBackTrans->RegisterYourself();
1076 TGeoTranslation* subSliceTrans =
new TGeoTranslation(
"subSliceTrans", 0, (heightBaseBox / 2.0) + sliceHeight, 0);
1077 subSliceTrans->RegisterYourself();
1079 TGeoTranslation* sHolesTopLeftTrans =
new TGeoTranslation(
"sHolesTopLeftTrans", sHolesUpFromCenter, 0, sHolesLateralFromCenter);
1080 sHolesTopLeftTrans->RegisterYourself();
1082 TGeoTranslation* sHolesTopRightTrans =
new TGeoTranslation(
"sHolesTopRightTrans", sHolesUpFromCenter, 0, -1.0 * sHolesLateralFromCenter);
1083 sHolesTopRightTrans->RegisterYourself();
1085 TGeoTranslation* testTrans =
new TGeoTranslation(
"testTrans", 0.1, 0.1, 0);
1086 testTrans->RegisterYourself();
1088 TGeoRotation* switchToZ =
new TGeoRotation(
"switchToZ", 90, 90, 0);
1089 switchToZ->RegisterYourself();
1091 TGeoRotation* rotateHolesLeft =
new TGeoRotation(
"rotateHolesLeft", 345, 0, 0);
1092 rotateHolesLeft->RegisterYourself();
1094 TGeoRotation* rotateHolesRight =
new TGeoRotation(
"rotatetHolesRight", 15, 0, 0);
1095 rotateHolesRight->RegisterYourself();
1098 TGeoCombiTrans* rHolesBottomLeftTrans =
new TGeoCombiTrans(
"rHolesBottomLeftTrans", -1.0 * sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesLeft);
1099 rHolesBottomLeftTrans->RegisterYourself();
1101 TGeoCombiTrans* rHolesBottomRightTrans =
new TGeoCombiTrans(
"rHolesBottomRightTrans", sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesRight);
1102 rHolesBottomRightTrans->RegisterYourself();
1104 std::string plateString =
" ";
1105 plateString +=
"(((BASE:rTrans";
1106 plateString +=
"- BASE_SUBTRACTION)";
1107 plateString +=
"+ (SLICE:rTrans))";
1108 plateString +=
":rBackTrans";
1109 plateString +=
"- BASE:subSliceTrans";
1110 plateString +=
"- (CABLE:sHolesTopLeftTrans)";
1111 plateString +=
"- (CABLE:sHolesTopRightTrans))";
1112 plateString +=
":switchToZ";
1113 plateString +=
"- (CABLE2:rHolesBottomLeftTrans)";
1114 plateString +=
"- (CABLE2:rHolesBottomRightTrans)";
1125 Int_t volID = fMC->CurrentVolID(copy);
1126 if (fMC->IsTrackEntering() && !fMC->IsNewTrack() && fMC->TrackCharge() != 0 && volID == mTOPVolID) {
1128 if (o2stack->GetCurrentTrackNumber() != mTrackRefLastTrackID) {
1129 mTrackRefLastTrackID = o2stack->GetCurrentTrackNumber();
1134 TVirtualMCStack*
stack = fMC->GetStack();
1135 Int_t quadrant, mcp;
1136 if (fMC->IsTrackEntering()) {
1138 fMC->TrackPosition(
x,
y,
z);
1139 fMC->CurrentVolID(quadrant);
1140 fMC->CurrentVolOffID(1, mcp);
1141 float time = fMC->TrackTime() * 1.0e9;
1142 int trackID =
stack->GetCurrentTrackNumber();
1143 int detID = mSim2LUT[4 * mcp + quadrant - 1];
1144 int iPart = fMC->TrackPid();
1145 if (fMC->TrackCharge() && volID == mREGVolID) {
1148 if (iPart == 50000050) {
1149 float etot = fMC->Etot();
1150 float enDep = fMC->Edep();
1151 Int_t parentID =
stack->GetCurrentTrack()->GetMother(0);
1152 if (volID == mTOPVolID) {
1157 mTrackIdTop = trackID;
1160 if (volID == mMTOVolID) {
1161 if (trackID != mTrackIdTop) {
1166 mTrackIdMCPtop = trackID;
1170 if (volID == mREGVolID) {
1171 if (trackID != mTrackIdTop && trackID != mTrackIdMCPtop) {
1176 if (trackID == mTrackIdTop || trackID == mTrackIdMCPtop) {
1189 mHits->emplace_back(
x,
y,
z,
time, energy, trackId, detId);
1192 stack->addHit(GetDetId());
1195 stack->modifiesHit(GetDetId());
1197 return &(mHits->back());
1206 if (FairRootManager::Instance()) {
1207 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits, kTRUE);
1216 mTrackRefLastTrackID = -1;
1229 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
1230 Float_t zAir[4] = {6., 7., 8., 18.};
1231 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
1235 Float_t aglass[2] = {28.0855, 15.9994};
1236 Float_t zglass[2] = {14., 8.};
1249 Float_t aCeramic[2] = {26.981539, 15.9994};
1250 Float_t zCeramic[2] = {13., 8.};
1251 Float_t wCeramic[2] = {2., 3.};
1255 const Int_t nCeramicNice = 3;
1256 Float_t aCeramicNicel[3] = {26.981539, 15.9994, 58.6934};
1257 Float_t zCeramicNicel[3] = {13., 8., 28};
1258 Float_t wCeramicNicel[3] = {0.2, 0.3, 0.5};
1259 Float_t denscerCeramicNickel = 5.6;
1263 const Int_t nPlast = 4;
1264 Float_t aPlast[nPlast] = {1.00784, 12.0107, 15.999, 63.54};
1265 Float_t zPlast[nPlast] = {1, 6, 8, 29};
1266 Float_t wPlast[nPlast] = {0.08, 0.53, 0.22, 0.17};
1267 const Float_t denCable = 3.66;
1275 Material(11,
"Aliminium$", 26.98, 13.0, 2.7, 8.9, 999);
1276 Mixture(1,
"Vacuum$", aAir, zAir, dAir1, 4, wAir);
1277 Mixture(2,
"Air$", aAir, zAir, dAir, 4, wAir);
1278 Mixture(4,
"MCP glass $", aglass, zglass, dglass_mcp, -2, wglass);
1279 Mixture(24,
"Radiator Optical glass$", aglass, zglass, dglass, -2, wglass);
1280 Mixture(3,
"Ceramic$", aCeramic, zCeramic, denscer, -2, wCeramic);
1281 Mixture(23,
"CablePlasticCooper$", aPlast, zPlast, denCable, 4, wPlast);
1282 Mixture(25,
"MCPwalls $", aCeramicNicel, zCeramicNicel, denscerCeramicNickel, 3, wCeramicNicel);
1284 Medium(1,
"Air$", 2, 0, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1285 Medium(3,
"Vacuum$", 1, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1286 Medium(4,
"Ceramic$", 3, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1287 Medium(6,
"Glass$", 4, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1288 Medium(15,
"Aluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1289 Medium(17,
"OptAluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1290 Medium(16,
"OpticalGlass$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .01);
1291 Medium(19,
"OpticalGlassCathode$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1293 Medium(23,
"Cables$", 23, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1294 Medium(25,
"MCPWalls", 25, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1302 const char* aliceO2env = std::getenv(
"O2_ROOT");
1304 inputDir = aliceO2env;
1306 inputDir +=
"/share/Detectors/FT0/files/";
1308 TString optPropPath = inputDir +
"quartzOptProperties.txt";
1309 gSystem->ExpandPathName(optPropPath);
1314 LOG(error) <<
"Could not read FIT optical properties " <<
result <<
" " << optPropPath.Data();
1317 Int_t nBins = mPhotonEnergyD.size();
1319 mPMTeff =
new TGraph(nBins, &(mPhotonEnergyD[0]), &(mQuantumEfficiency[0]));
1325 TVirtualMC::GetMC()->SetCerenkov(
getMediumID(
kOpGlass), nBins, &(mPhotonEnergyD[0]), &(mAbsorptionLength[0]),
1326 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1328 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1331 TVirtualMC::GetMC()->DefineOpSurface(
"surfRd", kUnified, kDielectric_dielectric, kPolishedbackpainted, 0.);
1332 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEfficMet[0]));
1333 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflMet[0]));
1334 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder0",
"0TOP", 1,
"0RFV", 1,
"surfRd");
1335 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder1",
"0TOP", 1,
"0RFH", 1,
"surfRd");
1336 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder2",
"0TOP", 1,
"0RFV", 2,
"surfRd");
1337 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder3",
"0TOP", 1,
"0RFH", 2,
"surfRd");
1339 TVirtualMC::GetMC()->DefineOpSurface(
"surFrontBWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1340 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1341 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1342 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderFrontBWindow",
"0REG", 1,
"0MTO", 1,
"surFrontBWindow");
1344 TVirtualMC::GetMC()->DefineOpSurface(
"surBackFrontWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1345 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1346 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1347 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderBackFrontWindow",
"0TOP", 1,
"0MTO", 1,
"surBackFrontWindow");
1352 for (Int_t
i = 0;
i < mPhotonEnergyD.size();
i++) {
1353 mReflBlackPaper.push_back(0.);
1354 mEffBlackPaper.push_back(0);
1355 mAbsBlackPaper.push_back(1);
1357 mReflFrontWindow.push_back(0.01);
1358 mEffFrontWindow.push_back(1);
1359 mRindexFrontWindow.push_back(1);
1361 mRindexAir.push_back(1.);
1362 mAbsorAir.push_back(0.3);
1363 mRindexCathodeNext.push_back(1);
1365 mAbsorbCathodeNext.push_back(1);
1366 mEfficMet.push_back(0);
1367 mRindexMet.push_back(1);
1368 mReflMet.push_back(1);
1375 float eff = mPMTeff->Eval(energy);
1376 float p = gRandom->Rndm();
1386 std::ifstream infile;
1387 infile.open(filePath.c_str());
1388 LOG(info) <<
" file " << filePath.c_str();
1390 if (infile.fail() ==
true) {
1395 std::string comment;
1396 if (!getline(infile, comment)) {
1397 LOG(error) <<
"Error opening ascii file (it is probably a folder!): " << filePath.c_str();
1400 getline(infile, comment);
1405 if (nLines < 0 || nLines > 1e4) {
1409 getline(infile, comment);
1410 getline(infile, comment);
1415 getline(infile, sLine);
1416 while (!infile.eof()) {
1417 if (iLine >= nLines) {
1421 std::stringstream ssLine(sLine);
1426 mPhotonEnergyD.push_back(energy);
1428 Double_t absorption;
1429 ssLine >> absorption;
1430 mAbsorptionLength.push_back(absorption);
1432 Double_t refraction;
1433 ssLine >> refraction;
1434 mRefractionIndex.push_back(refraction);
1436 Double_t efficiency;
1437 ssLine >> efficiency;
1438 mQuantumEfficiency.push_back(efficiency);
1439 if (!(ssLine.good() || ssLine.eof())) {
1444 getline(infile, sLine);
1447 if (iLine != mPhotonEnergyD.size()) {
1453 LOG(info) <<
"Optical properties taken from the file: " << filePath.c_str() <<
" Number of lines read: " << iLine;
1460 std::string inputDir;
1461 const char* aliceO2env = std::getenv(
"O2_ROOT");
1463 inputDir = aliceO2env;
1465 inputDir +=
"/share/Detectors/FT0/files/";
1467 TString indPath = inputDir +
"Sim2DataChannels.txt";
1468 gSystem->ExpandPathName(indPath);
1470 std::ifstream infile;
1471 infile.open(indPath.Data());
1472 LOG(info) <<
" file open " << indPath.Data();
1474 if (infile.fail() ==
true) {
1475 LOG(error) <<
"Error opening ascii file (it is probably a folder!): " << indPath;
1480 mSim2LUT[iind] = fromfile;
Definition of the Stack class.
Definition of the Detector class.
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"