16#include "TGeoManager.h"
17#include "TGeoVolume.h"
19#include "TVirtualMC.h"
23#include "FairGeoNode.h"
24#include "FairRootManager.h"
25#include "FairVolume.h"
35#include <boost/algorithm/string/predicate.hpp>
36#include <boost/range/irange.hpp>
50 mVolumeIDScintillator(-1),
53 mSuperParentsIndices(),
55 mCurrentSuperparent(nullptr),
57 mCurrentPrimaryID(-1),
66 using boost::algorithm::contains;
67 memset(mParEMOD, 0,
sizeof(Double_t) * 5);
71 LOG(fatal) <<
"Geometry is nullptr";
73 std::string gn = geo->
GetName();
74 std::transform(gn.begin(), gn.end(), gn.begin(), ::toupper);
78 if (contains(gn,
"V1")) {
91 mVolumeIDScintillator(-1),
93 mGeometry(rhs.mGeometry),
94 mSuperParentsIndices(),
96 mCurrentSuperparent(nullptr),
98 mCurrentPrimaryID(-1),
100 mSampleWidth(rhs.mSampleWidth),
101 mSmodPar0(rhs.mSmodPar0),
102 mSmodPar1(rhs.mSmodPar1),
103 mSmodPar2(rhs.mSmodPar2),
104 mInnerEdge(rhs.mInnerEdge),
105 mDCALInnerGap(rhs.mDCALInnerGap)
107 for (
int i = 0;
i < 5; ++
i) {
108 mParEMOD[
i] = rhs.mParEMOD[
i];
121 for (
const auto& child : mSensitive) {
122 LOG(debug1) <<
"Adding sensitive volume " << child;
124 if (child ==
"SCMX") {
125 LOG(debug1) <<
"Adding SCMX volume as sensitive volume with ID " << svolID;
126 mVolumeIDScintillator = svolID;
128 auto smtype = mSMVolNames.find(child);
129 if (smtype != mSMVolNames.end()) {
130 std::cout <<
"Adding supermodule type " << smtype->second <<
" for SM " << smtype->first <<
" with volume ID " << svolID << std::endl;
131 mSMVolumeID[svolID] = smtype->second;
135 LOG(debug1) <<
"Supermodule volume map: ";
136 for (
auto [volID, volType] : mSMVolumeID) {
137 LOG(debug1) <<
"Volume " << volID <<
", type " <<
int(volType);
145 using boost::algorithm::contains;
146 LOG(
debug) <<
"Creating EMCAL geometry";
150 LOG(error) <<
"ConstructGeometry: EMCAL Geometry class has not been set up.";
161 LOG(debug2) <<
"Shish-Kebab geometry : " << GetTitle();
165 LOG(info) <<
"Using EMCAL sampling fraction " << geom->
GetSampling() <<
" for " << TVirtualMC::GetMC()->GetName() <<
" / " << TVirtualMC::GetMC()->GetTitle();
167 gGeoManager->CheckGeometry();
172 int track = fMC->GetStack()->GetCurrentTrackNumber(),
173 directparent = fMC->GetStack()->GetCurrentParentTrackNumber();
174 if (track != mCurrentTrack) {
175 LOG(debug4) <<
"Doing new track " << track <<
" current (" << mCurrentTrack <<
"), direct parent (" << directparent <<
")" << std::endl;
177 auto hasSuperParent = mSuperParentsIndices.find(directparent);
178 if (hasSuperParent != mSuperParentsIndices.end()) {
180 mCurrentParentID = hasSuperParent->second;
181 mSuperParentsIndices[track] = hasSuperParent->second;
182 auto superparent = mSuperParents.find(mCurrentParentID);
183 if (superparent != mSuperParents.end()) {
184 mCurrentSuperparent = &(superparent->second);
186 LOG(error) <<
"Attention: No superparent object found (parent " << mCurrentParentID <<
")";
187 mCurrentSuperparent =
nullptr;
189 LOG(debug4) <<
"Found superparent " << mCurrentParentID << std::endl;
193 mSuperParentsIndices[track] = track;
194 mCurrentSuperparent =
AddSuperparent(track, fMC->TrackPid(), fMC->Etot());
195 mCurrentParentID = track;
197 mCurrentTrack = track;
199 if (
v->getVolumeId() == mVolumeIDScintillator) {
200 LOG(debug4) <<
"We are in sensitive volume " <<
v->GetName() <<
": " << fMC->CurrentVolPath() << std::endl;
202 Double_t eloss = fMC->Edep();
203 if (eloss < DBL_EPSILON) {
213 Int_t copyEta, copyPhi, copyMod, copySmod;
214 fMC->CurrentVolID(copyEta);
215 fMC->CurrentVolOffID(1, copyPhi);
216 fMC->CurrentVolOffID(3, copyMod);
217 auto smvolID = fMC->CurrentVolOffID(
220 auto typeFromVolID = mSMVolumeID.find(smvolID);
221 if (typeFromVolID == mSMVolumeID.end()) {
222 LOG(error) <<
"No supermodule with volume ID " << smvolID <<
" found";
225 auto supermoduletype = typeFromVolID->second;
226 switch (supermoduletype) {
242 LOG(debug3) <<
"Supermodule copy " << copySmod <<
", module copy " << copyMod <<
", y-dir " << copyPhi <<
", x-dir "
243 << copyEta <<
", supermodule ID " << copySmod +
offset - 1;
244 LOG(debug3) <<
"path " << fMC->CurrentVolPath();
245 LOG(debug3) <<
"Name of the supermodule type " << fMC->CurrentVolOffName(4) <<
", Module name "
246 << fMC->CurrentVolOffName(3);
253 Int_t smNumber =
offset + copySmod - 1, smTypeID = 1;
257 if (smNumber % 2 == 0) {
283 float x,
y,
z, px, py, pz, e;
284 fMC->TrackPosition(
x,
y,
z);
285 fMC->TrackMomentum(px, py, pz, e);
286 o2::TrackReference trackref(
x,
y,
z, px, py, pz, fMC->TrackLength(), fMC->TrackTime(), mCurrentParentID, GetDetId());
287 o2stack->addTrackReference(trackref);
291 Double_t lightyield(eloss);
292 if (fMC->TrackCharge()) {
297 auto currenthit =
FindHit(detID, mCurrentParentID);
303 Float_t posX, posY, posZ, momX, momY, momZ, energy;
304 fMC->TrackPosition(posX, posY, posZ);
305 fMC->TrackMomentum(momX, momY, momZ, energy);
306 Double_t
time = fMC->TrackTime() * 1e9;
307 LOG(debug3) <<
"Adding new hit for parent " << mCurrentParentID <<
" and cell " << detID << std::endl;
312 o2stack->addHit(GetDetId());
314 LOG(debug3) <<
"Adding energy to the current hit" << std::endl;
315 currenthit->SetEnergyLoss(currenthit->GetEnergyLoss() + lightyield);
325 LOG(debug3) <<
"Adding hit for track " << trackID <<
" with position (" <<
pos.X() <<
", "
326 <<
pos.Y() <<
", " <<
pos.Z() <<
") and momentum (" << mom.X() <<
", " << mom.Y() <<
", " << mom.Z()
327 <<
") with energy " << initialEnergy <<
" loosing " << eLoss;
328 mHits->emplace_back(primary, trackID, detID, initialEnergy,
pos, mom,
time, eLoss);
329 return &(mHits->back());
334 LOG(debug3) <<
"Adding superparent for track " << trackID <<
" with PID " << pdg <<
" and energy " << energy;
335 auto entry = mSuperParents.insert({trackID, {pdg, energy,
false}});
336 return &(
entry.first->second);
342 return energydeposit;
348 if (std::abs(
charge) >= 2) {
349 birkC1Mod = mBirkC1 * 7.2 / 12.6;
356 if (tracklength > 0) {
357 dedxcm = 1000. * energydeposit / tracklength;
362 return energydeposit / (1. + birkC1Mod * dedxcm + mBirkC2 * dedxcm * dedxcm);
367 auto result = std::find_if(mHits->begin(), mHits->end(), [cellID, parentID](
const Hit& hit) { return hit.GetTrackID() == parentID && hit.GetDetectorID() == cellID; });
368 if (
result == mHits->end()) {
376 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits, kTRUE);
381 LOG(
debug) <<
"Cleaning EMCAL hits ...";
385 mSuperParentsIndices.clear();
386 mSuperParents.clear();
388 mCurrentParentID = -1;
397 LOG(error) <<
"Failure accessing geometry";
404 using boost::algorithm::contains;
407 std::string gn = geom->
GetName();
408 std::transform(gn.begin(), gn.end(), gn.begin(), ::toupper);
410 Int_t rotMatrixID(-1);
412 Matrix(rotMatrixID, 90.0, 0., 90.0, 90.0, 0.0, 0.0);
415 if (contains(gn,
"WSUC")) {
417 Double_t envelopA[3];
423 for (Int_t
i = 0;
i < 3;
i++) {
426 TVirtualMC::GetMC()->Gspos(geom->
GetNameOfEMCALEnvelope(), 1,
"WSUC", 0.0, 0.0, +265., rotMatrixID,
"ONLY");
429 Double_t envelopA[10];
439 envelopA[8] = envelopA[5];
440 envelopA[9] = envelopA[6];
447 LOG(debug2) <<
"ConstructGeometry: XU0 = " << envelopA[5] <<
", " << envelopA[6];
450 TVirtualMC::GetMC()->Gspos(geom->
GetNameOfEMCALEnvelope(), 1,
"barrel", 0.0, 0.0, 0.0, rotMatrixID,
"ONLY");
457 using boost::algorithm::contains;
459 std::string gn =
g->GetName();
460 std::transform(gn.begin(), gn.end(), gn.begin(), ::toupper);
462 Double_t trd1Angle =
g->GetTrd1Angle() * TMath::DegToRad(), tanTrd1 = TMath::Tan(trd1Angle / 2.);
467 Double_t par[10], xpos = 0., ypos = 0., zpos = 0.;
469 std::string mothervolume;
470 if (contains(
g->GetName(),
"WSUC")) {
471 mothervolume =
"WSUC";
473 mothervolume =
"barrel";
475 LOG(debug2) <<
"Name of mother volume: " << mothervolume;
478 auto SMTypeList =
g->GetEMCSystem();
480 std::string namesmtype;
481 for (
auto i : boost::irange(0,
g->GetNumberOfSuperModules())) {
482 if (SMTypeList[
i] == tmpType) {
485 tmpType = SMTypeList[
i];
496 namesmtype =
"SM3rd";
502 namesmtype =
"DCEXT";
505 LOG(error) <<
"Unkown SM Type!!";
507 LOG(debug2) <<
"Creating EMCAL module for SM " << namesmtype << std::endl;
508 if (namesmtype.length()) {
514 Double_t parSCM0[5] = {0, 0, 0, 0}, *dummy =
nullptr, parTRAP[11];
515 if (!contains(gn,
"V1")) {
516 Double_t wallThickness =
g->GetPhiModuleSize() /
g->GetNPHIdiv() -
g->GetPhiTileSize();
517 for (Int_t
i = 0;
i < 3;
i++) {
518 parSCM0[
i] = mParEMOD[
i] - wallThickness;
520 parSCM0[3] = mParEMOD[3];
522 TVirtualMC::GetMC()->Gspos(
"SCM0", 1,
"EMOD", 0., 0., 0., 0,
"ONLY");
524 Double_t wTh =
g->GetLateralSteelStrip();
525 parSCM0[0] = mParEMOD[0] - wTh + tanTrd1 *
g->GetTrd1AlFrontThick();
526 parSCM0[1] = mParEMOD[1] - wTh;
527 parSCM0[2] = mParEMOD[2] - wTh;
528 parSCM0[3] = mParEMOD[3] -
g->GetTrd1AlFrontThick() / 2.;
530 Double_t zshift =
g->GetTrd1AlFrontThick() / 2.;
531 TVirtualMC::GetMC()->Gspos(
"SCM0", 1,
"EMOD", 0., 0., zshift, 0,
"ONLY");
536 if (
g->GetNPHIdiv() == 2 &&
g->GetNETAdiv() == 2) {
538 LOG(debug2) <<
" Divide SCM0 on y-axis " <<
g->GetNETAdiv();
539 TVirtualMC::GetMC()->Gsdvn(
"SCMY",
"SCM0",
g->GetNETAdiv(), 2);
540 mSensitive.emplace_back(
"SCMY");
543 parTRAP[0] = parSCM0[3];
544 parTRAP[1] = TMath::ATan2((parSCM0[1] - parSCM0[0]) / 2., 2. * parSCM0[3]) * 180. / TMath::Pi();
548 parTRAP[3] = parSCM0[2] / 2.;
549 parTRAP[4] = parSCM0[0] / 2.;
550 parTRAP[5] = parTRAP[4];
554 parTRAP[7] = parSCM0[2] / 2.;
555 parTRAP[8] = parSCM0[1] / 2.;
556 parTRAP[9] = parTRAP[8];
559 LOG(debug2) <<
" ** TRAP ** ";
560 for (Int_t
i = 0;
i < 11;
i++) {
561 LOG(debug3) <<
" par[" << std::setw(2) << std::setprecision(2) <<
i <<
"] " << std::setw(9)
562 << std::setprecision(4) << parTRAP[
i];
566 xpos = +(parSCM0[1] + parSCM0[0]) / 4.;
567 TVirtualMC::GetMC()->Gspos(
"SCMX", 1,
"SCMY", xpos, 0.0, 0.0, 0,
"ONLY");
571 Int_t rotMatrixID(-1);
572 Matrix(rotMatrixID, 90.0, 180., 90.0, 270.0, 0.0, 0.0);
573 TVirtualMC::GetMC()->Gspos(
"SCMX", 2,
"SCMY", xpos, 0.0, 0.0, rotMatrixID,
"ONLY");
581 Double_t xCenterSCMX = (parTRAP[4] + parTRAP[8]) / 2.;
582 if (!contains(gn,
"V1")) {
583 par[1] = parSCM0[2] / 2;
584 par[2] =
g->GetECPbRadThick() / 2.;
587 zpos = -mSampleWidth *
g->GetNECLayers() / 2. +
g->GetECPbRadThick() / 2.;
588 LOG(debug2) <<
" Pb tiles ";
590 for (Int_t iz = 0; iz <
g->GetNECLayers(); iz++) {
591 par[0] = (parSCM0[0] + tanBetta * mSampleWidth * iz) / 2.;
592 xpos = par[0] - xCenterSCMX;
593 TVirtualMC::GetMC()->Gsposp(
"PBTI", ++nr,
"SCMX", xpos, ypos, zpos, 0,
"ONLY", par, 3);
594 LOG(debug3) << iz + 1 <<
" xpos " << xpos <<
" zpos " << zpos <<
" par[0] " << par[0];
595 zpos += mSampleWidth;
598 LOG(debug2) <<
" Number of Pb tiles in SCMX " << nr;
602 par[1] = parSCM0[2] / 2.;
603 par[2] =
g->GetTrd1BondPaperThick() / 2.;
604 par[0] = parSCM0[0] / 2.;
607 xpos = par[0] - xCenterSCMX;
608 zpos = -parSCM0[3] +
g->GetTrd1BondPaperThick() / 2.;
609 TVirtualMC::GetMC()->Gspos(
"PAP1", 1,
"SCMX", xpos, ypos, zpos, 0,
"ONLY");
611 for (
auto iz : boost::irange(0,
g->GetNECLayers() - 1)) {
613 Double_t dz =
g->GetECScintThick() +
g->GetTrd1BondPaperThick() + mSampleWidth * iz;
616 par[2] =
g->GetECPbRadThick() / 2. +
g->GetTrd1BondPaperThick();
617 par[0] = (parSCM0[0] + tanBetta * dz) / 2.;
618 std::string pa(Form(
"PA%2.2i", nr));
621 xpos = par[0] - xCenterSCMX;
622 zpos = -parSCM0[3] + dz + par[2];
623 TVirtualMC::GetMC()->Gspos(pa.data(), 1,
"SCMX", xpos, ypos, zpos, 0,
"ONLY");
626 std::string pb(Form(
"PB%2.2i", nr));
627 par[2] =
g->GetECPbRadThick() / 2.;
629 TVirtualMC::GetMC()->Gspos(pb.data(), 1, pa.data(), 0.0, 0.0, 0.0, 0,
"ONLY");
639 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
640 Float_t zAir[4] = {6., 7., 8., 18.};
641 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
643 Mixture(0,
"Air$", aAir, zAir, dAir, 4, wAir);
646 Material(1,
"Pb$", 207.2, 82, 11.35, 0.56, 0.,
nullptr, 0);
649 Float_t aP[2] = {12.011, 1.00794};
654 Mixture(2,
"Polystyrene$", aP, zP, dP, -2, wP);
657 Material(3,
"Al$", 26.98, 13., 2.7, 8.9, 999.,
nullptr, 0);
661 Float_t asteel[4] = {55.847, 51.9961, 58.6934, 28.0855};
662 Float_t zsteel[4] = {26., 24., 28., 14.};
663 Float_t wsteel[4] = {.715, .18, .1, .005};
664 Mixture(4,
"STAINLESS STEEL$", asteel, zsteel, 7.88, 4, wsteel);
671 Float_t apaper[3] = {12.01, 1.0, 16.0};
672 Float_t zpaper[3] = {6.0, 1.0, 8.0};
673 Float_t wpaper[3] = {6. / 21., 10. / 21., 5. / 21.};
674 Mixture(5,
"BondPaper$", apaper, zpaper, 0.75, 3, wpaper);
688 Medium(
ID_AIR,
"Air$", 0, 0, isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0,
nullptr, 0);
691 Medium(
ID_PB,
"Lead$", 1, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1,
nullptr, 0);
695 Medium(
ID_SC,
"Scintillator$", 2, 1, isxfld, sxmgmx, 10.0, 0.001, deemax, 0.001, 0.001,
nullptr, 0);
698 Medium(
ID_AL,
"Al$", 3, 0, isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001,
nullptr, 0);
701 Medium(
ID_STEEL,
"S steel$", 4, 0, isxfld, sxmgmx, 10.0, 0.01, 0.1, 0.001, 0.001,
nullptr, 0);
705 Medium(
ID_PAPER,
"Paper$", 5, 0, isxfld, sxmgmx, 10.0, deemax, 0.1, 0.001, 0.001,
nullptr, 0);
709 mBirkC1 = 0.013 / dP;
710 mBirkC2 = 9.6e-6 / (dP * dP);
712 std::array<std::string, 6> materialNames = {
"Air",
"Pb",
"Scintillator",
"Aluminium",
"Steel",
"Paper"};
713 for (
int i = 0;
i < 6;
i++) {
714 LOG(
debug) <<
"Created material of type " << materialNames[
i] <<
" with global index " <<
getMediumID(
i);
724 using boost::algorithm::contains;
726 std::string gn =
g->GetName();
727 std::transform(gn.begin(), gn.end(), gn.begin(), ::toupper);
729 Double_t par[3], xpos = 0., ypos = 0., zpos = 0., rpos = 0., dphi = 0., phi = 0.0, phiRad = 0.;
730 Double_t parC[3] = {0};
735 LOG(debug2) <<
"\n ## Super Module | fSampleWidth " << std::setw(5) << std::setprecision(3) << mSampleWidth <<
" ## "
737 par[0] =
g->GetShellThickness() / 2.;
738 par[1] =
g->GetPhiModuleSize() *
g->GetNPhi() / 2.;
739 par[2] =
g->GetEtaModuleSize() *
g->GetNEta() / 2.;
741 Int_t nSMod =
g->GetNumberOfSuperModules();
742 Int_t nphism = nSMod / 2;
744 dphi =
g->GetPhiSuperModule();
745 rpos = (
g->GetEnvelop(0) +
g->GetEnvelop(1)) / 2.;
746 LOG(debug2) <<
" rpos " << std::setw(8) << std::setprecision(2) << rpos <<
" : dphi " << std::setw(6)
747 << std::setprecision(1) << dphi <<
" degree ";
750 if (contains(gn,
"WSUC")) {
752 par[0] =
g->GetPhiModuleSize() *
g->GetNPhi() / 2.;
753 par[1] =
g->GetShellThickness() / 2.;
754 par[2] =
g->GetEtaModuleSize() *
g->GetNZ() / 2. + 5;
758 LOG(debug2) <<
"SMOD in WSUC : tmed " <<
getMediumID(
ID_AIR) <<
" | dx " << std::setw(7) << std::setprecision(2)
759 << par[0] <<
" dy " << std::setw(7) << std::setprecision(2) << par[1] <<
" dz " << std::setw(7)
760 << std::setprecision(2) << par[2] <<
" (SMOD, BOX)";
764 nphism =
g->GetNumberOfSuperModules();
765 for (Int_t
i = 0;
i < nphism;
i++) {
766 xpos = ypos = zpos = 0.0;
767 TVirtualMC::GetMC()->Gspos(
"SMOD", 1, mother.data(), xpos, ypos, zpos, 0,
"ONLY");
769 LOG(debug2) <<
" fIdRotm " << std::setw(3) << 0 <<
" phi " << std::setw(7) << std::setprecision(1) << phi <<
"("
770 << std::setw(5) << std::setprecision(3) << phiRad <<
") xpos " << std::setw(7) << std::setprecision(2)
771 << xpos <<
" ypos " << std::setw(7) << std::setprecision(2) << ypos <<
" zpos " << std::setw(7)
772 << std::setprecision(2) << zpos;
777 LOG(debug2) <<
" par[0] " << std::setw(7) << std::setprecision(2) << par[0] <<
" (old) ";
778 for (Int_t
i = 0;
i < 3;
i++) {
779 par[
i] =
g->GetSuperModulesPar(
i);
786 for (
auto smodnum : boost::irange(0, nSMod)) {
787 memcpy(parC, par,
sizeof(
double) * 3);
788 if (
g->GetSMType(smodnum) == tmpType) {
791 tmpType =
g->GetSMType(smodnum);
795 phiRad =
g->GetPhiCenterOfSMSec(smodnum);
796 phi = phiRad * 180. / TMath::Pi();
797 Double_t phiy = 90. + phi;
800 xpos = rpos * TMath::Cos(phiRad);
801 ypos = rpos * TMath::Sin(phiRad);
811 xpos += (par[1] / 2. * TMath::Sin(phiRad));
812 ypos -= (par[1] / 2. * TMath::Cos(phiRad));
818 xpos += (2. * par[1] / 3. * TMath::Sin(phiRad));
819 ypos -= (2. * par[1] / 3. * TMath::Cos(phiRad));
826 parC[2] += mDCALInnerGap / 2.;
827 zpos = mSmodPar2 + (
g->GetDCALInnerEdge() - mDCALInnerGap) / 2.;
833 xpos += (2. * par[1] / 3. * TMath::Sin(phiRad));
834 ypos -= (2. * par[1] / 3. * TMath::Cos(phiRad));
838 LOG(error) <<
"Unkown SM Type!!";
846 LOG(debug2) << R
"( Super module with name \")" << smName << R"(\" was created in \"box\" with: par[0] = )"
847 << parC[0] << ", par[1] = " << parC[1] <<
", par[2] = " << parC[2];
850 if (smodnum % 2 == 1) {
859 Int_t rotMatrixID(-1);
860 Matrix(rotMatrixID, 90.0, phi, 90.0, phiy, phiz, 0.0);
861 TVirtualMC::GetMC()->Gspos(smName.data(), SMOrder, mother.data(), xpos, ypos + 30., zpos, rotMatrixID,
"ONLY");
863 LOG(debug3) << smName <<
" : " << std::setw(2) << SMOrder <<
", fIdRotm " << std::setw(3) << rotMatrixID
864 <<
" phi " << std::setw(6) << std::setprecision(1) << phi <<
"(" << std::setw(5)
865 << std::setprecision(3) << phiRad <<
") xpos " << std::setw(7) << std::setprecision(2) << xpos
866 <<
" ypos " << std::setw(7) << std::setprecision(2) << ypos <<
" zpos " << std::setw(7)
867 << std::setprecision(2) << zpos <<
" : i " << smodnum;
871 LOG(debug2) <<
" Number of Super Modules " << nSMod;
874 if (
g->GetSteelFrontThickness() > 0.0) {
875 par[0] =
g->GetSteelFrontThickness() / 2.;
878 LOG(debug1) <<
"tmed " <<
getMediumID(
ID_STEEL) <<
" | dx " << std::setw(7) << std::setprecision(2) << par[0]
879 <<
" dy " << std::setw(7) << std::setprecision(2) << par[1] <<
" dz " << std::setw(7)
880 << std::setprecision(2) << par[2] <<
" (STPL) ";
882 xpos = -(
g->GetShellThickness() -
g->GetSteelFrontThickness()) / 2.;
883 TVirtualMC::GetMC()->Gspos(
"STPL", 1,
"SMOD", xpos, 0.0, 0.0, 0,
"ONLY");
891 using boost::algorithm::contains;
893 std::string gn =
g->GetName();
894 std::transform(gn.begin(), gn.end(), gn.begin(), ::toupper);
897 Double_t xpos = 0., ypos = 0., zpos = 0.;
900 if (mother ==
"SMOD") {
901 mParEMOD[0] =
g->GetEtaModuleSize() / 2.;
902 mParEMOD[1] =
g->Get2Trd1Dx2() / 2.;
903 mParEMOD[2] =
g->GetPhiModuleSize() / 2.;
904 mParEMOD[3] =
g->GetLongModuleSize() / 2.;
909 Int_t rotMatrixID(-1);
912 for (
auto iz : boost::irange(0,
g->GetNZ())) {
916 if (!contains(gn,
"WSUC")) {
919 LOG(debug4) << std::setw(2) << iz + 1 <<
" | angle | " << std::setw(6) << std::setprecision(3) <<
angle <<
" - "
920 << std::setw(6) << std::setprecision(3) << phiOK <<
" = " << std::setw(6) << std::setprecision(3)
923 xpos = mod.
GetPosXfromR() +
g->GetSteelFrontThickness() - mSmodPar0;
924 zpos = mod.
GetPosZ() - mSmodPar2;
926 Int_t iyMax =
g->GetNPhi();
927 if (mother ==
"SM10") {
929 }
else if (mother ==
"SM3rd") {
931 }
else if (mother ==
"DCEXT") {
933 }
else if (mother ==
"DCSM") {
939 zpos = mod.
GetPosZ() - mSmodPar2 - (
g->GetDCALInnerEdge() - mDCALInnerGap) / 2.;
940 }
else if (mother.compare(
"SMOD")) {
941 LOG(error) <<
"Unknown super module Type!!";
944 for (
auto iy : boost::irange(0, iyMax)) {
945 ypos =
g->GetPhiModuleSize() * (2 * iy + 1 - iyMax) / 2.;
946 TVirtualMC::GetMC()->Gspos(child.data(), ++nr, mother.data(), xpos, ypos, zpos, rotMatrixID,
"ONLY");
949 LOG(debug3) << std::setw(3) << std::setprecision(3) << nr <<
"(" << std::setw(2) << std::setprecision(2)
950 << iy + 1 <<
"," << std::setw(2) << std::setprecision(2) << iz + 1 <<
")";
955 Matrix(rotMatrixID, 0., 0., 90., 0., 90., 90.);
962 LOG(debug4) << std::setw(2) << iz + 1 <<
" | angle -phiOK | " << std::setw(6) << std::setprecision(3) <<
angle
963 <<
" - " << std::setw(6) << std::setprecision(3) << phiOK <<
" = " << std::setw(6)
964 << std::setprecision(3) <<
angle - phiOK <<
"(eta " << std::setw(5) << std::setprecision(3)
967 zpos = mod.
GetPosZ() - mSmodPar2;
972 for (
auto ix : boost::irange(0,
g->GetNPhi())) {
973 xpos =
g->GetPhiModuleSize() * (2 * ix + 1 -
g->GetNPhi()) / 2.;
974 TVirtualMC::GetMC()->Gspos(child.data(), ++nr, mother.data(), xpos, ypos, zpos, rotMatrixID,
"ONLY");
981 LOG(debug2) <<
" Number of modules in Super Module(" << mother <<
") " << nr;
989 Double_t trd1Angle =
g->GetTrd1Angle() * TMath::DegToRad(), tanTrd1 = TMath::Tan(trd1Angle / 2.);
990 Double_t parALFP[5], zposALFP = 0.;
992 parALFP[0] =
g->GetEtaModuleSize() / 2. -
g->GetLateralSteelStrip();
993 parALFP[1] = parALFP[0] + tanTrd1 *
g->GetTrd1AlFrontThick();
994 parALFP[2] =
g->GetPhiModuleSize() / 2. -
g->GetLateralSteelStrip();
995 parALFP[3] =
g->GetTrd1AlFrontThick() / 2.;
999 zposALFP = -mParEMOD[3] +
g->GetTrd1AlFrontThick() / 2.;
1000 TVirtualMC::GetMC()->Gspos(child.data(), 1, mother.data(), 0.0, 0.0, zposALFP, 0,
"ONLY");
1005 int volID = TVirtualMC::GetMC()->Gsvolu(
name.data(), shape.data(),
getMediumID(mediumID), shapeParams, nparams);
1006 mSensitive.emplace_back(
name.data());
1012 mCurrentPrimaryID = fMC->GetStack()->GetCurrentTrackNumber();
1013 LOG(
debug) <<
"Starting primary " << mCurrentPrimaryID <<
" with energy " << fMC->GetStack()->GetCurrentTrack()->Energy();
1018 LOG(
debug) <<
"Finishing primary " << mCurrentPrimaryID << std::endl;
1020 mCurrentPrimaryID = -1;
Definition of the Stack class.
int registerSensitiveVolumeAndGetVolID(std::string const &name)
void Matrix(Int_t &nmat, Float_t theta1, Float_t phi1, Float_t theta2, Float_t phi2, Float_t theta3, Float_t phi3) const
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
static void initFieldTrackingParams(int &mode, float &maxfield)
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
Detector simulation class for the EMCAL detector.
Hit * AddHit(Int_t trackID, Int_t primary, Double_t initialEnergy, Int_t detID, const math_utils::Point3D< float > &pos, const math_utils::Vector3D< float > &mom, Double_t time, Double_t energyloss)
Add EMCAL hit.
void CreateEmcalModuleGeometry(const std::string_view mother="SMOD", const std::string_view child="EMOD")
Generate module geometry (2x2 towers)
Double_t CalculateLightYield(Double_t energydeposit, Double_t tracklength, Int_t charge) const
Calculate the amount of light seen by the APD for a given track segment (charged particles only) acco...
Parent * AddSuperparent(Int_t trackID, Int_t pdg, Double_t energy)
Hit * FindHit(Int_t cellID, Int_t parentID)
Try to find hit with same cell and parent track ID.
void CreateSupermoduleGeometry(const std::string_view mother="XEN1")
Generate super module geometry.
~Detector() override
Destructor.
void InitializeO2Detector() override
Initializing detector.
int CreateEMCALVolume(const std::string_view name, const std::string_view shape, MediumType_t mediumID, Double_t *shapeParams, Int_t nparams)
Create new EMCAL volume and add it to the list of sensitive volumes.
Geometry * GetGeometry()
Get the EMCAL geometry desciption.
Detector()=default
Default constructor.
void CreateEmcalEnvelope()
Generate EMCAL envelop (mother volume of all supermodules)
void Register() override
register container with hits
void FinishPrimary() override
Finish current primary.
void ConstructGeometry() override
void CreateMaterials()
Creating detector materials for the EMCAL detector and space frame.
Bool_t ProcessHits(FairVolume *v=nullptr) final
Processing hit creation in the EMCAL scintillator volume.
void EndOfEvent() final
Steps to be carried out at the end of the event.
void BeginPrimary() override
Begin primaray.
void Reset() final
Clean point collection.
void CreateShiskebabGeometry()
Generate tower geometry.
void CreateAlFrontPlate(const std::string_view mother="EMOD", const std::string_view child="ALFP")
Generate aluminium plates geometry.
EMCAL geometry definition.
static Geometry * GetInstanceFromRunNumber(Int_t runNumber, const std::string_view="", const std::string_view mcname="TGeant3", const std::string_view mctitle="")
Instanciate geometry depending on the run number. Mostly used in analysis and MC anchors.
std::tuple< int, int > GetCellPhiEtaIndexInSModule(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
Get eta-phi indexes of cell in SM.
Float_t GetSampling() const
Float_t GetArm1PhiMin() const
static Bool_t IsInitialized()
const Char_t * GetNameOfEMCALEnvelope() const
std::vector< Double_t > GetCentersOfCellsPhiDir() const
Float_t GetPhiSuperModule() const
const std::string & GetName() const
Float_t GetECScintThick() const
Float_t GetTrd1BondPaperThick() const
std::vector< Double_t > GetCentersOfCellsEtaDir() const
Int_t GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
Transition from super module number (nSupMod) and cell indexes (ieta,iphi) to cell absolute ID number...
void DefineSamplingFraction(const std::string_view mcname="", const std::string_view mctitle="")
Set the value of the Sampling used to calibrate the MC hits energy (check)
Float_t GetEnvelop(Int_t index) const
Float_t GetECPbRadThick() const
Float_t GetArm1PhiMax() const
EMCAL simulation hit information.
Main class for TRD1 geometry of Shish-Kebab case.
Double_t GetPosXfromR() const
Double_t GetThetaInDegree() const
Double_t GetTanBetta() const
const TVector2 & GetCenterOfModule() const
Double_t GetEtaOfCenterOfModule() const
Space Frame implementation.
void CreateGeometry()
Assembles the Geometries and places them into the Alice master volume.
static ShmManager & Instance()
GLuint const GLchar * name
GLdouble GLdouble GLdouble z
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.
Information about superparent (particle entering EMCAL)
double mEnergy
Total energy.
bool mHasTrackReference
Flag indicating whether parent has a track reference.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"