96 const std::vector<float> rInn{7.f, 9.f, 12.f, 20.f, 30.f, 45.f, 60.f, 80.f};
97 const float thick = 100.e-3;
99 switch (trkPars.layoutMLOT) {
101 const std::vector<float>
length{127.985f, 127.985f, 127.985f, 127.985f, 127.985f, 255.9f, 255.9f, 255.9f};
102 LOGP(warning,
"Loading cylindrical configuration for ALICE3 TRK");
110 const std::vector<float> tiltAngles{11.2f, 11.9f, 11.4f, 0.f, 0.f, 0.f, 0.f, 0.f};
112 const std::vector<int> nStaves{10, 14, 18, 26, 38, 32, 42, 56};
114 const std::vector<int> nMods{11, 11, 11, 11, 11, 22, 22, 22};
116 const std::vector<float> stagOffsets{0.f, 0.f, 0.f, 1.17f, 0.89f};
118 LOGP(warning,
"Loading segmented configuration for ALICE3 TRK");
131 const std::vector<float> tiltAngles{11.2f, 11.9f, 11.4f, 0.f, 0.f, 0.f, 0.f, 0.f};
132 const std::vector<int> nMods{11, 11, 11, 11, 11, 22, 22, 22};
133 const std::vector<float> stagOffsets{0.f, 0.f, 0.f, 1.17f, 0.89f};
137 std::vector<float> rInnReal = rInn;
142 const std::vector<int> nStaves{10, 14, 18, 26, 38, 30, 42, 54};
144 LOGP(warning,
"Loading simplified-realistic configuration for ALICE3 TRK");
156 LOGP(fatal,
"Unknown option {} for configMLOT",
static_cast<int>(trkPars.layoutMLOT));
164 std::ifstream confFile(fileName);
165 if (!confFile.good()) {
166 LOGP(fatal,
"File {} not found, aborting.", fileName);
173 LOGP(info,
"Overriding geometry of ALICE3 TRK using {} file.", fileName);
176 std::vector<float> tmpBuff;
178 while (std::getline(confFile, line)) {
179 if (line[0] ==
'/') {
183 std::stringstream ss(line);
186 while (getline(ss, substr,
'\t')) {
187 tmpBuff.push_back(std::stof(substr));
192 switch (trkPars.layoutMLOT) {
201 if (tmpBuff.size() < 3) {
202 LOGP(fatal,
"Invalid configuration for cylindrical layer {}: insufficient parameters.", layerCount);
205 float rInn = tmpBuff[0];
206 float length = tmpBuff[1];
207 float thick = tmpBuff[2];
211 if (tmpBuff.size() >= 4) {
215 mLayers.push_back(std::make_unique<TRKCylindricalLayer>(layerCount,
name, rInn,
length, thick, matBudgetMode));
230 if (tmpBuff.size() < 5) {
231 LOGP(fatal,
"Invalid configuration for segmented layer {}: missing base parameters.", layerCount);
234 float rInn = tmpBuff[0];
235 float thick = tmpBuff[1];
236 float tiltAngle = tmpBuff[2];
237 int nStaves =
static_cast<int>(tmpBuff[3]);
238 int nMods =
static_cast<int>(tmpBuff[4]);
245 if (tmpBuff.size() < 6) {
246 LOGP(fatal,
"Invalid configuration for ML layer {}: stagOffset is missing.", layerCount);
248 float stagOffset = tmpBuff[5];
250 if (tmpBuff.size() >= 7) {
254 mLayers.push_back(std::make_unique<TRKMLLayer>(layerCount,
name, rInn, stagOffset, tiltAngle, nStaves, nMods, thick, matBudgetMode));
257 if (tmpBuff.size() >= 6) {
262 mLayers.push_back(std::make_unique<TRKOTLayerRealistic>(layerCount,
name, rInn, tiltAngle, nStaves, nMods, thick, matBudgetMode));
264 mLayers.push_back(std::make_unique<TRKOTLayer>(layerCount,
name, rInn, tiltAngle, nStaves, nMods, thick, matBudgetMode));
270 LOGP(fatal,
"Unknown option {} for configMLOT",
static_cast<int>(trkPars.layoutMLOT));
299 float tmaxfdSi = 0.1;
300 float stemaxSi = 0.0075;
301 float deemaxSi = 0.1;
302 float epsilSi = 1.0E-4;
305 float tmaxfdAir = 0.1;
306 float stemaxAir = .10000E+01;
307 float deemaxAir = 0.1;
308 float epsilAir = 1.0E-4;
309 float stminAir = 0.0;
311 float tmaxfdCer = 0.1;
312 float stemaxCer = .10000E+01;
313 float deemaxCer = 0.1;
314 float epsilCer = 1.0E-4;
315 float stminCer = 0.0;
318 float tmaxfdPas = 0.1;
319 float stemaxPas = 1.0;
320 float deemaxPas = 0.1;
321 float epsilPas = 1.0E-4;
322 float stminPas = 0.0;
325 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
326 float zAir[4] = {6., 7., 8., 18.};
327 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
328 float dAir = 1.20479E-3;
331 float aCf[2] = {12.0107, 1.00794};
332 float zCf[2] = {6., 1.};
335 float aFpc[2] = {63.546f, 12.0107f};
336 float zFpc[2] = {29.f, 6.f};
337 float wFpc[2] = {0.40f, 0.60f};
341 float aLcpCu[2] = {63.546f, 12.0107f};
342 float zLcpCu[2] = {29.f, 6.f};
343 float wLcpCu[2] = {0.60f, 0.40f};
347 float aBaTiO3[3] = {137.327f, 47.867f, 15.9994f};
348 float zBaTiO3[3] = {56.f, 22.f, 8.f};
349 float wBaTiO3[3] = {0.5879f, 0.2054f, 0.2067f};
350 float dBaTiO3 = 6.0f;
353 float aFr4[4] = {28.0855f, 15.9994f, 12.0107f, 1.00794f};
354 float zFr4[4] = {14.f, 8.f, 6.f, 1.f};
355 float wFr4[4] = {0.2804f, 0.3836f, 0.3040f, 0.0320f};
359 o2::base::Detector::Medium(1,
"AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
362 o2::base::Detector::Medium(3,
"SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
366 o2::base::Detector::Medium(4,
"CARBONFIBER$", 4, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
369 o2::base::Detector::Medium(5,
"FPC$", 5, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
372 o2::base::Detector::Medium(6,
"LCPCU$", 6, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
375 o2::base::Detector::Medium(7,
"BATIO3$", 7, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
379 o2::base::Detector::Medium(8,
"PEEK$", 8, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
382 o2::base::Detector::Medium(9,
"FR4$", 9, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
386 o2::base::Detector::Medium(10,
"COPPER$", 10, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
552 if (!(fMC->TrackCharge())) {
559 int volID = vol->getMCid();
561 bool notSens =
false;
562 while ((volume < mNumberOfVolumes) && (notSens = (volID !=
mSensorID[volume]))) {
570 if (volume < mNumberOfVolumesVD) {
574 layer = volume - mNumberOfVolumesVD;
580 if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) {
585 stack->addTrackReference(tr);
587 bool startHit =
false, stopHit =
false;
588 unsigned char status = 0;
589 if (fMC->IsTrackEntering()) {
590 status |= Hit::kTrackEntering;
592 if (fMC->IsTrackInside()) {
593 status |= Hit::kTrackInside;
595 if (fMC->IsTrackExiting()) {
596 status |= Hit::kTrackExiting;
598 if (fMC->IsTrackOut()) {
599 status |= Hit::kTrackOut;
601 if (fMC->IsTrackStop()) {
602 status |= Hit::kTrackStopped;
604 if (fMC->IsTrackAlive()) {
605 status |= Hit::kTrackAlive;
609 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
611 }
else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
617 mTrackData.mEnergyLoss += fMC->Edep();
619 if (!(startHit | stopHit)) {
624 mTrackData.mEnergyLoss = 0.;
625 fMC->TrackMomentum(mTrackData.mMomentumStart);
626 fMC->TrackPosition(mTrackData.mPositionStart);
627 mTrackData.mTrkStatusStart = status;
628 mTrackData.mHitStarted =
true;
631 TLorentzVector positionStop;
632 fMC->TrackPosition(positionStop);
635 int stave(0), halfstave(0), mod(0), chip(0);
641 fMC->CurrentVolOffID(1, chip);
642 fMC->CurrentVolOffID(2, mod);
644 fMC->CurrentVolOffID(3, halfstave);
645 fMC->CurrentVolOffID(4, stave);
647 fMC->CurrentVolOffID(3, stave);
649 LOGP(fatal,
"Wrong number of halfstaves for layer {}",
layer);
654 const TVector3 mid = (mTrackData.mPositionStart.Vect() + positionStop.Vect()) * 0.5;
655 gGeoManager->PushPath();
656 if (gGeoManager->FindNode(mid.X(), mid.Y(), mid.Z())) {
657 auto copyUp = [](
int up) { TGeoNode*
n = gGeoManager->GetMother(up);
return n ?
n->GetNumber() : 0; };
661 halfstave = copyUp(3);
666 LOGP(fatal,
"Wrong number of halfstaves for layer {}",
layer);
669 gGeoManager->PopPath();
673 unsigned short chipID = mGeometryTGeo->
getChipIndex(subDetID, volume,
layer, stave, halfstave, mod, chip);
679 Hit* p =
addHit(
stack->GetCurrentTrackNumber(), chipID, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
680 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
681 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
686 stack->addHit(GetDetId());