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");
300 const float kBeamPipeHoleRadius = 3.;
301 new TGeoBBox(
"0CAAbox", pcableplane[0], pcableplane[1], pcableplane[2]);
302 new TGeoTube(
"0CAAhole", 0., kBeamPipeHoleRadius, pcableplane[2] + 0.1);
303 cableplane->SetShape(
new TGeoCompositeShape(
"0CAAshape",
"0CAAbox-0CAAhole"));
306 double xcell[24], ycell[24];
307 for (
int imcp = 0; imcp < 24; imcp++) {
308 xcell[na] = mPosModuleAx[imcp];
309 ycell[na] = mPosModuleAy[imcp];
311 cableplane->AddNode(vol, na,
new TGeoTranslation(xcell[na], ycell[na], 0));
316 Float_t pcablesextend[3] = {2, 15, 0.245};
317 Float_t pcablesextendsmall[3] = {3, 2, 0.245};
318 Float_t* ppcablesextend[] = {pcablesextend, pcablesextend, pcablesextendsmall, pcablesextendsmall};
320 double xcell_side[] = {-mStartA[0] + pcablesextend[0], mStartA[0] - pcablesextend[0], 0, 0};
321 double ycell_side[] = {0, 0, -mStartA[1] + pcablesextendsmall[1], mStartA[1] - pcablesextendsmall[1]};
323 for (
int icab = 0; icab < 4; icab++) {
324 const std::string volName = Form(
"CAB%2.i", 52 + icab);
325 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
" BOX",
getMediumID(
kCable), ppcablesextend[icab], 3);
326 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
327 cableplane->AddNode(vol, 1,
new TGeoTranslation(xcell_side[icab], ycell_side[icab], 0));
329 float zcableplane = mStartA[2] - pcableplane[2] - 3;
330 stl->AddNode(cableplane, 1,
new TGeoTranslation(0, 0, zcableplane));
339 int mcpcables[52] = {2, 1, 2, 1, 2,
355 double xcell[ncells], ycell[ncells], zcell[ncells];
356 float xsize[3] = {1.8, 1.8, 2.6};
357 float ysize[3] = {0.6, 1.7, 2.};
358 float zsize[3] = {0.1, 0.1, 0.1};
360 int ic = mcpcables[mod];
362 calblesize[0] = xsize[ic - 1];
363 calblesize[1] = ysize[ic - 1];
364 calblesize[2] = zsize[ic - 1];
365 const std::string volName = Form(
"CAB%2.i", mod);
366 TVirtualMC::GetMC()->Gsvolu(volName.c_str(),
"BOX",
getMediumID(
kCable), calblesize, 3);
367 TGeoVolume* vol = gGeoManager->GetVolume(volName.c_str());
368 LOG(
debug) <<
"C cables " << mod <<
" " << volName <<
" " << ic;
381 LOG(info) <<
"Add FT0 alignable volumes";
384 LOG(fatal) <<
"TGeoManager doesn't exist !";
388 TString volPath = Form(
"/cave_1/barrel_1");
390 TString volPathA = volPath + Form(
"/FT0A_1");
391 TString symNameA =
"FT0A";
392 LOG(info) << symNameA <<
" <-> " << volPathA;
393 if (!gGeoManager->SetAlignableEntry(symNameA.Data(), volPathA.Data())) {
394 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
397 TString volPathC = volPath + Form(
"/FT0C_1");
398 TString symNameC =
"FT0C";
399 LOG(info) << symNameC <<
" <-> " << volPathC;
400 if (!gGeoManager->SetAlignableEntry(symNameC.Data(), volPathC.Data())) {
401 LOG(fatal) <<
"Unable to set alignable entry ! " << symNameA <<
" : " << volPathA;
403 TString volPathMod, symNameMod;
406 volPathMod = volPath + Form(
"/0MOD_%d", imod);
407 symNameMod = Form(
"0MOD_%d", imod);
408 if (!gGeoManager->SetAlignableEntry(symNameMod.Data(), volPathMod.Data())) {
409 LOG(fatal) << (Form(
"Alignable entry %s not created. Volume path %s not valid", symNameMod.Data(), volPathMod.Data()));
426TGeoVolume* Detector::constructFrameAGeometry()
429 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
430 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
433 TGeoVolumeAssembly* FT0_Frame =
new TGeoVolumeAssembly(
"FT0_Frame");
436 Double_t blockdX = 37.1;
437 Double_t blockdY = 36.85;
438 Double_t blockdZ = 6.95;
439 TGeoBBox* block =
new TGeoBBox(
"block", blockdX / 2, blockdY / 2, blockdZ / 2);
445 Double_t box1dX = 1.57;
446 Double_t box1dY = 6.55;
447 Double_t box1PosX = -(blockdX / 2 - box1dX / 2);
448 Double_t box1PosY = 0;
450 TGeoTranslation* box1Tr1 =
new TGeoTranslation(
"box1Tr1", box1PosX, box1PosY, 0);
451 box1Tr1->RegisterYourself();
452 TGeoTranslation* box1Tr2 =
new TGeoTranslation(
"box1Tr2", -box1PosX, -box1PosY, 0);
453 box1Tr2->RegisterYourself();
455 Double_t box2dX = 2.9;
456 Double_t box2dY = 15.1;
457 Double_t box2PosX = -(blockdX / 2 - box2dX / 2);
458 Double_t box2PosY = blockdY / 2 - box2dY / 2;
460 TGeoTranslation* box2Tr1 =
new TGeoTranslation(
"box2Tr1", box2PosX, box2PosY, 0);
461 box2Tr1->RegisterYourself();
462 TGeoTranslation* box2Tr2 =
new TGeoTranslation(
"box2Tr2", -box2PosX, -box2PosY, 0);
463 box2Tr2->RegisterYourself();
467 Double_t box3dX = 12.7;
469 Double_t box3dZ = 5.45;
470 Double_t box3PosX = -(blockdX / 2 - box2dX - box3dZ / 2);
471 Double_t box3PosY = blockdY / 2 - box3dY / 2;
472 Double_t box3PosZ = blockdZ / 2 - box3dZ / 2;
474 TGeoTranslation* box3Tr1 =
new TGeoTranslation(
"box3Tr1", box3PosX, box3PosY, box3PosZ);
475 box3Tr1->RegisterYourself();
476 TGeoTranslation* box3Tr2 =
new TGeoTranslation(
"box3Tr2", -box3PosX, -box3PosY, box3PosZ);
477 box3Tr2->RegisterYourself();
479 Double_t box4dX = 6.6;
480 Double_t box4dY = 1.67;
481 Double_t box4PosX = 0;
482 Double_t box4PosY = blockdY / 2 - box4dY / 2;
484 TGeoTranslation* box4Tr1 =
new TGeoTranslation(
"box4Tr1", box4PosX, box4PosY, 0);
485 box4Tr1->RegisterYourself();
486 TGeoTranslation* box4Tr2 =
new TGeoTranslation(
"box4Tr2", -box4PosX, -box4PosY, 0);
487 box4Tr2->RegisterYourself();
489 Double_t box5dX = 15;
491 Double_t box5PosX = blockdX / 2 - box5dX / 2;
492 Double_t box5PosY = blockdY / 2 - box5dY / 2;
494 TGeoTranslation* box5Tr1 =
new TGeoTranslation(
"box5Tr1", box5PosX, box5PosY, 0);
495 box5Tr1->RegisterYourself();
496 TGeoTranslation* box5Tr2 =
new TGeoTranslation(
"box5Tr2", -box5PosX, -box5PosY, 0);
497 box5Tr2->RegisterYourself();
501 Double_t box6dX = 2.9;
502 Double_t box6dY = 12.2;
503 Double_t box6dZ = 5.45;
504 Double_t box6PosX = blockdX / 2 - box6dX / 2;
505 Double_t box6PosY = blockdY / 2 - box5dY - box6dY / 2;
506 Double_t box6PosZ = blockdZ / 2 - box6dZ / 2;
508 TGeoTranslation* box6Tr1 =
new TGeoTranslation(
"box6Tr1", box6PosX, box6PosY, box6PosZ);
509 box6Tr1->RegisterYourself();
510 TGeoTranslation* box6Tr2 =
new TGeoTranslation(
"box6Tr2", -box6PosX, -box6PosY, box6PosZ);
511 box6Tr2->RegisterYourself();
517 Double_t cbox1dX = 7.175;
518 Double_t cbox1dY = 5.5;
519 Double_t cbox1Xoffset = 14.425;
520 Double_t cbox1PosX = -(blockdX / 2 - cbox1Xoffset - cbox1dX / 2);
521 Double_t cbox1PosY = 0;
522 TGeoBBox* cbox1 =
new TGeoBBox(
"cbox1", cbox1dX / 2, cbox1dY / 2, blockdZ / 2);
523 TGeoTranslation* cbox1Tr1 =
new TGeoTranslation(
"cbox1Tr1", cbox1PosX, cbox1PosY, 0);
524 cbox1Tr1->RegisterYourself();
525 TGeoTranslation* cbox1Tr2 =
new TGeoTranslation(
"cbox1Tr2", -cbox1PosX, -cbox1PosY, 0);
526 cbox1Tr2->RegisterYourself();
528 Double_t cbox2dX = 5.75;
530 Double_t cbox2dY = 6.575;
531 Double_t cbox2Yoffset = 14.425;
532 Double_t cbox2PosX = 0;
533 Double_t cbox2PosY = blockdY / 2 - cbox2Yoffset - cbox2dY / 2;
534 TGeoBBox* cbox2 =
new TGeoBBox(
"cbox2", cbox2dX / 2, cbox2dY / 2, blockdZ / 2);
535 TGeoTranslation* cbox2Tr1 =
new TGeoTranslation(
"cbox2Tr1", cbox2PosX, cbox2PosY, 0);
536 cbox2Tr1->RegisterYourself();
537 TGeoTranslation* cbox2Tr2 =
new TGeoTranslation(
"cbox2Tr2", -cbox2PosX, -cbox2PosY, 0);
538 cbox2Tr2->RegisterYourself();
545 Double_t gapBoxdX = 0.1;
546 Double_t gapBoxdY = blockdY / 2;
547 Double_t gapPosX = -(sPmtSide / 2 + sEps + gapBoxdX / 2);
548 Double_t gapPosY = blockdY / 4;
549 TGeoBBox* gapBox =
new TGeoBBox(
"gapBox", gapBoxdX / 2, gapBoxdY / 2, blockdZ / 2);
550 TGeoTranslation* gapBoxTr1 =
new TGeoTranslation(
"gapBoxTr1", gapPosX, gapPosY, 0);
551 gapBoxTr1->RegisterYourself();
552 TGeoTranslation* gapBoxTr2 =
new TGeoTranslation(
"gapBoxTr2", -gapPosX, -gapPosY, 0);
553 gapBoxTr2->RegisterYourself();
557 std::string frameACompositeString =
"block ";
558 frameACompositeString +=
"- box1:box1Tr1 - box1:box1Tr2 ";
559 frameACompositeString +=
"- box2:box2Tr1 - box2:box2Tr2 ";
560 frameACompositeString +=
"- box3:box3Tr1 - box3:box3Tr2 ";
561 frameACompositeString +=
"- box4:box4Tr1 - box4:box4Tr2 ";
562 frameACompositeString +=
"- box5:box5Tr1 - box5:box5Tr2 ";
563 frameACompositeString +=
"- box6:box6Tr1 - box6:box6Tr2 ";
564 frameACompositeString +=
"- cbox1:cbox1Tr1 - cbox1:cbox1Tr2 ";
565 frameACompositeString +=
"- cbox2:cbox2Tr1 - cbox2:cbox2Tr2 ";
566 frameACompositeString +=
"- gapBox:gapBoxTr1 - gapBox:gapBoxTr2";
576 Double_t coverPlatedZ = 0.2;
577 Double_t fiberPlatedZ = 0.5;
580 Double_t opticalFiberHeaddY = 0.52;
581 Double_t opticalFiberHeaddX = 1.142;
587 Double_t fh1TopPosX = -1.6;
588 Double_t fh1TopPosY = 1.325;
589 Double_t fh1BotPosX = 1.555;
590 Double_t fh1BotPosY = 1.249;
591 Double_t fh1BotAngle = 16;
595 Double_t fh2TopPosX = -1.563;
596 Double_t fh2TopPosY = 1.4625;
597 Double_t fh2TopAngle = 60;
599 Double_t fh2BotPosX = 1.084;
600 Double_t fh2BotPosY = 1.186;
601 Double_t fh2BotAngle = -30;
604 TGeoBBox* coverPlate =
new TGeoBBox(
"coverPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, coverPlatedZ / 2);
605 TGeoBBox* fiberPlate =
new TGeoBBox(
"fiberPlate", sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, fiberPlatedZ / 2);
606 TGeoBBox* opticalFiberHead =
new TGeoBBox(
"opticalFiberHead", opticalFiberHeaddX / 2, opticalFiberHeaddY / 2, fiberPlatedZ / 2);
609 TGeoTranslation* coverPlateTr =
new TGeoTranslation(
"coverPlateTr", 0, 0, fiberPlatedZ / 2 + coverPlatedZ / 2);
610 coverPlateTr->RegisterYourself();
611 TGeoTranslation* fh1TopTr1 =
new TGeoTranslation(
"fh1TopTr1", fh1TopPosX, fh1TopPosY, 0);
612 fh1TopTr1->RegisterYourself();
613 TGeoTranslation* fh1TopTr2 =
new TGeoTranslation(
"fh1TopTr2", fh1TopPosX, -fh1TopPosY, 0);
614 fh1TopTr2->RegisterYourself();
615 TGeoCombiTrans* fh1BotTr1 =
new TGeoCombiTrans(
"fh1BotTr1", fh1BotPosX, fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot1", fh1BotAngle, 0, 0));
616 fh1BotTr1->RegisterYourself();
617 TGeoCombiTrans* fh1BotTr2 =
new TGeoCombiTrans(
"fh1BotTr2", fh1BotPosX, -fh1BotPosY, 0,
new TGeoRotation(
"fh1BotRot2", -fh1BotAngle, 0, 0));
618 fh1BotTr2->RegisterYourself();
619 TGeoCombiTrans* fh2TopTr1 =
new TGeoCombiTrans(
"fh2TopTr1", fh2TopPosX, fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot1", fh2TopAngle + 90, 0, 0));
620 fh2TopTr1->RegisterYourself();
621 TGeoCombiTrans* fh2TopTr2 =
new TGeoCombiTrans(
"fh2TopTr2", fh2TopPosX, -fh2TopPosY, 0,
new TGeoRotation(
"fh2TopRot2", -fh2TopAngle - 90, 0, 0));
622 fh2TopTr2->RegisterYourself();
623 TGeoCombiTrans* fh2BotTr1 =
new TGeoCombiTrans(
"fh2BotTr1", fh2BotPosX, fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot1", -fh2BotAngle, 0, 0));
624 fh2BotTr1->RegisterYourself();
625 TGeoCombiTrans* fh2BotTr2 =
new TGeoCombiTrans(
"fh2BotTr2", fh2BotPosX, -fh2BotPosY, 0,
new TGeoRotation(
"fh2BotRot2", fh2BotAngle, 0, 0));
626 fh2BotTr2->RegisterYourself();
629 std::string outerPlateGroupString =
"fiberPlate ";
630 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr1 ";
631 outerPlateGroupString +=
"- opticalFiberHead:fh1TopTr2 ";
632 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr1 ";
633 outerPlateGroupString +=
"- opticalFiberHead:fh1BotTr2 ";
634 outerPlateGroupString +=
"+ coverPlate:coverPlateTr";
637 TGeoCompositeShape* outerPlateGroup =
new TGeoCompositeShape(
"outerPlateGroup", outerPlateGroupString.c_str());
640 std::string innerPlateGroupString =
"fiberPlate ";
641 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr1 ";
642 innerPlateGroupString +=
"- opticalFiberHead:fh2TopTr2 ";
643 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr1 ";
644 innerPlateGroupString +=
"- opticalFiberHead:fh2BotTr2 ";
645 innerPlateGroupString +=
"+ coverPlate:coverPlateTr";
648 TGeoCompositeShape* innerPlateGroup =
new TGeoCompositeShape(
"innerPlateGroup", innerPlateGroupString.c_str());
653 Double_t backPlanedZ = 0.25;
654 Double_t socketdZ = blockdZ - backPlanedZ;
657 TGeoVolume* socket = gGeoManager->MakeBox(
"Socket", Vacuum, sPmtSide / 2 + sEps, sPmtSide / 2 + sEps, socketdZ / 2);
661 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};
664 TString nameTrSocket;
666 TString nameTrPlateGroup;
673 nameTrSocket = Form(
"trSocket%i", itr + 1);
674 float z = -backPlanedZ / 4.0;
675 trSocket[itr] =
new TGeoTranslation(nameTrSocket.Data(), mPosModuleAx[itr], mPosModuleAy[itr],
z);
676 trSocket[itr]->RegisterYourself();
677 frameACompositeString +=
"- Socket:";
678 frameACompositeString += nameTrSocket.Data();
680 nameTrPlateGroup = Form(
"trPlateGroup%i", itr + 1);
681 namePGRot = Form(
"pgRot%i", itr + 1);
682 float z2 = -blockdZ / 2 + (coverPlatedZ + fiberPlatedZ) / 2;
683 trPlateGroup[itr] =
new TGeoCombiTrans(nameTrPlateGroup.Data(), mPosModuleAx[itr], mPosModuleAy[itr], z2,
new TGeoRotation(namePGRot.Data(), rotAngle[itr], 0, 0));
684 trPlateGroup[itr]->RegisterYourself();
686 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) {
687 frameACompositeString +=
" + outerPlateGroup:";
688 frameACompositeString += nameTrPlateGroup.Data();
689 frameACompositeString +=
" ";
691 frameACompositeString +=
" + innerPlateGroup:";
692 frameACompositeString += nameTrPlateGroup.Data();
693 frameACompositeString +=
" ";
698 TGeoVolume* frameA =
new TGeoVolume(
"frameA",
new TGeoCompositeShape(
"frameA", frameACompositeString.c_str()), Al);
701 FT0_Frame->AddNode(frameA, 1);
710TGeoVolume* Detector::constructFrameCGeometry()
714 TGeoMedium* Vacuum = gGeoManager->GetMedium(
"FT0_Vacuum$");
715 TGeoMedium* Al = gGeoManager->GetMedium(
"FT0_Aluminium$");
716 static constexpr Double_t sFrameZC = 5.5632;
717 static constexpr Double_t frameHeightC = 2.5;
720 static constexpr Double_t sensShift = 0.5;
721 static constexpr Double_t sQuartzRadiatorZC = 1.94360;
722 static constexpr Double_t sQuartzHeightC = (-sFrameZC / 2 + sQuartzRadiatorZC / 2);
723 static constexpr Double_t sPmtZC = 3.600;
724 static constexpr Double_t sPmtHeightC = (sFrameZC / 2 - sPmtZC / 2);
732 Float_t rMax = rMin + sFrameZC;
737 Float_t pinstart[3] = {2.9491, 2.9491, 2.5};
738 Float_t pstartC[3] = {20., 20, 5};
741 Double_t xCorn = multCorn * (-14.75272569);
742 Double_t yCorn = multCorn * (14.9043284);
743 Double_t zCorn = 79.27306024;
745 Double_t xCorn2 = -xCorn;
746 Double_t yCorn2 = yCorn;
747 Double_t zCorn2 = zCorn;
749 Double_t acCorn = TMath::ATan(yCorn / xCorn) - TMath::Pi() / 2 + 2 * TMath::Pi();
750 Double_t bcCorn = TMath::ACos(zCorn / crad);
751 Double_t gcCorn = -1 * acCorn;
755 Double_t flopsErr = 0.00001;
759 Double_t errPMTZ = 10 * sEps;
760 Double_t errPMTXY = 0.02;
761 Double_t errQrdZ = 0.143 + 0.22;
762 Double_t errQrdXY = 0.35;
769 TGeoSphere* sphere1 =
new TGeoSphere(
"sphere1", rMin, rMax, tMin, tMax, pMin, pMax);
770 TGeoSphere* sphere2 =
new TGeoSphere(
"sphere2", rMin - sweep, rMax + sweep, tMin, tMax, pMin, pMax);
771 TGeoSphere* sphere3 =
new TGeoSphere(
"sphere3", rMin, rMin + backPlateZ, tMin, tMax, pMin, pMax);
772 TGeoSphere* sphere4 =
new TGeoSphere(
"sphere4", rMin - sweep, rMax + backPlateZ + sweep, tMin, tMax, pMin, pMax);
774 TGeoBBox* insSeat =
new TGeoBBox(
"insSeat", pinstart[0] * 2, pinstart[1] * 2, pinstart[2] * 2);
777 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
778 sQuartzRadiatorSide / 2 + sEps + errQrdXY,
779 sQuartzRadiatorZC / 2 + sEps + errQrdZ);
782 sPmtSide / 2 + sEps + errPMTXY,
783 sPmtSide / 2 + sEps + errPMTXY,
784 sPmtZ / 2 + sEps + errPMTZ);
786 sCornerRadius / 2 - flopsErr,
787 sCornerRadius / 2 - flopsErr,
793 TGeoRotation* rot1 =
new TGeoRotation(
"rot1", 90, 0, 0);
794 rot1->RegisterYourself();
795 TGeoCombiTrans* rotTr1 =
new TGeoCombiTrans(
"rotTr1", -20, -1, -5, rot1);
796 rotTr1->RegisterYourself();
798 TGeoRotation* rot2 =
new TGeoRotation(
"rot2", -90, 0, 0);
799 rot2->RegisterYourself();
800 TGeoCombiTrans* rotTr2 =
new TGeoCombiTrans(
"rotTr2", 20, -1, -5, rot2);
801 rotTr2->RegisterYourself();
803 TGeoRotation* rot3 =
new TGeoRotation(
"rot3", 0, 0, 0);
804 rot3->RegisterYourself();
805 TGeoCombiTrans* rotTr3 =
new TGeoCombiTrans(
"rotTr3", 0, 20, -5, rot3);
806 rotTr3->RegisterYourself();
808 TGeoTranslation* centerTrans =
new TGeoTranslation(
"centerTrans", 0, 0, 85);
809 centerTrans->RegisterYourself();
811 TGeoRotation* reflectC1 =
new TGeoRotation(
"reflectC1", 0, 0, 0);
812 reflectC1->ReflectX(
true);
813 reflectC1->ReflectY(
true);
814 reflectC1->RegisterYourself();
816 TGeoRotation* rotCorners =
new TGeoRotation(
"rotCorners", acCorn, bcCorn, gcCorn);
817 rotCorners->RegisterYourself();
819 TGeoCombiTrans* comCorners =
new TGeoCombiTrans(
"comCorners", xCorn, yCorn, zCorn, rotCorners);
820 comCorners->RegisterYourself();
822 TGeoCombiTrans* comCorners2 =
new TGeoCombiTrans(
"comCorners2", xCorn2, yCorn2, zCorn2, rotCorners);
823 comCorners2->RegisterYourself();
826 std::string shellString =
"";
827 shellString +=
"sphere1";
828 shellString +=
"- sphere2:rotTr1";
829 shellString +=
"- sphere2:rotTr2";
830 shellString +=
"- sphere2:rotTr3";
831 shellString +=
"- insSeat:centerTrans";
832 shellString +=
"- framecornerBox:comCorners";
833 shellString +=
"- framecornerBox:comCorners2";
836 std::string backPlateString =
"";
837 backPlateString +=
"sphere3";
838 backPlateString +=
"- sphere4:rotTr1";
839 backPlateString +=
"- sphere4:rotTr2";
840 backPlateString +=
"- sphere4:rotTr3";
841 backPlateString +=
"- insSeat:centerTrans";
842 backPlateString +=
"- framecornerBox:comCorners";
843 backPlateString +=
"- framecornerBox:comCorners2";
847 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};
848 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};
850 Double_t zi[NCellsC];
851 for (Int_t ic = 0; ic < NCellsC; ic++) {
852 zi[ic] = TMath::Sqrt(TMath::Power(crad, 2) - TMath::Power(xi[ic], 2) - TMath::Power(yi[ic], 2));
856 Double_t ac[NCellsC],
bc[NCellsC], gc[NCellsC];
857 for (Int_t
i = 0;
i < NCellsC;
i++) {
858 ac[
i] = TMath::ATan(yi[
i] / xi[
i]) - TMath::Pi() / 2 + 2 * TMath::Pi();
860 bc[
i] = TMath::ACos(zi[
i] / crad);
862 bc[
i] = -1 * TMath::ACos(zi[
i] / crad);
866 Double_t xc2[NCellsC], yc2[NCellsC], zc2[NCellsC];
870 Double_t rcomp = crad + pstartC[2] / 2.0;
871 for (Int_t
i = 0;
i < NCellsC;
i++) {
873 xc2[
i] = rcomp * TMath::Cos(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
874 yc2[
i] = rcomp * TMath::Sin(ac[
i] + TMath::Pi() / 2) * TMath::Sin(-1 *
bc[
i]);
875 zc2[
i] = rcomp * TMath::Cos(
bc[
i]);
878 ac[
i] *= 180 / TMath::Pi();
879 bc[
i] *= 180 / TMath::Pi();
883 Double_t rmag = sqrt(xc2[0] * xc2[0] + yc2[0] * yc2[0] + zc2[0] * zc2[0]);
885 Double_t scalePMT = (rmag + (frameHeightC / 2.0) - (sPmtHeightC / 2)) / rmag;
886 Double_t scaleQrad = (rmag + (frameHeightC / 2.0) - sPmtHeightC - (sQuartzRadiatorZC / 2.0)) / rmag;
888 Double_t xPMT[NCellsC];
889 Double_t yPMT[NCellsC];
890 Double_t zPMT[NCellsC];
892 Double_t xQrad[NCellsC];
893 Double_t yQrad[NCellsC];
894 Double_t zQrad[NCellsC];
896 Double_t rotC[NCellsC];
897 Double_t comC[NCellsC];
899 for (Int_t
i = 0;
i < NCellsC;
i++) {
901 xPMT[
i] = scalePMT * xc2[
i];
902 yPMT[
i] = scalePMT * yc2[
i];
903 zPMT[
i] = scalePMT * zc2[
i];
906 xQrad[
i] = scaleQrad * xc2[
i];
907 yQrad[
i] = scaleQrad * yc2[
i];
908 zQrad[
i] = scaleQrad * zc2[
i];
913 TString nameComQuartz;
914 TString nameComPlates;
917 for (Int_t itr = NCellsA; itr < NCellsA + NCellsC; itr++) {
918 nameRot = Form(
"0Rot%i", itr + 1);
919 int ic = itr - NCellsA;
920 nameComPMT = Form(
"0ComPMT%i", ic + 1);
921 nameComQuartz = Form(
"0ComQuartz%i", ic + 1);
926 TGeoRotation* rotC =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
927 rotC->RegisterYourself();
929 TGeoCombiTrans* comC =
new TGeoCombiTrans(nameComC.Data(), xc2[ic], yc2[ic], zc2[ic], rotC);
930 comC->RegisterYourself();
932 TGeoRotation* rotPMT =
new TGeoRotation(nameRot.Data(), ac[ic],
bc[ic], gc[ic]);
933 rotPMT->RegisterYourself();
935 TGeoCombiTrans* comPMT =
new TGeoCombiTrans(nameComPMT.Data(),
938 comPMT->RegisterYourself();
940 TGeoRotation* rotQuartz =
new TGeoRotation(nameRot.Data(),
941 ac[ic],
bc[ic], gc[ic]);
942 rotQuartz->RegisterYourself();
944 TGeoCombiTrans* comQuartz =
new TGeoCombiTrans(nameComQuartz.Data(),
945 xQrad[ic], yQrad[ic],
946 zQrad[ic] - (sQuartzRadiatorZC / 2 + 3 * sEps),
948 comQuartz->RegisterYourself();
950 TGeoRotation* rotPlates =
new TGeoRotation(nameRot.Data(),
951 ac[ic],
bc[ic], gc[ic]);
952 rotPlates->RegisterYourself();
953 TGeoCombiTrans* comPlates =
new TGeoCombiTrans(nameComPlates.Data(),
954 xQrad[ic], yQrad[ic],
957 comPlates->RegisterYourself();
960 std::string pmtCombiString =
"";
961 pmtCombiString +=
"- ";
962 pmtCombiString +=
"pmtBoxSeat:";
963 pmtCombiString += nameComPMT.Data();
964 shellString += pmtCombiString;
967 std::string quartzCombiString =
"";
968 quartzCombiString +=
"- ";
969 quartzCombiString +=
"quartzRadiatorSeat:";
970 quartzCombiString += nameComQuartz.Data();
971 shellString += quartzCombiString;
976 TGeoCompositeShape* shellCompShape =
new TGeoCompositeShape(
"shellCompShape", shellString.c_str());
978 TGeoVolume* shellVol =
new TGeoVolume(
"shellVol", shellCompShape, Al);
981 TGeoVolumeAssembly* FT0_C_Frame =
new TGeoVolumeAssembly(
"FT0_C_Frame");
984 TGeoTranslation* shellTr1 =
new TGeoTranslation(
"shellTr1", 0, 0, -80);
985 shellTr1->RegisterYourself();
987 TGeoCombiTrans* shellTr2 =
new TGeoCombiTrans(
"shellTr2", 0, 0, -80, reflectC1);
988 shellTr2->RegisterYourself();
990 FT0_C_Frame->AddNode(shellVol, 1, shellTr1);
991 FT0_C_Frame->AddNode(shellVol, 2, shellTr2);
993 TGeoTranslation* backPlateTr1 =
new TGeoTranslation(
"backPlateTr1", 0, 0, -74);
994 backPlateTr1->RegisterYourself();
996 TGeoCombiTrans* backPlateTr2 =
new TGeoCombiTrans(
"backPlateTr2", 0, 0, -74, reflectC1);
997 backPlateTr2->RegisterYourself();
999 TGeoCompositeShape* backPlateShape =
new TGeoCompositeShape(
"backPlateShape", backPlateString.c_str());
1000 TGeoVolume* backPlateVol =
new TGeoVolume(
"backPlateVol", backPlateShape, Al);
1002 FT0_C_Frame->AddNode(backPlateVol, 3, backPlateTr1);
1003 FT0_C_Frame->AddNode(backPlateVol, 4, backPlateTr2);
1008std::string Detector::cPlateShapeString()
1010 Double_t prismHeight = 0.3895;
1011 Double_t prismSide = 5.9;
1012 Double_t radCurve = 81.9469;
1013 Double_t delHeight = radCurve * (1.0 - TMath::Sqrt(1.0 - 0.5 * TMath::Power(prismSide / radCurve, 2.0)));
1016 Double_t heightBase = prismHeight + delHeight;
1017 Double_t sliceSide = 5.3;
1018 Double_t heightBaseBox = 2 * heightBase;
1019 Double_t totalHeight = 0.5;
1020 Double_t sliceHeight = 0.5 - heightBase;
1023 Double_t cableHoleWidth = 0.3503;
1024 Double_t cableHoleLength = 0.9003;
1025 Double_t cableHoleDepth = 1;
1030 Double_t sHolesBottomEdge = 1.585;
1031 Double_t sHolesTopEdge = 0.515;
1032 Double_t sHolesAvgTopBottom = (sHolesBottomEdge + sHolesTopEdge) / 2.0;
1033 Double_t sHolesUpFromCenter = ((sliceSide / 2.0) - sHolesAvgTopBottom);
1035 Double_t sHolesFarEdge = 1.585;
1036 Double_t sHolesNearEdge = 1.065;
1037 Double_t sHolesAvgNearFar = (sHolesFarEdge + sHolesNearEdge) / 2.0;
1038 Double_t sHolesLateralFromCenter = ((sliceSide / 2.0) - sHolesAvgNearFar);
1041 TGeoBBox*
box =
new TGeoBBox(
"BASE", prismSide / 2.0, heightBaseBox / 2.0, prismSide / 2.0);
1044 TGeoBBox* slice =
new TGeoBBox(
"SLICE", sliceSide / 2.0, heightBaseBox / 2.0, sliceSide / 2.0);
1045 TGeoBBox* cableHole =
new TGeoBBox(
"CABLE", cableHoleLength / 2.0, cableHoleDepth / 2.0, cableHoleWidth / 2.0);
1046 TGeoBBox* cableHole2 =
new TGeoBBox(
"CABLE2", cableHoleWidth / 2.0, cableHoleLength / 2.0, cableHoleDepth / 2.0);
1048 TGeoSphere* baseShape =
new TGeoSphere(
"BASE_SUBTRACTION", radCurve, radCurve + 5.0, 80, 100, 80, 100);
1050 TGeoTranslation* rTrans =
new TGeoTranslation(
"rTrans", 0, radCurve, 0);
1051 rTrans->RegisterYourself();
1053 TGeoTranslation* rBackTrans =
new TGeoTranslation(
"rBackTrans", 0, -1.0 * radCurve, 0);
1054 rBackTrans->RegisterYourself();
1056 TGeoTranslation* subSliceTrans =
new TGeoTranslation(
"subSliceTrans", 0, (heightBaseBox / 2.0) + sliceHeight, 0);
1057 subSliceTrans->RegisterYourself();
1059 TGeoTranslation* sHolesTopLeftTrans =
new TGeoTranslation(
"sHolesTopLeftTrans", sHolesUpFromCenter, 0, sHolesLateralFromCenter);
1060 sHolesTopLeftTrans->RegisterYourself();
1062 TGeoTranslation* sHolesTopRightTrans =
new TGeoTranslation(
"sHolesTopRightTrans", sHolesUpFromCenter, 0, -1.0 * sHolesLateralFromCenter);
1063 sHolesTopRightTrans->RegisterYourself();
1065 TGeoTranslation* testTrans =
new TGeoTranslation(
"testTrans", 0.1, 0.1, 0);
1066 testTrans->RegisterYourself();
1068 TGeoRotation* switchToZ =
new TGeoRotation(
"switchToZ", 90, 90, 0);
1069 switchToZ->RegisterYourself();
1071 TGeoRotation* rotateHolesLeft =
new TGeoRotation(
"rotateHolesLeft", 345, 0, 0);
1072 rotateHolesLeft->RegisterYourself();
1074 TGeoRotation* rotateHolesRight =
new TGeoRotation(
"rotatetHolesRight", 15, 0, 0);
1075 rotateHolesRight->RegisterYourself();
1078 TGeoCombiTrans* rHolesBottomLeftTrans =
new TGeoCombiTrans(
"rHolesBottomLeftTrans", -1.0 * sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesLeft);
1079 rHolesBottomLeftTrans->RegisterYourself();
1081 TGeoCombiTrans* rHolesBottomRightTrans =
new TGeoCombiTrans(
"rHolesBottomRightTrans", sHolesLateralFromCenter, -1.0 * sHolesUpFromCenter, 0, rotateHolesRight);
1082 rHolesBottomRightTrans->RegisterYourself();
1084 std::string plateString =
" ";
1085 plateString +=
"(((BASE:rTrans";
1086 plateString +=
"- BASE_SUBTRACTION)";
1087 plateString +=
"+ (SLICE:rTrans))";
1088 plateString +=
":rBackTrans";
1089 plateString +=
"- BASE:subSliceTrans";
1090 plateString +=
"- (CABLE:sHolesTopLeftTrans)";
1091 plateString +=
"- (CABLE:sHolesTopRightTrans))";
1092 plateString +=
":switchToZ";
1093 plateString +=
"- (CABLE2:rHolesBottomLeftTrans)";
1094 plateString +=
"- (CABLE2:rHolesBottomRightTrans)";
1105 Int_t volID = fMC->CurrentVolID(copy);
1107 TVirtualMCStack*
stack = fMC->GetStack();
1108 Int_t quadrant, mcp;
1109 if (fMC->IsTrackEntering()) {
1111 fMC->TrackPosition(
x,
y,
z);
1112 fMC->CurrentVolID(quadrant);
1113 fMC->CurrentVolOffID(1, mcp);
1114 float time = fMC->TrackTime() * 1.0e9;
1115 int trackID =
stack->GetCurrentTrackNumber();
1116 int detID = mSim2LUT[4 * mcp + quadrant - 1];
1117 int iPart = fMC->TrackPid();
1118 if (fMC->TrackCharge() && volID == mREGVolID) {
1121 if (iPart == 50000050) {
1122 float etot = fMC->Etot();
1123 float enDep = fMC->Edep();
1124 Int_t parentID =
stack->GetCurrentTrack()->GetMother(0);
1125 if (volID == mTOPVolID) {
1130 mTrackIdTop = trackID;
1133 if (volID == mMTOVolID) {
1134 if (trackID != mTrackIdTop) {
1139 mTrackIdMCPtop = trackID;
1143 if (volID == mREGVolID) {
1144 if (trackID != mTrackIdTop && trackID != mTrackIdMCPtop) {
1149 if (trackID == mTrackIdTop || trackID == mTrackIdMCPtop) {
1162 mHits->emplace_back(
x,
y,
z,
time, energy, trackId, detId);
1165 stack->addHit(GetDetId());
1167 return &(mHits->back());
1176 if (FairRootManager::Instance()) {
1177 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits, kTRUE);
1198 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
1199 Float_t zAir[4] = {6., 7., 8., 18.};
1200 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
1204 Float_t aglass[2] = {28.0855, 15.9994};
1205 Float_t zglass[2] = {14., 8.};
1218 Float_t aCeramic[2] = {26.981539, 15.9994};
1219 Float_t zCeramic[2] = {13., 8.};
1220 Float_t wCeramic[2] = {2., 3.};
1224 const Int_t nCeramicNice = 3;
1225 Float_t aCeramicNicel[3] = {26.981539, 15.9994, 58.6934};
1226 Float_t zCeramicNicel[3] = {13., 8., 28};
1227 Float_t wCeramicNicel[3] = {0.2, 0.3, 0.5};
1228 Float_t denscerCeramicNickel = 5.6;
1232 const Int_t nPlast = 4;
1233 Float_t aPlast[nPlast] = {1.00784, 12.0107, 15.999, 63.54};
1234 Float_t zPlast[nPlast] = {1, 6, 8, 29};
1235 Float_t wPlast[nPlast] = {0.08, 0.53, 0.22, 0.17};
1236 const Float_t denCable = 3.66;
1244 Material(11,
"Aliminium$", 26.98, 13.0, 2.7, 8.9, 999);
1245 Mixture(1,
"Vacuum$", aAir, zAir, dAir1, 4, wAir);
1246 Mixture(2,
"Air$", aAir, zAir, dAir, 4, wAir);
1247 Mixture(4,
"MCP glass $", aglass, zglass, dglass_mcp, -2, wglass);
1248 Mixture(24,
"Radiator Optical glass$", aglass, zglass, dglass, -2, wglass);
1249 Mixture(3,
"Ceramic$", aCeramic, zCeramic, denscer, -2, wCeramic);
1250 Mixture(23,
"CablePlasticCooper$", aPlast, zPlast, denCable, 4, wPlast);
1251 Mixture(25,
"MCPwalls $", aCeramicNicel, zCeramicNicel, denscerCeramicNickel, 3, wCeramicNicel);
1253 Medium(1,
"Air$", 2, 0, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1254 Medium(3,
"Vacuum$", 1, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1255 Medium(4,
"Ceramic$", 3, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1256 Medium(6,
"Glass$", 4, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1257 Medium(15,
"Aluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1258 Medium(17,
"OptAluminium$", 11, 0, isxfld, sxmgmx, 10., .01, 1., .003, .003);
1259 Medium(16,
"OpticalGlass$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .01);
1260 Medium(19,
"OpticalGlassCathode$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
1262 Medium(23,
"Cables$", 23, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1263 Medium(25,
"MCPWalls", 25, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
1271 const char* aliceO2env = std::getenv(
"O2_ROOT");
1273 inputDir = aliceO2env;
1275 inputDir +=
"/share/Detectors/FT0/files/";
1277 TString optPropPath = inputDir +
"quartzOptProperties.txt";
1278 gSystem->ExpandPathName(optPropPath);
1283 LOG(error) <<
"Could not read FIT optical properties " <<
result <<
" " << optPropPath.Data();
1286 Int_t nBins = mPhotonEnergyD.size();
1288 mPMTeff =
new TGraph(nBins, &(mPhotonEnergyD[0]), &(mQuantumEfficiency[0]));
1294 TVirtualMC::GetMC()->SetCerenkov(
getMediumID(
kOpGlass), nBins, &(mPhotonEnergyD[0]), &(mAbsorptionLength[0]),
1295 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1297 &(mQuantumEfficiency[0]), &(mRefractionIndex[0]));
1300 TVirtualMC::GetMC()->DefineOpSurface(
"surfRd", kUnified, kDielectric_dielectric, kPolishedbackpainted, 0.);
1301 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEfficMet[0]));
1302 TVirtualMC::GetMC()->SetMaterialProperty(
"surfRd",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflMet[0]));
1303 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder0",
"0TOP", 1,
"0RFV", 1,
"surfRd");
1304 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder1",
"0TOP", 1,
"0RFH", 1,
"surfRd");
1305 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder2",
"0TOP", 1,
"0RFV", 2,
"surfRd");
1306 TVirtualMC::GetMC()->SetBorderSurface(
"surMirrorBorder3",
"0TOP", 1,
"0RFH", 2,
"surfRd");
1308 TVirtualMC::GetMC()->DefineOpSurface(
"surFrontBWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1309 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1310 TVirtualMC::GetMC()->SetMaterialProperty(
"surFrontBWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1311 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderFrontBWindow",
"0REG", 1,
"0MTO", 1,
"surFrontBWindow");
1313 TVirtualMC::GetMC()->DefineOpSurface(
"surBackFrontWindow", kUnified, kDielectric_dielectric, kPolished, 0.);
1314 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"EFFICIENCY", nBins, &(mPhotonEnergyD[0]), &(mEffFrontWindow[0]));
1315 TVirtualMC::GetMC()->SetMaterialProperty(
"surBackFrontWindow",
"REFLECTIVITY", nBins, &(mPhotonEnergyD[0]), &(mReflFrontWindow[0]));
1316 TVirtualMC::GetMC()->SetBorderSurface(
"surBorderBackFrontWindow",
"0TOP", 1,
"0MTO", 1,
"surBackFrontWindow");
1321 for (Int_t
i = 0;
i < mPhotonEnergyD.size();
i++) {
1322 mReflBlackPaper.push_back(0.);
1323 mEffBlackPaper.push_back(0);
1324 mAbsBlackPaper.push_back(1);
1326 mReflFrontWindow.push_back(0.01);
1327 mEffFrontWindow.push_back(1);
1328 mRindexFrontWindow.push_back(1);
1330 mRindexAir.push_back(1.);
1331 mAbsorAir.push_back(0.3);
1332 mRindexCathodeNext.push_back(1);
1334 mAbsorbCathodeNext.push_back(1);
1335 mEfficMet.push_back(0);
1336 mRindexMet.push_back(1);
1337 mReflMet.push_back(1);
1344 float eff = mPMTeff->Eval(energy);
1345 float p = gRandom->Rndm();
1355 std::ifstream infile;
1356 infile.open(filePath.c_str());
1357 LOG(info) <<
" file " << filePath.c_str();
1359 if (infile.fail() ==
true) {
1364 std::string comment;
1365 if (!getline(infile, comment)) {
1366 LOG(error) <<
"Error opening ascii file (it is probably a folder!): " << filePath.c_str();
1369 getline(infile, comment);
1374 if (nLines < 0 || nLines > 1e4) {
1378 getline(infile, comment);
1379 getline(infile, comment);
1384 getline(infile, sLine);
1385 while (!infile.eof()) {
1386 if (iLine >= nLines) {
1390 std::stringstream ssLine(sLine);
1395 mPhotonEnergyD.push_back(energy);
1397 Double_t absorption;
1398 ssLine >> absorption;
1399 mAbsorptionLength.push_back(absorption);
1401 Double_t refraction;
1402 ssLine >> refraction;
1403 mRefractionIndex.push_back(refraction);
1405 Double_t efficiency;
1406 ssLine >> efficiency;
1407 mQuantumEfficiency.push_back(efficiency);
1408 if (!(ssLine.good() || ssLine.eof())) {
1413 getline(infile, sLine);
1416 if (iLine != mPhotonEnergyD.size()) {
1422 LOG(info) <<
"Optical properties taken from the file: " << filePath.c_str() <<
" Number of lines read: " << iLine;
1429 std::string inputDir;
1430 const char* aliceO2env = std::getenv(
"O2_ROOT");
1432 inputDir = aliceO2env;
1434 inputDir +=
"/share/Detectors/FT0/files/";
1436 TString indPath = inputDir +
"Sim2DataChannels.txt";
1437 gSystem->ExpandPathName(indPath);
1439 std::ifstream infile;
1440 infile.open(indPath.Data());
1441 LOG(info) <<
" file open " << indPath.Data();
1443 if (infile.fail() ==
true) {
1444 LOG(error) <<
"Error opening ascii file (it is probably a folder!): " << indPath;
1449 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"