From e12b3938d5a68f91abc4f865032f302fc2d8a6b3 Mon Sep 17 00:00:00 2001 From: jesgum Date: Wed, 12 Nov 2025 14:25:48 +0100 Subject: [PATCH 01/12] use multiple configs for one exec --- ALICE3/Core/DelphesO2TrackSmearer.cxx | 10 + ALICE3/DataModel/OTFMulticharm.h | 4 +- ALICE3/DataModel/OTFTracks.h | 35 ++++ ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 177 +++++++++++------- .../TableProducer/alice3-multicharmTable.cxx | 71 +++++-- ALICE3/Tasks/alice3-multicharm.cxx | 24 +++ 6 files changed, 236 insertions(+), 85 deletions(-) create mode 100644 ALICE3/DataModel/OTFTracks.h diff --git a/ALICE3/Core/DelphesO2TrackSmearer.cxx b/ALICE3/Core/DelphesO2TrackSmearer.cxx index 599d9cd9413..c2c622a99db 100644 --- a/ALICE3/Core/DelphesO2TrackSmearer.cxx +++ b/ALICE3/Core/DelphesO2TrackSmearer.cxx @@ -48,6 +48,16 @@ namespace delphes { /*****************************************************************/ +// bool TrackSmearer::closeTable(int pdg, const char* filename) +// { +// const std::string outPath = "/tmp/LUTs/"; +// const std::string filePath = Form("%s/%s/snapshot.root", outPath.c_str(), filename); +// std::ifstream checkFile(filePath); +// if (!checkFile.is_open()) { +// LOG(warning) << "--- Could not find table to close."; +// } +// checkFile.close(); +// } bool TrackSmearer::loadTable(int pdg, const char* filename, bool forceReload) { diff --git a/ALICE3/DataModel/OTFMulticharm.h b/ALICE3/DataModel/OTFMulticharm.h index 2c3a715f16c..944aa578ab2 100644 --- a/ALICE3/DataModel/OTFMulticharm.h +++ b/ALICE3/DataModel/OTFMulticharm.h @@ -36,6 +36,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(XiCCPion, xiCCPion, int, Tracks, "_PiXiCC"); DECLARE_SOA_COLUMN(XicMass, xicMass, float); DECLARE_SOA_COLUMN(XiccMass, xiccMass, float); +DECLARE_SOA_COLUMN(LUTConfigId, lutConfigId, int); //! Index for LUT configuration // kine vars DECLARE_SOA_COLUMN(XiccPt, xiccPt, float); @@ -155,7 +156,8 @@ DECLARE_SOA_TABLE(MCharmCores, "AOD", "MCharmCores", otfmulticharm::XiccProperLength, otfmulticharm::Pi1cPt, otfmulticharm::Pi2cPt, - otfmulticharm::PiccPt); + otfmulticharm::PiccPt, + otfmulticharm::LUTConfigId); DECLARE_SOA_TABLE(MCharmPID, "AOD", "MCharmPID", otfmulticharm::Pi1cTofDeltaInner, diff --git a/ALICE3/DataModel/OTFTracks.h b/ALICE3/DataModel/OTFTracks.h new file mode 100644 index 00000000000..baeb530cbee --- /dev/null +++ b/ALICE3/DataModel/OTFTracks.h @@ -0,0 +1,35 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file OTFTracks.h +/// \author Jesper Karlsson Gumprecht +/// \since 11/11/2025 +/// \brief Table to map track to LUT configuration +/// + +#ifndef ALICE3_DATAMODEL_OTFTRACKS_H_ +#define ALICE3_DATAMODEL_OTFTRACKS_H_ + +// O2 includes +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +namespace otftracks +{ +DECLARE_SOA_COLUMN(LUTConfigId, lutConfigId, int); //! Index for LUT configuration +} // namespace otftracks + +DECLARE_SOA_TABLE(OTFLUTConfigId, "AOD", "OTFLUTConfigId", otftracks::LUTConfigId); +} // namespace o2::aod + +#endif // ALICE3_DATAMODEL_OTFMULTICHARM_H_ diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 1bf0331e6ee..2f4db3d03b4 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -28,6 +28,7 @@ #include "ALICE3/Core/FastTracker.h" #include "ALICE3/Core/TrackUtilities.h" #include "ALICE3/DataModel/OTFStrangeness.h" +#include "ALICE3/DataModel/OTFTracks.h" #include "ALICE3/DataModel/collisionAlice3.h" #include "ALICE3/DataModel/tracksAlice3.h" #include "Common/Core/RecoDecay.h" @@ -64,6 +65,8 @@ using namespace o2; using namespace o2::framework; using std::array; +#define getHist(type, name) std::get>(histPointers[name]) + struct OnTheFlyTracker { Produces tableCollisions; @@ -79,6 +82,7 @@ struct OnTheFlyTracker { Produces tableTracksAlice3; Produces tableTracksExtraA3; Produces tableUpgradeCascades; + Produces tableOTFLUTConfigId; // optionally produced, empty (to be tuned later) Produces tableStoredTracksExtra; // base table, extend later @@ -106,15 +110,18 @@ 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 (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 (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)"}; - Configurable lutAl{"lutAl", "", "LUT for Alphas (if emtpy no LUT is taken)"}; + struct : ConfigurableGroup { + std::string prefix = "lookUpTables"; // JSON group name + Configurable> lutEl{"lutEl", std::vector{"lutCovm.el.dat"}, "LUT for electrons (if emtpy no LUT is taken)"}; + Configurable> lutMu{"lutMu", std::vector{"lutCovm.mu.dat"}, "LUT for muons (if emtpy no LUT is taken)"}; + Configurable> lutPi{"lutPi", std::vector{"lutCovm.pi.dat"}, "LUT for pions (if emtpy no LUT is taken)"}; + Configurable> lutKa{"lutKa", std::vector{"lutCovm.ka.dat"}, "LUT for kaons (if emtpy no LUT is taken)"}; + Configurable> lutPr{"lutPr", std::vector{"lutCovm.pr.dat"}, "LUT for protons (if emtpy no LUT is taken)"}; + Configurable> lutDe{"lutDe", std::vector{""}, "LUT for deuterons (if emtpy no LUT is taken)"}; + Configurable> lutTr{"lutTr", std::vector{""}, "LUT for tritons (if emtpy no LUT is taken)"}; + Configurable> lutHe3{"lutHe3", std::vector{""}, "LUT for Helium-3 (if emtpy no LUT is taken)"}; + Configurable> lutAl{"lutAl", std::vector{""}, "LUT for Alphas (if emtpy no LUT is taken)"}; + } lookUpTables; 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})"}; @@ -238,11 +245,12 @@ struct OnTheFlyTracker { // for handling basic QA histograms if requested HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::map histPointers; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; // Track smearer - o2::delphes::DelphesO2TrackSmearer mSmearer; + std::vector> mSmearer; // For processing and vertexing std::vector tracksAlice3; @@ -255,37 +263,74 @@ struct OnTheFlyTracker { // For TGenPhaseSpace seed TRandom3 rand; Service ccdb; - + + static constexpr int kMaxLUTConfigs = 20; void init(o2::framework::InitContext&) { - + ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setTimestamp(-1); if (enableLUT) { - mSmearer.setCcdbManager(ccdb.operator->()); - - auto loadLUT = [&](int pdg, const std::string& lutFile) { - bool success = mSmearer.loadTable(pdg, lutFile.c_str()); + auto loadLUT = [&](int icfg, int pdg, const std::vector& tables) { + const bool foundNewCfg = static_cast(icfg) < tables.size(); + const std::string& lutFile = foundNewCfg ? tables[icfg] : tables.front(); + bool success = mSmearer[icfg]->loadTable(pdg, lutFile.c_str()); if (!success && !lutFile.empty()) { LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; } + + return foundNewCfg; }; - loadLUT(kElectron, lutEl.value); - loadLUT(kMuonMinus, lutMu.value); - loadLUT(kPiPlus, 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)); - - // smear un-reco'ed tracks if asked to do so - mSmearer.skipUnreconstructed(static_cast(!processUnreconstructedTracks)); + + for (int icfg = 0; icfg < kMaxLUTConfigs; ++icfg) { + mSmearer.emplace_back(std::make_unique()); + mSmearer[icfg]->setCcdbManager(ccdb.operator->()); + + // check if more configs were provided, fall back to first entry + bool newLUTLoaded = false; + newLUTLoaded |= loadLUT(icfg, kElectron, lookUpTables.lutEl.value); + newLUTLoaded |= loadLUT(icfg, kMuonMinus, lookUpTables.lutMu.value); + newLUTLoaded |= loadLUT(icfg, kPiPlus, lookUpTables.lutPi.value); + newLUTLoaded |= loadLUT(icfg, kKPlus, lookUpTables.lutKa.value); + newLUTLoaded |= loadLUT(icfg, kProton, lookUpTables.lutPr.value); + newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kDeuteron, lookUpTables.lutDe.value); + newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kTriton, lookUpTables.lutTr.value); + newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kHelium3, lookUpTables.lutHe3.value); + newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kAlpha, lookUpTables.lutAl.value); + + if (!newLUTLoaded) { + mSmearer.pop_back(); + break; + } + + // interpolate efficiencies if requested to do so + mSmearer[icfg]->interpolateEfficiency(static_cast(interpolateLutEfficiencyVsNch)); + + // smear un-reco'ed tracks if asked to do so + mSmearer[icfg]->skipUnreconstructed(static_cast(!processUnreconstructedTracks)); + + std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; + histPointers.insert({histPath + "hPtGenerated", histos.add((histPath + "hPtGenerated").c_str(), "hPtGenerated", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPhiGenerated", histos.add((histPath + "hPhiGenerated").c_str(), "hPhiGenerated", {kTH1D, {{100, 0.0f, 2 * M_PI, "#phi (rad)"}}})}); + + histPointers.insert({histPath + "hPtGeneratedEl", histos.add((histPath + "hPtGeneratedEl").c_str(), "hPtGeneratedEl", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtGeneratedPi", histos.add((histPath + "hPtGeneratedPi").c_str(), "hPtGeneratedPi", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtGeneratedKa", histos.add((histPath + "hPtGeneratedKa").c_str(), "hPtGeneratedKa", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtGeneratedPr", histos.add((histPath + "hPtGeneratedPr").c_str(), "hPtGeneratedPr", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtReconstructed", histos.add((histPath + "hPtReconstructed").c_str(), "hPtReconstructed", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtReconstructedEl", histos.add((histPath + "hPtReconstructedEl").c_str(), "hPtReconstructedEl", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtReconstructedPi", histos.add((histPath + "hPtReconstructedPi").c_str(), "hPtReconstructedPi", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtReconstructedKa", histos.add((histPath + "hPtReconstructedKa").c_str(), "hPtReconstructedKa", {kTH1D, {{axes.axisMomentum}}})}); + histPointers.insert({histPath + "hPtReconstructedPr", histos.add((histPath + "hPtReconstructedPr").c_str(), "hPtReconstructedPr", {kTH1D, {{axes.axisMomentum}}})}); + + // Collision QA + histPointers.insert({histPath + "hPVz", histos.add((histPath + "hPVz").c_str(), "hPVz", {kTH1D, {{axes.axisVertexZ}}})}); + histPointers.insert({histPath + "hLUTMultiplicity", histos.add((histPath + "hLUTMultiplicity").c_str(), "hLUTMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + histPointers.insert({histPath + "hSimMultiplicity", histos.add((histPath + "hSimMultiplicity").c_str(), "hSimMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + histPointers.insert({histPath + "hRecoMultiplicity", histos.add((histPath + "hRecoMultiplicity").c_str(), "hRecoMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + + } // end config loop } // Basic QA @@ -303,24 +348,6 @@ struct OnTheFlyTracker { hCovMatOK->GetXaxis()->SetBinLabel(1, "Not OK"); hCovMatOK->GetXaxis()->SetBinLabel(2, "OK"); - histos.add("hPtGenerated", "hPtGenerated", kTH1F, {axes.axisMomentum}); - histos.add("hPhiGenerated", "hPhiGenerated", kTH1F, {{100, 0.0f, 2 * M_PI, "#phi (rad)"}}); - histos.add("hPtGeneratedEl", "hPtGeneratedEl", kTH1F, {axes.axisMomentum}); - histos.add("hPtGeneratedPi", "hPtGeneratedPi", kTH1F, {axes.axisMomentum}); - histos.add("hPtGeneratedKa", "hPtGeneratedKa", kTH1F, {axes.axisMomentum}); - histos.add("hPtGeneratedPr", "hPtGeneratedPr", kTH1F, {axes.axisMomentum}); - histos.add("hPtReconstructed", "hPtReconstructed", kTH1F, {axes.axisMomentum}); - histos.add("hPtReconstructedEl", "hPtReconstructedEl", kTH1F, {axes.axisMomentum}); - histos.add("hPtReconstructedPi", "hPtReconstructedPi", kTH1F, {axes.axisMomentum}); - histos.add("hPtReconstructedKa", "hPtReconstructedKa", kTH1F, {axes.axisMomentum}); - histos.add("hPtReconstructedPr", "hPtReconstructedPr", kTH1F, {axes.axisMomentum}); - - // Collision QA - histos.add("hPVz", "hPVz", kTH1F, {axes.axisVertexZ}); - histos.add("hLUTMultiplicity", "hLUTMultiplicity", kTH1F, {axes.axisMultiplicity}); - histos.add("hSimMultiplicity", "hSimMultiplicity", kTH1F, {axes.axisMultiplicity}); - histos.add("hRecoMultiplicity", "hRecoMultiplicity", kTH1F, {axes.axisMultiplicity}); - if (doExtraQA) { histos.add("h2dVerticesVsContributors", "h2dVerticesVsContributors", kTH2F, {axes.axisMultiplicity, axes.axisNVertices}); histos.add("hRecoVsSimMultiplicity", "hRecoVsSimMultiplicity", kTH2F, {axes.axisMultiplicity, axes.axisMultiplicity}); @@ -521,9 +548,10 @@ 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) + void processWithLUTs(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, int const& cfgId) { int lastTrackIndex = tableStoredTracksCov.lastIndex() + 1; // bookkeep the last added track + const std::string histPath = "Configuration_" + std::to_string(cfgId) + "/"; tracksAlice3.clear(); ghostTracksAlice3.clear(); @@ -580,7 +608,8 @@ struct OnTheFlyTracker { dNdEta /= (multEtaRange * 2.0f); uint32_t multiplicityCounter = 0; - histos.fill(HIST("hLUTMultiplicity"), dNdEta); + getHist(TH1, histPath + "hLUTMultiplicity")->Fill(dNdEta); + gRandom->SetSeed(seed); for (const auto& mcParticle : mcParticles) { @@ -614,16 +643,17 @@ struct OnTheFlyTracker { continue; } - histos.fill(HIST("hPtGenerated"), mcParticle.pt()); - histos.fill(HIST("hPhiGenerated"), mcParticle.phi()); + + getHist(TH1, histPath + "hPtGenerated")->Fill(mcParticle.pt()); + getHist(TH1, histPath + "hPhiGenerated")->Fill(mcParticle.phi()); if (std::abs(mcParticle.pdgCode()) == kElectron) - histos.fill(HIST("hPtGeneratedEl"), mcParticle.pt()); + getHist(TH1, histPath + "hPtGeneratedEl")->Fill(mcParticle.pt()); if (std::abs(mcParticle.pdgCode()) == kPiPlus) - histos.fill(HIST("hPtGeneratedPi"), mcParticle.pt()); + getHist(TH1, histPath + "hPtGeneratedPi")->Fill(mcParticle.pt()); if (std::abs(mcParticle.pdgCode()) == kKPlus) - histos.fill(HIST("hPtGeneratedKa"), mcParticle.pt()); + getHist(TH1, histPath + "hPtGeneratedKa")->Fill(mcParticle.pt()); if (std::abs(mcParticle.pdgCode()) == kProton) - histos.fill(HIST("hPtGeneratedPr"), mcParticle.pt()); + getHist(TH1, histPath + "hPtGeneratedPr")->Fill(mcParticle.pt()); if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == kXiMinus) { histos.fill(HIST("hGenXi"), xiDecayRadius2D, mcParticle.pt()); @@ -918,7 +948,7 @@ struct OnTheFlyTracker { bool reconstructed = true; if (enablePrimarySmearing && !fastPrimaryTrackerSettings.fastTrackPrimaries) { - reconstructed = mSmearer.smearTrack(trackParCov, mcParticle.pdgCode(), dNdEta); + reconstructed = mSmearer[cfgId]->smearTrack(trackParCov, mcParticle.pdgCode(), dNdEta); } else if (fastPrimaryTrackerSettings.fastTrackPrimaries) { o2::track::TrackParCov o2Track; o2::upgrade::convertMCParticleToO2Track(mcParticle, o2Track, pdgDB); @@ -940,15 +970,15 @@ struct OnTheFlyTracker { } // Base QA (note: reco pT here) - histos.fill(HIST("hPtReconstructed"), trackParCov.getPt()); + getHist(TH1, histPath + "hPtReconstructed")->Fill(trackParCov.getPt()); if (std::abs(mcParticle.pdgCode()) == kElectron) - histos.fill(HIST("hPtReconstructedEl"), mcParticle.pt()); + getHist(TH1, histPath + "hPtReconstructedEl")->Fill(trackParCov.getPt()); if (std::abs(mcParticle.pdgCode()) == kPiPlus) - histos.fill(HIST("hPtReconstructedPi"), mcParticle.pt()); + getHist(TH1, histPath + "hPtReconstructedPi")->Fill(trackParCov.getPt()); if (std::abs(mcParticle.pdgCode()) == kKPlus) - histos.fill(HIST("hPtReconstructedKa"), mcParticle.pt()); + getHist(TH1, histPath + "hPtReconstructedKa")->Fill(trackParCov.getPt()); if (std::abs(mcParticle.pdgCode()) == kProton) - histos.fill(HIST("hPtReconstructedPr"), mcParticle.pt()); + getHist(TH1, histPath + "hPtReconstructedPr")->Fill(trackParCov.getPt()); if (doExtraQA) { histos.fill(HIST("hRecoTrackX"), trackParCov.getX()); @@ -1012,9 +1042,13 @@ struct OnTheFlyTracker { // *+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+* // debug / informational - histos.fill(HIST("hSimMultiplicity"), multiplicityCounter); - histos.fill(HIST("hRecoMultiplicity"), tracksAlice3.size()); - histos.fill(HIST("hPVz"), primaryVertex.getZ()); + // histos.fill(HIST("hSimMultiplicity"), multiplicityCounter); + // histos.fill(HIST("hRecoMultiplicity"), tracksAlice3.size()); + // histos.fill(HIST("hPVz"), primaryVertex.getZ()); + getHist(TH1, histPath + "hSimMultiplicity")->Fill(multiplicityCounter); + getHist(TH1, histPath + "hRecoMultiplicity")->Fill(tracksAlice3.size()); + getHist(TH1, histPath + "hPVz")->Fill(primaryVertex.getZ()); + if (doExtraQA) { histos.fill(HIST("hRecoVsSimMultiplicity"), multiplicityCounter, tracksAlice3.size()); @@ -1073,6 +1107,7 @@ struct OnTheFlyTracker { tableTracksDCACov(dcaInfo.getSigmaY2(), dcaInfo.getSigmaZ2()); } } + tableOTFLUTConfigId(cfgId); 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()); @@ -1170,6 +1205,16 @@ struct OnTheFlyTracker { histos.fill(HIST("hCovMatOK"), 0.0f, fastTracker.GetCovMatNotOK()); histos.fill(HIST("hCovMatOK"), 1.0f, fastTracker.GetCovMatOK()); } // end process + + void process(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) + { + static int ievt = 0; + std::cout << "Proccesing event " << ievt << std::endl; + for (size_t icfg = 0; icfg < mSmearer.size(); ++icfg) { + processWithLUTs(mcCollision, mcParticles, static_cast(icfg)); + } + ievt++; + } }; /// Extends TracksExtra if necessary diff --git a/ALICE3/TableProducer/alice3-multicharmTable.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx index 890b645bb51..bfc96c2c803 100644 --- a/ALICE3/TableProducer/alice3-multicharmTable.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -25,6 +25,7 @@ #include "ALICE3/DataModel/OTFRICH.h" #include "ALICE3/DataModel/OTFStrangeness.h" #include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/OTFTracks.h" #include "ALICE3/DataModel/tracksAlice3.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" @@ -64,6 +65,7 @@ using std::array; // #define biton(var, nbit) ((var) |= (static_cast(1) << (nbit))) #define bitoff(var, nbit) ((var) &= ~(static_cast(1) << (nbit))) //((a) &= ~(1ULL<<(b))) #define bitcheck(var, nbit) ((var) & (static_cast(1) << (nbit))) +#define getHist(type, name) std::get>(histPointers[name]) using FullTracksExt = soa::Join; @@ -71,7 +73,7 @@ using FullTracksExt = soa::Join; using labeledTracks = soa::Join; using tofTracks = soa::Join; using richTracks = soa::Join; -using alice3tracks = soa::Join; +using alice3tracks = soa::Join; struct alice3multicharmTable { SliceCache cache; @@ -149,6 +151,8 @@ struct alice3multicharmTable { o2::vertexing::DCAFitterN<3> fitter3; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::map histPointers; + std::vector savedConfigs; Partition trueXi = aod::mcparticle::pdgCode == 3312; Partition trueXiC = aod::mcparticle::pdgCode == 4232; @@ -389,6 +393,15 @@ struct alice3multicharmTable { return returnValue; } + template + bool checkSameLUTConf(TTrackType const& track1, const int track2) + { + if (track1.lutConfigId() == track2) { + return true; + } + return false; + } + void init(InitContext&) { // initialize O2 2-prong fitter (only once) @@ -484,6 +497,21 @@ struct alice3multicharmTable { } } + void initConf(const int icfg) + { + const bool confExists = std::find(savedConfigs.begin(), savedConfigs.end(), icfg) != savedConfigs.end(); + if (confExists) { + return; + } + savedConfigs.push_back(icfg); + + // do more plots + std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; + histPointers.insert({histPath + "hMassXiCC", histos.add((histPath + "hMassXiCC").c_str(), "hMassXiCC", {kTH1D, {{axisXiCCMass}}})}); + histPointers.insert({histPath + "hNCollisions", histos.add((histPath + "hNCollisions").c_str(), "hNCollisions", {kTH1D, {{2, 0.5, 2.5}}})}); + histPointers.insert({histPath + "hNTracks", histos.add((histPath + "hNTracks").c_str(), "hNTracks", {kTH1D, {{20000, 0, 20000}}})}); + } + //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processGenerated(aod::McParticles const&) { @@ -499,13 +527,13 @@ struct alice3multicharmTable { //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processFindXiCC(aod::Collision const& collision, alice3tracks const& tracks, aod::McParticles const&, aod::UpgradeCascades const& cascades) { - histos.fill(HIST("hNCollisions"), 1); - histos.fill(HIST("hNTracks"), tracks.size()); + // histos.fill(HIST("hNCollisions"), 1); + // histos.fill(HIST("hNTracks"), tracks.size()); - if (tracks.size() < minNTracks) - return; + // if (tracks.size() < minNTracks) + // return; - histos.fill(HIST("hNCollisions"), 2); + // histos.fill(HIST("hNCollisions"), 2); // group with this collision // n.b. cascades do not need to be grouped, being used directly in iterator-grouping @@ -521,6 +549,7 @@ struct alice3multicharmTable { LOGF(info, "Damn, something is wrong"); } } + for (auto const& track : tracks) { if (bitcheck(track.decayMap(), kTruePiFromXiC)) histos.fill(HIST("h2dDCAxyVsPtPiFromXiC"), track.pt(), track.dcaXY() * 1e+4); @@ -530,20 +559,22 @@ struct alice3multicharmTable { } for (auto const& xiCand : cascades) { - histos.fill(HIST("hMassXi"), xiCand.mXi()); + auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track + int lutConfigId = xi.lutConfigId(); + std::string histPath = "Configuration_" + std::to_string(lutConfigId) + "/"; + initConf(lutConfigId); + histos.fill(HIST("hMassXi"), xiCand.mXi()); if (std::fabs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > massWindowXi) continue; // out of mass region - + uint32_t nCombinationsC = 0; - auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track auto piFromXi = xiCand.bachTrack_as(); // de-reference bach track auto piFromLa = xiCand.negTrack_as(); // de-reference neg track auto prFromLa = xiCand.posTrack_as(); // de-reference pos track - + if (!bitcheck(xi.decayMap(), kTrueXiFromXiC)) continue; - if (std::fabs(xi.dcaXY()) < xiFromXiC_dcaXYconstant || std::fabs(xi.dcaZ()) < xiFromXiC_dcaZconstant) continue; // likely a primary xi @@ -555,11 +586,12 @@ struct alice3multicharmTable { histos.fill(HIST("hMinXiDecayRadius"), xiCand.cascRadius()); for (auto const& pi1c : tracksPiFromXiCgrouped) { + if (!checkSameLUTConf(pi1c, lutConfigId)) + continue; if (mcSameMotherCheck && !checkSameMother(xi, pi1c)) continue; if (xiCand.posTrackId() == pi1c.globalIndex() || xiCand.negTrackId() == pi1c.globalIndex() || xiCand.bachTrackId() == pi1c.globalIndex()) continue; // avoid using any track that was already used - if (pi1c.pt() < minPiCPt) continue; // too low momentum @@ -572,15 +604,14 @@ struct alice3multicharmTable { histos.fill(HIST("hInnerTOFTrackTimeRecoPi1c"), pi1cTOFDiffInner); // second pion from XiC decay for starts here for (auto const& pi2c : tracksPiFromXiCgrouped) { + if (!checkSameLUTConf(pi2c, lutConfigId)) + continue; if (mcSameMotherCheck && !checkSameMother(xi, pi2c)) continue; // keep only if same mother - if (pi1c.globalIndex() >= pi2c.globalIndex()) continue; // avoid same-mother, avoid double-counting - if (xiCand.posTrackId() == pi2c.globalIndex() || xiCand.negTrackId() == pi2c.globalIndex() || xiCand.bachTrackId() == pi2c.globalIndex()) continue; // avoid using any track that was already used - if (pi2c.pt() < minPiCPt) continue; // too low momentum @@ -644,6 +675,9 @@ struct alice3multicharmTable { // attempt XiCC finding uint32_t nCombinationsCC = 0; for (auto const& picc : tracksPiFromXiCCgrouped) { + if (!checkSameLUTConf(picc, lutConfigId)) + continue; + if (mcSameMotherCheck && !checkSameMotherExtra(xi, picc)) continue; @@ -736,6 +770,8 @@ struct alice3multicharmTable { histos.fill(HIST("hCharmBuilding"), 3.0f); histos.fill(HIST("hMassXiCC"), thisXiCCcandidate.mass); + getHist(TH1, histPath + "hMassXiCC")->Fill(thisXiCCcandidate.mass); + histos.fill(HIST("hPtXiCC"), thisXiCCcandidate.pt); histos.fill(HIST("hEtaXiCC"), thisXiCCcandidate.eta); histos.fill(HIST("h3dMassXiCC"), thisXiCCcandidate.pt, thisXiCCcandidate.eta, thisXiCCcandidate.mass); @@ -762,9 +798,8 @@ struct alice3multicharmTable { xicProperLength, xicDecayDistanceFromPV, xiccProperLength, - pi1c.pt(), - pi2c.pt(), - picc.pt()); + pi1c.pt(), pi2c.pt(), picc.pt(), + lutConfigId); multiCharmPID( pi1cTOFDiffInner, pi1c.nSigmaPionInnerTOF(), diff --git a/ALICE3/Tasks/alice3-multicharm.cxx b/ALICE3/Tasks/alice3-multicharm.cxx index f001cb6e08c..659d2278afe 100644 --- a/ALICE3/Tasks/alice3-multicharm.cxx +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -71,6 +71,7 @@ using multiCharmTracksFull = soa::Join histPointers; + std::vector savedConfigs; std::string histPath; std::map pdgToBin; @@ -287,6 +288,20 @@ struct alice3multicharm { } } + void initConf(int icfg) + { + const bool confExists = std::find(savedConfigs.begin(), savedConfigs.end(), icfg) != savedConfigs.end(); + if (confExists) { + return; + } + savedConfigs.push_back(icfg); + + // do more plots + histPath = "Configuration_" + std::to_string(icfg) + "/"; + histPointers.insert({histPath + "hXiccMass", histos.add((histPath + "hXiccMass").c_str(), "hXiccMass", {kTH1D, {{axisXiccMass}}})}); + histPointers.insert({histPath + "h3dXicc", histos.add((histPath + "h3dXicc").c_str(), "h3dXicc", {kTH3D, {{axisPt, axisEta, axisXiccMass}}})}); + } + int getBin(const std::map& pdgToBin, int pdg) { auto it = pdgToBin.find(pdg); @@ -297,6 +312,9 @@ struct alice3multicharm { void genericProcessXicc(TMCharmCands const& xiccCands) { for (const auto& xiccCand : xiccCands) { + int icfg = xiccCand.lutConfigId(); + initConf(icfg); + if (bdt.enableML) { std::vector inputFeatures{ xiccCand.xicDauDCA(), @@ -488,6 +506,12 @@ struct alice3multicharm { histos.fill(HIST("hMCharmBuilding"), 21); } + histPath = "Configuration_" + std::to_string(icfg) + "/"; + getHist(TH1, histPath + "hXiccMass")->Fill(xiccCand.xiccMass()); + getHist(TH3, histPath + "h3dXicc")->Fill(xiccCand.xiccPt(), xiccCand.xiccEta(), xiccCand.xiccMass()); + + + histos.fill(HIST("SelectionQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * 1e+4); histos.fill(HIST("SelectionQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * 1e+4); histos.fill(HIST("SelectionQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * 1e+4)); From 8bd003bc34a92c8b060fc5bcf56b3e23f780f230 Mon Sep 17 00:00:00 2001 From: jesgum Date: Wed, 12 Nov 2025 14:34:07 +0100 Subject: [PATCH 02/12] remove unused --- ALICE3/Core/DelphesO2TrackSmearer.cxx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/ALICE3/Core/DelphesO2TrackSmearer.cxx b/ALICE3/Core/DelphesO2TrackSmearer.cxx index c2c622a99db..0ca78cfea99 100644 --- a/ALICE3/Core/DelphesO2TrackSmearer.cxx +++ b/ALICE3/Core/DelphesO2TrackSmearer.cxx @@ -47,18 +47,6 @@ namespace o2 namespace delphes { -/*****************************************************************/ -// bool TrackSmearer::closeTable(int pdg, const char* filename) -// { -// const std::string outPath = "/tmp/LUTs/"; -// const std::string filePath = Form("%s/%s/snapshot.root", outPath.c_str(), filename); -// std::ifstream checkFile(filePath); -// if (!checkFile.is_open()) { -// LOG(warning) << "--- Could not find table to close."; -// } -// checkFile.close(); -// } - bool TrackSmearer::loadTable(int pdg, const char* filename, bool forceReload) { if (!filename || filename[0] == '\0') { From a5fb6e5dcceaa9d37a2216d7947a576814e02313 Mon Sep 17 00:00:00 2001 From: jesgum Date: Wed, 12 Nov 2025 14:34:59 +0100 Subject: [PATCH 03/12] revert --- ALICE3/Core/DelphesO2TrackSmearer.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ALICE3/Core/DelphesO2TrackSmearer.cxx b/ALICE3/Core/DelphesO2TrackSmearer.cxx index 0ca78cfea99..599d9cd9413 100644 --- a/ALICE3/Core/DelphesO2TrackSmearer.cxx +++ b/ALICE3/Core/DelphesO2TrackSmearer.cxx @@ -47,6 +47,8 @@ namespace o2 namespace delphes { +/*****************************************************************/ + bool TrackSmearer::loadTable(int pdg, const char* filename, bool forceReload) { if (!filename || filename[0] == '\0') { From 1547a51cebcddbed73b99e6e1c62b6ef57c7e2f1 Mon Sep 17 00:00:00 2001 From: jesgum Date: Thu, 13 Nov 2025 10:47:25 +0100 Subject: [PATCH 04/12] select on mult in mcharm for different lut conf --- .../TableProducer/alice3-multicharmTable.cxx | 49 +++++++++---------- ALICE3/Tasks/alice3-multicharm.cxx | 2 - 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/ALICE3/TableProducer/alice3-multicharmTable.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx index bfc96c2c803..cff25cee1ff 100644 --- a/ALICE3/TableProducer/alice3-multicharmTable.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -113,7 +113,7 @@ struct alice3multicharmTable { Configurable minPiCPt{"minPiCPt", 0.15, "Minimum pT for XiC pions"}; Configurable minPiCCPt{"minPiCCPt", 0.3, "Minimum pT for XiCC pions"}; - Configurable minNTracks{"minNTracks", -1, "Minimum number of tracks"}; + Configurable> minNTracks{"minNTracks", {-1}, "Minimum number of tracks"}; Configurable minXiRadius{"minXiRadius", 0.5, "Minimum R2D for XiC decay (cm)"}; Configurable minXiCRadius{"minXiCRadius", 0.001, "Minimum R2D for XiC decay (cm)"}; @@ -527,44 +527,41 @@ struct alice3multicharmTable { //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processFindXiCC(aod::Collision const& collision, alice3tracks const& tracks, aod::McParticles const&, aod::UpgradeCascades const& cascades) { - // histos.fill(HIST("hNCollisions"), 1); - // histos.fill(HIST("hNTracks"), tracks.size()); - - // if (tracks.size() < minNTracks) - // return; - - // histos.fill(HIST("hNCollisions"), 2); - // group with this collision // n.b. cascades do not need to be grouped, being used directly in iterator-grouping auto tracksPiFromXiCgrouped = tracksPiFromXiC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto tracksPiFromXiCCgrouped = tracksPiFromXiCC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - if (doDCAplots) { - for (auto const& cascade : cascades) { - if (cascade.has_cascadeTrack()) { - auto track = cascade.cascadeTrack_as(); // de-reference cascade track - histos.fill(HIST("h2dDCAxyVsPtXiFromXiC"), track.pt(), track.dcaXY() * 1e+4); - } else { - LOGF(info, "Damn, something is wrong"); - } - } + static constexpr int kMaxLUTConfigs = 20; + std::vector nTracks(kMaxLUTConfigs); + for (auto const& track : tracks) { + int lutConfigId = track.lutConfigId(); + nTracks[lutConfigId]++; - for (auto const& track : tracks) { - if (bitcheck(track.decayMap(), kTruePiFromXiC)) - histos.fill(HIST("h2dDCAxyVsPtPiFromXiC"), track.pt(), track.dcaXY() * 1e+4); - if (bitcheck(track.decayMap(), kTruePiFromXiCC)) - histos.fill(HIST("h2dDCAxyVsPtPiFromXiCC"), track.pt(), track.dcaXY() * 1e+4); - } + if (bitcheck(track.decayMap(), kTruePiFromXiC)) + histos.fill(HIST("h2dDCAxyVsPtPiFromXiC"), track.pt(), track.dcaXY() * 1e+4); + if (bitcheck(track.decayMap(), kTruePiFromXiCC)) + histos.fill(HIST("h2dDCAxyVsPtPiFromXiCC"), track.pt(), track.dcaXY() * 1e+4); } - + for (auto const& xiCand : cascades) { auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track int lutConfigId = xi.lutConfigId(); - std::string histPath = "Configuration_" + std::to_string(lutConfigId) + "/"; initConf(lutConfigId); + if (minNTracks.value.size() < static_cast(lutConfigId)) { + if (nTracks[lutConfigId] < minNTracks.value.front()) { + continue; // fallback to first + } + } else { + if (nTracks[lutConfigId] < minNTracks.value[lutConfigId]) { + continue; + } + } + + std::string histPath = "Configuration_" + std::to_string(lutConfigId) + "/"; histos.fill(HIST("hMassXi"), xiCand.mXi()); + histos.fill(HIST("h2dDCAxyVsPtXiFromXiC"), xi.pt(), xi.dcaXY() * 1e+4); if (std::fabs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > massWindowXi) continue; // out of mass region diff --git a/ALICE3/Tasks/alice3-multicharm.cxx b/ALICE3/Tasks/alice3-multicharm.cxx index 659d2278afe..606322606bd 100644 --- a/ALICE3/Tasks/alice3-multicharm.cxx +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -510,8 +510,6 @@ struct alice3multicharm { getHist(TH1, histPath + "hXiccMass")->Fill(xiccCand.xiccMass()); getHist(TH3, histPath + "h3dXicc")->Fill(xiccCand.xiccPt(), xiccCand.xiccEta(), xiccCand.xiccMass()); - - histos.fill(HIST("SelectionQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * 1e+4); histos.fill(HIST("SelectionQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * 1e+4); histos.fill(HIST("SelectionQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * 1e+4)); From e7101fa821e1d5103415a3ad6113425aca4f4b3a Mon Sep 17 00:00:00 2001 From: jesgum Date: Mon, 17 Nov 2025 08:33:16 +0100 Subject: [PATCH 05/12] and allow multiple configs for the fasttracker --- ALICE3/Core/FastTracker.cxx | 15 ++-- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 90 ++++++++++---------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index d43bf10fc6d..c6ebb119684 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -442,11 +442,12 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa inputTrack.getXYZGlo(posIni); const float initialRadius = std::hypot(posIni[0], posIni[1]); const float kTrackingMargin = 0.1; - const int kMaxNumberOfDetectors = 20; - if (kMaxNumberOfDetectors < layers.size()) { - LOG(fatal) << "Too many layers in FastTracker, increase kMaxNumberOfDetectors"; - return -1; // too many layers - } + + // Delphes sets this to 20, but does not count all points in the tpc as layers which we do here + // Loop over all the added layers to prevent crash when adding the tpc + // Should not affect efficiency calculation + const int kMaxNumberOfDetectors = layers.size(); + int firstActiveLayer = -1; // first layer that is not inert for (size_t i = 0; i < layers.size(); ++i) { if (!layers[i].isInert()) { @@ -462,7 +463,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa const bool applyAngularCorrection = true; goodHitProbability.clear(); - for (int i = 0; i < kMaxNumberOfDetectors; ++i) { + for (size_t i = 0; i < layers.size(); ++i) { goodHitProbability.push_back(-1.); } goodHitProbability[0] = 1.; // we use layer zero to accumulate @@ -650,7 +651,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa // generate efficiency float eff = 1.; - for (int i = 0; i < kMaxNumberOfDetectors; i++) { + for (size_t i = 0; i < layers.size(); i++) { float iGoodHit = goodHitProbability[i]; if (iGoodHit <= 0) continue; diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 2f4db3d03b4..af50cb4a0b0 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -94,7 +94,6 @@ struct OnTheFlyTracker { Configurable maxEta{"maxEta", 1.5, "maximum eta to consider viable"}; Configurable multEtaRange{"multEtaRange", 0.8, "eta range to compute the multiplicity"}; Configurable minPt{"minPt", 0.1, "minimum pt to consider viable"}; - Configurable enableLUT{"enableLUT", false, "Enable track smearing"}; Configurable enablePrimarySmearing{"enablePrimarySmearing", false, "Enable smearing of primary particles"}; Configurable enableSecondarySmearing{"enableSecondarySmearing", false, "Enable smearing of weak decay daughters"}; Configurable enableNucleiSmearing{"enableNucleiSmearing", false, "Enable smearing of nuclei"}; @@ -147,7 +146,7 @@ struct OnTheFlyTracker { Configurable minSiliconHits{"minSiliconHits", 6, "minimum number of silicon hits to accept track"}; Configurable minSiliconHitsIfTPCUsed{"minSiliconHitsIfTPCUsed", 2, "minimum number of silicon hits to accept track in case TPC info is present"}; Configurable minTPCClusters{"minTPCClusters", 70, "minimum number of TPC hits necessary to consider minSiliconHitsIfTPCUsed"}; - 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> alice3geo{"alice3geo", std::vector{"2"}, "0: ALICE 3 v1, 1: ALICE 3 v4, 2: ALICE 3 Sep 2025, or path to ccdb with a3 geo (ccdb:Users/u/user/)"}; 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"}; @@ -181,7 +180,8 @@ struct OnTheFlyTracker { o2::vertexing::DCAFitterN<2> fitter; // FastTracker machinery - o2::fastsim::FastTracker fastTracker; + // o2::fastsim::FastTracker fastTracker; + std::vector> fastTracker; o2::fastsim::FastTracker fastPrimaryTracker; // Class to hold the track information for the O2 vertexing @@ -267,11 +267,10 @@ struct OnTheFlyTracker { static constexpr int kMaxLUTConfigs = 20; void init(o2::framework::InitContext&) { - ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setTimestamp(-1); - if (enableLUT) { + if (enablePrimarySmearing) { auto loadLUT = [&](int icfg, int pdg, const std::vector& tables) { const bool foundNewCfg = static_cast(icfg) < tables.size(); const std::string& lutFile = foundNewCfg ? tables[icfg] : tables.front(); @@ -330,6 +329,31 @@ struct OnTheFlyTracker { histPointers.insert({histPath + "hSimMultiplicity", histos.add((histPath + "hSimMultiplicity").c_str(), "hSimMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); histPointers.insert({histPath + "hRecoMultiplicity", histos.add((histPath + "hRecoMultiplicity").c_str(), "hRecoMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + if (enableSecondarySmearing) { + fastTracker.emplace_back(std::make_unique()); + fastTracker[icfg]->SetMagneticField(magneticField); + fastTracker[icfg]->SetApplyZacceptance(fastTrackerSettings.applyZacceptance); + fastTracker[icfg]->SetApplyMSCorrection(fastTrackerSettings.applyMSCorrection); + fastTracker[icfg]->SetApplyElossCorrection(fastTrackerSettings.applyElossCorrection); + + if (fastTrackerSettings.alice3geo.value[icfg] == "0") { + fastTracker[icfg]->AddSiliconALICE3v2(fastTrackerSettings.pixelRes); + } else if (fastTrackerSettings.alice3geo.value[icfg] == "1") { + fastTracker[icfg]->AddSiliconALICE3v4(fastTrackerSettings.pixelRes); + fastTracker[icfg]->AddTPC(0.1, 0.1); + } else if (fastTrackerSettings.alice3geo.value[icfg] == "2") { + fastTracker[icfg]->AddSiliconALICE3(fastTrackerSettings.scaleVD, fastTrackerSettings.pixelRes); + } else { + fastTracker[icfg]->AddGenericDetector(fastTrackerSettings.alice3geo.value[icfg], ccdb.operator->()); + } + + // print fastTracker settings + fastTracker[icfg]->Print(); + histPointers.insert({histPath + "hMassXi", histos.add((histPath + "hMassXi").c_str(), "hMassXi", {kTH1D, {{axes.axisXiMass}}})}); + + } + + } // end config loop } @@ -449,28 +473,7 @@ struct OnTheFlyTracker { // Set seed for TGenPhaseSpace rand.SetSeed(seed); - // configure FastTracker - if (enableSecondarySmearing) { - fastTracker.SetMagneticField(magneticField); - fastTracker.SetApplyZacceptance(fastTrackerSettings.applyZacceptance); - fastTracker.SetApplyMSCorrection(fastTrackerSettings.applyMSCorrection); - fastTracker.SetApplyElossCorrection(fastTrackerSettings.applyElossCorrection); - - if (fastTrackerSettings.alice3geo.value == "0") { - fastTracker.AddSiliconALICE3v2(fastTrackerSettings.pixelRes); - } else if (fastTrackerSettings.alice3geo.value == "1") { - fastTracker.AddSiliconALICE3v4(fastTrackerSettings.pixelRes); - fastTracker.AddTPC(0.1, 0.1); - } else if (fastTrackerSettings.alice3geo.value == "2") { - fastTracker.AddSiliconALICE3(fastTrackerSettings.scaleVD, fastTrackerSettings.pixelRes); - } else { - fastTracker.AddGenericDetector(fastTrackerSettings.alice3geo, ccdb.operator->()); - } - - // print fastTracker settings - fastTracker.Print(); - } - + // Configure FastTracker for primaries if (fastPrimaryTrackerSettings.fastTrackPrimaries) { fastPrimaryTracker.SetMagneticField(magneticField); fastPrimaryTracker.SetApplyZacceptance(fastPrimaryTrackerSettings.applyZacceptance); @@ -548,10 +551,10 @@ struct OnTheFlyTracker { } float dNdEta = 0.f; // Charged particle multiplicity to use in the efficiency evaluation - void processWithLUTs(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, int const& cfgId) + void processWithLUTs(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, int const& icfg) { int lastTrackIndex = tableStoredTracksCov.lastIndex() + 1; // bookkeep the last added track - const std::string histPath = "Configuration_" + std::to_string(cfgId) + "/"; + const std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; tracksAlice3.clear(); ghostTracksAlice3.clear(); @@ -697,9 +700,9 @@ struct OnTheFlyTracker { nSiliconHits[i] = 0; nTPCHits[i] = 0; if (enableSecondarySmearing) { - nHits[i] = fastTracker.FastTrack(xiDaughterTrackParCovsPerfect[i], xiDaughterTrackParCovsTracked[i], dNdEta); - nSiliconHits[i] = fastTracker.GetNSiliconPoints(); - nTPCHits[i] = fastTracker.GetNGasPoints(); + nHits[i] = fastTracker[icfg]->FastTrack(xiDaughterTrackParCovsPerfect[i], xiDaughterTrackParCovsTracked[i], dNdEta); + nSiliconHits[i] = fastTracker[icfg]->GetNSiliconPoints(); + nTPCHits[i] = fastTracker[icfg]->GetNGasPoints(); if (nHits[i] < 0) { // QA histos.fill(HIST("hFastTrackerQA"), o2::math_utils::abs(nHits[i])); @@ -710,8 +713,8 @@ struct OnTheFlyTracker { } else { continue; // extra sure } - for (uint32_t ih = 0; ih < fastTracker.GetNHits(); ih++) { - histos.fill(HIST("hFastTrackerHits"), fastTracker.GetHitZ(ih), std::hypot(fastTracker.GetHitX(ih), fastTracker.GetHitY(ih))); + for (uint32_t ih = 0; ih < fastTracker[icfg]->GetNHits(); ih++) { + histos.fill(HIST("hFastTrackerHits"), fastTracker[icfg]->GetHitZ(ih), std::hypot(fastTracker[icfg]->GetHitX(ih), fastTracker[icfg]->GetHitY(ih))); } } else { isReco[i] = true; @@ -860,8 +863,8 @@ 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 = fastTracker.GetLayers().size() - 1; i >= 0; --i) { - o2::fastsim::DetLayer layer = fastTracker.GetLayer(i); + for (int i = fastTracker[icfg]->GetLayers().size() - 1; i >= 0; --i) { + o2::fastsim::DetLayer layer = fastTracker[icfg]->GetLayer(i); if (layer.isInert()) { continue; // Not an active tracking layer } @@ -931,6 +934,7 @@ struct OnTheFlyTracker { histos.fill(HIST("hMassLambda"), thisCascade.mLambda); histos.fill(HIST("hMassXi"), thisCascade.mXi); histos.fill(HIST("hFoundVsFindable"), thisCascade.findableClusters, thisCascade.foundClusters); + getHist(TH1, histPath + "hMassXi")->Fill(thisCascade.mXi); } // add this cascade to vector (will fill cursor later with collision ID) @@ -948,7 +952,7 @@ struct OnTheFlyTracker { bool reconstructed = true; if (enablePrimarySmearing && !fastPrimaryTrackerSettings.fastTrackPrimaries) { - reconstructed = mSmearer[cfgId]->smearTrack(trackParCov, mcParticle.pdgCode(), dNdEta); + reconstructed = mSmearer[icfg]->smearTrack(trackParCov, mcParticle.pdgCode(), dNdEta); } else if (fastPrimaryTrackerSettings.fastTrackPrimaries) { o2::track::TrackParCov o2Track; o2::upgrade::convertMCParticleToO2Track(mcParticle, o2Track, pdgDB); @@ -1042,9 +1046,6 @@ struct OnTheFlyTracker { // *+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+* // debug / informational - // histos.fill(HIST("hSimMultiplicity"), multiplicityCounter); - // histos.fill(HIST("hRecoMultiplicity"), tracksAlice3.size()); - // histos.fill(HIST("hPVz"), primaryVertex.getZ()); getHist(TH1, histPath + "hSimMultiplicity")->Fill(multiplicityCounter); getHist(TH1, histPath + "hRecoMultiplicity")->Fill(tracksAlice3.size()); getHist(TH1, histPath + "hPVz")->Fill(primaryVertex.getZ()); @@ -1107,7 +1108,7 @@ struct OnTheFlyTracker { tableTracksDCACov(dcaInfo.getSigmaY2(), dcaInfo.getSigmaZ2()); } } - tableOTFLUTConfigId(cfgId); + tableOTFLUTConfigId(icfg); 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()); @@ -1202,18 +1203,15 @@ struct OnTheFlyTracker { } // do bookkeeping of fastTracker tracking - histos.fill(HIST("hCovMatOK"), 0.0f, fastTracker.GetCovMatNotOK()); - histos.fill(HIST("hCovMatOK"), 1.0f, fastTracker.GetCovMatOK()); + histos.fill(HIST("hCovMatOK"), 0.0f, fastTracker[icfg]->GetCovMatNotOK()); + histos.fill(HIST("hCovMatOK"), 1.0f, fastTracker[icfg]->GetCovMatOK()); } // end process void process(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) { - static int ievt = 0; - std::cout << "Proccesing event " << ievt << std::endl; for (size_t icfg = 0; icfg < mSmearer.size(); ++icfg) { processWithLUTs(mcCollision, mcParticles, static_cast(icfg)); } - ievt++; } }; From 6d6370aeeef312e7ea91a181b50da8d2747c9434 Mon Sep 17 00:00:00 2001 From: jesgum Date: Mon, 17 Nov 2025 08:33:59 +0100 Subject: [PATCH 06/12] formatting --- ALICE3/Core/FastTracker.cxx | 2 +- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index c6ebb119684..d75c67a9fdb 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -445,7 +445,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa // Delphes sets this to 20, but does not count all points in the tpc as layers which we do here // Loop over all the added layers to prevent crash when adding the tpc - // Should not affect efficiency calculation + // Should not affect efficiency calculation const int kMaxNumberOfDetectors = layers.size(); int firstActiveLayer = -1; // first layer that is not inert diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index af50cb4a0b0..dabfa266da7 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -67,7 +67,6 @@ using namespace o2::framework; using std::array; #define getHist(type, name) std::get>(histPointers[name]) - struct OnTheFlyTracker { Produces tableCollisions; Produces tableMcCollisionLabels; @@ -263,7 +262,7 @@ struct OnTheFlyTracker { // For TGenPhaseSpace seed TRandom3 rand; Service ccdb; - + static constexpr int kMaxLUTConfigs = 20; void init(o2::framework::InitContext&) { @@ -281,7 +280,7 @@ struct OnTheFlyTracker { return foundNewCfg; }; - + for (int icfg = 0; icfg < kMaxLUTConfigs; ++icfg) { mSmearer.emplace_back(std::make_unique()); mSmearer[icfg]->setCcdbManager(ccdb.operator->()); @@ -302,10 +301,10 @@ struct OnTheFlyTracker { mSmearer.pop_back(); break; } - + // interpolate efficiencies if requested to do so mSmearer[icfg]->interpolateEfficiency(static_cast(interpolateLutEfficiencyVsNch)); - + // smear un-reco'ed tracks if asked to do so mSmearer[icfg]->skipUnreconstructed(static_cast(!processUnreconstructedTracks)); @@ -322,7 +321,7 @@ struct OnTheFlyTracker { histPointers.insert({histPath + "hPtReconstructedPi", histos.add((histPath + "hPtReconstructedPi").c_str(), "hPtReconstructedPi", {kTH1D, {{axes.axisMomentum}}})}); histPointers.insert({histPath + "hPtReconstructedKa", histos.add((histPath + "hPtReconstructedKa").c_str(), "hPtReconstructedKa", {kTH1D, {{axes.axisMomentum}}})}); histPointers.insert({histPath + "hPtReconstructedPr", histos.add((histPath + "hPtReconstructedPr").c_str(), "hPtReconstructedPr", {kTH1D, {{axes.axisMomentum}}})}); - + // Collision QA histPointers.insert({histPath + "hPVz", histos.add((histPath + "hPVz").c_str(), "hPVz", {kTH1D, {{axes.axisVertexZ}}})}); histPointers.insert({histPath + "hLUTMultiplicity", histos.add((histPath + "hLUTMultiplicity").c_str(), "hLUTMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); @@ -350,10 +349,8 @@ struct OnTheFlyTracker { // print fastTracker settings fastTracker[icfg]->Print(); histPointers.insert({histPath + "hMassXi", histos.add((histPath + "hMassXi").c_str(), "hMassXi", {kTH1D, {{axes.axisXiMass}}})}); - } - } // end config loop } @@ -646,7 +643,6 @@ struct OnTheFlyTracker { continue; } - getHist(TH1, histPath + "hPtGenerated")->Fill(mcParticle.pt()); getHist(TH1, histPath + "hPhiGenerated")->Fill(mcParticle.phi()); if (std::abs(mcParticle.pdgCode()) == kElectron) @@ -1050,7 +1046,6 @@ struct OnTheFlyTracker { getHist(TH1, histPath + "hRecoMultiplicity")->Fill(tracksAlice3.size()); getHist(TH1, histPath + "hPVz")->Fill(primaryVertex.getZ()); - if (doExtraQA) { histos.fill(HIST("hRecoVsSimMultiplicity"), multiplicityCounter, tracksAlice3.size()); } From 6106a1921c4bd7ad3f987444a9dc64377ae7d81a Mon Sep 17 00:00:00 2001 From: jesgum Date: Mon, 17 Nov 2025 09:03:26 +0100 Subject: [PATCH 07/12] formatting --- ALICE3/TableProducer/alice3-multicharmTable.cxx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ALICE3/TableProducer/alice3-multicharmTable.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx index cff25cee1ff..9f58ecd26ef 100644 --- a/ALICE3/TableProducer/alice3-multicharmTable.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -543,9 +543,9 @@ struct alice3multicharmTable { if (bitcheck(track.decayMap(), kTruePiFromXiCC)) histos.fill(HIST("h2dDCAxyVsPtPiFromXiCC"), track.pt(), track.dcaXY() * 1e+4); } - + for (auto const& xiCand : cascades) { - auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track + auto xi = xiCand.cascadeTrack_as(); // de-reference cascade track int lutConfigId = xi.lutConfigId(); initConf(lutConfigId); if (minNTracks.value.size() < static_cast(lutConfigId)) { @@ -558,18 +558,17 @@ struct alice3multicharmTable { } } - std::string histPath = "Configuration_" + std::to_string(lutConfigId) + "/"; histos.fill(HIST("hMassXi"), xiCand.mXi()); histos.fill(HIST("h2dDCAxyVsPtXiFromXiC"), xi.pt(), xi.dcaXY() * 1e+4); if (std::fabs(xiCand.mXi() - o2::constants::physics::MassXiMinus) > massWindowXi) continue; // out of mass region - + uint32_t nCombinationsC = 0; auto piFromXi = xiCand.bachTrack_as(); // de-reference bach track auto piFromLa = xiCand.negTrack_as(); // de-reference neg track auto prFromLa = xiCand.posTrack_as(); // de-reference pos track - + if (!bitcheck(xi.decayMap(), kTrueXiFromXiC)) continue; if (std::fabs(xi.dcaXY()) < xiFromXiC_dcaXYconstant || std::fabs(xi.dcaZ()) < xiFromXiC_dcaZconstant) From c5a62eab208d5ee3069491004df07713fe91ba63 Mon Sep 17 00:00:00 2001 From: jesgum Date: Mon, 17 Nov 2025 09:11:14 +0100 Subject: [PATCH 08/12] make megalinter happy --- ALICE3/DataModel/OTFTracks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ALICE3/DataModel/OTFTracks.h b/ALICE3/DataModel/OTFTracks.h index baeb530cbee..8c49bd8a717 100644 --- a/ALICE3/DataModel/OTFTracks.h +++ b/ALICE3/DataModel/OTFTracks.h @@ -32,4 +32,4 @@ DECLARE_SOA_COLUMN(LUTConfigId, lutConfigId, int); //! Index for LUT configurati DECLARE_SOA_TABLE(OTFLUTConfigId, "AOD", "OTFLUTConfigId", otftracks::LUTConfigId); } // namespace o2::aod -#endif // ALICE3_DATAMODEL_OTFMULTICHARM_H_ +#endif // ALICE3_DATAMODEL_OTFTRACKS_H_ \ No newline at end of file From d31a6af3e32e565368e2dfaf37f076bdb82fe518 Mon Sep 17 00:00:00 2001 From: jesgum Date: Mon, 17 Nov 2025 09:12:40 +0100 Subject: [PATCH 09/12] formatting --- ALICE3/DataModel/OTFTracks.h | 2 +- ALICE3/TableProducer/alice3-multicharmTable.cxx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ALICE3/DataModel/OTFTracks.h b/ALICE3/DataModel/OTFTracks.h index 8c49bd8a717..390e3680716 100644 --- a/ALICE3/DataModel/OTFTracks.h +++ b/ALICE3/DataModel/OTFTracks.h @@ -32,4 +32,4 @@ DECLARE_SOA_COLUMN(LUTConfigId, lutConfigId, int); //! Index for LUT configurati DECLARE_SOA_TABLE(OTFLUTConfigId, "AOD", "OTFLUTConfigId", otftracks::LUTConfigId); } // namespace o2::aod -#endif // ALICE3_DATAMODEL_OTFTRACKS_H_ \ No newline at end of file +#endif // ALICE3_DATAMODEL_OTFTRACKS_H_ diff --git a/ALICE3/TableProducer/alice3-multicharmTable.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx index 9f58ecd26ef..b642e18ed6a 100644 --- a/ALICE3/TableProducer/alice3-multicharmTable.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -54,7 +54,9 @@ #include #include #include +#include #include +#include using namespace o2; using namespace o2::framework; From 2b72589c384644ff273dc07a24d0eb3e69a76a98 Mon Sep 17 00:00:00 2001 From: jesgum Date: Tue, 18 Nov 2025 18:13:01 +0100 Subject: [PATCH 10/12] fix --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index dabfa266da7..dd253ca68df 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -132,6 +132,7 @@ struct OnTheFlyTracker { ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; ConfigurableAxis axisXiMass{"axisXiMass", {200, 1.22f, 1.42f}, ""}; + ConfigurableAxis axisPtRes{"axisPtRes", {200, -0.4f, 0.4f}, "#Delta p_{T} / Reco p_{T}"}; ConfigurableAxis axisDeltaPt{"axisDeltaPt", {200, -1.0f, +1.0f}, "#Delta p_{T}"}; ConfigurableAxis axisDeltaEta{"axisDeltaEta", {200, -0.5f, +0.5f}, "#Delta #eta"}; @@ -351,6 +352,12 @@ struct OnTheFlyTracker { histPointers.insert({histPath + "hMassXi", histos.add((histPath + "hMassXi").c_str(), "hMassXi", {kTH1D, {{axes.axisXiMass}}})}); } + if (doExtraQA) { + histPointers.insert({histPath + "h2dPtRes", histos.add((histPath + "h2dPtRes").c_str(), "h2dPtRes", {kTH2D, {{axes.axisMomentum, axes.axisPtRes}}})}); + histPointers.insert({histPath + "h2dDCAxy", histos.add((histPath + "h2dDCAxy").c_str(), "h2dDCAxy", {kTH2D, {{axes.axisMomentum, axes.axisDCA}}})}); + histPointers.insert({histPath + "h2dDCAz", histos.add((histPath + "h2dDCAz").c_str(), "h2dDCAz", {kTH2D, {{axes.axisMomentum, axes.axisDCA}}})}); + } + } // end config loop } @@ -372,8 +379,6 @@ struct OnTheFlyTracker { if (doExtraQA) { histos.add("h2dVerticesVsContributors", "h2dVerticesVsContributors", kTH2F, {axes.axisMultiplicity, axes.axisNVertices}); histos.add("hRecoVsSimMultiplicity", "hRecoVsSimMultiplicity", kTH2F, {axes.axisMultiplicity, axes.axisMultiplicity}); - histos.add("h2dDCAxy", "h2dDCAxy", kTH2F, {axes.axisMomentum, axes.axisDCA}); - histos.add("h2dDCAz", "h2dDCAz", kTH2F, {axes.axisMomentum, axes.axisDCA}); histos.add("hSimTrackX", "hSimTrackX", kTH1F, {axes.axisX}); histos.add("hRecoTrackX", "hRecoTrackX", kTH1F, {axes.axisX}); @@ -981,6 +986,7 @@ struct OnTheFlyTracker { getHist(TH1, histPath + "hPtReconstructedPr")->Fill(trackParCov.getPt()); if (doExtraQA) { + getHist(TH2, histPath + "h2dPtRes")->Fill(trackParCov.getPt(), (trackParCov.getPt() - mcParticle.pt()) / trackParCov.getPt()); histos.fill(HIST("hRecoTrackX"), trackParCov.getX()); } @@ -1076,8 +1082,8 @@ struct OnTheFlyTracker { dcaZ = dcaInfo.getZ(); } if (doExtraQA && (!extraQAwithoutDecayDaughters || (extraQAwithoutDecayDaughters && !trackParCov.isDecayDau))) { - histos.fill(HIST("h2dDCAxy"), trackParametrization.getPt(), dcaXY * 1e+4); // in microns, please - histos.fill(HIST("h2dDCAz"), trackParametrization.getPt(), dcaZ * 1e+4); // in microns, please + getHist(TH2, histPath + "h2dDCAxy")->Fill(trackParametrization.getPt(), dcaXY * 1e+4); + getHist(TH2, histPath + "h2dDCAz")->Fill(trackParametrization.getPt(), dcaZ * 1e+4); histos.fill(HIST("hTrackXatDCA"), trackParametrization.getX()); } if (cascadeDecaySettings.doXiQA) { @@ -1198,8 +1204,10 @@ struct OnTheFlyTracker { } // do bookkeeping of fastTracker tracking - histos.fill(HIST("hCovMatOK"), 0.0f, fastTracker[icfg]->GetCovMatNotOK()); - histos.fill(HIST("hCovMatOK"), 1.0f, fastTracker[icfg]->GetCovMatOK()); + if (enableSecondarySmearing) { + histos.fill(HIST("hCovMatOK"), 0.0f, fastTracker[icfg]->GetCovMatNotOK()); + histos.fill(HIST("hCovMatOK"), 1.0f, fastTracker[icfg]->GetCovMatOK()); + } } // end process void process(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) From 825a8fd6e6e1727705085710f1d31aae2f56fce7 Mon Sep 17 00:00:00 2001 From: jesgum Date: Wed, 19 Nov 2025 10:30:16 +0100 Subject: [PATCH 11/12] remove unused variable --- ALICE3/Core/FastTracker.cxx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index d75c67a9fdb..ba148521724 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -443,11 +443,6 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa const float initialRadius = std::hypot(posIni[0], posIni[1]); const float kTrackingMargin = 0.1; - // Delphes sets this to 20, but does not count all points in the tpc as layers which we do here - // Loop over all the added layers to prevent crash when adding the tpc - // Should not affect efficiency calculation - const int kMaxNumberOfDetectors = layers.size(); - int firstActiveLayer = -1; // first layer that is not inert for (size_t i = 0; i < layers.size(); ++i) { if (!layers[i].isInert()) { @@ -461,7 +456,11 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa } const int xrhosteps = 100; const bool applyAngularCorrection = true; - + + // Delphes sets this to 20 instead of the number of layers, + // but does not count all points in the tpc as layers which we do here + // Loop over all the added layers to prevent crash when adding the tpc + // Should not affect efficiency calculation goodHitProbability.clear(); for (size_t i = 0; i < layers.size(); ++i) { goodHitProbability.push_back(-1.); From 788e02ff977a42c7efe1639999b6423aae17dc61 Mon Sep 17 00:00:00 2001 From: jesgum Date: Wed, 19 Nov 2025 11:14:51 +0100 Subject: [PATCH 12/12] remove whitespace --- ALICE3/Core/FastTracker.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index ba148521724..ef45e99ca01 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -456,7 +456,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa } const int xrhosteps = 100; const bool applyAngularCorrection = true; - + // Delphes sets this to 20 instead of the number of layers, // but does not count all points in the tpc as layers which we do here // Loop over all the added layers to prevent crash when adding the tpc