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};
136 std::vector<float> rInnReal = rInn;
140 const std::vector<int> nStaves{10, 14, 18, 26, 38, 30, 42, 56};
142 LOGP(warning,
"Loading simplified-realistic configuration for ALICE3 TRK");
154 LOGP(fatal,
"Unknown option {} for configMLOT",
static_cast<int>(trkPars.layoutMLOT));
162 std::ifstream confFile(fileName);
163 if (!confFile.good()) {
164 LOGP(fatal,
"File {} not found, aborting.", fileName);
171 LOGP(info,
"Overriding geometry of ALICE3 TRK using {} file.", fileName);
174 std::vector<float> tmpBuff;
176 while (std::getline(confFile, line)) {
177 if (line[0] ==
'/') {
181 std::stringstream ss(line);
184 while (getline(ss, substr,
'\t')) {
185 tmpBuff.push_back(std::stof(substr));
190 switch (trkPars.layoutMLOT) {
199 if (tmpBuff.size() < 3) {
200 LOGP(fatal,
"Invalid configuration for cylindrical layer {}: insufficient parameters.", layerCount);
203 float rInn = tmpBuff[0];
204 float length = tmpBuff[1];
205 float thick = tmpBuff[2];
209 if (tmpBuff.size() >= 4) {
213 mLayers.push_back(std::make_unique<TRKCylindricalLayer>(layerCount,
name, rInn,
length, thick, matBudgetMode));
232 if (tmpBuff.size() < 5) {
233 LOGP(fatal,
"Invalid configuration for segmented layer {}: missing base parameters.", layerCount);
236 float rInn = tmpBuff[0];
237 float thick = tmpBuff[1];
238 float tiltAngle = tmpBuff[2];
239 int nStaves =
static_cast<int>(tmpBuff[3]);
240 int nMods =
static_cast<int>(tmpBuff[4]);
247 if (tmpBuff.size() < 6) {
248 LOGP(fatal,
"Invalid configuration for ML layer {}: stagOffset is missing.", layerCount);
250 float stagOffset = tmpBuff[5];
252 if (tmpBuff.size() >= 7) {
255 const int rInnRow = (tmpBuff.size() >= 8) ?
static_cast<int>(tmpBuff[7]) : 0;
256 const float phiOffset = (tmpBuff.size() >= 9) ? tmpBuff[8] : 0.f;
258 mLayers.push_back(std::make_unique<TRKMLLayer>(layerCount,
name, rInn, stagOffset, tiltAngle, nStaves, nMods, thick, matBudgetMode, rInnRow, phiOffset));
261 if (tmpBuff.size() >= 6) {
266 mLayers.push_back(std::make_unique<TRKOTLayerRealistic>(layerCount,
name, rInn, tiltAngle, nStaves, nMods, thick, matBudgetMode));
268 mLayers.push_back(std::make_unique<TRKOTLayer>(layerCount,
name, rInn, tiltAngle, nStaves, nMods, thick, matBudgetMode));
274 LOGP(fatal,
"Unknown option {} for configMLOT",
static_cast<int>(trkPars.layoutMLOT));
303 float tmaxfdSi = 0.1;
304 float stemaxSi = 0.0075;
305 float deemaxSi = 0.1;
306 float epsilSi = 1.0E-4;
309 float tmaxfdAir = 0.1;
310 float stemaxAir = .10000E+01;
311 float deemaxAir = 0.1;
312 float epsilAir = 1.0E-4;
313 float stminAir = 0.0;
315 float tmaxfdCer = 0.1;
316 float stemaxCer = .10000E+01;
317 float deemaxCer = 0.1;
318 float epsilCer = 1.0E-4;
319 float stminCer = 0.0;
322 float tmaxfdPas = 0.1;
323 float stemaxPas = 1.0;
324 float deemaxPas = 0.1;
325 float epsilPas = 1.0E-4;
326 float stminPas = 0.0;
329 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
330 float zAir[4] = {6., 7., 8., 18.};
331 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
332 float dAir = 1.20479E-3;
335 float aCf[2] = {12.0107, 1.00794};
336 float zCf[2] = {6., 1.};
339 float aFpc[2] = {63.546f, 12.0107f};
340 float zFpc[2] = {29.f, 6.f};
341 float wFpc[2] = {0.40f, 0.60f};
345 float aLcpCu[2] = {63.546f, 12.0107f};
346 float zLcpCu[2] = {29.f, 6.f};
347 float wLcpCu[2] = {0.60f, 0.40f};
351 float aBaTiO3[3] = {137.327f, 47.867f, 15.9994f};
352 float zBaTiO3[3] = {56.f, 22.f, 8.f};
353 float wBaTiO3[3] = {0.5879f, 0.2054f, 0.2067f};
354 float dBaTiO3 = 6.0f;
357 float aFr4[4] = {28.0855f, 15.9994f, 12.0107f, 1.00794f};
358 float zFr4[4] = {14.f, 8.f, 6.f, 1.f};
359 float wFr4[4] = {0.2804f, 0.3836f, 0.3040f, 0.0320f};
363 o2::base::Detector::Medium(1,
"AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
366 o2::base::Detector::Medium(3,
"SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
370 o2::base::Detector::Medium(4,
"CARBONFIBER$", 4, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
373 o2::base::Detector::Medium(5,
"FPC$", 5, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
376 o2::base::Detector::Medium(6,
"LCPCU$", 6, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
379 o2::base::Detector::Medium(7,
"BATIO3$", 7, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
383 o2::base::Detector::Medium(8,
"PEEK$", 8, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
386 o2::base::Detector::Medium(9,
"FR4$", 9, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
390 o2::base::Detector::Medium(10,
"COPPER$", 10, 0, ifield, fieldm, tmaxfdPas, stemaxPas, deemaxPas, epsilPas, stminPas);
556 if (!(fMC->TrackCharge())) {
563 int volID = vol->getMCid();
565 bool notSens =
false;
566 while ((volume < mNumberOfVolumes) && (notSens = (volID !=
mSensorID[volume]))) {
574 if (volume < mNumberOfVolumesVD) {
578 layer = volume - mNumberOfVolumesVD;
584 if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) {
589 stack->addTrackReference(tr);
591 bool startHit =
false, stopHit =
false;
592 unsigned char status = 0;
593 if (fMC->IsTrackEntering()) {
594 status |= Hit::kTrackEntering;
596 if (fMC->IsTrackInside()) {
597 status |= Hit::kTrackInside;
599 if (fMC->IsTrackExiting()) {
600 status |= Hit::kTrackExiting;
602 if (fMC->IsTrackOut()) {
603 status |= Hit::kTrackOut;
605 if (fMC->IsTrackStop()) {
606 status |= Hit::kTrackStopped;
608 if (fMC->IsTrackAlive()) {
609 status |= Hit::kTrackAlive;
613 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
615 }
else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
621 mTrackData.mEnergyLoss += fMC->Edep();
623 if (!(startHit | stopHit)) {
628 mTrackData.mEnergyLoss = 0.;
629 fMC->TrackMomentum(mTrackData.mMomentumStart);
630 fMC->TrackPosition(mTrackData.mPositionStart);
631 mTrackData.mTrkStatusStart = status;
632 mTrackData.mHitStarted =
true;
635 TLorentzVector positionStop;
636 fMC->TrackPosition(positionStop);
639 int stave(0), halfstave(0), mod(0), chip(0);
645 fMC->CurrentVolOffID(1, chip);
646 fMC->CurrentVolOffID(2, mod);
648 fMC->CurrentVolOffID(3, halfstave);
649 fMC->CurrentVolOffID(4, stave);
651 fMC->CurrentVolOffID(3, stave);
653 LOGP(fatal,
"Wrong number of halfstaves for layer {}",
layer);
658 const TVector3 mid = (mTrackData.mPositionStart.Vect() + positionStop.Vect()) * 0.5;
659 gGeoManager->PushPath();
660 if (gGeoManager->FindNode(mid.X(), mid.Y(), mid.Z())) {
661 auto copyUp = [](
int up) { TGeoNode*
n = gGeoManager->GetMother(up);
return n ?
n->GetNumber() : 0; };
665 halfstave = copyUp(3);
670 LOGP(fatal,
"Wrong number of halfstaves for layer {}",
layer);
673 gGeoManager->PopPath();
677 unsigned short chipID = mGeometryTGeo->
getChipIndex(subDetID, volume,
layer, stave, halfstave, mod, chip);
683 Hit* p =
addHit(
stack->GetCurrentTrackNumber(), chipID, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
684 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
685 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
690 stack->addHit(GetDetId());