From 60b8fafa05545065f7472c4f6b27e2da53ea9636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:11:38 +0200 Subject: [PATCH 01/10] Update LUT configurations to allow empty values --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 1be815b2411..ccd0393d07c 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -105,15 +105,15 @@ struct OnTheFlyTracker { Configurable doExtraQA{"doExtraQA", false, "do extra 2D QA plots"}; Configurable extraQAwithoutDecayDaughters{"extraQAwithoutDecayDaughters", false, "remove decay daughters from qa plots (yes/no)"}; - Configurable lutEl{"lutEl", "lutCovm.el.dat", "LUT for electrons"}; - Configurable lutMu{"lutMu", "lutCovm.mu.dat", "LUT for muons"}; - Configurable lutPi{"lutPi", "lutCovm.pi.dat", "LUT for pions"}; - Configurable lutKa{"lutKa", "lutCovm.ka.dat", "LUT for kaons"}; + Configurable lutEl{"lutEl", "lutCovm.el.dat", "LUT for electrons (if emtpy no LUT is taken)"}; + Configurable lutMu{"lutMu", "lutCovm.mu.dat", "LUT for muons (if emtpy no LUT is taken)"}; + Configurable lutPi{"lutPi", "lutCovm.pi.dat", "LUT for pions (if emtpy no LUT is taken)"}; + Configurable lutKa{"lutKa", "lutCovm.ka.dat", "LUT for kaons (if emtpy no LUT is taken)"}; Configurable lutPr{"lutPr", "lutCovm.pr.dat", "LUT for protons"}; - Configurable lutDe{"lutDe", "lutCovm.de.dat", "LUT for deuterons"}; - Configurable lutTr{"lutTr", "lutCovm.tr.dat", "LUT for tritons"}; - Configurable lutHe3{"lutHe3", "lutCovm.he3.dat", "LUT for Helium-3"}; - Configurable lutAl{"lutAl", "lutCovm.he3.dat", "LUT for Alphas"}; + Configurable lutDe{"lutDe", "", "LUT for deuterons (if emtpy no LUT is taken)"}; + Configurable lutTr{"lutTr", "", "LUT for tritons (if emtpy no LUT is taken)"}; + Configurable lutHe3{"lutHe3", "", "LUT for Helium-3 (if emtpy no LUT is taken)"}; + Configurable lutAl{"lutAl", "", "LUT for Alphas (if emtpy no LUT is taken)"}; struct : ConfigurableGroup { ConfigurableAxis axisMomentum{"axisMomentum", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "#it{p} (GeV/#it{c})"}; From 26361ab0bc9386a8e66de3de5a4ffd6c68032e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:15:29 +0200 Subject: [PATCH 02/10] Fix linter --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 34 ++++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index ccd0393d07c..4e416e55e8a 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -255,7 +255,7 @@ struct OnTheFlyTracker { auto loadLUT = [&](int pdg, const std::string& lutFile) { bool success = mSmearer.loadTable(pdg, lutFile.c_str()); if (!success && !lutFile.empty()) { - LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; + std::LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; } }; loadLUT(11, lutEl.value); @@ -363,7 +363,7 @@ struct OnTheFlyTracker { hFastTrackerQA->GetXaxis()->SetBinLabel(8, "efficiency"); } - LOGF(info, "Initializing magnetic field to value: %.3f kG", static_cast(magneticField)); + std::LOGF(info, "Initializing magnetic field to value: %.3f kG", static_cast(magneticField)); o2::parameters::GRPMagField grpmag; grpmag.setFieldUniformity(true); grpmag.setL3Current(30000.f * (magneticField / 5.0f)); @@ -372,18 +372,18 @@ struct OnTheFlyTracker { auto fieldInstance = static_cast(TGeoGlobalMagField::Instance()->GetField()); if (!fieldInstance) { - LOGF(fatal, "Failed to set up magnetic field! Stopping now!"); + std::LOGF(fatal, "Failed to set up magnetic field! Stopping now!"); } // Cross-check - LOGF(info, "Check field at (0, 0, 0): %.1f kG, nominal: %.1f", static_cast(fieldInstance->GetBz(0, 0, 0)), static_cast(field)); + std::LOGF(info, "Check field at (0, 0, 0): %.1f kG, nominal: %.1f", static_cast(fieldInstance->GetBz(0, 0, 0)), static_cast(field)); - LOGF(info, "Initializing empty material cylinder LUT - could be better in the future"); + std::LOGF(info, "Initializing empty material cylinder LUT - could be better in the future"); o2::base::MatLayerCylSet* lut = new o2::base::MatLayerCylSet(); lut->addLayer(200, 200.1, 2, 1.0f, 100.0f); - LOGF(info, "MatLayerCylSet::optimizePhiSlices()"); + std::LOGF(info, "MatLayerCylSet::optimizePhiSlices()"); lut->optimizePhiSlices(); - LOGF(info, "Setting lut now..."); + std::LOGF(info, "Setting lut now..."); o2::base::Propagator::Instance()->setMatLUT(lut); irSampler.setInteractionRate(100); @@ -447,13 +447,13 @@ struct OnTheFlyTracker { double pi_mass = o2::constants::physics::MassPionCharged; double pr_mass = o2::constants::physics::MassProton; - double xi_gamma = 1 / sqrt(1 + (particle.p() * particle.p()) / (xi_mass * xi_mass)); + double xi_gamma = 1 / std::sqrt(1 + (particle.p() * particle.p()) / (xi_mass * xi_mass)); double xi_ctau = 4.91 * xi_gamma; - double xi_rxyz = (-xi_ctau * log(1 - u)); + double xi_rxyz = (-xi_ctau * std::log(1 - u)); float sna, csa; o2::math_utils::CircleXYf_t xi_circle; track.getCircleParams(magneticField, xi_circle, sna, csa); - double xi_rxy = xi_rxyz / sqrt(1. + track.getTgl() * track.getTgl()); + double xi_rxy = xi_rxyz / std::sqrt(1. + track.getTgl() * track.getTgl()); double theta = xi_rxy / xi_circle.rC; double newX = ((particle.vx() - xi_circle.xC) * std::cos(theta) - (particle.vy() - xi_circle.yC) * std::sin(theta)) + xi_circle.xC; double newY = ((particle.vy() - xi_circle.yC) * std::cos(theta) + (particle.vx() - xi_circle.xC) * std::sin(theta)) + xi_circle.yC; @@ -471,10 +471,10 @@ struct OnTheFlyTracker { decayDaughters.push_back(*xiDecay.GetDecay(1)); TLorentzVector la = *xiDecay.GetDecay(0); - double la_gamma = 1 / sqrt(1 + (la.P() * la.P()) / (la_mass * la_mass)); + double la_gamma = 1 / std::sqrt(1 + (la.P() * la.P()) / (la_mass * la_mass)); double la_ctau = 7.89 * la_gamma; std::vector laDaughters = {pi_mass, pr_mass}; - double la_rxyz = (-la_ctau * log(1 - u)); + double la_rxyz = (-la_ctau * std::log(1 - u)); laDecayVertex.push_back(xiDecayVertex[0] + la_rxyz * (xiDecay.GetDecay(0)->Px() / xiDecay.GetDecay(0)->P())); laDecayVertex.push_back(xiDecayVertex[1] + la_rxyz * (xiDecay.GetDecay(0)->Py() / xiDecay.GetDecay(0)->P())); laDecayVertex.push_back(xiDecayVertex[2] + la_rxyz * (xiDecay.GetDecay(0)->Pz() / xiDecay.GetDecay(0)->P())); @@ -533,7 +533,7 @@ struct OnTheFlyTracker { } const auto& pdgInfo = pdgDB->GetParticle(mcParticle.pdgCode()); if (!pdgInfo) { - LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; + std::LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; continue; } if (pdgInfo->Charge() == 0) { @@ -558,8 +558,8 @@ struct OnTheFlyTracker { o2::track::TrackParCov xiTrackParCov; o2::upgrade::convertMCParticleToO2Track(mcParticle, xiTrackParCov, pdgDB); decayParticle(mcParticle, xiTrackParCov, decayProducts, xiDecayVertex, laDecayVertex); - xiDecayRadius2D = sqrt(xiDecayVertex[0] * xiDecayVertex[0] + xiDecayVertex[1] * xiDecayVertex[1]); - laDecayRadius2D = sqrt(laDecayVertex[0] * laDecayVertex[0] + laDecayVertex[1] * laDecayVertex[1]); + xiDecayRadius2D = std::sqrt(xiDecayVertex[0] * xiDecayVertex[0] + xiDecayVertex[1] * xiDecayVertex[1]); + laDecayRadius2D = std::sqrt(laDecayVertex[0] * laDecayVertex[0] + laDecayVertex[1] * laDecayVertex[1]); } } @@ -703,7 +703,7 @@ struct OnTheFlyTracker { try { nCand = fitter.process(xiDaughterTrackParCovsTracked[1], xiDaughterTrackParCovsTracked[2]); } catch (...) { - // LOG(error) << "Exception caught in DCA fitter process call!"; + // std::LOG(error) << "Exception caught in DCA fitter process call!"; dcaFitterOK_V0 = false; } if (nCand == 0) { @@ -756,7 +756,7 @@ struct OnTheFlyTracker { try { nCand = fitter.process(v0Track, xiDaughterTrackParCovsTracked[0]); } catch (...) { - // LOG(error) << "Exception caught in DCA fitter process call!"; + // std::LOG(error) << "Exception caught in DCA fitter process call!"; dcaFitterOK_Cascade = false; } if (nCand == 0) { From ee784f9e20ad0c04fe1bbd0965b6c0a8db5816ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:17:44 +0200 Subject: [PATCH 03/10] Fix --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 4e416e55e8a..66688511f4b 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -734,7 +734,10 @@ struct OnTheFlyTracker { // DCA to PV taken care of in daughter tracks already, not necessary thisCascade.dcaV0dau = TMath::Sqrt(fitter.getChi2AtPCACandidate()); thisCascade.v0radius = std::hypot(pos[0], pos[1]); - thisCascade.mLambda = RecoDecay::m(array{array{posP[0], posP[1], posP[2]}, array{negP[0], negP[1], negP[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + thisCascade.mLambda = RecoDecay::m(std::array{std::array{posP[0], posP[1], posP[2]}, + std::array{negP[0], negP[1], negP[2]}}, + std::array{o2::constants::physics::MassProton, + o2::constants::physics::MassPionCharged}); // go for cascade: create V0 (pseudo)track from reconstructed V0 std::array covV = {0.}; From 34fb6242754977486111f2abaa7c414300d9069f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:18:40 +0200 Subject: [PATCH 04/10] Fix --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 66688511f4b..be23836538c 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -584,13 +584,13 @@ struct OnTheFlyTracker { } histos.fill(HIST("hPtGenerated"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 11) + if (std::abs(mcParticle.pdgCode()) == 11) histos.fill(HIST("hPtGeneratedEl"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 211) + if (std::abs(mcParticle.pdgCode()) == 211) histos.fill(HIST("hPtGeneratedPi"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 321) + if (std::abs(mcParticle.pdgCode()) == 321) histos.fill(HIST("hPtGeneratedKa"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 2212) + if (std::abs(mcParticle.pdgCode()) == 2212) histos.fill(HIST("hPtGeneratedPr"), mcParticle.pt()); if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == 3312) { @@ -899,13 +899,13 @@ struct OnTheFlyTracker { // Base QA (note: reco pT here) histos.fill(HIST("hPtReconstructed"), trackParCov.getPt()); - if (TMath::Abs(mcParticle.pdgCode()) == 11) + if (std::abs(mcParticle.pdgCode()) == 11) histos.fill(HIST("hPtReconstructedEl"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 211) + if (std::abs(mcParticle.pdgCode()) == 211) histos.fill(HIST("hPtReconstructedPi"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 321) + if (std::abs(mcParticle.pdgCode()) == 321) histos.fill(HIST("hPtReconstructedKa"), mcParticle.pt()); - if (TMath::Abs(mcParticle.pdgCode()) == 2212) + if (std::abs(mcParticle.pdgCode()) == 2212) histos.fill(HIST("hPtReconstructedPr"), mcParticle.pt()); if (doExtraQA) { From e0f9dd5064d0ce7447715669ec2729ddd7bb0399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:28:49 +0200 Subject: [PATCH 05/10] Update --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 45 ++++++++++---------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index be23836538c..f00173fa02c 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -33,20 +33,21 @@ #include "Common/Core/RecoDecay.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DCAFitter/DCAFitterN.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsVertexing/PVertexer.h" -#include "DetectorsVertexing/PVertexerHelpers.h" -#include "Field/MagneticField.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/DCA.h" -#include "SimulationDataFormat/InteractionSampler.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -527,7 +528,7 @@ struct OnTheFlyTracker { if (!longLivedToBeHandled) { if (!cascadeDecaySettings.decayXi) { continue; - } else if (pdg != 3312) { + } else if (pdg != kXiMinus) { continue; } } @@ -554,7 +555,7 @@ struct OnTheFlyTracker { std::vector xiDecayVertex, laDecayVertex; std::vector layers = {0.50, 1.20, 2.50, 3.75, 7.00, 12.0, 20.0}; if (cascadeDecaySettings.decayXi) { - if (mcParticle.pdgCode() == 3312) { + if (mcParticle.pdgCode() == kXiMinus) { o2::track::TrackParCov xiTrackParCov; o2::upgrade::convertMCParticleToO2Track(mcParticle, xiTrackParCov, pdgDB); decayParticle(mcParticle, xiTrackParCov, decayProducts, xiDecayVertex, laDecayVertex); @@ -567,7 +568,7 @@ struct OnTheFlyTracker { if (!mcParticle.isPhysicalPrimary()) { if (!cascadeDecaySettings.decayXi) { continue; - } else if (pdg != 3312) { + } else if (pdg != kXiMinus) { continue; } } @@ -575,7 +576,7 @@ struct OnTheFlyTracker { if (!longLivedToBeHandled) { if (!cascadeDecaySettings.decayXi) { continue; - } else if (pdg != 3312) { + } else if (pdg != kXiMinus) { continue; } } @@ -593,7 +594,7 @@ struct OnTheFlyTracker { if (std::abs(mcParticle.pdgCode()) == 2212) histos.fill(HIST("hPtGeneratedPr"), mcParticle.pt()); - if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == 3312) { + if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == kXiMinus) { histos.fill(HIST("hGenXi"), xiDecayRadius2D, mcParticle.pt()); histos.fill(HIST("hGenPiFromXi"), xiDecayRadius2D, decayProducts[0].Pt()); histos.fill(HIST("hGenPiFromLa"), laDecayRadius2D, decayProducts[1].Pt()); @@ -619,7 +620,7 @@ struct OnTheFlyTracker { std::vector nHits(3); // total std::vector nSiliconHits(3); // silicon type std::vector nTPCHits(3); // TPC type - if (cascadeDecaySettings.decayXi && mcParticle.pdgCode() == 3312) { + if (cascadeDecaySettings.decayXi && mcParticle.pdgCode() == kXiMinus) { if (cascadeDecaySettings.doXiQA) histos.fill(HIST("hXiBuilding"), 0.0f); if (xiDecayRadius2D > 20) { @@ -669,7 +670,7 @@ struct OnTheFlyTracker { } } - if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == 3312) { + if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == kXiMinus) { if (isReco[0] && isReco[1] && isReco[2]) { histos.fill(HIST("hXiBuilding"), 2.0f); histos.fill(HIST("hRecoXi"), xiDecayRadius2D, mcParticle.pt()); @@ -685,7 +686,7 @@ struct OnTheFlyTracker { // +-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+ // combine particles into actual Xi candidate // cascade building starts here - if (cascadeDecaySettings.findXi && mcParticle.pdgCode() == 3312 && isReco[0] && isReco[1] && isReco[2]) { + if (cascadeDecaySettings.findXi && mcParticle.pdgCode() == kXiMinus && isReco[0] && isReco[1] && isReco[2]) { if (cascadeDecaySettings.doXiQA) histos.fill(HIST("hXiBuilding"), 3.0f); // assign indices of the particles we've used From f26de1b61414190fca1ed70cd55cf1dd969150cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:31:09 +0200 Subject: [PATCH 06/10] U --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index f00173fa02c..0c701945136 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -585,13 +585,13 @@ struct OnTheFlyTracker { } histos.fill(HIST("hPtGenerated"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 11) + if (std::abs(mcParticle.pdgCode()) == kElectron) histos.fill(HIST("hPtGeneratedEl"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 211) + if (std::abs(mcParticle.pdgCode()) == kPiPlus) histos.fill(HIST("hPtGeneratedPi"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 321) + if (std::abs(mcParticle.pdgCode()) == kKPlus) histos.fill(HIST("hPtGeneratedKa"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 2212) + if (std::abs(mcParticle.pdgCode()) == kProton) histos.fill(HIST("hPtGeneratedPr"), mcParticle.pt()); if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == kXiMinus) { @@ -900,13 +900,13 @@ struct OnTheFlyTracker { // Base QA (note: reco pT here) histos.fill(HIST("hPtReconstructed"), trackParCov.getPt()); - if (std::abs(mcParticle.pdgCode()) == 11) + if (std::abs(mcParticle.pdgCode()) == kElectron) histos.fill(HIST("hPtReconstructedEl"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 211) + if (std::abs(mcParticle.pdgCode()) == kPiPlus) histos.fill(HIST("hPtReconstructedPi"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 321) + if (std::abs(mcParticle.pdgCode()) == kKPlus) histos.fill(HIST("hPtReconstructedKa"), mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == 2212) + if (std::abs(mcParticle.pdgCode()) == kProton) histos.fill(HIST("hPtReconstructedPr"), mcParticle.pt()); if (doExtraQA) { From 32bb4c64e5f1d74f042429fb8e7e97f7acf90c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:35:58 +0200 Subject: [PATCH 07/10] U --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 0c701945136..a3f09584d49 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -259,15 +259,15 @@ struct OnTheFlyTracker { std::LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; } }; - loadLUT(11, lutEl.value); - loadLUT(13, lutMu.value); - loadLUT(211, lutPi.value); - loadLUT(321, lutKa.value); - loadLUT(2212, lutPr.value); - loadLUT(1000010020, lutDe.value); - loadLUT(1000010030, lutTr.value); - loadLUT(1000020030, lutHe3.value); - loadLUT(1000020040, lutAl.value); + loadLUT(kElectron, lutEl.value); + loadLUT(kMuonMinus, lutMu.value); + loadLUT(kPiMinus, lutPi.value); + loadLUT(kKPlus, lutKa.value); + loadLUT(kProton, lutPr.value); + loadLUT(o2::constants::physics::kDeuteron, lutDe.value); + loadLUT(o2::constants::physics::kTriton, lutTr.value); + loadLUT(o2::constants::physics::kHelium3, lutHe3.value); + loadLUT(o2::constants::physics::kAlpha, lutAl.value); // interpolate efficiencies if requested to do so mSmearer.interpolateEfficiency(static_cast(interpolateLutEfficiencyVsNch)); @@ -609,7 +609,7 @@ struct OnTheFlyTracker { o2::upgrade::convertMCParticleToO2Track(mcParticle, trackParCov, pdgDB); bool isDecayDaughter = false; - if (mcParticle.getProcess() == 4) + if (mcParticle.getProcess() == TMCProcess::kPDecay) isDecayDaughter = true; multiplicityCounter++; @@ -627,9 +627,9 @@ struct OnTheFlyTracker { continue; } - o2::upgrade::convertTLorentzVectorToO2Track(-211, decayProducts[0], xiDecayVertex, xiDaughterTrackParCovsPerfect[0], pdgDB); - o2::upgrade::convertTLorentzVectorToO2Track(-211, decayProducts[1], laDecayVertex, xiDaughterTrackParCovsPerfect[1], pdgDB); - o2::upgrade::convertTLorentzVectorToO2Track(2212, decayProducts[2], laDecayVertex, xiDaughterTrackParCovsPerfect[2], pdgDB); + o2::upgrade::convertTLorentzVectorToO2Track(kPiMinus, decayProducts[0], xiDecayVertex, xiDaughterTrackParCovsPerfect[0], pdgDB); + o2::upgrade::convertTLorentzVectorToO2Track(kPiMinus, decayProducts[1], laDecayVertex, xiDaughterTrackParCovsPerfect[1], pdgDB); + o2::upgrade::convertTLorentzVectorToO2Track(kProton, decayProducts[2], laDecayVertex, xiDaughterTrackParCovsPerfect[2], pdgDB); for (int i = 0; i < 3; i++) { isReco[i] = false; From 3042dfd19d09184fb5cb6943db336e981c493424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:38:46 +0200 Subject: [PATCH 08/10] U --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index a3f09584d49..0b7eeb31fa2 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -623,7 +623,8 @@ struct OnTheFlyTracker { if (cascadeDecaySettings.decayXi && mcParticle.pdgCode() == kXiMinus) { if (cascadeDecaySettings.doXiQA) histos.fill(HIST("hXiBuilding"), 0.0f); - if (xiDecayRadius2D > 20) { + static constexpr float kMaxRadius = 20; // cm + if (xiDecayRadius2D > kMaxRadius) { continue; } @@ -783,7 +784,10 @@ struct OnTheFlyTracker { thisCascade.cascradius = std::hypot(posCascade[0], posCascade[1]); bachelorTrackAtPCA.getPxPyPzGlo(bachP); - thisCascade.mXi = RecoDecay::m(array{array{bachP[0], bachP[1], bachP[2]}, array{posP[0] + negP[0], posP[1] + negP[1], posP[2] + negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassLambda}); + thisCascade.mXi = RecoDecay::m(std::array{std::array{bachP[0], bachP[1], bachP[2]}, + std::array{posP[0] + negP[0], posP[1] + negP[1], posP[2] + negP[2]}}, + std::array{o2::constants::physics::MassPionCharged, + o2::constants::physics::MassLambda}); // initialize cascade track o2::track::TrackParCov cascadeTrack = fitter.createParentTrackParCov(); From 810c7db99eabdd46c10ebf8224fecf184a2c527d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 15:40:59 +0200 Subject: [PATCH 09/10] Replace std::LOG with LOG for logging --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 0b7eeb31fa2..a08274f2b8a 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -256,7 +256,7 @@ struct OnTheFlyTracker { auto loadLUT = [&](int pdg, const std::string& lutFile) { bool success = mSmearer.loadTable(pdg, lutFile.c_str()); if (!success && !lutFile.empty()) { - std::LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; + LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; } }; loadLUT(kElectron, lutEl.value); @@ -364,7 +364,7 @@ struct OnTheFlyTracker { hFastTrackerQA->GetXaxis()->SetBinLabel(8, "efficiency"); } - std::LOGF(info, "Initializing magnetic field to value: %.3f kG", static_cast(magneticField)); + LOGF(info, "Initializing magnetic field to value: %.3f kG", static_cast(magneticField)); o2::parameters::GRPMagField grpmag; grpmag.setFieldUniformity(true); grpmag.setL3Current(30000.f * (magneticField / 5.0f)); @@ -373,18 +373,18 @@ struct OnTheFlyTracker { auto fieldInstance = static_cast(TGeoGlobalMagField::Instance()->GetField()); if (!fieldInstance) { - std::LOGF(fatal, "Failed to set up magnetic field! Stopping now!"); + LOGF(fatal, "Failed to set up magnetic field! Stopping now!"); } // Cross-check - std::LOGF(info, "Check field at (0, 0, 0): %.1f kG, nominal: %.1f", static_cast(fieldInstance->GetBz(0, 0, 0)), static_cast(field)); + LOGF(info, "Check field at (0, 0, 0): %.1f kG, nominal: %.1f", static_cast(fieldInstance->GetBz(0, 0, 0)), static_cast(field)); - std::LOGF(info, "Initializing empty material cylinder LUT - could be better in the future"); + LOGF(info, "Initializing empty material cylinder LUT - could be better in the future"); o2::base::MatLayerCylSet* lut = new o2::base::MatLayerCylSet(); lut->addLayer(200, 200.1, 2, 1.0f, 100.0f); - std::LOGF(info, "MatLayerCylSet::optimizePhiSlices()"); + LOGF(info, "MatLayerCylSet::optimizePhiSlices()"); lut->optimizePhiSlices(); - std::LOGF(info, "Setting lut now..."); + LOGF(info, "Setting lut now..."); o2::base::Propagator::Instance()->setMatLUT(lut); irSampler.setInteractionRate(100); @@ -450,7 +450,7 @@ struct OnTheFlyTracker { double xi_gamma = 1 / std::sqrt(1 + (particle.p() * particle.p()) / (xi_mass * xi_mass)); double xi_ctau = 4.91 * xi_gamma; - double xi_rxyz = (-xi_ctau * std::log(1 - u)); + double xi_rxyz = (-xi_ctau * log(1 - u)); float sna, csa; o2::math_utils::CircleXYf_t xi_circle; track.getCircleParams(magneticField, xi_circle, sna, csa); @@ -475,7 +475,7 @@ struct OnTheFlyTracker { double la_gamma = 1 / std::sqrt(1 + (la.P() * la.P()) / (la_mass * la_mass)); double la_ctau = 7.89 * la_gamma; std::vector laDaughters = {pi_mass, pr_mass}; - double la_rxyz = (-la_ctau * std::log(1 - u)); + double la_rxyz = (-la_ctau * log(1 - u)); laDecayVertex.push_back(xiDecayVertex[0] + la_rxyz * (xiDecay.GetDecay(0)->Px() / xiDecay.GetDecay(0)->P())); laDecayVertex.push_back(xiDecayVertex[1] + la_rxyz * (xiDecay.GetDecay(0)->Py() / xiDecay.GetDecay(0)->P())); laDecayVertex.push_back(xiDecayVertex[2] + la_rxyz * (xiDecay.GetDecay(0)->Pz() / xiDecay.GetDecay(0)->P())); @@ -534,7 +534,7 @@ struct OnTheFlyTracker { } const auto& pdgInfo = pdgDB->GetParticle(mcParticle.pdgCode()); if (!pdgInfo) { - std::LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; + LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; continue; } if (pdgInfo->Charge() == 0) { @@ -705,7 +705,7 @@ struct OnTheFlyTracker { try { nCand = fitter.process(xiDaughterTrackParCovsTracked[1], xiDaughterTrackParCovsTracked[2]); } catch (...) { - // std::LOG(error) << "Exception caught in DCA fitter process call!"; + // LOG(error) << "Exception caught in DCA fitter process call!"; dcaFitterOK_V0 = false; } if (nCand == 0) { @@ -761,7 +761,7 @@ struct OnTheFlyTracker { try { nCand = fitter.process(v0Track, xiDaughterTrackParCovsTracked[0]); } catch (...) { - // std::LOG(error) << "Exception caught in DCA fitter process call!"; + // LOG(error) << "Exception caught in DCA fitter process call!"; dcaFitterOK_Cascade = false; } if (nCand == 0) { From 313f3bd3447ef3a73062f1c0bb166cd1ec4e3bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 15 Oct 2025 16:01:03 +0200 Subject: [PATCH 10/10] Refactor OnTheFlyTracker to use table prefixes --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 383 ++++++++++--------- 1 file changed, 208 insertions(+), 175 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index a08274f2b8a..838aa081132 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -66,24 +66,24 @@ using namespace o2::framework; using std::array; struct OnTheFlyTracker { - Produces collisions; - Produces collLabels; - Produces tracksPar; - Produces tracksParExtension; - Produces tracksParCov; - Produces tracksParCovExtension; - Produces tracksLabels; - Produces tracksDCA; - Produces tracksDCACov; - Produces collisionsAlice3; - Produces TracksAlice3; - Produces TracksExtraA3; - Produces upgradeCascades; + Produces tableCollisions; + Produces tableMcCollisionLabels; + Produces tableStoredTracks; + Produces tableTracksExtension; + Produces tableStoredTracksCov; + Produces tableTracksCovExtension; + Produces tableMcTrackLabels; + Produces tableTracksDCA; + Produces tableTracksDCACov; + Produces tableCollisionsAlice3; + Produces tableTracksAlice3; + Produces tableTracksExtraA3; + Produces tableUpgradeCascades; // optionally produced, empty (to be tuned later) - Produces tracksExtra; // base table, extend later - Produces trackSelection; - Produces trackSelectionExtension; + Produces tableStoredTracksExtra; // base table, extend later + Produces tableTrackSelection; + Produces tableTrackSelectionExtension; Configurable seed{"seed", 0, "TGenPhaseSpace seed"}; Configurable magneticField{"magneticField", 20.0f, "magnetic field in kG"}; @@ -110,7 +110,7 @@ struct OnTheFlyTracker { Configurable lutMu{"lutMu", "lutCovm.mu.dat", "LUT for muons (if emtpy no LUT is taken)"}; Configurable lutPi{"lutPi", "lutCovm.pi.dat", "LUT for pions (if emtpy no LUT is taken)"}; Configurable lutKa{"lutKa", "lutCovm.ka.dat", "LUT for kaons (if emtpy no LUT is taken)"}; - Configurable lutPr{"lutPr", "lutCovm.pr.dat", "LUT for protons"}; + Configurable lutPr{"lutPr", "lutCovm.pr.dat", "LUT for protons (if emtpy no LUT is taken)"}; Configurable lutDe{"lutDe", "", "LUT for deuterons (if emtpy no LUT is taken)"}; Configurable lutTr{"lutTr", "", "LUT for tritons (if emtpy no LUT is taken)"}; Configurable lutHe3{"lutHe3", "", "LUT for Helium-3 (if emtpy no LUT is taken)"}; @@ -149,6 +149,17 @@ struct OnTheFlyTracker { Configurable> pixelRes{"pixelRes", {0.00025, 0.00025, 0.001, 0.001}, "RPhiIT, ZIT, RPhiOT, ZOT"}; } fastTrackerSettings; // allows for gap between peak and bg in case someone wants to + struct : ConfigurableGroup { + std::string prefix = "fastPrimaryTrackerSettings"; + Configurable fastTrackPrimaries{"fastTrackPrimaries", false, "Use fasttracker for primary tracks. Enable with care"}; + Configurable minSiliconHits{"minSiliconHits", 4, "minimum number of silicon hits to accept track"}; + Configurable alice3geo{"alice3geo", "2", "0: ALICE 3 v1, 1: ALICE 3 v4, 2: ALICE 3 Sep 2025, or path to ccdb with a3 geo"}; + Configurable applyZacceptance{"applyZacceptance", false, "apply z limits to detector layers or not"}; + Configurable applyMSCorrection{"applyMSCorrection", true, "apply ms corrections for secondaries or not"}; + Configurable applyElossCorrection{"applyElossCorrection", true, "apply eloss corrections for secondaries or not"}; + Configurable applyEffCorrection{"applyEffCorrection", true, "apply efficiency correction or not"}; + } fastPrimaryTrackerSettings; + struct : ConfigurableGroup { std::string prefix = "cascadeDecaySettings"; // Cascade decay settings Configurable decayXi{"decayXi", false, "Manually decay Xi and fill tables with daughters"}; @@ -164,6 +175,7 @@ struct OnTheFlyTracker { // FastTracker machinery o2::fastsim::FastTracker fastTracker; + o2::fastsim::FastTracker fastPrimaryTracker; // Class to hold the track information for the O2 vertexing class TrackAlice3 : public o2::track::TrackParCov @@ -261,7 +273,7 @@ struct OnTheFlyTracker { }; loadLUT(kElectron, lutEl.value); loadLUT(kMuonMinus, lutMu.value); - loadLUT(kPiMinus, lutPi.value); + loadLUT(kPiPlus, lutPi.value); loadLUT(kKPlus, lutKa.value); loadLUT(kProton, lutPr.value); loadLUT(o2::constants::physics::kDeuteron, lutDe.value); @@ -378,7 +390,6 @@ struct OnTheFlyTracker { // Cross-check LOGF(info, "Check field at (0, 0, 0): %.1f kG, nominal: %.1f", static_cast(fieldInstance->GetBz(0, 0, 0)), static_cast(field)); - LOGF(info, "Initializing empty material cylinder LUT - could be better in the future"); o2::base::MatLayerCylSet* lut = new o2::base::MatLayerCylSet(); lut->addLayer(200, 200.1, 2, 1.0f, 100.0f); @@ -431,6 +442,27 @@ struct OnTheFlyTracker { // print fastTracker settings fastTracker.Print(); } + + if (fastPrimaryTrackerSettings.fastTrackPrimaries) { + fastPrimaryTracker.SetMagneticField(magneticField); + fastPrimaryTracker.SetApplyZacceptance(fastPrimaryTrackerSettings.applyZacceptance); + fastPrimaryTracker.SetApplyMSCorrection(fastPrimaryTrackerSettings.applyMSCorrection); + fastPrimaryTracker.SetApplyElossCorrection(fastPrimaryTrackerSettings.applyElossCorrection); + + if (fastPrimaryTrackerSettings.alice3geo.value == "0") { + fastPrimaryTracker.AddSiliconALICE3v2({0.00025, 0.00025, 0.001, 0.001}); + } else if (fastPrimaryTrackerSettings.alice3geo.value == "1") { + fastPrimaryTracker.AddSiliconALICE3v4({0.00025, 0.00025, 0.001, 0.001}); + fastPrimaryTracker.AddTPC(0.1, 0.1); + } else if (fastPrimaryTrackerSettings.alice3geo.value == "2") { + fastPrimaryTracker.AddSiliconALICE3(1., {0.00025, 0.00025, 0.001, 0.001}); + } else { + fastPrimaryTracker.AddGenericDetector(fastPrimaryTrackerSettings.alice3geo, ccdb.operator->()); + } + + // print fastTracker settings + fastPrimaryTracker.Print(); + } } /// Function to decay the xi @@ -490,7 +522,7 @@ struct OnTheFlyTracker { float dNdEta = 0.f; // Charged particle multiplicity to use in the efficiency evaluation void process(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) { - int lastTrackIndex = tracksParCov.lastIndex() + 1; // bookkeep the last added track + int lastTrackIndex = tableStoredTracksCov.lastIndex() + 1; // bookkeep the last added track tracksAlice3.clear(); ghostTracksAlice3.clear(); @@ -504,15 +536,16 @@ struct OnTheFlyTracker { auto ir = irSampler.generateCollisionTime(); const float eventCollisionTime = ir.timeInBCNS; - constexpr std::array longLivedHandledPDGs = {kElectron, + constexpr std::array longLivedHandledPDGs = {kElectron, kMuonMinus, kPiPlus, kKPlus, - kProton, - o2::constants::physics::kDeuteron, - o2::constants::physics::kTriton, - o2::constants::physics::kHelium3, - o2::constants::physics::kAlpha}; + kProton}; + + constexpr std::array nucleiPDGs = {o2::constants::physics::kDeuteron, + o2::constants::physics::kTriton, + o2::constants::physics::kHelium3, + o2::constants::physics::kAlpha}; // First we compute the number of charged particles in the event dNdEta = 0.f; @@ -520,18 +553,19 @@ struct OnTheFlyTracker { if (std::abs(mcParticle.eta()) > multEtaRange) { continue; } + if (!mcParticle.isPhysicalPrimary()) { continue; } + const auto pdg = std::abs(mcParticle.pdgCode()); const bool longLivedToBeHandled = std::find(longLivedHandledPDGs.begin(), longLivedHandledPDGs.end(), pdg) != longLivedHandledPDGs.end(); - if (!longLivedToBeHandled) { - if (!cascadeDecaySettings.decayXi) { - continue; - } else if (pdg != kXiMinus) { - continue; - } + const bool nucleiToBeHandled = std::find(nucleiPDGs.begin(), nucleiPDGs.end(), pdg) != nucleiPDGs.end(); + const bool pdgsToBeHandled = longLivedToBeHandled || (enableNucleiSmearing && nucleiToBeHandled) || (cascadeDecaySettings.decayXi && mcParticle.pdgCode() == kXiMinus); + if (!pdgsToBeHandled) { + continue; } + const auto& pdgInfo = pdgDB->GetParticle(mcParticle.pdgCode()); if (!pdgInfo) { LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; @@ -553,33 +587,28 @@ struct OnTheFlyTracker { double laDecayRadius2D = 0; std::vector decayProducts; std::vector xiDecayVertex, laDecayVertex; - std::vector layers = {0.50, 1.20, 2.50, 3.75, 7.00, 12.0, 20.0}; if (cascadeDecaySettings.decayXi) { if (mcParticle.pdgCode() == kXiMinus) { o2::track::TrackParCov xiTrackParCov; o2::upgrade::convertMCParticleToO2Track(mcParticle, xiTrackParCov, pdgDB); decayParticle(mcParticle, xiTrackParCov, decayProducts, xiDecayVertex, laDecayVertex); - xiDecayRadius2D = std::sqrt(xiDecayVertex[0] * xiDecayVertex[0] + xiDecayVertex[1] * xiDecayVertex[1]); - laDecayRadius2D = std::sqrt(laDecayVertex[0] * laDecayVertex[0] + laDecayVertex[1] * laDecayVertex[1]); + xiDecayRadius2D = std::hypot(xiDecayVertex[0], xiDecayVertex[1]); + laDecayRadius2D = std::hypot(laDecayVertex[0], laDecayVertex[1]); } } - const auto pdg = std::abs(mcParticle.pdgCode()); if (!mcParticle.isPhysicalPrimary()) { - if (!cascadeDecaySettings.decayXi) { - continue; - } else if (pdg != kXiMinus) { - continue; - } + continue; } + + const auto pdg = std::abs(mcParticle.pdgCode()); const bool longLivedToBeHandled = std::find(longLivedHandledPDGs.begin(), longLivedHandledPDGs.end(), pdg) != longLivedHandledPDGs.end(); - if (!longLivedToBeHandled) { - if (!cascadeDecaySettings.decayXi) { - continue; - } else if (pdg != kXiMinus) { - continue; - } + const bool nucleiToBeHandled = std::find(nucleiPDGs.begin(), nucleiPDGs.end(), pdg) != nucleiPDGs.end(); + const bool pdgsToBeHandled = longLivedToBeHandled || (enableNucleiSmearing && nucleiToBeHandled) || (cascadeDecaySettings.decayXi && mcParticle.pdgCode() == kXiMinus); + if (!pdgsToBeHandled) { + continue; } + if (std::fabs(mcParticle.eta()) > maxEta) { continue; } @@ -614,25 +643,23 @@ struct OnTheFlyTracker { multiplicityCounter++; const float t = (eventCollisionTime + gRandom->Gaus(0., 100.)) * 1e-3; + static constexpr int kCascProngs = 3; std::vector xiDaughterTrackParCovsPerfect(3); std::vector xiDaughterTrackParCovsTracked(3); - std::vector isReco(3); - std::vector nHits(3); // total - std::vector nSiliconHits(3); // silicon type - std::vector nTPCHits(3); // TPC type + std::vector isReco(kCascProngs); + std::vector nHits(kCascProngs); // total + std::vector nSiliconHits(kCascProngs); // silicon type + std::vector nTPCHits(kCascProngs); // TPC type if (cascadeDecaySettings.decayXi && mcParticle.pdgCode() == kXiMinus) { - if (cascadeDecaySettings.doXiQA) + if (cascadeDecaySettings.doXiQA) { histos.fill(HIST("hXiBuilding"), 0.0f); - static constexpr float kMaxRadius = 20; // cm - if (xiDecayRadius2D > kMaxRadius) { - continue; } o2::upgrade::convertTLorentzVectorToO2Track(kPiMinus, decayProducts[0], xiDecayVertex, xiDaughterTrackParCovsPerfect[0], pdgDB); o2::upgrade::convertTLorentzVectorToO2Track(kPiMinus, decayProducts[1], laDecayVertex, xiDaughterTrackParCovsPerfect[1], pdgDB); o2::upgrade::convertTLorentzVectorToO2Track(kProton, decayProducts[2], laDecayVertex, xiDaughterTrackParCovsPerfect[2], pdgDB); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < kCascProngs; i++) { isReco[i] = false; nHits[i] = 0; nSiliconHits[i] = 0; @@ -801,65 +828,67 @@ struct OnTheFlyTracker { if (cascadeDecaySettings.trackXi) { // optionally, add the points in the layers before the decay of the Xi // will back-track the perfect MC cascade to relevant layers, find hit, smear and add to smeared cascade - for (int i = layers.size() - 1; i >= 0; i--) { - if (thisCascade.cascradiusMC > layers[i]) { - // will add this layer, since cascade decayed after the corresponding radius - thisCascade.findableClusters++; // add to findable - - // find perfect intercept XYZ - float targetX = 1e+3; - trackParCov.getXatLabR(layers[i], targetX, magneticField); - if (targetX > 999) - continue; // failed to find intercept - - if (!trackParCov.propagateTo(targetX, magneticField)) { - continue; // failed to propagate - } - - // get potential cluster position - std::array posClusterCandidate; - trackParCov.getXYZGlo(posClusterCandidate); - float r{std::hypot(posClusterCandidate[0], posClusterCandidate[1])}; - float phi{std::atan2(-posClusterCandidate[1], -posClusterCandidate[0]) + o2::constants::math::PI}; - o2::fastsim::DetLayer currentTrackingLayer = fastTracker.GetLayer(i); - - if (currentTrackingLayer.getResolutionRPhi() > 1e-8 && currentTrackingLayer.getResolutionZ() > 1e-8) { // catch zero (though should not really happen...) - phi = gRandom->Gaus(phi, std::asin(currentTrackingLayer.getResolutionRPhi() / r)); - posClusterCandidate[0] = r * std::cos(phi); - posClusterCandidate[1] = r * std::sin(phi); - posClusterCandidate[2] = gRandom->Gaus(posClusterCandidate[2], currentTrackingLayer.getResolutionZ()); - } - - if (std::isnan(phi)) - continue; // Catch when getXatLabR misses layer[i] - - // towards adding cluster: move to track alpha - double alpha = cascadeTrack.getAlpha(); - double xyz1[3]{ - TMath::Cos(alpha) * posClusterCandidate[0] + TMath::Sin(alpha) * posClusterCandidate[1], - -TMath::Sin(alpha) * posClusterCandidate[0] + TMath::Cos(alpha) * posClusterCandidate[1], - posClusterCandidate[2]}; - - if (!(cascadeTrack.propagateTo(xyz1[0], magneticField))) - continue; - const o2::track::TrackParametrization::dim2_t hitpoint = { - static_cast(xyz1[1]), - static_cast(xyz1[2])}; - const o2::track::TrackParametrization::dim3_t hitpointcov = {currentTrackingLayer.getResolutionRPhi() * currentTrackingLayer.getResolutionRPhi(), 0.f, currentTrackingLayer.getResolutionZ() * currentTrackingLayer.getResolutionZ()}; - if (currentTrackingLayer.isInDeadPhiRegion(phi)) { - continue; // No hit for strangeness tracking update - } - - cascadeTrack.update(hitpoint, hitpointcov); - thisCascade.foundClusters++; // add to findable + for (int i = fastTracker.GetLayers().size() - 1; i >= 0; --i) { + o2::fastsim::DetLayer layer = fastTracker.GetLayer(i); + if (layer.isInert()) { + continue; // Not an active tracking layer + } + + if (thisCascade.cascradiusMC < layer.getRadius()) { + continue; // Cascade did not reach this layer + } + + // cascade decayed after the corresponding radius + thisCascade.findableClusters++; // add to findable + + // find perfect intercept XYZ + float targetX = 1e+3; + trackParCov.getXatLabR(layer.getRadius(), targetX, magneticField); + if (targetX > 999) + continue; // failed to find intercept + + if (!trackParCov.propagateTo(targetX, magneticField)) { + continue; // failed to propagate + } + + // get potential cluster position + std::array posClusterCandidate; + trackParCov.getXYZGlo(posClusterCandidate); + float r{std::hypot(posClusterCandidate[0], posClusterCandidate[1])}; + float phi{std::atan2(-posClusterCandidate[1], -posClusterCandidate[0]) + o2::constants::math::PI}; + + if (layer.getResolutionRPhi() > 1e-8 && layer.getResolutionZ() > 1e-8) { // catch zero (though should not really happen...) + phi = gRandom->Gaus(phi, std::asin(layer.getResolutionRPhi() / r)); + posClusterCandidate[0] = r * std::cos(phi); + posClusterCandidate[1] = r * std::sin(phi); + posClusterCandidate[2] = gRandom->Gaus(posClusterCandidate[2], layer.getResolutionZ()); } + + if (std::isnan(phi)) + continue; // Catch when getXatLabR misses layer[i] + + // towards adding cluster: move to track alpha + double alpha = cascadeTrack.getAlpha(); + double xyz1[3]{ + TMath::Cos(alpha) * posClusterCandidate[0] + TMath::Sin(alpha) * posClusterCandidate[1], + -TMath::Sin(alpha) * posClusterCandidate[0] + TMath::Cos(alpha) * posClusterCandidate[1], + posClusterCandidate[2]}; + + if (!(cascadeTrack.propagateTo(xyz1[0], magneticField))) + continue; + const o2::track::TrackParametrization::dim2_t hitpoint = {static_cast(xyz1[1]), static_cast(xyz1[2])}; + const o2::track::TrackParametrization::dim3_t hitpointcov = {layer.getResolutionRPhi() * layer.getResolutionRPhi(), 0.f, layer.getResolutionZ() * layer.getResolutionZ()}; + if (layer.isInDeadPhiRegion(phi)) { + continue; // No hit for strangeness tracking update + } + + cascadeTrack.update(hitpoint, hitpointcov); + thisCascade.foundClusters++; // add to findable } } // add cascade track - thisCascade.cascadeTrackId = lastTrackIndex + tracksAlice3.size(); // this is the next index to be filled -> should be it - tracksAlice3.push_back(TrackAlice3{cascadeTrack, mcParticle.globalIndex(), t, 100.f * 1e-3, false, false, 1, thisCascade.foundClusters}); if (cascadeDecaySettings.doXiQA) { @@ -878,8 +907,7 @@ struct OnTheFlyTracker { } } // end cascade building // +-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+ - - continue; // Not filling the tables with the xi itself + continue; // Cascade handling done, should not be considered anymore } if (doExtraQA) { @@ -887,8 +915,15 @@ struct OnTheFlyTracker { } bool reconstructed = true; - if (enablePrimarySmearing) { + if (enablePrimarySmearing && !fastPrimaryTrackerSettings.fastTrackPrimaries) { reconstructed = mSmearer.smearTrack(trackParCov, mcParticle.pdgCode(), dNdEta); + } else if (fastPrimaryTrackerSettings.fastTrackPrimaries) { + o2::track::TrackParCov o2Track; + o2::upgrade::convertMCParticleToO2Track(mcParticle, o2Track, pdgDB); + int nHits = fastPrimaryTracker.FastTrack(o2Track, trackParCov, dNdEta); + if (nHits < fastPrimaryTrackerSettings.minSiliconHits) { + reconstructed = false; + } } if (!reconstructed && !processUnreconstructedTracks) { @@ -929,7 +964,6 @@ struct OnTheFlyTracker { // Calculate primary vertex with tracks from this collision // data preparation o2::vertexing::PVertex primaryVertex; - if (enablePrimaryVertexing) { std::vector lblTracks; std::vector vertices; @@ -986,14 +1020,14 @@ struct OnTheFlyTracker { // *+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+* // populate collisions - collisions(-1, // BC is irrelevant in synthetic MC tests for now, could be adjusted in future - primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), - primaryVertex.getSigmaX2(), primaryVertex.getSigmaXY(), primaryVertex.getSigmaY2(), - primaryVertex.getSigmaXZ(), primaryVertex.getSigmaYZ(), primaryVertex.getSigmaZ2(), - 0, primaryVertex.getChi2(), primaryVertex.getNContributors(), - eventCollisionTime, 0.f); // For the moment the event collision time is taken as the "GEANT" time, the computation of the event time is done a posteriori from the tracks in the OTF TOF PID task - collLabels(mcCollision.globalIndex(), 0); - collisionsAlice3(dNdEta); + tableCollisions(-1, // BC is irrelevant in synthetic MC tests for now, could be adjusted in future + primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), + primaryVertex.getSigmaX2(), primaryVertex.getSigmaXY(), primaryVertex.getSigmaY2(), + primaryVertex.getSigmaXZ(), primaryVertex.getSigmaYZ(), primaryVertex.getSigmaZ2(), + 0, primaryVertex.getChi2(), primaryVertex.getNContributors(), + eventCollisionTime, 0.f); // For the moment the event collision time is taken as the "GEANT" time, the computation of the event time is done a posteriori from the tracks in the OTF TOF PID task + tableMcCollisionLabels(mcCollision.globalIndex(), 0); + tableCollisionsAlice3(dNdEta); // *+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+* // *+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+* @@ -1032,36 +1066,36 @@ struct OnTheFlyTracker { histos.fill(HIST("h2dDCAzCascadePositive"), trackParametrization.getPt(), dcaZ * 1e+4); // in microns, please } } - tracksDCA(dcaXY, dcaZ); + tableTracksDCA(dcaXY, dcaZ); if (populateTracksDCACov) { - tracksDCACov(dcaInfo.getSigmaY2(), dcaInfo.getSigmaZ2()); + tableTracksDCACov(dcaInfo.getSigmaY2(), dcaInfo.getSigmaZ2()); } } - tracksPar(collisions.lastIndex(), trackType, trackParCov.getX(), trackParCov.getAlpha(), trackParCov.getY(), trackParCov.getZ(), trackParCov.getSnp(), trackParCov.getTgl(), trackParCov.getQ2Pt()); - tracksParExtension(trackParCov.getPt(), trackParCov.getP(), trackParCov.getEta(), trackParCov.getPhi()); + tableStoredTracks(tableCollisions.lastIndex(), trackType, trackParCov.getX(), trackParCov.getAlpha(), trackParCov.getY(), trackParCov.getZ(), trackParCov.getSnp(), trackParCov.getTgl(), trackParCov.getQ2Pt()); + tableTracksExtension(trackParCov.getPt(), trackParCov.getP(), trackParCov.getEta(), trackParCov.getPhi()); // TODO do we keep the rho as 0? Also the sigma's are duplicated information - tracksParCov(std::sqrt(trackParCov.getSigmaY2()), std::sqrt(trackParCov.getSigmaZ2()), std::sqrt(trackParCov.getSigmaSnp2()), - std::sqrt(trackParCov.getSigmaTgl2()), std::sqrt(trackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - tracksParCovExtension(trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(), - trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), trackParCov.getSigmaTglY(), trackParCov.getSigmaTglZ(), trackParCov.getSigmaTglSnp(), - trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), - trackParCov.getSigma1Pt2()); - tracksLabels(trackParCov.mcLabel, 0); - TracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits); + tableStoredTracksCov(std::sqrt(trackParCov.getSigmaY2()), std::sqrt(trackParCov.getSigmaZ2()), std::sqrt(trackParCov.getSigmaSnp2()), + std::sqrt(trackParCov.getSigmaTgl2()), std::sqrt(trackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + tableTracksCovExtension(trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(), + trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), trackParCov.getSigmaTglY(), trackParCov.getSigmaTglZ(), trackParCov.getSigmaTglSnp(), + trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), + trackParCov.getSigma1Pt2()); + tableMcTrackLabels(trackParCov.mcLabel, 0); + tableTracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits); // populate extra tables if required to do so if (populateTracksExtra) { - tracksExtra(0.0f, static_cast(0), static_cast(0), static_cast(0), static_cast(0), - static_cast(0), static_cast(0), static_cast(0), static_cast(0), - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + tableStoredTracksExtra(0.0f, static_cast(0), static_cast(0), static_cast(0), static_cast(0), + static_cast(0), static_cast(0), static_cast(0), static_cast(0), + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); } if (populateTrackSelection) { - trackSelection(static_cast(0), false, false, false, false, false, false); - trackSelectionExtension(false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); + tableTrackSelection(static_cast(0), false, false, false, false, false, false); + tableTrackSelectionExtension(false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); } - TracksAlice3(true); + tableTracksAlice3(true); } // populate ghost tracks for (const auto& trackParCov : ghostTracksAlice3) { @@ -1080,55 +1114,54 @@ struct OnTheFlyTracker { histos.fill(HIST("h2dDCAz"), trackParametrization.getPt(), dcaZ * 1e+4); // in microns, please histos.fill(HIST("hTrackXatDCA"), trackParametrization.getX()); } - tracksDCA(dcaXY, dcaZ); + tableTracksDCA(dcaXY, dcaZ); if (populateTracksDCACov) { - tracksDCACov(dcaInfo.getSigmaY2(), dcaInfo.getSigmaZ2()); + tableTracksDCACov(dcaInfo.getSigmaY2(), dcaInfo.getSigmaZ2()); } } - tracksPar(collisions.lastIndex(), trackType, trackParCov.getX(), trackParCov.getAlpha(), trackParCov.getY(), trackParCov.getZ(), trackParCov.getSnp(), trackParCov.getTgl(), trackParCov.getQ2Pt()); - tracksParExtension(trackParCov.getPt(), trackParCov.getP(), trackParCov.getEta(), trackParCov.getPhi()); + tableStoredTracks(tableCollisions.lastIndex(), trackType, trackParCov.getX(), trackParCov.getAlpha(), trackParCov.getY(), trackParCov.getZ(), trackParCov.getSnp(), trackParCov.getTgl(), trackParCov.getQ2Pt()); + tableTracksExtension(trackParCov.getPt(), trackParCov.getP(), trackParCov.getEta(), trackParCov.getPhi()); // TODO do we keep the rho as 0? Also the sigma's are duplicated information - tracksParCov(std::sqrt(trackParCov.getSigmaY2()), std::sqrt(trackParCov.getSigmaZ2()), std::sqrt(trackParCov.getSigmaSnp2()), - std::sqrt(trackParCov.getSigmaTgl2()), std::sqrt(trackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - tracksParCovExtension(trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(), - trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), trackParCov.getSigmaTglY(), trackParCov.getSigmaTglZ(), trackParCov.getSigmaTglSnp(), - trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), - trackParCov.getSigma1Pt2()); - tracksLabels(trackParCov.mcLabel, 0); - TracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits); + tableStoredTracksCov(std::sqrt(trackParCov.getSigmaY2()), std::sqrt(trackParCov.getSigmaZ2()), std::sqrt(trackParCov.getSigmaSnp2()), + std::sqrt(trackParCov.getSigmaTgl2()), std::sqrt(trackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + tableTracksCovExtension(trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(), + trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), trackParCov.getSigmaTglY(), trackParCov.getSigmaTglZ(), trackParCov.getSigmaTglSnp(), + trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), + trackParCov.getSigma1Pt2()); + tableMcTrackLabels(trackParCov.mcLabel, 0); + tableTracksExtraA3(trackParCov.nSiliconHits, trackParCov.nTPCHits); // populate extra tables if required to do so if (populateTracksExtra) { - tracksExtra(0.0f, static_cast(0), static_cast(0), static_cast(0), static_cast(0), - static_cast(0), static_cast(0), static_cast(0), static_cast(0), - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + tableStoredTracksExtra(0.0f, static_cast(0), static_cast(0), static_cast(0), static_cast(0), + static_cast(0), static_cast(0), static_cast(0), static_cast(0), + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); } if (populateTrackSelection) { - trackSelection(static_cast(0), false, false, false, false, false, false); - trackSelectionExtension(false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); + tableTrackSelection(static_cast(0), false, false, false, false, false, false); + tableTrackSelectionExtension(false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); } - TracksAlice3(false); + tableTracksAlice3(false); } for (const auto& cascade : cascadesAlice3) { - upgradeCascades( - collisions.lastIndex(), // now we know the collision index -> populate table - cascade.cascadeTrackId, - cascade.positiveId, - cascade.negativeId, - cascade.bachelorId, - cascade.dcaV0dau, - cascade.dcacascdau, - cascade.v0radius, - cascade.cascradius, - cascade.cascradiusMC, - cascade.mLambda, - cascade.mXi, - cascade.findableClusters, - cascade.foundClusters); + tableUpgradeCascades(tableCollisions.lastIndex(), // now we know the collision index -> populate table + cascade.cascadeTrackId, + cascade.positiveId, + cascade.negativeId, + cascade.bachelorId, + cascade.dcaV0dau, + cascade.dcacascdau, + cascade.v0radius, + cascade.cascradius, + cascade.cascradiusMC, + cascade.mLambda, + cascade.mXi, + cascade.findableClusters, + cascade.foundClusters); } // do bookkeeping of fastTracker tracking @@ -1139,7 +1172,7 @@ struct OnTheFlyTracker { /// Extends TracksExtra if necessary struct onTheFlyTrackerInitializer { - Spawns tracksExtra; + Spawns tableStoredTracksExtra; void init(InitContext const&) {} };