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 Float_t ptopref[3] = {1.3241, 1.3241, 1.};
208 Double_t prfv[3] = {0.0002, 1.323, 1.};
209 Double_t prfh[3] = {1.323, 0.0002, 1.};
210 Float_t pmcp[3] = {2.949, 2.949, 0.66};
211 Float_t pmcpinner[3] = {2.749, 2.749, 0.1};
212 Float_t pmcpbase[3] = {2.949, 2.949, 0.675};
213 Float_t pmcpside[3] = {0.15, 2.949, 0.65};
214 Float_t pmcptopglass[3] = {2.949, 2.949, 0.1};
215 Float_t preg[3] = {1.324, 1.324, 0.005};
218 TGeoVolume*
top = gGeoManager->GetVolume(
"0TOP");
219 TVirtualMC::GetMC()->Gsvolu(
"0TRE",
"BOX",
getMediumID(
kAir), ptopref, 3);
220 TGeoVolume* topref = gGeoManager->GetVolume(
"0TRE");
222 TGeoVolume* rfv = gGeoManager->GetVolume(
"0RFV");
224 TGeoVolume* rfh = gGeoManager->GetVolume(
"0RFH");
227 TGeoVolume* cat = gGeoManager->GetVolume(
"0REG");
231 Int_t ntops = 0, nrfvs = 0, nrfhs = 0;
233 topref->AddNode(
top, 1,
new TGeoTranslation(0, 0, 0));
234 float xinv = -ptop[0] - prfv[0];
235 topref->AddNode(rfv, 1,
new TGeoTranslation(xinv, 0, 0));
236 xinv = ptop[0] + prfv[0];
237 topref->AddNode(rfv, 2,
new TGeoTranslation(xinv, 0, 0));
238 float yinv = -ptop[1] - prfh[1];
239 topref->AddNode(rfh, 1,
new TGeoTranslation(0, yinv, 0));
240 yinv = ptop[1] + prfh[1];
241 topref->AddNode(rfh, 2,
new TGeoTranslation(0, yinv, 0));
244 for (Int_t ix = 0; ix < 2; ix++) {
245 float xin = -mInStart[0] + 0.3 + (ix + 0.5) * 2 * ptopref[0];
246 for (Int_t iy = 0; iy < 2; iy++) {
247 float yin = -mInStart[1] + 0.3 + (iy + 0.5) * 2 * ptopref[1];
249 z = -mInStart[2] + ptopref[2];
250 ins->AddNode(topref, ntops,
new TGeoTranslation(xin, yin,
z));
251 LOG(
debug) <<
" n " << ntops <<
" x " << xin <<
" y " << yin <<
" z radiator " <<
z;
252 z += ptopref[2] + 2. * pmcptopglass[2] + preg[2];
253 ins->AddNode(cat, ntops,
new TGeoTranslation(xin, yin,
z));
254 LOG(
debug) <<
" n " << ntops <<
" x " << xin <<
" y " << yin <<
" z cathod " <<
z;
259 TGeoVolume* mcptop = gGeoManager->GetVolume(
"0MTO");
260 z = -mInStart[2] + 2 * ptopref[2] + pmcptopglass[2];
261 ins->AddNode(mcptop, 1,
new TGeoTranslation(0, 0,
z));
263 TVirtualMC::GetMC()->Gsvolu(
"0MCP",
"BOX",
getMediumID(
kAir), pmcp, 3);
264 TGeoVolume* mcp = gGeoManager->GetVolume(
"0MCP");
265 z = -mInStart[2] + 2 * ptopref[2] + 2 * pmcptopglass[2] + 2 * preg[2] + pmcp[2];
266 ins->AddNode(mcp, 1,
new TGeoTranslation(0, 0,
z));
269 TGeoVolume* mcpside = gGeoManager->GetVolume(
"0MSI");
270 x = -pmcp[0] + pmcpside[0];
271 y = -pmcp[1] + pmcpside[1];
272 mcp->AddNode(mcpside, 1,
new TGeoTranslation(
x,
y, 0));
273 x = pmcp[0] - pmcpside[0];
274 y = pmcp[1] - pmcpside[1];
275 mcp->AddNode(mcpside, 2,
new TGeoTranslation(
x,
y, 0));
276 x = -pmcp[1] + pmcpside[1];
277 y = -pmcp[0] + pmcpside[0];
278 mcp->AddNode(mcpside, 3,
new TGeoCombiTrans(
x,
y, 0,
new TGeoRotation(
"R2", 90, 0, 0)));
279 x = pmcp[1] - pmcpside[1];
280 y = pmcp[0] - pmcpside[0];
281 mcp->AddNode(mcpside, 4,
new TGeoCombiTrans(
x,
y, 0,
new TGeoRotation(
"R2", 90, 0, 0)));
284 TGeoVolume* mcpbase = gGeoManager->GetVolume(
"0MBA");
285 z = -mInStart[2] + 2 * ptopref[2] + pmcptopglass[2] + 2 * pmcp[2] + pmcpbase[2];
286 ins->AddNode(mcpbase, 1,
new TGeoTranslation(0, 0,
z));
293 float pcableplane[3] = {20, 20, 0.25};
295 TVirtualMC::GetMC()->Gsvolu(
"0CAA",
"BOX",
getMediumID(
kAir), pcableplane, 3);
296 TGeoVolume* cableplane = gGeoManager->GetVolume(
"0CAA");
299 double xcell[24], ycell[24];
300 for (
int imcp = 0; imcp < 24; imcp++) {
301 xcell[na] = mPosModuleAx[imcp];
302 ycell[na] = mPosModuleAy[imcp];
304 cableplane->AddNode(vol, na,
new TGeoTranslation(xcell[na], ycell[na], 0));
309 Float_t pcablesextend[3] = {2, 15, 0.245};
310 Float_t pcablesextendsmall[3] = {3, 2, 0.245};
311 Float_t* ppcablesextend[] = {pcablesextend, pcablesextend, pcablesextendsmall, pcablesextendsmall};
313 double xcell_side[] = {-mStartA[0] + pcablesextend[0], mStartA[0] - pcablesextend[0], 0, 0};
314 double ycell_side[] = {0, 0, -mStartA[1] + pcablesextendsmall[1], mStartA[1] - pcablesextendsmall[1]};
316 for (
int icab = 0; icab < 4; icab++) {
317 const std::string volName = Form(
"CAB%2.i", 52 + icab);
318 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
" BOX",
getMediumID(
kCable), ppcablesextend[icab], 3);
319 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
320 cableplane->AddNode(vol, 1,
new TGeoTranslation(xcell_side[icab], ycell_side[icab], 0));
322 float zcableplane = mStartA[2] - pcableplane[2] - 3;
323 stl->AddNode(cableplane, 1,
new TGeoTranslation(0, 0, zcableplane));
332 int mcpcables[52] = {2, 1, 2, 1, 2,
348 double xcell[ncells], ycell[ncells], zcell[ncells];
349 float xsize[3] = {1.8, 1.8, 2.6};
350 float ysize[3] = {0.6, 1.7, 2.};
351 float zsize[3] = {0.1, 0.1, 0.1};
353 int ic = mcpcables[mod];
355 calblesize[0] = xsize[ic - 1];
356 calblesize[1] = ysize[ic - 1];
357 calblesize[2] = zsize[ic - 1];
358 const std::string volName = Form(
"CAB%2.i", mod);
359 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
"BOX",
getMediumID(
kCable), calblesize, 3);
360 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
361 LOG(
debug) <<
"C cables " << mod <<
" " << volName <<
" " << ic;
374 LOG(info) <<
"Add FT0 alignable volumes";
377 LOG(fatal) <<
"TGeoManager doesn't exist !";
381 TString volPath = Form(
"/cave_1/barrel_1");
383 TString volPathA = volPath + Form(
"/FT0A_1");
384 TString symNameA =
"FT0A";
385 LOG(info) << symNameA <<
" <-> " << volPathA;
386 if (!gGeoManager->SetAlignableEntry(symNameA.Data(), volPathA.Data())) {
387 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
390 TString volPathC = volPath + Form(
"/FT0C_1");
391 TString symNameC =
"FT0C";
392 LOG(info) << symNameC <<
" <-> " << volPathC;
393 if (!gGeoManager->SetAlignableEntry(symNameC.Data(), volPathC.Data())) {
394 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
396 TString volPathMod, symNameMod;
399 volPathMod = volPath + Form(
"/0MOD_%d", imod);
400 symNameMod = Form(
"0MOD_%d", imod);
401 if (!gGeoManager->SetAlignableEntry(symNameMod.Data(), volPathMod.Data())) {
402 LOG(fatal) << (Form(
"Alignable entry %s not created. Volume path %s not valid", symNameMod.Data(), volPathMod.Data()));
419TGeoVolume* Detector::constructFrameAGeometry()
422 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
423 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
426 TGeoVolumeAssembly* FT0_Frame =
new TGeoVolumeAssembly(
"FT0_Frame");
429 Double_t blockdX = 37.1;
430 Double_t blockdY = 36.85;
431 Double_t blockdZ = 6.95;
432 TGeoBBox* block =
new TGeoBBox(
"block", blockdX / 2, blockdY / 2, blockdZ / 2);
438 Double_t box1dX = 1.57;
439 Double_t box1dY = 6.55;
440 Double_t box1PosX = -(blockdX / 2 - box1dX / 2);
441 Double_t box1PosY = 0;
442 TGeoBBox* box1 =
new TGeoBBox(
"box1", box1dX / 2, box1dY / 2, blockdZ / 2);
443 TGeoTranslation* box1Tr1 =
new TGeoTranslation(
"box1Tr1", box1PosX, box1PosY, 0);
444 box1Tr1->RegisterYourself();
445 TGeoTranslation* box1Tr2 =
new TGeoTranslation(
"box1Tr2", -box1PosX, -box1PosY, 0);
446 box1Tr2->RegisterYourself();
448 Double_t box2dX = 2.9;
449 Double_t box2dY = 15.1;
450 Double_t box2PosX = -(blockdX / 2 - box2dX / 2);
451 Double_t box2PosY = blockdY / 2 - box2dY / 2;
452 TGeoBBox* box2 =
new TGeoBBox(
"box2", box2dX / 2, box2dY / 2, blockdZ / 2);
453 TGeoTranslation* box2Tr1 =
new TGeoTranslation(
"box2Tr1", box2PosX, box2PosY, 0);
454 box2Tr1->RegisterYourself();
455 TGeoTranslation* box2Tr2 =
new TGeoTranslation(
"box2Tr2", -box2PosX, -box2PosY, 0);
456 box2Tr2->RegisterYourself();
460 Double_t box3dX = 12.7;
462 Double_t box3dZ = 5.45;
463 Double_t box3PosX = -(blockdX / 2 - box2dX - box3dZ / 2);
464 Double_t box3PosY = blockdY / 2 - box3dY / 2;
465 Double_t box3PosZ = blockdZ / 2 - box3dZ / 2;
466 TGeoBBox* box3 =
new TGeoBBox(
"box3", box3dX / 2, box3dY / 2, box3dZ / 2);
467 TGeoTranslation* box3Tr1 =
new TGeoTranslation(
"box3Tr1", box3PosX, box3PosY, box3PosZ);
468 box3Tr1->RegisterYourself();
469 TGeoTranslation* box3Tr2 =
new TGeoTranslation(
"box3Tr2", -box3PosX, -box3PosY, box3PosZ);
470 box3Tr2->RegisterYourself();
472 Double_t box4dX = 6.6;
473 Double_t box4dY = 1.67;
474 Double_t box4PosX = 0;
475 Double_t box4PosY = blockdY / 2 - box4dY / 2;
476 TGeoBBox* box4 =
new TGeoBBox(
"box4", box4dX / 2, box4dY / 2, blockdZ / 2);
477 TGeoTranslation* box4Tr1 =
new TGeoTranslation(
"box4Tr1", box4PosX, box4PosY, 0);
478 box4Tr1->RegisterYourself();
479 TGeoTranslation* box4Tr2 =
new TGeoTranslation(
"box4Tr2", -box4PosX, -box4PosY, 0);
480 box4Tr2->RegisterYourself();
482 Double_t box5dX = 15;
484 Double_t box5PosX = blockdX / 2 - box5dX / 2;
485 Double_t box5PosY = blockdY / 2 - box5dY / 2;
486 TGeoBBox* box5 =
new TGeoBBox(
"box5", box5dX / 2, box5dY / 2, blockdZ / 2);
487 TGeoTranslation* box5Tr1 =
new TGeoTranslation(
"box5Tr1", box5PosX, box5PosY, 0);
488 box5Tr1->RegisterYourself();
489 TGeoTranslation* box5Tr2 =
new TGeoTranslation(
"box5Tr2", -box5PosX, -box5PosY, 0);
490 box5Tr2->RegisterYourself();
494 Double_t box6dX = 2.9;
495 Double_t box6dY = 12.2;
496 Double_t box6dZ = 5.45;
497 Double_t box6PosX = blockdX / 2 - box6dX / 2;
498 Double_t box6PosY = blockdY / 2 - box5dY - box6dY / 2;
499 Double_t box6PosZ = blockdZ / 2 - box6dZ / 2;
500 TGeoBBox* box6 =
new TGeoBBox(
"box6", box6dX / 2, box6dY / 2, box6dZ / 2);
501 TGeoTranslation* box6Tr1 =
new TGeoTranslation(
"box6Tr1", box6PosX, box6PosY, box6PosZ);
502 box6Tr1->RegisterYourself();
503 TGeoTranslation* box6Tr2 =
new TGeoTranslation(
"box6Tr2", -box6PosX, -box6PosY, box6PosZ);
504 box6Tr2->RegisterYourself();
510 Double_t cbox1dX = 7.175;
511 Double_t cbox1dY = 5.5;
512 Double_t cbox1Xoffset = 14.425;
513 Double_t cbox1PosX = -(blockdX / 2 - cbox1Xoffset - cbox1dX / 2);
514 Double_t cbox1PosY = 0;
515 TGeoBBox* cbox1 =
new TGeoBBox(
"cbox1", cbox1dX / 2, cbox1dY / 2, blockdZ / 2);
516 TGeoTranslation* cbox1Tr1 =
new TGeoTranslation(
"cbox1Tr1", cbox1PosX, cbox1PosY, 0);
517 cbox1Tr1->RegisterYourself();
518 TGeoTranslation* cbox1Tr2 =
new TGeoTranslation(
"cbox1Tr2", -cbox1PosX, -cbox1PosY, 0);
519 cbox1Tr2->RegisterYourself();
521 Double_t cbox2dX = 5.75;
523 Double_t cbox2dY = 6.575;
524 Double_t cbox2Yoffset = 14.425;
525 Double_t cbox2PosX = 0;
526 Double_t cbox2PosY = blockdY / 2 - cbox2Yoffset - cbox2dY / 2;
527 TGeoBBox* cbox2 =
new TGeoBBox(
"cbox2", cbox2dX / 2, cbox2dY / 2, blockdZ / 2);
528 TGeoTranslation* cbox2Tr1 =
new TGeoTranslation(
"cbox2Tr1", cbox2PosX, cbox2PosY, 0);
529 cbox2Tr1->RegisterYourself();
530 TGeoTranslation* cbox2Tr2 =
new TGeoTranslation(
"cbox2Tr2", -cbox2PosX, -cbox2PosY, 0);
531 cbox2Tr2->RegisterYourself();
538 Double_t gapBoxdX = 0.1;
539 Double_t gapBoxdY = blockdY / 2;
540 Double_t gapPosX = -(sPmtSide / 2 + sEps + gapBoxdX / 2);
541 Double_t gapPosY = blockdY / 4;
542 TGeoBBox* gapBox =
new TGeoBBox(
"gapBox", gapBoxdX / 2, gapBoxdY / 2, blockdZ / 2);
543 TGeoTranslation* gapBoxTr1 =
new TGeoTranslation(
"gapBoxTr1", gapPosX, gapPosY, 0);
544 gapBoxTr1->RegisterYourself();
545 TGeoTranslation* gapBoxTr2 =
new TGeoTranslation(
"gapBoxTr2", -gapPosX, -gapPosY, 0);
546 gapBoxTr2->RegisterYourself();
550 std::string frameACompositeString =
"block ";
551 frameACompositeString +=
"- box1:box1Tr1 - box1:box1Tr2 ";
552 frameACompositeString +=
"- box2:box2Tr1 - box2:box2Tr2 ";
553 frameACompositeString +=
"- box3:box3Tr1 - box3:box3Tr2 ";
554 frameACompositeString +=
"- box4:box4Tr1 - box4:box4Tr2 ";
555 frameACompositeString +=
"- box5:box5Tr1 - box5:box5Tr2 ";
556 frameACompositeString +=
"- box6:box6Tr1 - box6:box6Tr2 ";
557 frameACompositeString +=
"- cbox1:cbox1Tr1 - cbox1:cbox1Tr2 ";
558 frameACompositeString +=
"- cbox2:cbox2Tr1 - cbox2:cbox2Tr2 ";
559 frameACompositeString +=
"- gapBox:gapBoxTr1 - gapBox:gapBoxTr2";
569 Double_t coverPlatedZ = 0.2;
570 Double_t fiberPlatedZ = 0.5;
573 Double_t opticalFiberHeaddY = 0.52;
574 Double_t opticalFiberHeaddX = 1.142;
580 Double_t fh1TopPosX = -1.6;
581 Double_t fh1TopPosY = 1.325;
582 Double_t fh1BotPosX = 1.555;
583 Double_t fh1BotPosY = 1.249;
584 Double_t fh1BotAngle = 16;
588 Double_t fh2TopPosX = -1.563;
589 Double_t fh2TopPosY = 1.4625;
590 Double_t fh2TopAngle = 60;
592 Double_t fh2BotPosX = 1.084;
593 Double_t fh2BotPosY = 1.186;
594 Double_t fh2BotAngle = -30;
597 TGeoBBox* coverPlate =
new TGeoBBox(
"coverPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, coverPlatedZ / 2);
598 TGeoBBox* fiberPlate =
new TGeoBBox(
"fiberPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, fiberPlatedZ / 2);
599 TGeoBBox* opticalFiberHead =
new TGeoBBox(
"opticalFiberHead", opticalFiberHeaddX / 2, opticalFiberHeaddY / 2, fiberPlatedZ / 2);
602 TGeoTranslation* coverPlateTr =
new TGeoTranslation(
"coverPlateTr", 0, 0, fiberPlatedZ / 2 + coverPlatedZ / 2);
603 coverPlateTr->RegisterYourself();
604 TGeoTranslation* fh1TopTr1 =
new TGeoTranslation(
"fh1TopTr1", fh1TopPosX, fh1TopPosY, 0);
605 fh1TopTr1->RegisterYourself();
606 TGeoTranslation* fh1TopTr2 =
new TGeoTranslation(
"fh1TopTr2", fh1TopPosX, -fh1TopPosY, 0);
607 fh1TopTr2->RegisterYourself();
608 TGeoCombiTrans* fh1BotTr1 =
new TGeoCombiTrans(
"fh1BotTr1", fh1BotPosX, fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot1", fh1BotAngle, 0, 0));
609 fh1BotTr1->RegisterYourself();
610 TGeoCombiTrans* fh1BotTr2 =
new TGeoCombiTrans(
"fh1BotTr2", fh1BotPosX, -fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot2", -fh1BotAngle, 0, 0));
611 fh1BotTr2->RegisterYourself();
612 TGeoCombiTrans* fh2TopTr1 =
new TGeoCombiTrans(
"fh2TopTr1", fh2TopPosX, fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot1", fh2TopAngle + 90, 0, 0));
613 fh2TopTr1->RegisterYourself();
614 TGeoCombiTrans* fh2TopTr2 =
new TGeoCombiTrans(
"fh2TopTr2", fh2TopPosX, -fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot2", -fh2TopAngle - 90, 0, 0));
615 fh2TopTr2->RegisterYourself();
616 TGeoCombiTrans* fh2BotTr1 =
new TGeoCombiTrans(
"fh2BotTr1", fh2BotPosX, fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot1", -fh2BotAngle, 0, 0));
617 fh2BotTr1->RegisterYourself();
618 TGeoCombiTrans* fh2BotTr2 =
new TGeoCombiTrans(
"fh2BotTr2", fh2BotPosX, -fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot2", fh2BotAngle, 0, 0));
619 fh2BotTr2->RegisterYourself();
622 std::string outerPlateGroupString =
"fiberPlate ";
623 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr1 ";
624 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr2 ";
625 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr1 ";
626 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr2 ";
627 outerPlateGroupString +=
"+ coverPlate:coverPlateTr";
630 TGeoCompositeShape* outerPlateGroup =
new TGeoCompositeShape(
"outerPlateGroup", outerPlateGroupString.c_str());
633 std::string innerPlateGroupString =
"fiberPlate ";
634 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr1 ";
635 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr2 ";
636 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr1 ";
637 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr2 ";
638 innerPlateGroupString +=
"+ coverPlate:coverPlateTr";
641 TGeoCompositeShape* innerPlateGroup =
new TGeoCompositeShape(
"innerPlateGroup", innerPlateGroupString.c_str());
646 Double_t backPlanedZ = 0.25;
647 Double_t socketdZ = blockdZ - backPlanedZ;
650 TGeoVolume* socket = gGeoManager->MakeBox(
"Socket", Vacuum, sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, socketdZ / 2);
654 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};
657 TString nameTrSocket;
659 TString nameTrPlateGroup;
666 nameTrSocket = Form(
"trSocket%i", itr + 1);
667 float z = -backPlanedZ / 4.0;
668 trSocket[itr] =
new TGeoTranslation(nameTrSocket.Data(), mPosModuleAx[itr], mPosModuleAy[itr],
z);
669 trSocket[itr]->RegisterYourself();
670 frameACompositeString +=
"- Socket:";
671 frameACompositeString += nameTrSocket.Data();
673 nameTrPlateGroup = Form(
"trPlateGroup%i", itr + 1);
674 namePGRot = Form(
"pgRot%i", itr + 1);
675 float z2 = -blockdZ / 2 + (coverPlatedZ + fiberPlatedZ) / 2;
676 trPlateGroup[itr] =
new TGeoCombiTrans(nameTrPlateGroup.Data(), mPosModuleAx[itr], mPosModuleAy[itr], z2,
new TGeoRotation(namePGRot.Data(), rotAngle[itr], 0, 0));
677 trPlateGroup[itr]->RegisterYourself();
679 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) {
680 frameACompositeString +=
" + outerPlateGroup:";
681 frameACompositeString += nameTrPlateGroup.Data();
682 frameACompositeString +=
" ";
684 frameACompositeString +=
" + innerPlateGroup:";
685 frameACompositeString += nameTrPlateGroup.Data();
686 frameACompositeString +=
" ";
691 TGeoVolume* frameA =
new TGeoVolume(
"frameA",
new TGeoCompositeShape(
"frameA", frameACompositeString.c_str()), Al);
694 FT0_Frame->AddNode(frameA, 1);
703TGeoVolume* Detector::constructFrameCGeometry()
707 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
708 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
709 static constexpr Double_t sFrameZC = 5.5632;
710 static constexpr Double_t frameHeightC = 2.5;
713 static constexpr Double_t sensShift = 0.5;
714 static constexpr Double_t sQuartzRadiatorZC = 1.94360;
715 static constexpr Double_t sQuartzHeightC = (-sFrameZC / 2 + sQuartzRadiatorZC / 2);
716 static constexpr Double_t sPmtZC = 3.600;
717 static constexpr Double_t sPmtHeightC = (sFrameZC / 2 - sPmtZC / 2);
725 Float_t rMax = rMin + sFrameZC;
730 Float_t pinstart[3] = {2.9491, 2.9491, 2.5};
731 Float_t pstartC[3] = {20., 20, 5};
734 Double_t xCorn = multCorn * (-14.75272569);
735 Double_t yCorn = multCorn * (14.9043284);
736 Double_t zCorn = 79.27306024;
738 Double_t xCorn2 = -xCorn;
739 Double_t yCorn2 = yCorn;
740 Double_t zCorn2 = zCorn;
742 Double_t acCorn = TMath::ATan(yCorn / xCorn) - TMath::Pi() / 2 + 2 * TMath::Pi();
743 Double_t bcCorn = TMath::ACos(zCorn / crad);
744 Double_t gcCorn = -1 * acCorn;
748 Double_t flopsErr = 0.00001;
752 Double_t errPMTZ = 10 * sEps;
753 Double_t errPMTXY = 0.02;
754 Double_t errQrdZ = 0.143 + 0.22;
755 Double_t errQrdXY = 0.35;
762 TGeoSphere* sphere1 =
new TGeoSphere(
"sphere1", rMin, rMax, tMin, tMax, pMin, pMax);
763 TGeoSphere* sphere2 =
new TGeoSphere(
"sphere2", rMin - sweep, rMax + sweep, tMin, tMax, pMin, pMax);
764 TGeoSphere* sphere3 =
new TGeoSphere(
"sphere3", rMin, rMin + backPlateZ, tMin, tMax, pMin, pMax);
765 TGeoSphere* sphere4 =
new TGeoSphere(
"sphere4", rMin - sweep, rMax + backPlateZ + sweep, tMin, tMax, pMin, pMax);
767 TGeoBBox* insSeat =
new TGeoBBox(
"insSeat", pinstart[0] * 2, pinstart[1] * 2, pinstart[2] * 2);
769 TGeoBBox* quartzRadiatorSeat =
new TGeoBBox(
"quartzRadiatorSeat",
770 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
771 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
772 sQuartzRadiatorZC / 2 + sEps + errQrdZ);
774 TGeoBBox* pmtBoxSeat =
new TGeoBBox(
"pmtBoxSeat",
775 sPmtSide / 2 + sEps + errPMTXY,
776 sPmtSide / 2 + sEps + errPMTXY,
777 sPmtZ / 2 + sEps + errPMTZ);
778 TGeoBBox* pmtCornerRect =
new TGeoBBox(
"pmtCornerRect",
779 sCornerRadius / 2 - flopsErr,
780 sCornerRadius / 2 - flopsErr,
783 TGeoBBox* framecornerBox =
new TGeoBBox(
"framecornerBox", 5, 5, 10);
786 TGeoRotation* rot1 =
new TGeoRotation(
"rot1", 90, 0, 0);
787 rot1->RegisterYourself();
788 TGeoCombiTrans* rotTr1 =
new TGeoCombiTrans(
"rotTr1", -20, -1, -5, rot1);
789 rotTr1->RegisterYourself();
791 TGeoRotation* rot2 =
new TGeoRotation(
"rot2", -90, 0, 0);
792 rot2->RegisterYourself();
793 TGeoCombiTrans* rotTr2 =
new TGeoCombiTrans(
"rotTr2", 20, -1, -5, rot2);
794 rotTr2->RegisterYourself();
796 TGeoRotation* rot3 =
new TGeoRotation(
"rot3", 0, 0, 0);
797 rot3->RegisterYourself();
798 TGeoCombiTrans* rotTr3 =
new TGeoCombiTrans(
"rotTr3", 0, 20, -5, rot3);
799 rotTr3->RegisterYourself();
801 TGeoTranslation* centerTrans =
new TGeoTranslation(
"centerTrans", 0, 0, 85);
802 centerTrans->RegisterYourself();
804 TGeoRotation* reflectC1 =
new TGeoRotation(
"reflectC1", 0, 0, 0);
805 reflectC1->ReflectX(
true);
806 reflectC1->ReflectY(
true);
807 reflectC1->RegisterYourself();
809 TGeoRotation* rotCorners =
new TGeoRotation(
"rotCorners", acCorn, bcCorn, gcCorn);
810 rotCorners->RegisterYourself();
812 TGeoCombiTrans* comCorners =
new TGeoCombiTrans(
"comCorners", xCorn, yCorn, zCorn, rotCorners);
813 comCorners->RegisterYourself();
815 TGeoCombiTrans* comCorners2 =
new TGeoCombiTrans(
"comCorners2", xCorn2, yCorn2, zCorn2, rotCorners);
816 comCorners2->RegisterYourself();
819 std::string shellString =
"";
820 shellString +=
"sphere1";
821 shellString +=
"- sphere2:rotTr1";
822 shellString +=
"- sphere2:rotTr2";
823 shellString +=
"- sphere2:rotTr3";
824 shellString +=
"- insSeat:centerTrans";
825 shellString +=
"- framecornerBox:comCorners";
826 shellString +=
"- framecornerBox:comCorners2";
829 std::string backPlateString =
"";
830 backPlateString +=
"sphere3";
831 backPlateString +=
"- sphere4:rotTr1";
832 backPlateString +=
"- sphere4:rotTr2";
833 backPlateString +=
"- sphere4:rotTr3";
834 backPlateString +=
"- insSeat:centerTrans";
835 backPlateString +=
"- framecornerBox:comCorners";
836 backPlateString +=
"- framecornerBox:comCorners2";
840 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};
841 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};
843 Double_t zi[NCellsC];
844 for (Int_t ic = 0; ic < NCellsC; ic++) {
845 zi[ic] = TMath::Sqrt(TMath::Power(crad, 2) - TMath::Power(xi[ic], 2) - TMath::Power(yi[ic], 2));
849 Double_t ac[NCellsC],
bc[NCellsC], gc[NCellsC];
850 for (Int_t
i = 0;
i < NCellsC;
i++) {
851 ac[
i] = TMath::ATan(yi[
i] / xi[
i]) - TMath::Pi() / 2 + 2 * TMath::Pi();
853 bc[
i] = TMath::ACos(zi[
i] / crad);
855 bc[
i] = -1 * TMath::ACos(zi[
i] / crad);
859 Double_t xc2[NCellsC], yc2[NCellsC], zc2[NCellsC];
863 Double_t rcomp = crad + pstartC[2] / 2.0;
864 for (Int_t
i = 0;
i < NCellsC;
i++) {
866 xc2[
i] = rcomp * TMath::Cos(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
867 yc2[
i] = rcomp * TMath::Sin(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
868 zc2[
i] = rcomp * TMath::Cos(
bc[
i]);
871 ac[
i] *= 180 / TMath::Pi();
872 bc[
i] *= 180 / TMath::Pi();
876 Double_t rmag = sqrt(xc2[0] * xc2[0] + yc2[0] * yc2[0] + zc2[0] * zc2[0]);
878 Double_t scalePMT = (rmag + (frameHeightC / 2.0) - (sPmtHeightC / 2)) / rmag;
879 Double_t scaleQrad = (rmag + (frameHeightC / 2.0) - sPmtHeightC - (sQuartzRadiatorZC / 2.0)) / rmag;
881 Double_t xPMT[NCellsC];
882 Double_t yPMT[NCellsC];
883 Double_t zPMT[NCellsC];
885 Double_t xQrad[NCellsC];
886 Double_t yQrad[NCellsC];
887 Double_t zQrad[NCellsC];
889 Double_t rotC[NCellsC];
890 Double_t comC[NCellsC];
892 for (Int_t
i = 0;
i < NCellsC;
i++) {
894 xPMT[
i] = scalePMT * xc2[
i];
895 yPMT[
i] = scalePMT * yc2[
i];
896 zPMT[
i] = scalePMT * zc2[
i];
899 xQrad[
i] = scaleQrad * xc2[
i];
900 yQrad[
i] = scaleQrad * yc2[
i];
901 zQrad[
i] = scaleQrad * zc2[
i];
906 TString nameComQuartz;
907 TString nameComPlates;
910 for (Int_t itr = NCellsA; itr < NCellsA + NCellsC; itr++) {
911 nameRot = Form(
"0Rot%i", itr + 1);
912 int ic = itr - NCellsA;
913 nameComPMT = Form(
"0ComPMT%i", ic + 1);
914 nameComQuartz = Form(
"0ComQuartz%i", ic + 1);
919 TGeoRotation* rotC =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
920 rotC->RegisterYourself();
922 TGeoCombiTrans* comC =
new TGeoCombiTrans(nameComC.Data(), xc2[ic], yc2[ic], zc2[ic], rotC);
923 comC->RegisterYourself();
925 TGeoRotation* rotPMT =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
926 rotPMT->RegisterYourself();
928 TGeoCombiTrans* comPMT =
new TGeoCombiTrans(nameComPMT.Data(),
931 comPMT->RegisterYourself();
933 TGeoRotation* rotQuartz =
new TGeoRotation(nameRot.Data(),
934 ac[ic],
bc[ic], gc[ic]);
935 rotQuartz->RegisterYourself();
937 TGeoCombiTrans* comQuartz =
new TGeoCombiTrans(nameComQuartz.Data(),
938 xQrad[ic], yQrad[ic],
939 zQrad[ic] - (sQuartzRadiatorZC / 2 + 3 * sEps),
941 comQuartz->RegisterYourself();
943 TGeoRotation* rotPlates =
new TGeoRotation(nameRot.Data(),
944 ac[ic],
bc[ic], gc[ic]);
945 rotPlates->RegisterYourself();
946 TGeoCombiTrans* comPlates =
new TGeoCombiTrans(nameComPlates.Data(),
947 xQrad[ic], yQrad[ic],
950 comPlates->RegisterYourself();
953 std::string pmtCombiString =
"";
954 pmtCombiString +=
"- ";
955 pmtCombiString +=
"pmtBoxSeat:";
956 pmtCombiString += nameComPMT.Data();
957 shellString += pmtCombiString;
960 std::string quartzCombiString =
"";
961 quartzCombiString +=
"- ";
962 quartzCombiString +=
"quartzRadiatorSeat:";
963 quartzCombiString += nameComQuartz.Data();
964 shellString += quartzCombiString;
969 TGeoCompositeShape* shellCompShape =
new TGeoCompositeShape(
"shellCompShape", shellString.c_str());
971 TGeoVolume* shellVol =
new TGeoVolume(
"shellVol", shellCompShape, Al);
974 TGeoVolumeAssembly* FT0_C_Frame =
new TGeoVolumeAssembly(
"FT0_C_Frame");
977 TGeoTranslation* shellTr1 =
new TGeoTranslation(
"shellTr1", 0, 0, -80);
978 shellTr1->RegisterYourself();
980 TGeoCombiTrans* shellTr2 =
new TGeoCombiTrans(
"shellTr2", 0, 0, -80, reflectC1);
981 shellTr2->RegisterYourself();
983 FT0_C_Frame->AddNode(shellVol, 1, shellTr1);
984 FT0_C_Frame->AddNode(shellVol, 2, shellTr2);
986 TGeoTranslation* backPlateTr1 =
new TGeoTranslation(
"backPlateTr1", 0, 0, -74);
987 backPlateTr1->RegisterYourself();
989 TGeoCombiTrans* backPlateTr2 =
new TGeoCombiTrans(
"backPlateTr2", 0, 0, -74, reflectC1);
990 backPlateTr2->RegisterYourself();
992 TGeoCompositeShape* backPlateShape =
new TGeoCompositeShape(
"backPlateShape", backPlateString.c_str());
993 TGeoVolume* backPlateVol =
new TGeoVolume(
"backPlateVol", backPlateShape, Al);
995 FT0_C_Frame->AddNode(backPlateVol, 3, backPlateTr1);
996 FT0_C_Frame->AddNode(backPlateVol, 4, backPlateTr2);
1001std::string Detector::cPlateShapeString()
1003 Double_t prismHeight = 0.3895;
1004 Double_t prismSide = 5.9;
1005 Double_t radCurve = 81.9469;
1006 Double_t delHeight = radCurve * (1.0 - TMath::Sqrt(1.0 - 0.5 * TMath::Power(prismSide / radCurve, 2.0)));
1009 Double_t heightBase = prismHeight + delHeight;
1010 Double_t sliceSide = 5.3;
1011 Double_t heightBaseBox = 2 * heightBase;
1012 Double_t totalHeight = 0.5;
1013 Double_t sliceHeight = 0.5 - heightBase;
1016 Double_t cableHoleWidth = 0.3503;
1017 Double_t cableHoleLength = 0.9003;
1018 Double_t cableHoleDepth = 1;
1023 Double_t sHolesBottomEdge = 1.585;
1024 Double_t sHolesTopEdge = 0.515;
1025 Double_t sHolesAvgTopBottom = (sHolesBottomEdge + sHolesTopEdge) / 2.0;
1026 Double_t sHolesUpFromCenter = ((sliceSide / 2.0) - sHolesAvgTopBottom);
1028 Double_t sHolesFarEdge = 1.585;
1029 Double_t sHolesNearEdge = 1.065;
1030 Double_t sHolesAvgNearFar = (sHolesFarEdge + sHolesNearEdge) / 2.0;
1031 Double_t sHolesLateralFromCenter = ((sliceSide / 2.0) - sHolesAvgNearFar);
1034 TGeoBBox*
box =
new TGeoBBox(
"BASE", prismSide / 2.0, heightBaseBox / 2.0, prismSide / 2.0);
1037 TGeoBBox* slice =
new TGeoBBox(
"SLICE", sliceSide / 2.0, heightBaseBox / 2.0, sliceSide / 2.0);
1038 TGeoBBox* cableHole =
new TGeoBBox(
"CABLE", cableHoleLength / 2.0, cableHoleDepth / 2.0, cableHoleWidth / 2.0);
1039 TGeoBBox* cableHole2 =
new TGeoBBox(
"CABLE2", cableHoleWidth / 2.0, cableHoleLength / 2.0, cableHoleDepth / 2.0);
1041 TGeoSphere* baseShape =
new TGeoSphere(
"BASE_SUBTRACTION", radCurve, radCurve + 5.0, 80, 100, 80, 100);
1043 TGeoTranslation* rTrans =
new TGeoTranslation(
"rTrans", 0, radCurve, 0);
1044 rTrans->RegisterYourself();
1046 TGeoTranslation* rBackTrans =
new TGeoTranslation(
"rBackTrans", 0, -1.0 * radCurve, 0);
1047 rBackTrans->RegisterYourself();
1049 TGeoTranslation* subSliceTrans =
new TGeoTranslation(
"subSliceTrans", 0, (heightBaseBox / 2.0) + sliceHeight, 0);
1050 subSliceTrans->RegisterYourself();
1052 TGeoTranslation* sHolesTopLeftTrans =
new TGeoTranslation(
"sHolesTopLeftTrans", sHolesUpFromCenter, 0, sHolesLateralFromCenter);
1053 sHolesTopLeftTrans->RegisterYourself();
1055 TGeoTranslation* sHolesTopRightTrans =
new TGeoTranslation(
"sHolesTopRightTrans", sHolesUpFromCenter, 0, -1.0 * sHolesLateralFromCenter);
1056 sHolesTopRightTrans->RegisterYourself();
1058 TGeoTranslation* testTrans =
new TGeoTranslation(
"testTrans", 0.1, 0.1, 0);
1059 testTrans->RegisterYourself();
1061 TGeoRotation* switchToZ =
new TGeoRotation(
"switchToZ", 90, 90, 0);
1062 switchToZ->RegisterYourself();
1064 TGeoRotation* rotateHolesLeft =
new TGeoRotation(
"rotateHolesLeft", 345, 0, 0);
1065 rotateHolesLeft->RegisterYourself();
1067 TGeoRotation* rotateHolesRight =
new TGeoRotation(
"rotatetHolesRight", 15, 0, 0);
1068 rotateHolesRight->RegisterYourself();
1071 TGeoCombiTrans* rHolesBottomLeftTrans =
new TGeoCombiTrans(
"rHolesBottomLeftTrans", -1.0 * sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesLeft);
1072 rHolesBottomLeftTrans->RegisterYourself();
1074 TGeoCombiTrans* rHolesBottomRightTrans =
new TGeoCombiTrans(
"rHolesBottomRightTrans", sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesRight);
1075 rHolesBottomRightTrans->RegisterYourself();
1077 std::string plateString =
" ";
1078 plateString +=
"(((BASE:rTrans";
1079 plateString +=
"- BASE_SUBTRACTION)";
1080 plateString +=
"+ (SLICE:rTrans))";
1081 plateString +=
":rBackTrans";
1082 plateString +=
"- BASE:subSliceTrans";
1083 plateString +=
"- (CABLE:sHolesTopLeftTrans)";
1084 plateString +=
"- (CABLE:sHolesTopRightTrans))";
1085 plateString +=
":switchToZ";
1086 plateString +=
"- (CABLE2:rHolesBottomLeftTrans)";
1087 plateString +=
"- (CABLE2:rHolesBottomRightTrans)";
1098 Int_t volID = fMC->CurrentVolID(copy);
1100 TVirtualMCStack*
stack = fMC->GetStack();
1101 Int_t quadrant, mcp;
1102 if (fMC->IsTrackEntering()) {
1104 fMC->TrackPosition(
x,
y,
z);
1105 fMC->CurrentVolID(quadrant);
1106 fMC->CurrentVolOffID(1, mcp);
1107 float time = fMC->TrackTime() * 1.0e9;
1108 int trackID =
stack->GetCurrentTrackNumber();
1109 int detID = mSim2LUT[4 * mcp + quadrant - 1];
1110 int iPart = fMC->TrackPid();
1111 if (fMC->TrackCharge() && volID == mREGVolID) {
1114 if (iPart == 50000050) {
1115 float etot = fMC->Etot();
1116 float enDep = fMC->Edep();
1117 Int_t parentID =
stack->GetCurrentTrack()->GetMother(0);
1118 if (volID == mTOPVolID) {
1123 mTrackIdTop = trackID;
1126 if (volID == mMTOVolID) {
1127 if (trackID != mTrackIdTop) {
1132 mTrackIdMCPtop = trackID;
1136 if (volID == mREGVolID) {
1137 if (trackID != mTrackIdTop && trackID != mTrackIdMCPtop) {
1142 if (trackID == mTrackIdTop || trackID == mTrackIdMCPtop) {
1155 mHits->emplace_back(
x,
y,
z,
time, energy, trackId, detId);
1158 stack->addHit(GetDetId());
1160 return &(mHits->back());
1169 if (FairRootManager::Instance()) {
1170 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits, kTRUE);
1191 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
1192 Float_t zAir[4] = {6., 7., 8., 18.};
1193 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
1197 Float_t aglass[2] = {28.0855, 15.9994};
1198 Float_t zglass[2] = {14., 8.};
1211 Float_t aCeramic[2] = {26.981539, 15.9994};
1212 Float_t zCeramic[2] = {13., 8.};
1213 Float_t wCeramic[2] = {2., 3.};
1217 const Int_t nCeramicNice = 3;
1218 Float_t aCeramicNicel[3] = {26.981539, 15.9994, 58.6934};
1219 Float_t zCeramicNicel[3] = {13., 8., 28};
1220 Float_t wCeramicNicel[3] = {0.2, 0.3, 0.5};
1221 Float_t denscerCeramicNickel = 5.6;
1225 const Int_t nPlast = 4;
1226 Float_t aPlast[nPlast] = {1.00784, 12.0107, 15.999, 63.54};
1227 Float_t zPlast[nPlast] = {1, 6, 8, 29};
1228 Float_t wPlast[nPlast] = {0.08, 0.53, 0.22, 0.17};
1229 const Float_t denCable = 3.66;
1237 Material(11,
"Aliminium$", 26.98, 13.0, 2.7, 8.9, 999);
1238 Mixture(1,
"Vacuum$", aAir, zAir, dAir1, 4, wAir);
1239 Mixture(2,
"Air$", aAir, zAir, dAir, 4, wAir);
1240 Mixture(4,
"MCP glass $", aglass, zglass, dglass_mcp, -2, wglass);
1241 Mixture(24,
"Radiator Optical glass$", aglass, zglass, dglass, -2, wglass);
1242 Mixture(3,
"Ceramic$", aCeramic, zCeramic, denscer, -2, wCeramic);
1243 Mixture(23,
"CablePlasticCooper$", aPlast, zPlast, denCable, 4, wPlast);
1244 Mixture(25,
"MCPwalls $", aCeramicNicel, zCeramicNicel, denscerCeramicNickel, 3, wCeramicNicel);
1246 Medium(1,
"Air$", 2, 0, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1247 Medium(3,
"Vacuum$", 1, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1248 Medium(4,
"Ceramic$", 3, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1249 Medium(6,
"Glass$", 4, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1250 Medium(15,
"Aluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1251 Medium(17,
"OptAluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1252 Medium(16,
"OpticalGlass$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .01);
1253 Medium(19,
"OpticalGlassCathode$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1255 Medium(23,
"Cables$", 23, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1256 Medium(25,
"MCPWalls", 25, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1264 const char* aliceO2env = std::getenv(
"O2_ROOT");
1266 inputDir = aliceO2env;
1268 inputDir +=
"/share/Detectors/FT0/files/";
1270 TString optPropPath = inputDir +
"quartzOptProperties.txt";
1271 optPropPath = gSystem->ExpandPathName(optPropPath.Data());
1276 LOG(error) <<
"Could not read FIT optical properties " <<
result <<
" " << optPropPath.Data();
1279 Int_t nBins = mPhotonEnergyD.size();
1281 mPMTeff =
new TGraph(nBins, &(mPhotonEnergyD[0]), &(mQuantumEfficiency[0]));
1287 TVirtualMC::GetMC()->SetCerenkov(
getMediumID(
kOpGlass), nBins, &(mPhotonEnergyD[0]), &(mAbsorptionLength[0]),
1288 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1290 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1293 TVirtualMC::GetMC()->DefineOpSurface(
"surfRd", kUnified, kDielectric_dielectric, kPolishedbackpainted, 0.);
1294 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEfficMet[0]));
1295 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflMet[0]));
1296 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder0",
"0TOP", 1,
"0RFV", 1,
"surfRd");
1297 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder1",
"0TOP", 1,
"0RFH", 1,
"surfRd");
1298 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder2",
"0TOP", 1,
"0RFV", 2,
"surfRd");
1299 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder3",
"0TOP", 1,
"0RFH", 2,
"surfRd");
1301 TVirtualMC::GetMC()->DefineOpSurface(
"surFrontBWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1302 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1303 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1304 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderFrontBWindow",
"0REG", 1,
"0MTO", 1,
"surFrontBWindow");
1306 TVirtualMC::GetMC()->DefineOpSurface(
"surBackFrontWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1307 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1308 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1309 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderBackFrontWindow",
"0TOP", 1,
"0MTO", 1,
"surBackFrontWindow");
1314 for (Int_t
i = 0;
i < mPhotonEnergyD.size();
i++) {
1315 mReflBlackPaper.push_back(0.);
1316 mEffBlackPaper.push_back(0);
1317 mAbsBlackPaper.push_back(1);
1319 mReflFrontWindow.push_back(0.01);
1320 mEffFrontWindow.push_back(1);
1321 mRindexFrontWindow.push_back(1);
1323 mRindexAir.push_back(1.);
1324 mAbsorAir.push_back(0.3);
1325 mRindexCathodeNext.push_back(1);
1327 mAbsorbCathodeNext.push_back(1);
1328 mEfficMet.push_back(0);
1329 mRindexMet.push_back(1);
1330 mReflMet.push_back(1);
1337 float eff = mPMTeff->Eval(energy);
1338 float p = gRandom->Rndm();
1348 std::ifstream infile;
1349 infile.open(filePath.c_str());
1350 LOG(info) <<
" file " << filePath.c_str();
1352 if (infile.fail() ==
true) {
1357 std::string comment;
1358 if (!getline(infile, comment)) {
1359 LOG(error) <<
"Error opening ascii file (it is probably a folder!): " << filePath.c_str();
1362 getline(infile, comment);
1367 if (nLines < 0 || nLines > 1e4) {
1371 getline(infile, comment);
1372 getline(infile, comment);
1377 getline(infile, sLine);
1378 while (!infile.eof()) {
1379 if (iLine >= nLines) {
1383 std::stringstream ssLine(sLine);
1388 mPhotonEnergyD.push_back(energy);
1390 Double_t absorption;
1391 ssLine >> absorption;
1392 mAbsorptionLength.push_back(absorption);
1394 Double_t refraction;
1395 ssLine >> refraction;
1396 mRefractionIndex.push_back(refraction);
1398 Double_t efficiency;
1399 ssLine >> efficiency;
1400 mQuantumEfficiency.push_back(efficiency);
1401 if (!(ssLine.good() || ssLine.eof())) {
1406 getline(infile, sLine);
1409 if (iLine != mPhotonEnergyD.size()) {
1415 LOG(info) <<
"Optical properties taken from the file: " << filePath.c_str() <<
" Number of lines read: " << iLine;
1422 std::string inputDir;
1423 const char* aliceO2env = std::getenv(
"O2_ROOT");
1425 inputDir = aliceO2env;
1427 inputDir +=
"/share/Detectors/FT0/files/";
1429 std::string indPath = inputDir +
"Sim2DataChannels.txt";
1430 indPath = gSystem->ExpandPathName(indPath.data());
1432 std::ifstream infile;
1433 infile.open(indPath.data());
1434 LOG(info) <<
" file open " << indPath.data();
1436 if (infile.fail() ==
true) {
1437 LOG(error) <<
"Error opening ascii file (it is probably a folder!): " << indPath.c_str();
1442 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"