From 9ea81c0db8f87219e81965a241bcd8c41f1d6bc0 Mon Sep 17 00:00:00 2001 From: Cristian Moscatelli Date: Wed, 25 Feb 2026 11:03:38 +0100 Subject: [PATCH 1/3] Change Gen Event selection --- PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx | 60 ++++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 6ba0b483c46..95663bd60a5 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -55,6 +55,8 @@ #include #include // for PDG codes #include +#include +#include #include #include @@ -334,6 +336,7 @@ struct nucleiSpectra { ConfigurableAxis cfgNTPCClusBins{"cfgNTPCClusBins", {3, 89.5, 159.5}, "N TPC clusters binning"}; Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Skimmed dataset processing"}; + Configurable cfgTriggerList{"cfgTriggerList", "fHe", "Trigger List"}; // running variables for track tuner o2::dataformats::DCA mDcaInfoCov; @@ -453,7 +456,7 @@ struct nucleiSpectra { return; } if (cfgSkimmedProcessing) { - zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), "fHe"); + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), cfgTriggerList); zorro.populateHistRegistry(spectra, bc.runNumber()); } auto timestamp = bc.timestamp(); @@ -911,21 +914,70 @@ struct nucleiSpectra { PROCESS_SWITCH(nucleiSpectra, processDataFlowAlternative, "Data analysis with flow - alternative framework", false); Preslice tracksPerCollisions = aod::track::collisionId; + Preslice particlesPerMcCollision = aod::mcparticle::mcCollisionId; void processMC(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& tracks, aod::McParticles const& particlesMC, aod::BCsWithTimestamps const&) { nuclei::candidates.clear(); + + bool selectINELgt0 = cfgEventSelections->get(nuclei::evSel::kINELgt0); + std::vector goodCollisions(mcCollisions.size(), false); + + auto *pdgDB = TDatabasePDG::Instance(); // Useful for evaluating the particle charge + for (const auto& c : mcCollisions) { - spectra.fill(HIST("hGenVtxZ"), c.posZ()); + + // Apply the |z| < 10 cm condition + if (std::abs(c.posZ()) > 10.f) + continue; + + const auto& slicedParticles = particlesMC.sliceBy(particlesPerMcCollision, c.globalIndex()); + + bool hasHitFT0A(false); + bool hasHitFT0C(false); + bool acceptEvent = !selectINELgt0; + + for (const auto& p : slicedParticles) { + if (!p.isPhysicalPrimary()) + continue; + + // Apply the TVX trigger condition + if (p.eta() > 3.5f && p.eta() < 4.9f) + hasHitFT0A = true; + else if (p.eta() > -3.3f && p.eta() < -2.1f) + hasHitFT0C = true; + + // Apply the INEL>0 selection (only in case of active configurable) + if (selectINELgt0 && !acceptEvent) { + if (std::abs(p.eta()) < 1.0f) { + auto* pdg = pdgDB->GetParticle(p.pdgCode()); + if (pdg && pdg->Charge()!= 0) + acceptEvent = true; + } + } + + if (hasHitFT0A && hasHitFT0C && acceptEvent) + break; + } + + if (hasHitFT0A && hasHitFT0C && acceptEvent) { + goodCollisions[c.globalIndex()] = true; + spectra.fill(HIST("hGenVtxZ"), c.posZ()); + } } - std::vector goodCollisions(mcCollisions.size(), false); + for (const auto& collision : collisions) { if (!eventSelectionWithHisto(collision)) { continue; } - goodCollisions[collision.mcCollisionId()] = true; + + int mcId = collision.mcCollisionId(); + if (mcId < 0) continue; + if(!goodCollisions[mcId]) continue; + const auto& slicedTracks = tracks.sliceBy(tracksPerCollisions, collision.globalIndex()); fillDataInfo(collision, slicedTracks); } + std::vector isReconstructed(particlesMC.size(), false); for (auto& c : nuclei::candidates) { auto label = tracks.iteratorAt(c.globalIndex); From 45987a48c17a516c45de961a74d1e47398b76607 Mon Sep 17 00:00:00 2001 From: Cristian Moscatelli Date: Wed, 25 Feb 2026 11:37:21 +0100 Subject: [PATCH 2/3] Clang-format correction --- PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 95663bd60a5..1c1ee16a4fb 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -52,11 +52,11 @@ #include "ReconstructionDataFormats/Track.h" #include +#include #include #include // for PDG codes -#include -#include #include +#include #include #include @@ -922,7 +922,7 @@ struct nucleiSpectra { bool selectINELgt0 = cfgEventSelections->get(nuclei::evSel::kINELgt0); std::vector goodCollisions(mcCollisions.size(), false); - auto *pdgDB = TDatabasePDG::Instance(); // Useful for evaluating the particle charge + auto* pdgDB = TDatabasePDG::Instance(); // Useful for evaluating the particle charge for (const auto& c : mcCollisions) { @@ -950,7 +950,7 @@ struct nucleiSpectra { if (selectINELgt0 && !acceptEvent) { if (std::abs(p.eta()) < 1.0f) { auto* pdg = pdgDB->GetParticle(p.pdgCode()); - if (pdg && pdg->Charge()!= 0) + if (pdg && pdg->Charge() != 0) acceptEvent = true; } } @@ -971,8 +971,10 @@ struct nucleiSpectra { } int mcId = collision.mcCollisionId(); - if (mcId < 0) continue; - if(!goodCollisions[mcId]) continue; + if (mcId < 0) + continue; + if (!goodCollisions[mcId]) + continue; const auto& slicedTracks = tracks.sliceBy(tracksPerCollisions, collision.globalIndex()); fillDataInfo(collision, slicedTracks); From 2555fa65a86dba00728ba70e26bb2adcf1417faf Mon Sep 17 00:00:00 2001 From: Cristian Moscatelli Date: Wed, 4 Mar 2026 12:11:49 +0100 Subject: [PATCH 3/3] Mask-gen-ev-selection --- PWGLF/DataModel/LFSlimNucleiTables.h | 36 ++++++++++- PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx | 63 ++++++++++++-------- 2 files changed, 72 insertions(+), 27 deletions(-) diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h index e266bed5001..d823b75aebd 100644 --- a/PWGLF/DataModel/LFSlimNucleiTables.h +++ b/PWGLF/DataModel/LFSlimNucleiTables.h @@ -55,7 +55,7 @@ DECLARE_SOA_COLUMN(MotherPDGcode, MotherpdgCode, int); DECLARE_SOA_COLUMN(MotherDecRad, motherDecRad, float); DECLARE_SOA_COLUMN(AbsoDecL, absoDecL, float); DECLARE_SOA_COLUMN(McProcess, mcProcess, uint64_t); - +DECLARE_SOA_COLUMN(gEventMask, genEventMask, uint8_t); } // namespace NucleiTableNS namespace NucleiPairTableNS @@ -203,6 +203,40 @@ DECLARE_SOA_TABLE(NucleiTableRed, "AOD", "NUCLEITABLERED", NucleiTableNS::PDGcode, NucleiTableNS::MotherPDGcode); +// Table for keeping track of selection of generated events +DECLARE_SOA_TABLE(GenEventMCSel, "AOD", "GENEVENTMCSEL", + NucleiTableNS::gEventMask); + +DECLARE_SOA_TABLE(NucleiTableMCExtension, "AOD", "NUCTABLEMCSEL", + NucleiTableNS::Pt, + NucleiTableNS::Eta, + NucleiTableNS::Phi, + NucleiTableNS::TPCInnerParam, + NucleiTableNS::Beta, + NucleiTableNS::Zvertex, + NucleiTableNS::NContrib, + NucleiTableNS::DCAxy, + NucleiTableNS::DCAz, + NucleiTableNS::TPCsignal, + NucleiTableNS::ITSchi2, + NucleiTableNS::TPCchi2, + NucleiTableNS::TOFchi2, + NucleiTableNS::Flags, + NucleiTableNS::TPCfindableCls, + NucleiTableNS::TPCcrossedRows, + NucleiTableNS::ITSclsMap, + NucleiTableNS::TPCnCls, + NucleiTableNS::TPCnClsShared, + NucleiTableNS::ITSclusterSizes, + NucleiTableNS::SurvivedEventSelection, + NucleiTableNS::gPt, + NucleiTableNS::gEta, + NucleiTableNS::gPhi, + NucleiTableNS::PDGcode, + NucleiTableNS::MotherPDGcode, + NucleiTableNS::MotherDecRad, + NucleiTableNS::AbsoDecL, + NucleiTableNS::gEventMask); } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSLIMNUCLEITABLES_H_ diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 1c1ee16a4fb..f4422453858 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -21,6 +21,7 @@ #include "PWGLF/DataModel/EPCalibrationTables.h" #include "PWGLF/DataModel/LFSlimNucleiTables.h" +#include "PWGLF/Utils/inelGt.h" #include "Common/Core/EventPlaneHelper.h" #include "Common/Core/PID/PIDTOF.h" @@ -250,6 +251,13 @@ constexpr int EvSelDefault[9][1]{ {0}, {0}, {0}}; + +enum EvGenSel : uint8_t { + kGenTVX = 1 << 0, + kGenZvtx = 1 << 1, + kGenINELgt0 = 1 << 2, +}; + } // namespace nuclei struct nucleiSpectra { @@ -271,7 +279,9 @@ struct nucleiSpectra { Produces nucleiTable; Produces nucleiPairTable; Produces nucleiTableMC; + Produces nucleiTableMCExtension; Produces nucleiTableFlow; + Produces GenEventMCSel; Service ccdb; Zorro zorro; OutputObj zorroSummary{"zorroSummary"}; @@ -921,61 +931,62 @@ struct nucleiSpectra { bool selectINELgt0 = cfgEventSelections->get(nuclei::evSel::kINELgt0); std::vector goodCollisions(mcCollisions.size(), false); + std::vector eventMask(mcCollisions.size(), 0); auto* pdgDB = TDatabasePDG::Instance(); // Useful for evaluating the particle charge for (const auto& c : mcCollisions) { - // Apply the |z| < 10 cm condition - if (std::abs(c.posZ()) > 10.f) - continue; + uint8_t mask = 0; const auto& slicedParticles = particlesMC.sliceBy(particlesPerMcCollision, c.globalIndex()); bool hasHitFT0A(false); bool hasHitFT0C(false); - bool acceptEvent = !selectINELgt0; + // TVX trigger for (const auto& p : slicedParticles) { if (!p.isPhysicalPrimary()) continue; + auto* pdg = pdgDB->GetParticle(p.pdgCode()); + if (!pdg || pdg->Charge() == 0) + continue; + // Apply the TVX trigger condition if (p.eta() > 3.5f && p.eta() < 4.9f) hasHitFT0A = true; else if (p.eta() > -3.3f && p.eta() < -2.1f) hasHitFT0C = true; - // Apply the INEL>0 selection (only in case of active configurable) - if (selectINELgt0 && !acceptEvent) { - if (std::abs(p.eta()) < 1.0f) { - auto* pdg = pdgDB->GetParticle(p.pdgCode()); - if (pdg && pdg->Charge() != 0) - acceptEvent = true; - } - } - - if (hasHitFT0A && hasHitFT0C && acceptEvent) + if (hasHitFT0A && hasHitFT0C) break; } - if (hasHitFT0A && hasHitFT0C && acceptEvent) { - goodCollisions[c.globalIndex()] = true; - spectra.fill(HIST("hGenVtxZ"), c.posZ()); + if (hasHitFT0A && hasHitFT0C) + mask |= nuclei::kGenTVX; + + // |z| condition + if (std::abs(c.posZ()) < cfgCutVertex) + mask |= nuclei::kGenZvtx; + + // INEL > 0 selection + if (selectINELgt0) { + if (o2::pwglf::isINELgt0mc(slicedParticles, pdgDB)) { + mask |= nuclei::kGenINELgt0; + } } + + eventMask[c.globalIndex()] = mask; + GenEventMCSel(mask); + spectra.fill(HIST("hGenVtxZ"), c.posZ()); } for (const auto& collision : collisions) { if (!eventSelectionWithHisto(collision)) { continue; } - - int mcId = collision.mcCollisionId(); - if (mcId < 0) - continue; - if (!goodCollisions[mcId]) - continue; - + goodCollisions[collision.mcCollisionId()] = true; const auto& slicedTracks = tracks.sliceBy(tracksPerCollisions, collision.globalIndex()); fillDataInfo(collision, slicedTracks); } @@ -1041,7 +1052,7 @@ struct nucleiSpectra { isReconstructed[particle.globalIndex()] = true; float absoDecL = computeAbsoDecL(particle); - nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.nContrib, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.TOFchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS, goodCollisions[particle.mcCollisionId()], particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), motherPdgCode, motherDecRadius, absoDecL); + nucleiTableMCExtension(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.nContrib, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.TOFchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS, goodCollisions[particle.mcCollisionId()], particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), motherPdgCode, motherDecRadius, absoDecL, eventMask[particle.mcCollisionId()]); } int index{0}; @@ -1093,7 +1104,7 @@ struct nucleiSpectra { continue; // skip secondaries from material if not requested } float absDecL = computeAbsoDecL(particle); - nucleiTableMC(999., 999., 999., 0., 0., 999., -1, 999., 999., -1, -1, -1, -1, flags, 0, 0, 0, 0, 0, 0, goodCollisions[particle.mcCollisionId()], particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), motherPdgCode, motherDecRadius, absDecL); + nucleiTableMCExtension(999., 999., 999., 0., 0., 999., -1, 999., 999., -1, -1, -1, -1, flags, 0, 0, 0, 0, 0, 0, goodCollisions[particle.mcCollisionId()], particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), motherPdgCode, motherDecRadius, absDecL, eventMask[particle.mcCollisionId()]); } break; }