From 0d37908d03aebe477a6b4e30a1525c387f3fa516 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Mon, 9 Jun 2025 14:54:54 +0200 Subject: [PATCH 01/62] dev: adding toi mask to table --- PWGLF/DataModel/LFNonPromptCascadeTables.h | 13 +++++--- PWGLF/Tasks/Strangeness/nonPromptCascade.cxx | 35 ++++++++++++++------ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/PWGLF/DataModel/LFNonPromptCascadeTables.h b/PWGLF/DataModel/LFNonPromptCascadeTables.h index 177167d5997..a4e15df33ef 100644 --- a/PWGLF/DataModel/LFNonPromptCascadeTables.h +++ b/PWGLF/DataModel/LFNonPromptCascadeTables.h @@ -119,6 +119,7 @@ DECLARE_SOA_COLUMN(MultFT0M, multFT0M, float); DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); DECLARE_SOA_COLUMN(CentFT0A, centFT0A, float); DECLARE_SOA_COLUMN(CentFT0M, centFT0M, float); +DECLARE_SOA_COLUMN(ToiMask, toiMask, uint32_t); } // namespace NPCascadeTable DECLARE_SOA_TABLE(NPCascTable, "AOD", "NPCASCTABLE", @@ -183,7 +184,8 @@ DECLARE_SOA_TABLE(NPCascTable, "AOD", "NPCASCTABLE", NPCascadeTable::MultFT0M, NPCascadeTable::CentFT0C, NPCascadeTable::CentFT0A, - NPCascadeTable::CentFT0M) + NPCascadeTable::CentFT0M, + NPCascadeTable::ToiMask) DECLARE_SOA_TABLE(NPCascTableNT, "AOD", "NPCASCTABLENT", NPCascadeTable::MatchingChi2, @@ -247,7 +249,8 @@ DECLARE_SOA_TABLE(NPCascTableNT, "AOD", "NPCASCTABLENT", NPCascadeTable::MultFT0M, NPCascadeTable::CentFT0C, NPCascadeTable::CentFT0A, - NPCascadeTable::CentFT0M) + NPCascadeTable::CentFT0M, + NPCascadeTable::ToiMask) DECLARE_SOA_TABLE(NPCascTableMC, "AOD", "NPCASCTABLEMC", NPCascadeTable::MatchingChi2, @@ -330,7 +333,8 @@ DECLARE_SOA_TABLE(NPCascTableMC, "AOD", "NPCASCTABLEMC", NPCascadeTable::DCAzMC, NPCascadeTable::MCcollisionMatch, NPCascadeTable::HasFakeReassociation, - NPCascadeTable::MotherDecayDaughters) + NPCascadeTable::MotherDecayDaughters, + NPCascadeTable::ToiMask) DECLARE_SOA_TABLE(NPCascTableMCNT, "AOD", "NPCASCTABLEMCNT", NPCascadeTable::MatchingChi2, @@ -413,7 +417,8 @@ DECLARE_SOA_TABLE(NPCascTableMCNT, "AOD", "NPCASCTABLEMCNT", NPCascadeTable::DCAzMC, NPCascadeTable::MCcollisionMatch, NPCascadeTable::HasFakeReassociation, - NPCascadeTable::MotherDecayDaughters) + NPCascadeTable::MotherDecayDaughters, + NPCascadeTable::ToiMask) DECLARE_SOA_TABLE(NPCascTableGen, "AOD", "NPCASCTABLEGen", NPCascadeTable::gPt, diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index c5388c034a2..2e738c511c3 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -125,6 +125,7 @@ struct NPCascCandidate { float centFT0C; float centFT0A; float centFT0M; + uint32_t toiMask; }; std::array isFromHF(auto& particle) { @@ -287,7 +288,7 @@ struct NonPromptCascadeTask { return true; } - void zorroAccounting(const auto& collisions) + void zorroAccounting(const auto& collisions, auto& toiMap) { if (cfgSkimmedProcessing) { int runNumber{-1}; @@ -298,12 +299,20 @@ struct NonPromptCascadeTask { mZorro.populateHistRegistry(mRegistry, bc.runNumber()); runNumber = bc.runNumber(); } - mZorro.isSelected(bc.globalBC()); /// Just let Zorro do the accounting + bool sel = mZorro.isSelected(bc.globalBC()); /// Just let Zorro do the accounting + if(sel) { + std::vector toivect = mZorro.getTriggerOfInterestResults(); + uint32_t toiMask = 0; + for(uint i = 0; i < toivect.size(); i++) { + toiMask += 1 << i; + } + toiMap[bc.globalBC()] = toiMask; + } } } } template - void fillCandidatesVector(CollisionType const&, TrackType const& tracks, auto const& cascades, auto& candidates) + void fillCandidatesVector(CollisionType const&, TrackType const& tracks, auto const& cascades, auto& candidates, std::map toiMap = {}) { const auto& getCascade = [](auto const& candidate) { @@ -507,6 +516,10 @@ struct NonPromptCascadeTask { } else { o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, ntCascadeTrack, mBz, 2.f, matCorr, &motherDCA); } + uint32_t toiMask = 0x0; + if(toiMap.count(bc.globalBC())) { + toiMask = toiMap[bc.globalBC()]; + } candidates.emplace_back(NPCascCandidate{mcParticleID, trackedCascGlobalIndex, itsTrackGlobalIndex, candidate.collisionId(), matchingChi2, deltaPtITSCascade, deltaPtCascade, cascITSclsSize, hasReassociatedClusters, hasFakeReassociation, isGoodMatch, isGoodCascade, pdgCodeMom, itsTrackPDG, fromHF[0], fromHF[1], collision.numContrib(), cascPVContribs, collision.collisionTimeRes(), primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), cascadeLvector.pt(), cascadeLvector.eta(), cascadeLvector.phi(), @@ -517,7 +530,7 @@ struct NonPromptCascadeTask { cascITSclusters, protonTrack.itsNCls(), pionTrack.itsNCls(), bachelor.itsNCls(), protonTrack.tpcNClsFound(), pionTrack.tpcNClsFound(), bachelor.tpcNClsFound(), protonTrack.tpcNSigmaPr(), pionTrack.tpcNSigmaPi(), bachelor.tpcNSigmaKa(), bachelor.tpcNSigmaPi(), protonTrack.hasTOF(), pionTrack.hasTOF(), bachelor.hasTOF(), - protonTrack.tofNSigmaPr(), pionTrack.tofNSigmaPi(), bachelor.tofNSigmaKa(), bachelor.tofNSigmaPi(), collision.sel8(), collision.multFT0C(), collision.multFT0A(), collision.multFT0M(), collision.centFT0C(), collision.centFT0A(), collision.centFT0M()}); + protonTrack.tofNSigmaPr(), pionTrack.tofNSigmaPi(), bachelor.tofNSigmaKa(), bachelor.tofNSigmaPi(), collision.sel8(), collision.multFT0C(), collision.multFT0A(), collision.multFT0M(), collision.centFT0C(), collision.centFT0A(), collision.centFT0M(), toiMask}); } } @@ -537,7 +550,7 @@ struct NonPromptCascadeTask { c.protonTPCNSigma, c.pionTPCNSigma, c.bachKaonTPCNSigma, c.bachPionTPCNSigma, c.protonHasTOF, c.pionHasTOF, c.bachHasTOF, c.protonTOFNSigma, c.pionTOFNSigma, c.bachKaonTOFNSigma, c.bachPionTOFNSigma, - c.sel8, c.multFT0C, c.multFT0A, c.multFT0M, c.centFT0C, c.centFT0A, c.centFT0M); + c.sel8, c.multFT0C, c.multFT0A, c.multFT0M, c.centFT0C, c.centFT0A, c.centFT0M, c.toiMask); } } @@ -576,7 +589,7 @@ struct NonPromptCascadeTask { c.sel8, c.multFT0C, c.multFT0A, c.multFT0M, c.centFT0C, c.centFT0A, c.centFT0M, particle.pt(), particle.eta(), particle.phi(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), particle.pdgCode(), mcCollision.posX() - particle.vx(), mcCollision.posY() - particle.vy(), - mcCollision.posZ() - particle.vz(), mcCollision.globalIndex() == recCollision.mcCollisionId(), c.hasFakeReassociation, motherDecayDaughters); + mcCollision.posZ() - particle.vz(), mcCollision.globalIndex() == recCollision.mcCollisionId(), c.hasFakeReassociation, motherDecayDaughters,c.toiMask); } } @@ -653,8 +666,9 @@ struct NonPromptCascadeTask { aod::V0s const& /*v0s*/, TracksExtData const& tracks, aod::BCsWithTimestamps const&) { - zorroAccounting(collisions); - fillCandidatesVector(collisions, tracks, trackedCascades, gCandidates); + std::map toiMap; + zorroAccounting(collisions, toiMap); + fillCandidatesVector(collisions, tracks, trackedCascades, gCandidates, toiMap); fillDataTable(gCandidates); } PROCESS_SWITCH(NonPromptCascadeTask, processTrackedCascadesData, "process cascades from strangeness tracking: Data analysis", false); @@ -663,8 +677,9 @@ struct NonPromptCascadeTask { aod::V0s const& /*v0s*/, TracksExtData const& tracks, aod::BCsWithTimestamps const&) { - zorroAccounting(collisions); - fillCandidatesVector(collisions, tracks, cascades, gCandidatesNT); + std::map toiMap; + zorroAccounting(collisions, toiMap); + fillCandidatesVector(collisions, tracks, cascades, gCandidatesNT, toiMap); fillDataTable(gCandidatesNT); } PROCESS_SWITCH(NonPromptCascadeTask, processCascadesData, "process cascades: Data analysis", false); From d086f9b4e10bef37bfaa3178dde5aaab73d009ad Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Mon, 9 Jun 2025 14:55:51 +0200 Subject: [PATCH 02/62] clang --- PWGLF/Tasks/Strangeness/nonPromptCascade.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index 2e738c511c3..917b260f2e3 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -300,10 +300,10 @@ struct NonPromptCascadeTask { runNumber = bc.runNumber(); } bool sel = mZorro.isSelected(bc.globalBC()); /// Just let Zorro do the accounting - if(sel) { + if (sel) { std::vector toivect = mZorro.getTriggerOfInterestResults(); uint32_t toiMask = 0; - for(uint i = 0; i < toivect.size(); i++) { + for (uint i = 0; i < toivect.size(); i++) { toiMask += 1 << i; } toiMap[bc.globalBC()] = toiMask; @@ -312,7 +312,7 @@ struct NonPromptCascadeTask { } } template - void fillCandidatesVector(CollisionType const&, TrackType const& tracks, auto const& cascades, auto& candidates, std::map toiMap = {}) + void fillCandidatesVector(CollisionType const&, TrackType const& tracks, auto const& cascades, auto& candidates, std::map toiMap = {}) { const auto& getCascade = [](auto const& candidate) { @@ -517,7 +517,7 @@ struct NonPromptCascadeTask { o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, ntCascadeTrack, mBz, 2.f, matCorr, &motherDCA); } uint32_t toiMask = 0x0; - if(toiMap.count(bc.globalBC())) { + if (toiMap.count(bc.globalBC())) { toiMask = toiMap[bc.globalBC()]; } candidates.emplace_back(NPCascCandidate{mcParticleID, trackedCascGlobalIndex, itsTrackGlobalIndex, candidate.collisionId(), matchingChi2, deltaPtITSCascade, deltaPtCascade, cascITSclsSize, hasReassociatedClusters, hasFakeReassociation, isGoodMatch, isGoodCascade, pdgCodeMom, itsTrackPDG, fromHF[0], fromHF[1], @@ -589,7 +589,7 @@ struct NonPromptCascadeTask { c.sel8, c.multFT0C, c.multFT0A, c.multFT0M, c.centFT0C, c.centFT0A, c.centFT0M, particle.pt(), particle.eta(), particle.phi(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), particle.pdgCode(), mcCollision.posX() - particle.vx(), mcCollision.posY() - particle.vy(), - mcCollision.posZ() - particle.vz(), mcCollision.globalIndex() == recCollision.mcCollisionId(), c.hasFakeReassociation, motherDecayDaughters,c.toiMask); + mcCollision.posZ() - particle.vz(), mcCollision.globalIndex() == recCollision.mcCollisionId(), c.hasFakeReassociation, motherDecayDaughters, c.toiMask); } } From 2ed2bdf89923d37cf77ddc351674a4537337a5b1 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Mon, 9 Jun 2025 18:29:07 +0200 Subject: [PATCH 03/62] fixes + zorro getter for number of tois --- EventFiltering/Zorro.h | 1 + PWGLF/Tasks/Strangeness/nonPromptCascade.cxx | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/EventFiltering/Zorro.h b/EventFiltering/Zorro.h index c818e45ce48..bfcf8709fb2 100644 --- a/EventFiltering/Zorro.h +++ b/EventFiltering/Zorro.h @@ -54,6 +54,7 @@ class Zorro std::vector getTOIcounters() const { return mTOIcounts; } std::vector getTriggerOfInterestResults(uint64_t bcGlobalId, uint64_t tolerance = 100); std::vector getTriggerOfInterestResults() const; + int getNTOIs() const { return mTOIs.size(); } void setCCDBpath(std::string path) { mBaseCCDBPath = path; } void setBaseCCDBPath(std::string path) { mBaseCCDBPath = path; } diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index 917b260f2e3..a9f8fca101b 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -296,6 +296,9 @@ struct NonPromptCascadeTask { auto bc = coll.template bc_as(); if (runNumber != bc.runNumber()) { mZorro.initCCDB(mCCDB.service, bc.runNumber(), bc.timestamp(), cfgTriggersOfInterest.value); + if(mZorro.getNTOIs() > 32) { + LOG(fatal) << "N TOIs:" << mZorro.getNTOIs() << " Max 32 TOIs possible."; + } mZorro.populateHistRegistry(mRegistry, bc.runNumber()); runNumber = bc.runNumber(); } @@ -303,8 +306,8 @@ struct NonPromptCascadeTask { if (sel) { std::vector toivect = mZorro.getTriggerOfInterestResults(); uint32_t toiMask = 0; - for (uint i = 0; i < toivect.size(); i++) { - toiMask += 1 << i; + for (int i{0}; i < toivect.size(); i++) { + toiMask += toivect[i] << i; } toiMap[bc.globalBC()] = toiMask; } From e97ca337ea4374ea8371b2945a3cc3ea4578b7fb Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Mon, 9 Jun 2025 18:30:35 +0200 Subject: [PATCH 04/62] clang --- PWGLF/Tasks/Strangeness/nonPromptCascade.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index a9f8fca101b..de1857deca3 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -296,7 +296,7 @@ struct NonPromptCascadeTask { auto bc = coll.template bc_as(); if (runNumber != bc.runNumber()) { mZorro.initCCDB(mCCDB.service, bc.runNumber(), bc.timestamp(), cfgTriggersOfInterest.value); - if(mZorro.getNTOIs() > 32) { + if (mZorro.getNTOIs() > 32) { LOG(fatal) << "N TOIs:" << mZorro.getNTOIs() << " Max 32 TOIs possible."; } mZorro.populateHistRegistry(mRegistry, bc.runNumber()); From d8dcc2f7ca314a2cbaca32fc3f7d8f67e23f77e8 Mon Sep 17 00:00:00 2001 From: Evgeny Kryshen Date: Mon, 9 Jun 2025 14:07:23 +0300 Subject: [PATCH 05/62] [Common] Setting processRun2 to true by default (#11514) --- Common/TableProducer/eventSelection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index b06e98b84c5..3c989f1848a 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -1223,7 +1223,7 @@ struct LumiTask { LOGP(debug, "Dummy process function for Run 2"); } - PROCESS_SWITCH(LumiTask, processRun2, "Process Run2 lumi task", false); + PROCESS_SWITCH(LumiTask, processRun2, "Process Run2 lumi task", true); void processRun3(BCsWithBcSelsRun3 const& bcs, aod::FT0s const&) { From bab575b9ad6a46a6f3468c64c8d257abdf4d316c Mon Sep 17 00:00:00 2001 From: basiach <74355517+basiach@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:33:33 +0200 Subject: [PATCH 06/62] [PWGCF] FemtoUniverse - Adding centrality for MC cascades and a PDG histogram (#11517) Co-authored-by: Barbara Chytla --- .../femtoUniverseProducerTask.cxx | 41 +++++++++++++++++++ .../Tasks/femtoUniverseEfficiencyBase.cxx | 6 +++ ...toUniversePairTaskTrackCascadeExtended.cxx | 7 +++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 00ed3161ce7..e9a07329468 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -2336,6 +2336,47 @@ struct FemtoUniverseProducerTask { } PROCESS_SWITCH(FemtoUniverseProducerTask, processTruthAndFullMCCasc, "Provide both MC truth and reco for tracks and Cascades", false); + void processTruthAndFullMCCentRun3Casc( + aod::McCollisions const& mccols, + aod::McParticles const& mcParticles, + aod::FemtoFullCollisionCentRun3MCs const& collisions, + soa::Filtered> const& tracks, + soa::Join const& fullCascades, + aod::BCsWithTimestamps const&) + { + + // recos + std::set recoMcIds; + for (const auto& col : collisions) { + auto groupedTracks = tracks.sliceBy(perCollisionTracks, col.globalIndex()); + auto groupedCascParts = fullCascades.sliceBy(perCollisionCascs, col.globalIndex()); + getMagneticFieldTesla(col.bc_as()); + const auto colcheck = fillCollisionsCentRun3(col); + if (colcheck) { + fillTracks(groupedTracks); + fillCascade(col, groupedCascParts, groupedTracks); + } + for (const auto& track : groupedTracks) { + if (trackCuts.isSelectedMinimal(track)) + recoMcIds.insert(track.mcParticleId()); + } + } + + // truth + for (const auto& mccol : mccols) { + auto groupedCollisions = collisions.sliceBy(recoCollsPerMCCollCentPbPb, mccol.globalIndex()); + for (const auto& col : groupedCollisions) { + const auto colcheck = fillMCTruthCollisionsCentRun3(col); // fills the reco collisions for mc collision + if (colcheck) { + auto groupedMCParticles = mcParticles.sliceBy(perMCCollision, mccol.globalIndex()); + outputCollExtra(1.0, 1.0); + fillParticles(groupedMCParticles, recoMcIds); // fills mc particles + } + } + } + } + PROCESS_SWITCH(FemtoUniverseProducerTask, processTruthAndFullMCCentRun3Casc, "Provide both MC truth and reco for tracks and cascades with centrality", false); + Preslice> perCollisionD0s = aod::track::collisionId; void processTrackD0MC(aod::McCollisions const& mccols, aod::TracksWMc const&, diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index 92e42134f0a..5397acf05dc 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -160,6 +160,7 @@ struct FemtoUniverseEfficiencyBase { trackHistoPartOneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, confPDGCodePartOne, confIsDebug); registryMCOrigin.add("part1/hPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{240, 0, 6}}}); registryPDG.add("part1/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); + registryPDG.add("part1/PDGvspTall", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); if (confParticleTypePartOne == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) { trackHistoV0OneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarCPABins, 0, confPDGCodePartOne, confIsDebug); trackHistoV0OneChildPosRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, 0, confIsDebug, "posChildV0_1"); @@ -169,6 +170,7 @@ struct FemtoUniverseEfficiencyBase { } registryPDG.add("part2/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); + registryPDG.add("part2/PDGvspTall", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); if (!confIsSame) { trackHistoPartTwoGen.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, 0, confPDGCodePartTwo, false); trackHistoPartTwoRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, confPDGCodePartTwo, confIsDebug); @@ -373,6 +375,8 @@ struct FemtoUniverseEfficiencyBase { continue; } + registryPDG.fill(HIST("part1/PDGvspTall"), part.pt(), mcParticle.pdgMCTruth()); + if (!(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartOne))) { continue; } @@ -397,6 +401,8 @@ struct FemtoUniverseEfficiencyBase { continue; } + registryPDG.fill(HIST("part2/PDGvspTall"), part.pt(), mcParticle.pdgMCTruth()); + if (!(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartTwo))) { continue; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index e4ebe2db60a..026cabb1367 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -631,6 +631,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { // MC truth void processSameEventMCgen(const FilteredFDCollision& col, [[maybe_unused]] const FemtoFullParticles& parts) { + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + auto groupPartsOne = partsOneMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto groupPartsTwo = partsTwoMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); @@ -665,7 +667,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { int pdgCodeCasc = static_cast(p2.pidCut()); if ((confCascType1 == 0 && pdgCodeCasc != 3334) || (confCascType1 == 2 && pdgCodeCasc != -3334) || (confCascType1 == 1 && pdgCodeCasc != 3312) || (confCascType1 == 3 && pdgCodeCasc != -3312)) continue; - sameEventCont.setPair(p1, p2, col.multNtr(), confUse3D, 1.0f); + sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } } } @@ -676,6 +678,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); auto groupPartsOne = partsOneMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); auto groupPartsTwo = partsTwoMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); @@ -692,7 +695,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { int pdgCodeCasc = static_cast(p2.pidCut()); if ((confCascType1 == 0 && pdgCodeCasc != 3334) || (confCascType1 == 2 && pdgCodeCasc != -3334) || (confCascType1 == 1 && pdgCodeCasc != 3312) || (confCascType1 == 3 && pdgCodeCasc != -3312)) continue; - mixedEventCont.setPair(p1, p2, collision1.multNtr(), confUse3D, 1.0f); + mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } } } From d9c15a2cd4c1aab4175984d64af9f24cc5aef25c Mon Sep 17 00:00:00 2001 From: Rahul Verma <110929992+rahulverma012@users.noreply.github.com> Date: Mon, 9 Jun 2025 20:26:52 +0530 Subject: [PATCH 07/62] [Common] modified aod::TracksQA_002 to aod::TracksQAVersion (#11485) Co-authored-by: Anton Alkin --- Common/TableProducer/occupancyTableProducer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/TableProducer/occupancyTableProducer.cxx b/Common/TableProducer/occupancyTableProducer.cxx index 2e4a01ddbb1..95d1ca72dea 100644 --- a/Common/TableProducer/occupancyTableProducer.cxx +++ b/Common/TableProducer/occupancyTableProducer.cxx @@ -1692,7 +1692,7 @@ struct TrackMeanOccTableProducer { } } - using MyTracksQA = aod::TracksQA_002; + using MyTracksQA = aod::TracksQAVersion; // using MyTracksQA = aod::TracksQA_002; // Process the Data int dfCount = 0; From c3b1387be5f4341e7bb836e1d684eadb0f0ff2ff Mon Sep 17 00:00:00 2001 From: Pritam Chakraborty <47203359+prchakra@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:23:33 +0200 Subject: [PATCH 08/62] [PWGCF] FemtoUniverse: Fine binning the helicity angle distribution (#11521) --- PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx index d35aa3fa779..fe1bf2e7983 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx @@ -85,7 +85,7 @@ struct FemtoUniverseDebugV0 { negativeChildHistos.init(&V0Registry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, confPDGCodeNegativeChild, true); V0Histos.init(&V0Registry, confV0TempFitVarpTBins, confV0TempFitVarBins, false, confPDGCodeV0.value, true); - thetaRegistry.add("Theta/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {50, -5, 5}}); + thetaRegistry.add("Theta/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); } /// Produce QA plots for V0 selection in FemtoUniverse framework From 4d949a7f3e0f7f3de65fa9661809912de5c2fc26 Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Mon, 9 Jun 2025 22:09:34 +0200 Subject: [PATCH 09/62] [PWGLF] Improve variable selection in mixed event (#11522) --- .../Tasks/Strangeness/taskLambdaSpinCorr.cxx | 135 +++++++++++------- 1 file changed, 87 insertions(+), 48 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx index 9badfb4b4ba..0472e380aed 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -61,8 +61,8 @@ struct LfTaskLambdaSpinCorr { Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; } rctCut; // mixing - Configurable cosCalculation{"cosCalculation", 1, "cos calculation"}; - Configurable mixingCombination{"mixingCombination", 1, "mixing Combination"}; + Configurable cosCalculation{"cosCalculation", 0, "cos calculation"}; + Configurable mixingCombination{"mixingCombination", 0, "mixing Combination"}; Configurable mixingEvSel{"mixingEvSel", false, "mixingEvSel"}; Configurable cfgCutOccupancy{"cfgCutOccupancy", 2000, "Occupancy cut"}; ConfigurableAxis axisVertex{"axisVertex", {5, -10, 10}, "vertex axis for bin"}; @@ -128,7 +128,8 @@ struct LfTaskLambdaSpinCorr { AxisSpec thnAxisInvMasspair{iMNbinspair, lbinIMpair, hbinIMpair, "#it{M} (GeV/#it{c}^{2})"}; histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); histos.add("hPtDiff", "hPtDiff", kTH1F, {{1000, 0, 100.0}}); - histos.add("hRDiff", "hRDiff", kTH1F, {{640, 0, 16.0}}); + histos.add("hPhiDiff", "hPhiDiff", kTH1F, {{800, -8.0, 8.0}}); + histos.add("hRDiff", "hRDiff", kTH1F, {{640, -16.0, 16.0}}); histos.add("hv0Mult", "hv0Mult", kTH1F, {{10001, -0.5, 10000.5}}); histos.add("hCentrality", "Centrality distribution", kTH1F, {{configcentAxis}}); histos.add("hSparseLambdaLambda", "hSparseLambdaLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); @@ -244,8 +245,8 @@ struct LfTaskLambdaSpinCorr { const ROOT::Math::PxPyPzMVector& Lambdadummy, const ROOT::Math::PxPyPzMVector& AntiLambdadummy) { - const double minMass = 1.0; - const double maxMass = 2.0; + const double minMass = 1.09; + const double maxMass = 1.14; return (lambdaTag && aLambdaTag && (Lambdadummy.M() > minMass && Lambdadummy.M() < maxMass) && (AntiLambdadummy.M() > minMass && AntiLambdadummy.M() < maxMass)); @@ -293,8 +294,8 @@ struct LfTaskLambdaSpinCorr { double cosTheta2 = proton2LambdaRF.Vect().Unit().Dot(quantizationAxis); cosThetaDiff = cosTheta1 * cosTheta2; } - - double deltaR = TMath::Sqrt(TMath::Power(particle1.Eta() - particle2.Eta(), 2.0) + TMath::Power(particle1.Phi() - particle2.Phi(), 2.0)); + double deltaPhi = RecoDecay::constrainAngle(particle1.Phi() - particle2.Phi(), 0.0); + double deltaR = TMath::Sqrt(TMath::Power(particle1.Eta() - particle2.Eta(), 2.0) + TMath::Power(deltaPhi, 2.0)); if (datatype == 0) { if (tag1 && tag3) { histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR); @@ -411,7 +412,7 @@ struct LfTaskLambdaSpinCorr { return {lambdaTag, aLambdaTag, true}; // Valid candidate } - + ROOT::Math::PxPyPzMVector lambda0, antiLambda0, proton0, pion0, antiProton0, antiPion0; ROOT::Math::PxPyPzMVector lambda, antiLambda, proton, pion, antiProton, antiPion; ROOT::Math::PxPyPzMVector lambda2, antiLambda2, proton2, pion2, antiProton2, antiPion2; ROOT::Math::PxPyPzMVector lambdamc, antiLambdamc, protonmc, pionmc, antiProtonmc, antiPionmc; @@ -478,7 +479,12 @@ struct LfTaskLambdaSpinCorr { pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); antiLambda = antiProton + pion; } - + if (lambdaTag && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } auto postrack1 = v0.template posTrack_as(); auto negtrack1 = v0.template negTrack_as(); @@ -504,6 +510,12 @@ struct LfTaskLambdaSpinCorr { pion2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassPionCharged); antiLambda2 = antiProton2 + pion2; } + if (lambdaTag2 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { + continue; + } auto postrack2 = v02.template posTrack_as(); auto negtrack2 = v02.template negTrack_as(); if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { @@ -630,8 +642,42 @@ struct LfTaskLambdaSpinCorr { if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { continue; } - auto samePairSumPt = t1.pt() + t2.pt(); - auto samePairR = TMath::Sqrt(TMath::Power(t1.phi() - t2.phi(), 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + // auto samePairSumPt = t1.pt() + t2.pt(); + double deltaPhiSame = RecoDecay::constrainAngle(t1.phi() - t2.phi(), 0.0); + auto samePairR = TMath::Sqrt(TMath::Power(deltaPhiSame, 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + + if (lambdaTag1) { + proton0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassProton); + antiPion0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassPionCharged); + lambda0 = proton0 + antiPion0; + } + if (aLambdaTag1) { + antiProton0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassProton); + pion0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda0 = antiProton0 + pion0; + } + if (lambdaTag1 && (lambda0.M() < lbinIM || lambda0.M() > hbinIM)) { + continue; + } + if (aLambdaTag1 && (antiLambda0.M() < lbinIM || antiLambda0.M() > hbinIM)) { + continue; + } + if (lambdaTag2) { + proton = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassPionCharged); + lambda = proton + antiPion; + } + if (aLambdaTag2) { + antiProton = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda = antiProton + pion; + } + if (lambdaTag2 && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } for (const auto& t3 : groupV03) { // if (pairStatus[t3.index()][t2.index()]) { // LOGF(info, "repeat match found v0 id: (%d, %d)", t3.index(), t2.index()); @@ -653,55 +699,49 @@ struct LfTaskLambdaSpinCorr { if (lambdaTag1 != lambdaTag3 || aLambdaTag1 != aLambdaTag3) { continue; } - // if (std::abs(t1.pt() - t3.pt()) > ptMix) { - // continue; - // } - // if (std::abs(t1.eta() - t3.eta()) > etaMix) { - // continue; - // } - // if (std::abs(t1.phi() - t3.phi()) > phiMix) { - // continue; - // } - auto mixPairSumPt = t3.pt() + t2.pt(); - auto mixPairR = TMath::Sqrt(TMath::Power(t3.phi() - t2.phi(), 2.0) + TMath::Power(t3.eta() - t2.eta(), 2.0)); - histos.fill(HIST("hPtDiff"), TMath::Abs(mixPairSumPt - samePairSumPt)); - histos.fill(HIST("hRDiff"), TMath::Abs(mixPairR - samePairR)); - if (mixingCombination == 0 && std::abs(t1.pt() - t3.pt()) > ptMix) { - continue; + + if (lambdaTag3) { + proton2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassProton); + antiPion2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassPionCharged); + lambda2 = proton2 + antiPion2; + } + if (aLambdaTag3) { + antiProton2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassProton); + pion2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda2 = antiProton2 + pion2; } - if (mixingCombination == 0 && std::abs(t1.eta() - t3.eta()) > etaMix) { + if (lambdaTag3 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { continue; } - if (mixingCombination == 0 && std::abs(t1.phi() - t3.phi()) > phiMix) { + if (aLambdaTag3 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { continue; } + double deltaPhiMix = RecoDecay::constrainAngle(t3.phi() - t2.phi(), 0.0); + auto mixPairR = TMath::Sqrt(TMath::Power(deltaPhiMix, 2.0) + TMath::Power(t3.eta() - t2.eta(), 2.0)); + auto etaDiff = t1.eta() - t3.eta(); + auto phiDiff = RecoDecay::constrainAngle(t1.phi() - t3.phi(), 0.0); - if (mixingCombination == 1 && std::abs(mixPairSumPt - samePairSumPt) > ptMix) { + histos.fill(HIST("hPtDiff"), t1.pt() - t3.pt()); + histos.fill(HIST("hPhiDiff"), phiDiff); + histos.fill(HIST("hRDiff"), etaDiff); + + if (mixingCombination == 0 && std::abs(t1.pt() - t3.pt()) > ptMix) { continue; } - if (mixingCombination == 1 && std::abs(mixPairR - samePairR) > etaMix) { + if (mixingCombination == 0 && t1.eta() * t3.eta() > 0 && std::abs(etaDiff) > etaMix) { continue; } - if (lambdaTag2) { - proton = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassProton); - antiPion = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassPionCharged); - lambda = proton + antiPion; - } - if (aLambdaTag2) { - antiProton = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassProton); - pion = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassPionCharged); - antiLambda = antiProton + pion; + if (mixingCombination == 0 && phiDiff > phiMix) { + continue; } - if (lambdaTag3) { - proton2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassProton); - antiPion2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassPionCharged); - lambda2 = proton2 + antiPion2; + + if (mixingCombination == 1 && std::abs(t1.pt() - t3.pt()) > ptMix) { + continue; } - if (aLambdaTag3) { - antiProton2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassProton); - pion2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassPionCharged); - antiLambda2 = antiProton2 + pion2; + if (mixingCombination == 1 && std::abs(mixPairR - samePairR) > etaMix) { + continue; } + if (lambdaTag2 && lambdaTag3) { fillHistograms(1, 0, 1, 0, lambda, lambda2, proton, proton2, centrality, 2); } else if (aLambdaTag2 && aLambdaTag3) { @@ -714,7 +754,6 @@ struct LfTaskLambdaSpinCorr { continue; } pairfound = true; - // pairStatus[t3.index()][t2.index()] = true; pairStatus[t3.index()][t2.index()] = true; // LOGF(info, "v0 id: (%d, %d)", t3.index(), t2.index()); if (pairfound) { From 42fd296371324f77db155709c959994a7b3ab034 Mon Sep 17 00:00:00 2001 From: sarjeetagami <162087855+sarjeetagami@users.noreply.github.com> Date: Tue, 10 Jun 2025 02:24:16 +0530 Subject: [PATCH 10/62] [PWGLF] fix event selection hist (#11524) Co-authored-by: sarjeeta gami --- PWGLF/Tasks/Resonances/kstarpbpb.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index 0093b921c80..a8ad0497647 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -184,9 +184,9 @@ struct kstarpbpb { AxisSpec centAxis = {8, 0, 80, "V0M (%)"}; AxisSpec occupancyAxis = {occupancyBinning, "Occupancy"}; if (!fillSA) { + histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); if (same) { histos.add("hSparseV2SASameEvent_V2", "hSparseV2SASameEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); } if (like) { histos.add("hSparseV2SAlikeEventNN_V2", "hSparseV2SAlikeEventNN_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); From 930559dc01fcd439c9dbc46cd3d47e605c44cb15 Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Mon, 9 Jun 2025 23:23:01 +0200 Subject: [PATCH 11/62] [PWGLF] use material LUT in fit and propagation (#11513) --- .../Strangeness/LFStrangeTreeCreator.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx b/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx index 955b4ebc142..4ab2f0cc745 100644 --- a/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx +++ b/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx @@ -157,8 +157,8 @@ struct LFStrangeTreeCreator { int mRunNumber; float d_bz; - // o2::base::MatLayerCylSet* lut = nullptr; - Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; + o2::base::MatLayerCylSet* lut = nullptr; + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"}; ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; @@ -248,7 +248,11 @@ struct LFStrangeTreeCreator { mRunNumber = bc.runNumber(); fitter.setBz(d_bz); - // o2::base::Propagator::Instance()->setMatLUT(lut); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + o2::base::Propagator::Instance()->setMatLUT(lut); + + int mat{static_cast(cfgMaterialCorrection)}; + fitter.setMatCorrType(static_cast(mat)); } void init(o2::framework::InitContext&) @@ -261,7 +265,6 @@ struct LFStrangeTreeCreator { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - // lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); fitter.setPropagateToPCA(true); fitter.setMaxR(200.); @@ -272,8 +275,6 @@ struct LFStrangeTreeCreator { fitter.setMaxChi2(1e9); fitter.setUseAbsDCA(true); fitter.setWeightedFinalPCA(false); - int mat{static_cast(cfgMaterialCorrection)}; - fitter.setMatCorrType(static_cast(mat)); // event QA histos.add("QA/zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); From be9d88fe88040ea8435ed312ed638bbaf5d78a09 Mon Sep 17 00:00:00 2001 From: mherzer <96999709+mherzer28@users.noreply.github.com> Date: Mon, 9 Jun 2025 23:50:29 +0200 Subject: [PATCH 12/62] [PWGLF] added second option for mass calculation (#11459) Co-authored-by: ALICE Action Bot --- PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx | 47 ++++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx index a33295b6021..f00fc314870 100644 --- a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx @@ -35,6 +35,7 @@ #include "PWGLF/DataModel/LFParticleIdentification.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/Track.h" +#include "PWGLF/DataModel/pidTOFGeneric.h" #include namespace o2::aod @@ -113,7 +114,7 @@ static const std::vector particleCharge{1, 2}; static const std::vector particleChargeFactor{2.3, 2.55}; static const std::vector betheBlochParNames{ "p0", "p1", "p2", "p3", "p4", "resolution"}; -constexpr float betheBlochDefault[nParticles][nBetheParams]{ +constexpr float BetheBlochDefault[nParticles][nBetheParams]{ {0.248753, 3.58634, 0.0167065, 2.29194, 0.774344, 0.07}, // triton {0.0274556, 18.3054, 3.99987e-05, 3.17219, 11.1775, @@ -126,7 +127,8 @@ using TracksFull = soa::Join; + aod::TOFSignal, aod::TrackSelectionExtension, + o2::aod::EvTimeTOFFT0ForTrack>; class Particle { @@ -186,7 +188,7 @@ struct TrHeAnalysis { } evselOptions; Configurable cfgTPCPidMethod{"cfgTPCPidMethod", false, "Using own or built in bethe parametrization"}; // false for built in - + Configurable cfgMassMethod{"cfgMassMethod", 0, "0: Using built in 1: mass calculated with beta 2: mass calculated with the event time"}; // Set the multiplity event limits Configurable cfgLowMultCut{"cfgLowMultCut", 0.0f, "Accepted multiplicity percentage lower limit"}; Configurable cfgHighMultCut{"cfgHighMultCut", 100.0f, "Accepted multiplicity percentage higher limit"}; @@ -226,7 +228,7 @@ struct TrHeAnalysis { Configurable nsigmaTPCTr{"nsigmaTPCTr", 5.f, "Value of the Nsigma TPC cut for tritons"}; Configurable nsigmaTPCHe{"nsigmaTPCHe", 5.f, "Value of the Nsigma TPC cut for helium-3"}; } nsigmaTPCvar; - Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {BetheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; void init(o2::framework::InitContext&) { @@ -663,12 +665,14 @@ struct TrHeAnalysis { constexpr int NNumLayers = 8; constexpr int NBitsPerLayer = 4; constexpr int NBitMask = (1 << NBitsPerLayer) - 1; + int sum = 0, n = 0; for (int i = 0; i < NNumLayers; i++) { int clsSize = (track.itsClusterSizes() >> (NBitsPerLayer * i)) & NBitMask; sum += clsSize; - if (clsSize) + if (clsSize) { n++; + } } return n > 0 ? static_cast(sum) / n : 0.f; } @@ -681,13 +685,34 @@ struct TrHeAnalysis { return hePID ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); } template - float getMass(T const& track) + float getMass(const T& track) { - const float beta = track.beta(); - const float rigidity = getRigidity(track); - float gamma = 1 / std::sqrt(1 - beta * beta); - float mass = (rigidity / std::sqrt(gamma * gamma - 1)); - return mass; + if (cfgMassMethod == 0) { + return track.mass(); + } + if (cfgMassMethod == 1) { + const float beta = track.beta(); + const float rigidity = getRigidity(track); + float gamma = 1 / std::sqrt(1 - beta * beta); + float mass = (rigidity / std::sqrt(gamma * gamma - 1.f)); + return mass; + } + if (cfgMassMethod == 2) { + const float rigidity = getRigidity(track); + float tofStartTime = track.evTimeForTrack(); + float tofTime = track.tofSignal(); + constexpr float CInCmPs = 2.99792458e-2f; + float length = track.length(); + float time = tofTime - tofStartTime; + if (time > 0.f && length > 0.f) { + float beta = length / (CInCmPs * time); + float gamma = 1 / std::sqrt(1 - beta * beta); + float mass = rigidity / std::sqrt(gamma * gamma - 1.f); + return mass; + } + return -1.f; + } + return -1.f; } }; From e2c61506e02777015cfc8d8b3cc3b7006636faa4 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Tue, 10 Jun 2025 00:27:03 +0200 Subject: [PATCH 13/62] [PWGEM/Dilepton] update dimuon analyses (#11526) --- PWGEM/Dilepton/Core/DielectronCut.h | 16 +- PWGEM/Dilepton/Core/Dilepton.h | 6 + PWGEM/Dilepton/Core/DileptonMC.h | 6 + PWGEM/Dilepton/Core/DimuonCut.cxx | 16 ++ PWGEM/Dilepton/Core/DimuonCut.h | 25 +++ PWGEM/Dilepton/Core/SingleTrackQC.h | 14 ++ PWGEM/Dilepton/Core/SingleTrackQCMC.h | 12 ++ .../treeCreatorElectronMLDDA.cxx | 177 ++++++++++-------- PWGEM/Dilepton/Tasks/createResolutionMap.cxx | 27 ++- PWGEM/Dilepton/Utils/EMTrackUtilities.h | 26 ++- 10 files changed, 226 insertions(+), 99 deletions(-) diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index 9ad54af870c..eec8c0928b9 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -359,13 +359,13 @@ class DielectronCut : public TNamed { switch (cut) { case DielectronCuts::kTrackPtRange: - return track.pt() >= mMinTrackPt && track.pt() <= mMaxTrackPt; + return track.pt() > mMinTrackPt && track.pt() < mMaxTrackPt; case DielectronCuts::kTrackEtaRange: - return track.eta() >= mMinTrackEta && track.eta() <= mMaxTrackEta; + return track.eta() > mMinTrackEta && track.eta() < mMaxTrackEta; case DielectronCuts::kTrackPhiRange: - return track.phi() >= mMinTrackPhi && track.phi() <= mMaxTrackPhi; + return track.phi() > mMinTrackPhi && track.phi() < mMaxTrackPhi; case DielectronCuts::kTPCNCls: return track.tpcNClsFound() >= mMinNClustersTPC; @@ -374,10 +374,10 @@ class DielectronCut : public TNamed return track.tpcNClsCrossedRows() >= mMinNCrossedRowsTPC; case DielectronCuts::kTPCCrossedRowsOverNCls: - return track.tpcCrossedRowsOverFindableCls() >= mMinNCrossedRowsOverFindableClustersTPC; + return track.tpcCrossedRowsOverFindableCls() > mMinNCrossedRowsOverFindableClustersTPC; case DielectronCuts::kTPCFracSharedClusters: - return track.tpcFractionSharedCls() <= mMaxFracSharedClustersTPC; + return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; case DielectronCuts::kRelDiffPin: return mMinRelDiffPin < (track.tpcInnerParam() - track.p()) / track.p() && (track.tpcInnerParam() - track.p()) / track.p() < mMaxRelDiffPin; @@ -386,13 +386,13 @@ class DielectronCut : public TNamed return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; case DielectronCuts::kDCA3Dsigma: - return mMinDca3D <= dca3DinSigma(track) && dca3DinSigma(track) <= mMaxDca3D; // in sigma for single leg + return mMinDca3D < dca3DinSigma(track) && dca3DinSigma(track) < mMaxDca3D; // in sigma for single leg case DielectronCuts::kDCAxy: - return std::fabs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); + return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); case DielectronCuts::kDCAz: - return std::fabs(track.dcaZ()) <= mMaxDcaZ; + return std::fabs(track.dcaZ()) < mMaxDcaZ; case DielectronCuts::kITSNCls: return mMinNClustersITS <= track.itsNCls() && track.itsNCls() <= mMaxNClustersITS; diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index 95bd4a0b6f8..46cecc81c87 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -281,6 +281,10 @@ struct Dilepton { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -749,6 +753,8 @@ struct Dilepton { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); } template diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 769c6b72ec3..00cec907de5 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -273,6 +273,10 @@ struct DileptonMC { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -715,6 +719,8 @@ struct DileptonMC { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); } template diff --git a/PWGEM/Dilepton/Core/DimuonCut.cxx b/PWGEM/Dilepton/Core/DimuonCut.cxx index ee18a8e4232..5ee3bf3d3bd 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.cxx +++ b/PWGEM/Dilepton/Core/DimuonCut.cxx @@ -119,3 +119,19 @@ void DimuonCut::SetMaxPDCARabsDep(std::function RabsDepCut) mMaxPDCARabsDep = RabsDepCut; LOG(info) << "Dimuon Cut, set max pDCA as a function of Rabs: " << mMaxPDCARabsDep(10.0); } +void DimuonCut::SetMFTHitMap(std::vector hitMap) +{ + mRequiredMFTDisks = hitMap; + for (const auto& iDisk : mRequiredMFTDisks) { + LOG(info) << "Dimuon Cut, require MFT hit on Disk: " << iDisk; + } +} +void DimuonCut::SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax) +{ + mMaxReldPtwrtMCHMID = reldPtMax; + mMaxdEtawrtMCHMID = dEtaMax; + mMaxdPhiwrtMCHMID = dPhiMax; + LOG(info) << "Dimuon Cut, set max rel. dpt between MFT-MCH-MID and associated MCH-MID: " << mMaxReldPtwrtMCHMID; + LOG(info) << "Dimuon Cut, set max deta between MFT-MCH-MID and associated MCH-MID: " << mMaxdEtawrtMCHMID; + LOG(info) << "Dimuon Cut, set max dphi between MFT-MCH-MID and associated MCH-MID: " << mMaxdPhiwrtMCHMID; +} diff --git a/PWGEM/Dilepton/Core/DimuonCut.h b/PWGEM/Dilepton/Core/DimuonCut.h index 4bb854c6b73..34d8364f65b 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.h +++ b/PWGEM/Dilepton/Core/DimuonCut.h @@ -59,6 +59,8 @@ class DimuonCut : public TNamed kMatchingChi2MCHMID, kRabs, kPDCA, + kMFTHitMap, + kDPtDEtaDPhiwrtMCHMID, kNCuts }; @@ -154,6 +156,12 @@ class DimuonCut : public TNamed if (!IsSelectedTrack(track, DimuonCuts::kRabs)) { return false; } + if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kMFTHitMap)) { + return false; + } + if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kDPtDEtaDPhiwrtMCHMID)) { + return false; + } return true; } @@ -198,6 +206,19 @@ class DimuonCut : public TNamed case DimuonCuts::kRabs: return mMinRabs < track.rAtAbsorberEnd() && track.rAtAbsorberEnd() < mMaxRabs; + case DimuonCuts::kMFTHitMap: { + std::vector mftHitMap{checkMFTHitMap<0, 1>(track), checkMFTHitMap<2, 3>(track), checkMFTHitMap<4, 5>(track), checkMFTHitMap<6, 7>(track), checkMFTHitMap<8, 9>(track)}; + for (const auto& iDisk : mRequiredMFTDisks) { + if (!mftHitMap[iDisk]) { + return false; + } + } + return true; + } + + case DimuonCuts::kDPtDEtaDPhiwrtMCHMID: + return std::fabs(track.ptMatchedMCHMID() - track.pt()) / track.pt() < mMaxReldPtwrtMCHMID && std::sqrt(std::pow((track.etaMatchedMCHMID() - track.eta()) / mMaxdEtawrtMCHMID, 2) + std::pow((track.phiMatchedMCHMID() - track.phi()) / mMaxdPhiwrtMCHMID, 2)) < 1.f; + default: return false; } @@ -222,6 +243,8 @@ class DimuonCut : public TNamed void SetDCAxy(float min, float max); // in cm void SetRabs(float min, float max); // in cm void SetMaxPDCARabsDep(std::function RabsDepCut); + void SetMFTHitMap(std::vector hitMap); + void SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax); // this is relevant for global muons private: // pair cuts @@ -249,6 +272,8 @@ class DimuonCut : public TNamed float mMinRabs{17.6}, mMaxRabs{89.5}; float mMinDcaXY{0.0f}, mMaxDcaXY{1e10f}; + float mMaxReldPtwrtMCHMID{1e10f}, mMaxdEtawrtMCHMID{1e10f}, mMaxdPhiwrtMCHMID{1e10f}; + std::vector mRequiredMFTDisks{}; ClassDef(DimuonCut, 1); }; diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index f5f8be20518..2fc94a8a91c 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -201,6 +201,10 @@ struct SingleTrackQC { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -282,6 +286,7 @@ struct SingleTrackQC { // track info fRegistry.add("Track/positive/hs", "rec. single muon", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca}, true); fRegistry.add("Track/positive/hEtaPhi_MatchMCHMID", "#eta vs. #varphi of matched MCHMID", kTH2F, {{180, 0, 2.f * M_PI}, {100, -6, -1}}, false); + fRegistry.add("Track/positive/hdEtadPhi", "#Delta#eta vs. #Delta#varphi between MFT-MCH-MID and MCH-MID;#varphi_{sa} - #varphi_{gl} (rad.);#eta_{sa} - #eta_{gl}", kTH2F, {{90, -M_PI / 4, M_PI / 4}, {100, -0.5, +0.5}}, false); fRegistry.add("Track/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); fRegistry.add("Track/positive/hTrackType", "track type", kTH1F, {{6, -0.5f, 5.5}}, false); fRegistry.add("Track/positive/hDCAxy", "DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)", kTH2F, {{200, -0.5f, 0.5f}, {200, -0.5f, 0.5f}}, false); @@ -452,6 +457,8 @@ struct SingleTrackQC { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); } template @@ -560,9 +567,15 @@ struct SingleTrackQC { weight = map_weight[track.globalIndex()]; } float dca_xy = fwdDcaXYinSigma(track); + + float deta = track.etaMatchedMCHMID() - track.eta(); + float dphi = track.phiMatchedMCHMID() - track.phi(); + o2::math_utils::bringToPMPi(dphi); + if (track.sign() > 0) { fRegistry.fill(HIST("Track/positive/hs"), track.pt(), track.eta(), track.phi(), dca_xy, weight); fRegistry.fill(HIST("Track/positive/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/positive/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/positive/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/positive/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/positive/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); @@ -580,6 +593,7 @@ struct SingleTrackQC { } else { fRegistry.fill(HIST("Track/negative/hs"), track.pt(), track.eta(), track.phi(), dca_xy, weight); fRegistry.fill(HIST("Track/negative/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/negative/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/negative/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/negative/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/negative/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index f400b617f1f..481bb2e9e5e 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -207,6 +207,10 @@ struct SingleTrackQCMC { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -339,6 +343,7 @@ struct SingleTrackQCMC { fRegistry.add("Track/lf/positive/hs", "rec. single muon", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca, axis_charge_gen}, true); if (cfgFillQA) { fRegistry.add("Track/lf/positive/hEtaPhi_MatchMCHMID", "#eta vs. #varphi of matched MCHMID", kTH2F, {{180, 0, 2.f * M_PI}, {100, -6, -1}}, false); + fRegistry.add("Track/lf/positive/hdEtadPhi", "#Delta#eta vs. #Delta#varphi between MFT-MCH-MID and MCH-MID;#varphi_{sa} - #varphi_{gl} (rad.);#eta_{sa} - #eta_{gl}", kTH2F, {{90, -M_PI / 4, M_PI / 4}, {100, -0.5, +0.5}}, false); fRegistry.add("Track/lf/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); fRegistry.add("Track/lf/positive/hTrackType", "track type", kTH1F, {{6, -0.5f, 5.5}}, false); fRegistry.add("Track/lf/positive/hDCAxy", "DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)", kTH2F, {{200, -0.5f, 0.5f}, {200, -0.5f, 0.5f}}, false); @@ -511,6 +516,8 @@ struct SingleTrackQCMC { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); } template @@ -670,6 +677,9 @@ struct SingleTrackQCMC { { auto mctrack = track.template emmcparticle_as(); float dca_xy = fwdDcaXYinSigma(track); + float deta = track.etaMatchedMCHMID() - track.eta(); + float dphi = track.phiMatchedMCHMID() - track.phi(); + o2::math_utils::bringToPMPi(dphi); float weight = 1.f; if (cfgApplyWeightTTCA) { @@ -681,6 +691,7 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hs"), track.pt(), track.eta(), track.phi(), dca_xy, -mctrack.pdgCode() / pdg_lepton, weight); if (cfgFillQA) { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); @@ -703,6 +714,7 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hs"), track.pt(), track.eta(), track.phi(), dca_xy, -mctrack.pdgCode() / pdg_lepton, weight); if (cfgFillQA) { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx index a24b62374f8..a0c7b6362f7 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx @@ -54,7 +54,7 @@ using namespace o2::constants::physics; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; @@ -77,19 +77,18 @@ struct TreeCreatorElectronMLDDA { {"V0/hMassK0Short", "V0 mass K0S", {HistType::kTH1F, {{200, 0.4, 0.6}}}}, {"V0/hMassLambda", "V0 mass Lambda", {HistType::kTH1F, {{100, 1.08, 1.18}}}}, {"V0/hMassAntiLambda", "V0 mass AntiLambda", {HistType::kTH1F, {{100, 1.08, 1.18}}}}, - {"hMvsPhiV", "mee vs. phiv", {HistType::kTH2F, {{72, 0, M_PI}, {100, 0, 0.1}}}}, - - {"V0/hTPCdEdx_P_El", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Mu", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Pi", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Ka", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Pr", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - - {"V0/hTOFbeta_P_El", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Mu", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Pi", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Ka", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Pr", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", {HistType::kTH2F, {{90, 0, M_PI}, {100, 0, 0.1}}}}, + + {"V0/hTPCdEdx_P_El", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Mu", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Pi", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Ka", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Pr", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTOFbeta_P_El", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Mu", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Pi", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Ka", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Pr", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, {"Cascade/hRxy_Xi", "R_{xy} of cascade vs. mass;m_{#Lambda#pi};R_{xy} (cm)", {HistType::kTH2F, {{200, 1.2, 1.4}, {200, 0, 20.f}}}}, {"Cascade/hRxy_Omega", "R_{xy} of cascade vs. mass;m_{#LambdaK};R_{xy} (cm)", {HistType::kTH2F, {{200, 1.6, 1.8}, {200, 0, 20.f}}}}, @@ -103,9 +102,7 @@ struct TreeCreatorElectronMLDDA { {"Cascade/hMassXi", "cascade mass #Xi", {HistType::kTH1F, {{200, 1.2, 1.4}}}}, {"Cascade/hMassOmega", "cascade mass #Omega", {HistType::kTH1F, {{200, 1.6, 1.8}}}}, {"Cascade/hMassPt_Xi", "cascade mass #Xi^{#pm};m_{#Lambda#pi} (GeV/c^{2});p_{T,#Lambda#pi} (GeV/c)", {HistType::kTH2F, {{200, 1.2, 1.4}, {100, 0, 10}}}}, - {"Cascade/hMassPt_Xi_bachelor", "cascade mass #Xi^{#pm};m_{#Lambda#pi} (GeV/c^{2});p_{T,#pi} (GeV/c)", {HistType::kTH2F, {{200, 1.2, 1.4}, {100, 0, 10}}}}, {"Cascade/hMassPt_Omega", "cascade mass #Omega^{#pm};m_{#LambdaK} (GeV/c^{2});p_{T,#LambdaK} (GeV/c)", {HistType::kTH2F, {{200, 1.6, 1.8}, {100, 0, 10}}}}, - {"Cascade/hMassPt_Omega_bachelor", "cascade mass #Omega^{#pm};m_{#LambdaK} (GeV/c^{2});p_{T,K} (GeV/c)", {HistType::kTH2F, {{200, 1.6, 1.8}, {100, 0, 10}}}}, }, }; @@ -386,15 +383,15 @@ struct TreeCreatorElectronMLDDA { } mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(track.pidForTracking()); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(track.pidForTracking()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); - if (std::fabs(track_par_cov_recalc.getEta()) > trackcuts.cfg_max_eta || track_par_cov_recalc.getPt() < trackcuts.cfg_min_pt) { + if (std::fabs(trackParCov.getEta()) > trackcuts.cfg_max_eta || trackParCov.getPt() < trackcuts.cfg_min_pt) { return false; } @@ -442,15 +439,15 @@ struct TreeCreatorElectronMLDDA { } mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(track.pidForTracking()); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(track.pidForTracking()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); // float dcaZ = mDcaInfoCov.getZ(); - if (std::fabs(track_par_cov_recalc.getEta()) > v0cuts.cfg_max_eta || track_par_cov_recalc.getPt() < v0cuts.cfg_min_pt) { + if (std::fabs(trackParCov.getEta()) > v0cuts.cfg_max_eta || trackParCov.getPt() < v0cuts.cfg_min_pt) { return false; } @@ -526,17 +523,17 @@ struct TreeCreatorElectronMLDDA { if (std::find(stored_trackIds.begin(), stored_trackIds.end(), track.globalIndex()) == stored_trackIds.end()) { mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(track.pidForTracking()); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(track.pidForTracking()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); emprimarytracks(collision.globalIndex(), collision.posZ(), collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange(), - track.pt(), track.eta(), track.phi(), track.tgl(), track.signed1Pt(), - dcaXY, dcaZ, track_par_cov_recalc.getSigmaY2(), track_par_cov_recalc.getSigmaZ2(), track_par_cov_recalc.getSigmaZY(), + trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi() > 0.f ? trackParCov.getPhi() : trackParCov.getPhi() + 2 * M_PI, trackParCov.getTgl(), trackParCov.getQ2Pt(), + dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY(), track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaMu(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), @@ -582,33 +579,32 @@ struct TreeCreatorElectronMLDDA { for (const auto& v0 : v0s_coll) { auto pos = v0.template posTrack_as(); auto neg = v0.template negTrack_as(); - if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg)) { + // LOGF(info, "v0.globalIndex() = %d, v0.collisionId() = %d, v0.posTrackId() = %d, v0.negTrackId() = %d", v0.globalIndex(), v0.collisionId(), v0.posTrackId(), v0.negTrackId()); + + if (v0.dcaV0daughters() > v0cuts.cfg_max_dcadau) { + continue; + } + if (v0.v0cosPA() < v0cuts.cfg_min_cospa) { continue; } if (pos.sign() * neg.sign() > 0) { continue; } - - // LOGF(info, "v0.globalIndex() = %d, v0.collisionId() = %d, v0.posTrackId() = %d, v0.negTrackId() = %d", v0.globalIndex(), v0.collisionId(), v0.posTrackId(), v0.negTrackId()); + if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg)) { + continue; + } registry.fill(HIST("V0/hPCA"), v0.dcaV0daughters()); registry.fill(HIST("V0/hCosPA"), v0.v0cosPA()); registry.fill(HIST("V0/hAP"), v0.alpha(), v0.qtarm()); - if (v0.dcaV0daughters() > v0cuts.cfg_max_dcadau) { - continue; - } - if (v0.v0cosPA() < v0cuts.cfg_min_cospa) { - continue; - } - if (isPion(pos) && isPion(neg)) { registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.p(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.p(), neg.beta()); - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.p(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.p(), pos.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.tpcInnerParam(), neg.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.tpcInnerParam(), pos.beta()); if (dist01(engine) < downscaling_pion || pos.tpcInnerParam() > max_pin_for_downscaling_pion) { fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::PID_Label::kPion), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } @@ -623,8 +619,8 @@ struct TreeCreatorElectronMLDDA { if (dist01(engine) < downscaling_proton || pos.tpcInnerParam() > max_pin_for_downscaling_proton) { fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::PID_Label::kProton), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } - registry.fill(HIST("V0/hTPCdEdx_P_Pr"), pos.p(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pr"), pos.p(), pos.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pr"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pr"), pos.tpcInnerParam(), pos.beta()); } } if (isPionTight(pos) && isProton(neg)) { @@ -633,14 +629,14 @@ struct TreeCreatorElectronMLDDA { if (dist01(engine) < downscaling_proton || neg.tpcInnerParam() > max_pin_for_downscaling_proton) { fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::PID_Label::kProton), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } - registry.fill(HIST("V0/hTPCdEdx_P_Pr"), neg.p(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pr"), neg.p(), neg.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pr"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pr"), neg.tpcInnerParam(), neg.beta()); } } - registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); - registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); - registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); if (isElectron(pos) && isElectron(neg)) { + registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); + registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); + registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); if ((v0cuts.cfg_min_mass_photon < v0.mGamma() && v0.mGamma() < v0cuts.cfg_max_mass_photon)) { if (dist01(engine) < downscaling_electron || pos.tpcInnerParam() > max_pin_for_downscaling_electron) { fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::PID_Label::kElectron), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); @@ -648,10 +644,10 @@ struct TreeCreatorElectronMLDDA { if (dist01(engine) < downscaling_electron || neg.tpcInnerParam() > max_pin_for_downscaling_electron) { fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::PID_Label::kElectron), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } - registry.fill(HIST("V0/hTPCdEdx_P_El"), neg.p(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_El"), neg.p(), neg.beta()); - registry.fill(HIST("V0/hTPCdEdx_P_El"), pos.p(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_El"), pos.p(), pos.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_El"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_El"), neg.tpcInnerParam(), neg.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_El"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_El"), pos.tpcInnerParam(), pos.beta()); } } } // end of v0 loop @@ -662,10 +658,6 @@ struct TreeCreatorElectronMLDDA { auto bachelor = cascade.template bachelor_as(); auto pos = cascade.template posTrack_as(); auto neg = cascade.template negTrack_as(); - if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg) || !isSelectedV0Leg(collision, bachelor)) { - continue; - } - if (pos.sign() * neg.sign() > 0) { continue; } @@ -680,7 +672,6 @@ struct TreeCreatorElectronMLDDA { } } - registry.fill(HIST("Cascade/hMassLambda"), cascade.mLambda()); if (!(v0cuts.cfg_min_mass_lambda < cascade.mLambda() && cascade.mLambda() < v0cuts.cfg_max_mass_lambda)) { continue; } @@ -689,11 +680,6 @@ struct TreeCreatorElectronMLDDA { continue; } - registry.fill(HIST("Cascade/hV0PCA"), cascade.dcaV0daughters()); - registry.fill(HIST("Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("Cascade/hPCA"), cascade.dcacascdaughters()); // distance between bachelor and V0. - registry.fill(HIST("Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); - if (cascade.dcaV0daughters() > cascadecuts.cfg_max_dcadau_v0) { continue; } @@ -715,6 +701,16 @@ struct TreeCreatorElectronMLDDA { continue; } + if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg) || !isSelectedV0Leg(collision, bachelor)) { + continue; + } + + registry.fill(HIST("Cascade/hMassLambda"), cascade.mLambda()); + registry.fill(HIST("Cascade/hV0PCA"), cascade.dcaV0daughters()); + registry.fill(HIST("Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + registry.fill(HIST("Cascade/hPCA"), cascade.dcacascdaughters()); // distance between bachelor and V0. + registry.fill(HIST("Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + float length = std::sqrt(std::pow(cascade.x() - collision.posX(), 2) + std::pow(cascade.y() - collision.posY(), 2) + std::pow(cascade.z() - collision.posZ(), 2)); float mom = cascade.p(); float ctauXi = length / mom * o2::constants::physics::MassXiMinus; // 4.91 cm in PDG @@ -723,19 +719,17 @@ struct TreeCreatorElectronMLDDA { if (isPion(bachelor)) { registry.fill(HIST("Cascade/hMassXi"), cascade.mXi()); registry.fill(HIST("Cascade/hMassPt_Xi"), cascade.mXi(), cascade.pt()); - registry.fill(HIST("Cascade/hMassPt_Xi_bachelor"), cascade.mXi(), bachelor.p()); registry.fill(HIST("Cascade/hRxy_Xi"), cascade.mXi(), cascade.cascradius()); registry.fill(HIST("Cascade/hCTau_Xi"), cascade.mXi(), ctauXi); } if (!(cascadecuts.cfg_min_mass_Xi < cascade.mXi() && cascade.mXi() < cascadecuts.cfg_max_mass_Xi) && isKaon(bachelor)) { // reject Xi candidates registry.fill(HIST("Cascade/hMassOmega"), cascade.mOmega()); registry.fill(HIST("Cascade/hMassPt_Omega"), cascade.mOmega(), cascade.pt()); - registry.fill(HIST("Cascade/hMassPt_Omega_bachelor"), cascade.mOmega(), bachelor.p()); registry.fill(HIST("Cascade/hRxy_Omega"), cascade.mOmega(), cascade.cascradius()); registry.fill(HIST("Cascade/hCTau_Omega"), cascade.mOmega(), ctauOmega); if (cascadecuts.cfg_min_mass_Omega < cascade.mOmega() && cascade.mOmega() < cascadecuts.cfg_max_mass_Omega) { // select Omega candidates - registry.fill(HIST("V0/hTPCdEdx_P_Ka"), bachelor.p(), bachelor.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Ka"), bachelor.p(), bachelor.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Ka"), bachelor.tpcInnerParam(), bachelor.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Ka"), bachelor.tpcInnerParam(), bachelor.beta()); if (dist01(engine) < downscaling_kaon || bachelor.tpcInnerParam() > max_pin_for_downscaling_kaon) { fillTrackTable(collision, bachelor, static_cast(o2::aod::pwgem::dilepton::PID_Label::kKaon), static_cast(o2::aod::pwgem::dilepton::Track_Type::kPrimary), false); } @@ -743,21 +737,38 @@ struct TreeCreatorElectronMLDDA { } } // end of cascade loop + std::array ppos{0, 0, 0}; + std::array pneg{0, 0, 0}; + // for electron sample for validation auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); for (const auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { - if (!isSelectedTrack(collision, pos) || !isSelectedTrack(collision, neg)) { + if (!isElectron(pos) || !isElectron(neg)) { continue; } - if (!isElectron(pos) || !isElectron(neg)) { + if (!isSelectedTrack(collision, pos) || !isSelectedTrack(collision, neg)) { continue; } - ROOT::Math::PtEtaPhiMVector v1(neg.pt(), neg.eta(), neg.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); + auto posParCov = getTrackParCov(pos); + posParCov.setPID(pos.pidForTracking()); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, posParCov, 2.f, matCorr, &mDcaInfoCov); + getPxPyPz(posParCov, ppos); + + auto negParCov = getTrackParCov(neg); + negParCov.setPID(pos.pidForTracking()); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, negParCov, 2.f, matCorr, &mDcaInfoCov); + getPxPyPz(negParCov, pneg); + + ROOT::Math::PtEtaPhiMVector v1(negParCov.getPt(), negParCov.getEta(), negParCov.getPhi() > 0.f ? negParCov.getPhi() : negParCov.getPhi() + 2 * M_PI, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(posParCov.getPt(), posParCov.getEta(), posParCov.getPhi() > 0.f ? posParCov.getPhi() : posParCov.getPhi() + 2 * M_PI, o2::constants::physics::MassElectron); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), neg.px(), neg.py(), neg.pz(), pos.sign(), neg.sign(), d_bz); + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(ppos[0], ppos[1], ppos[2], pneg[0], pneg[1], pneg[2], pos.sign(), neg.sign(), d_bz); registry.fill(HIST("hMvsPhiV"), phiv, v12.M()); if ((dalitzcuts.cfg_min_mass_ee < v12.M() && v12.M() < dalitzcuts.cfg_max_mass_ee) && (dalitzcuts.cfg_min_phiv_ee < phiv && phiv < dalitzcuts.cfg_max_phiv_ee)) { // ee from pi0 dalitz decay is found. @@ -793,19 +804,19 @@ struct MLTrackQC { { {"hTPCdEdx_P_All", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_All", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_All", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_All", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Electron", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Electron", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Electron", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Electron", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Pion", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Pion", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Pion", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Pion", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Kaon", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Kaon", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Kaon", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Kaon", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Proton", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Proton", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Proton", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Proton", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCNsigmaEl_P", "TPC n#sigma_{e} vs. p;p^{ITS-TPC} (GeV/c);n #sigma_{e}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, {"hTPCNsigmaPi_P", "TPC n#sigma_{#pi} vs. p;p^{ITS-TPC} (GeV/c);n #sigma_{#pi}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, @@ -823,29 +834,29 @@ struct MLTrackQC { for (const auto& track : tracks) { registry.fill(HIST("hTPCdEdx_P_All"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_All"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_All"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_All"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kElectron)) { registry.fill(HIST("hTPCdEdx_P_Electron"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Electron"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Electron"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Electron"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaEl_P"), track.p(), track.tpcNSigmaEl()); registry.fill(HIST("hTOFNsigmaEl_P"), track.p(), track.tofNSigmaEl()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kPion)) { registry.fill(HIST("hTPCdEdx_P_Pion"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Pion"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Pion"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Pion"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaPi_P"), track.p(), track.tpcNSigmaPi()); registry.fill(HIST("hTOFNsigmaPi_P"), track.p(), track.tofNSigmaPi()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kKaon)) { registry.fill(HIST("hTPCdEdx_P_Kaon"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Kaon"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Kaon"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Kaon"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaKa_P"), track.p(), track.tpcNSigmaKa()); registry.fill(HIST("hTOFNsigmaKa_P"), track.p(), track.tofNSigmaKa()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kProton)) { registry.fill(HIST("hTPCdEdx_P_Proton"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Proton"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Proton"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Proton"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaPr_P"), track.p(), track.tpcNSigmaPr()); registry.fill(HIST("hTOFNsigmaPr_P"), track.p(), track.tofNSigmaPr()); } diff --git a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx index c6c056b5dcb..8ae6b3e563f 100644 --- a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx +++ b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx @@ -157,12 +157,12 @@ struct CreateResolutionMap { Configurable cfg_mid_rabs{"cfg_mid_rabs", 26.5, "middle R at absorber end for pDCA cut"}; Configurable cfg_max_pdca_forLargeR{"cfg_max_pdca_forLargeR", 324.f, "max. pDCA for large R at absorber end"}; Configurable cfg_max_pdca_forSmallR{"cfg_max_pdca_forSmallR", 594.f, "max. pDCA for small R at absorber end"}; - Configurable cfg_min_nclusters_MFT{"cfg_min_nclusters_MFT", 5, "min nclusters MFT"}; - Configurable cfg_min_nclusters_MCH{"min_min_nclusters_MCH", 5, "min nclusters MCH"}; Configurable cfg_max_reldpt{"cfg_max_reldpt", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_deta{"cfg_max_deta", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_dphi{"cfg_max_dphi", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; Configurable refitGlobalMuon{"refitGlobalMuon", true, "flag to refit global muon"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to require MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{4}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } muoncuts; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -583,6 +583,15 @@ struct CreateResolutionMap { return; } + if (muoncuts.requireMFTHitMap) { + std::vector hasMFTs{hasMFT<0, 1>(mfttrack), hasMFT<2, 3>(mfttrack), hasMFT<4, 5>(mfttrack), hasMFT<6, 7>(mfttrack), hasMFT<8, 9>(mfttrack)}; + for (int i = 0; i < static_cast(muoncuts.requiredMFTDisks->size()); i++) { + if (!hasMFTs[muoncuts.requiredMFTDisks->at(i)]) { + return; + } + } + } + } else if (muon.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { o2::dataformats::GlobalFwdTrack propmuonAtRabs = propagateMuon(muon, collision, propagationPoint::kToRabs); // this is necessary only for MuonStandaloneTrack float xAbs = propmuonAtRabs.getX(); @@ -680,6 +689,20 @@ struct CreateResolutionMap { return true; } + template + bool hasMFT(T const& track) + { + // logical-OR + uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags(); + uint16_t clmap = 0; + for (unsigned int layer = begin; layer <= end; layer++) { + if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) { + clmap |= (1 << layer); + } + } + return (clmap > 0); + } + SliceCache cache; Preslice perCollision_mid = o2::aod::track::collisionId; Preslice perCollision_fwd = o2::aod::fwdtrack::collisionId; diff --git a/PWGEM/Dilepton/Utils/EMTrackUtilities.h b/PWGEM/Dilepton/Utils/EMTrackUtilities.h index 6ac2275aee1..eb73226cd1e 100644 --- a/PWGEM/Dilepton/Utils/EMTrackUtilities.h +++ b/PWGEM/Dilepton/Utils/EMTrackUtilities.h @@ -65,12 +65,12 @@ float dcaZinSigma(T const& track) template float fwdDcaXYinSigma(T const& track) { - float cXX = track.cXXatDCA(); // in cm^2 - float cYY = track.cYYatDCA(); // in cm^2 - float cXY = track.cXYatDCA(); // in cm^2 - float dcaX = track.fwdDcaX(); // in cm - float dcaY = track.fwdDcaY(); // in cm - float det = cXX * cYY - cXY * cXY; // determinant + float cXX = track.cXXatDCA(); // in cm^2 + float cYY = track.cYYatDCA(); // in cm^2 + float cXY = track.cXYatDCA(); // in cm^2 + float dcaX = track.fwdDcaX(); // in cm + float dcaY = track.fwdDcaY(); // in cm + float det = cXX * cYY - cXY * cXY; // determinant if (det < 0) { return 999.f; @@ -88,6 +88,20 @@ float sigmaFwdDcaXY(T const& track) return dcaXY / fwdDcaXYinSigma(track); } //_______________________________________________________________________ +template +bool checkMFTHitMap(T const& track) +{ + // logical-OR + uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags(); + uint16_t clmap = 0; + for (unsigned int layer = begin; layer <= end; layer++) { + if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) { + clmap |= (1 << layer); + } + } + return (clmap > 0); +} +//_______________________________________________________________________ template bool isBestMatch(TTrack const& track, TCut const& cut, TTracks const& tracks) { From 8e8ed8de966887b673179bb12842e2fcb74c8c3f Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres <88360333+PaolaVT@users.noreply.github.com> Date: Mon, 9 Jun 2025 19:53:30 -0600 Subject: [PATCH 14/62] [PWGLF] Phi cut was added (#11527) --- PWGMM/UE/Tasks/dedxAnalysis.cxx | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/PWGMM/UE/Tasks/dedxAnalysis.cxx b/PWGMM/UE/Tasks/dedxAnalysis.cxx index 0336638dade..34999be4f7e 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -28,6 +28,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "ReconstructionDataFormats/Track.h" #include "Common/Core/TrackSelectionDefaults.h" +#include "TF1.h" using namespace o2; using namespace o2::framework; @@ -58,6 +59,8 @@ struct DedxAnalysis { float pionTofCut = 1.0; float invMassCut = 0.01; float invMassCutGamma = 0.0015; + float magField = 1.0; + float pTcut = 2.0; // Configurable Parameters // Tracks cuts @@ -103,6 +106,10 @@ struct DedxAnalysis { Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; + // phi cut fits + TF1* fphiCutHigh = nullptr; + TF1* fphiCutLow = nullptr; + TrackSelection myTrackSelection() { TrackSelection selectedTracks; @@ -130,6 +137,8 @@ struct DedxAnalysis { AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; + fphiCutLow = new TF1("StandardPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 50); if (calibrationMode) { // MIP for pions registryDeDx.add( @@ -202,6 +211,11 @@ struct DedxAnalysis { "hdEdx_vs_phi", "dE/dx", HistType::kTH2F, {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); + // phi cut + registryDeDx.add( + "hpt_vs_phi", "phi cut", HistType::kTH2F, + {{ptAxis}, {100, 0.0, 6.4, "#phi"}}); + registryDeDx.add( "hbeta_vs_p_Neg", "beta", HistType::kTH2F, {{pAxis}, {100, 0.0, 1.1, "#beta"}}); @@ -375,6 +389,33 @@ struct DedxAnalysis { return true; } + // Phi cut + template + bool passedPhiCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + { + float pt = trk.pt(); + float phi = trk.phi(); + int charge = trk.sign(); + + if (pt < pTcut) + return true; + + if (magField < 0.) // for negatve polarity field + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) // for negatve charge + phi = o2::constants::math::TwoPI - phi; + + // to center gap in the middle + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + return false; // reject track + + registryDeDx.fill(HIST("hpt_vs_phi"), pt, phi); + return true; + } + // Process Data void process(SelectedCollisions::iterator const& collision, aod::V0Datas const& fullV0s, PIDTracks const& tracks) @@ -410,6 +451,10 @@ struct DedxAnalysis { if (!mySelectionPrim.IsSelected(trk)) continue; + // phi cut + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + float signedP = trk.sign() * trk.tpcInnerParam(); // MIP calibration for pions From b716a3d7a6bb0e469ddf5474d8cdf59e562d81c3 Mon Sep 17 00:00:00 2001 From: Anantha Padmanabhan M Nair <82643666+ananthapadmanabhan18@users.noreply.github.com> Date: Tue, 10 Jun 2025 11:52:07 +0530 Subject: [PATCH 15/62] [PWGUD] Added the bc selection cuts for the new pass5 and renamed histograms (#11520) --- PWGUD/Tasks/exclusiveRhoTo4Pi.cxx | 394 ++++++++++++++++-------------- 1 file changed, 205 insertions(+), 189 deletions(-) diff --git a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx index 14ffcc415a4..ac0a9459569 100644 --- a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx +++ b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx @@ -519,8 +519,11 @@ struct ExclusiveRhoTo4Pi { Configurable fv0Cut{"fv0Cut", 50., "FV0A threshold"}; Configurable ft0aCut{"ft0aCut", 150., "FT0A threshold"}; Configurable ft0cCut{"ft0cCut", 50., "FT0C threshold"}; - Configurable zdcCut{"zdcCut", 1., "ZDC threshold"}; - // Configurable occupancyCut{"occupancyCut", 1000, "Occupancy Cut"}; + Configurable zdcCut{"zdcCut", 0., "ZDC threshold"}; + Configurable sbpCut{"sbpCut", 1, "Sbp"}; + Configurable itsROFbCut{"itsROFbCut", 1, "itsROFbCut"}; + Configurable vtxITSTPCcut{"vtxITSTPCcut", 1, "vtxITSTPCcut"}; + Configurable tfbCut{"tfbCut", 1, "tfbCut"}; Configurable pvCut{"pvCut", 1.0, "Use Only PV tracks"}; Configurable numPVContrib{"numPVContrib", 4, "Number of PV Contributors"}; @@ -563,66 +566,66 @@ struct ExclusiveRhoTo4Pi { histosData.add("tpcNClsFindable", "TPC N Cls Findable; N Cls Findable; Counts", kTH1F, {{200, 0, 200}}); // TPC nSigma - histosData.add("tpcNSigmaPi_WTS", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaPi_WTS_PID_Pi", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaPi_all", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaPi_pions", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TPC nSigma of other particles with selected pion tracks - histosData.add("tpcNSigmaKa_WTS_PID_Pi", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaPr_WTS_PID_Pi", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaEl_WTS_PID_Pi", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaMu_WTS_PID_Pi", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaKa_pions", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaPr_pions", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaEl_pions", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaMu_pions", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma - histosData.add("tofNSigmaPi_WTS", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaPi_WTS_PID_Pi", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaPi_all", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaPi_pions", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma of other particles with selected pion tracks - histosData.add("tofNSigmaKa_WTS_PID_Pi", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaPr_WTS_PID_Pi", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaEl_WTS_PID_Pi", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaMu_WTS_PID_Pi", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaKa_pions", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaPr_pions", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaEl_pions", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaMu_pions", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // Track Transverse Momentum - histosData.add("pT_track_WTS", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); - histosData.add("pT_track_WTS_PID_Pi", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); - histosData.add("pT_track_WTS_PID_Pi_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("pT_track_all", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("pT_track_pions", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("pT_track_pions_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Track Rapidity - histosData.add("rapidity_track_WTS", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_track_WTS_PID_Pi", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_track_WTS_PID_Pi_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("rapidity_track_all", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("rapidity_track_pions", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("rapidity_track_pions_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Zero charge Event Transverse Momentum - histosData.add("pT_event_0charge_WTS_PID_Pi", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("fourpion_pT_0_charge", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Non Zero charge Event Transverse Momentum - histosData.add("pT_event_non0charge_WTS_PID_Pi", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("fourpion_pT_non_0_charge", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Rapidity of 0 charge Events - histosData.add("rapidity_event_0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosData.add("rapidity_event_0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosData.add("rapidity_event_0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosData.add("fourpion_rap_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosData.add("fourpion_rap_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosData.add("fourpion_rap_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); // Rapidity of non 0 charge Events - histosData.add("rapidity_event_non0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_event_non0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_event_non0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("fourpion_rap_non_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("fourpion_rap_non_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("fourpion_rap_non_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Pair Invariant Mass - histosData.add("invMass_pair_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosData.add("invMass_pair_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosData.add("invMass_pair_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosData.add("invMass_pair_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); // Invariant Mass of 0 charge events - histosData.add("invMass_event_0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosData.add("invMass_event_0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosData.add("invMass_event_0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosData.add("fourpion_mass_0_charge_domA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosData.add("fourpion_mass_0_charge_domB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosData.add("fourpion_mass_0_charge_domC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // Invariant mass of non 0 charge events - histosData.add("invMass_event_non0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosData.add("invMass_event_non0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosData.add("invMass_event_non0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosData.add("fourpion_mass_non_0_charge_domA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosData.add("fourpion_mass_non_0_charge_domB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosData.add("fourpion_mass_non_0_charge_domC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // tpc signal histosData.add("tpcSignal", "TPC dEdx vs p; p [GeV/c]; dEdx [a.u.]", kTH2F, {{500, 0, 10}, {5000, 0.0, 5000.0}}); @@ -640,12 +643,12 @@ struct ExclusiveRhoTo4Pi { histosData.add("V0A", "V0A amplitude", kTH1F, {{1000, 0.0, 100}}); // Collin Soper Theta and Phi - histosData.add("CS_phi_pair_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosData.add("CS_phi_pair_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosData.add("CS_costheta_pair_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosData.add("CS_costheta_pair_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosData.add("phi_cosTheta_pair_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); - histosData.add("phi_cosTheta_pair_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosData.add("collin_soper_phi_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosData.add("collin_soper_phi_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosData.add("collin_soper_costheta_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosData.add("collin_soper_costheta_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosData.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosData.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); // MC Gen Stuff @@ -679,8 +682,8 @@ struct ExclusiveRhoTo4Pi { histosMCgen.add("fourPion_phi_pair_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); histosMCgen.add("fourPion_costheta_pair_1", "#theta Distribution;cos(#theta); Events", kTH1F, {{nBinsCosTheta, -1, 1}}); histosMCgen.add("fourPion_costheta_pair_2", "#theta Distribution;cos(#theta); Events", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosMCgen.add("phi_cosTheta_pair_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); - histosMCgen.add("phi_cosTheta_pair_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCgen.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCgen.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); // MC Reco Stuff @@ -697,66 +700,66 @@ struct ExclusiveRhoTo4Pi { histosMCreco.add("EventCounts", "Total Events; Events", kTH1F, {{10, 0, 10}}); // TPC nSigma - histosMCreco.add("tpcNSigmaPi_WTS", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaPi_WTS_PID_Pi", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaPi_all", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaPi_pions", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TPC nSigma of other particles with selected pion tracks - histosMCreco.add("tpcNSigmaKa_WTS_PID_Pi", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaPr_WTS_PID_Pi", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaEl_WTS_PID_Pi", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaMu_WTS_PID_Pi", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaKa_pions", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaPr_pions", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaEl_pions", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaMu_pions", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma - histosMCreco.add("tofNSigmaPi_WTS", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaPi_WTS_PID_Pi", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaPi_all", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaPi_pions", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma of other particles with selected pion tracks - histosMCreco.add("tofNSigmaKa_WTS_PID_Pi", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaPr_WTS_PID_Pi", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaEl_WTS_PID_Pi", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaMu_WTS_PID_Pi", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaKa_pions", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaPr_pions", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaEl_pions", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaMu_pions", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // Track Transverse Momentum - histosMCreco.add("pT_track_WTS", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); - histosMCreco.add("pT_track_WTS_PID_Pi", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); - histosMCreco.add("pT_track_WTS_PID_Pi_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("pT_track_all", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("pT_track_pions", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("pT_track_pions_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Track Rapidity - histosMCreco.add("rapidity_track_WTS", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_track_WTS_PID_Pi", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_track_WTS_PID_Pi_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("rapidity_track_all", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("rapidity_track_pions", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("rapidity_track_pions_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Zero charge Event Transverse Momentum - histosMCreco.add("pT_event_0charge_WTS_PID_Pi", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("fourpion_pT_0_charge", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Non Zero charge Event Transverse Momentum - histosMCreco.add("pT_event_non0charge_WTS_PID_Pi", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("fourpion_pT_non_0_charge", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Rapidity of 0 charge Events - histosMCreco.add("rapidity_event_0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); // Rapidity of non 0 charge Events - histosMCreco.add("rapidity_event_non0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_non0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_non0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_non_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_non_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_non_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Pair Invariant Mass - histosMCreco.add("invMass_pair_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosMCreco.add("invMass_pair_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosMCreco.add("invMass_pair_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosMCreco.add("invMass_pair_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); // Invariant Mass of 0 charge events - histosMCreco.add("invMass_event_0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosMCreco.add("invMass_event_0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosMCreco.add("invMass_event_0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosMCreco.add("fourpion_mass_0_charge_domA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosMCreco.add("fourpion_mass_0_charge_domB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosMCreco.add("fourpion_mass_0_charge_domC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // Invariant mass of non 0 charge events - histosMCreco.add("invMass_event_non0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosMCreco.add("invMass_event_non0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosMCreco.add("invMass_event_non0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosMCreco.add("fourpion_mass_non_0_charge_domA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosMCreco.add("fourpion_mass_non_0_charge_domB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosMCreco.add("fourpion_mass_non_0_charge_domC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // tpc signal histosMCreco.add("tpcSignal", "TPC dEdx vs p; p [GeV/c]; dEdx [a.u.]", kTH2F, {{500, 0, 10}, {5000, 0.0, 5000.0}}); @@ -774,12 +777,12 @@ struct ExclusiveRhoTo4Pi { histosMCreco.add("V0A", "V0A amplitude", kTH1F, {{1000, 0.0, 100}}); // Collin Soper Theta and Phi - histosMCreco.add("CS_phi_pair_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosMCreco.add("CS_phi_pair_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosMCreco.add("CS_costheta_pair_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosMCreco.add("CS_costheta_pair_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosMCreco.add("phi_cosTheta_pair_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); - histosMCreco.add("phi_cosTheta_pair_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCreco.add("collin_soper_phi_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosMCreco.add("collin_soper_phi_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosMCreco.add("collin_soper_costheta_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosMCreco.add("collin_soper_costheta_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosMCreco.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCreco.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); } // End of init function //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -845,7 +848,9 @@ struct ExclusiveRhoTo4Pi { Filter vertexCut = (nabs(o2::aod::collision::posZ) <= vZCut) && (o2::aod::collision::numContrib == numPVContrib); Filter fitcuts = o2::aod::udcollision::totalFV0AmplitudeA < fv0Cut && o2::aod::udcollision::totalFT0AmplitudeA < ft0aCut && o2::aod::udcollision::totalFT0AmplitudeC < ft0cCut; Filter zdcCuts = (o2::aod::udzdc::energyCommonZNA < zdcCut) && (o2::aod::udzdc::energyCommonZNC < zdcCut); - using UDtracks = soa::Join; + Filter bcSelectionCut = (o2::aod::udcollision::sbp == sbpCut) && (o2::aod::udcollision::itsROFb == itsROFbCut) && (o2::aod::udcollision::vtxITSTPC == vtxITSTPCcut) && (o2::aod::udcollision::tfb == tfbCut); + Filter onlyPVtracks = o2::aod::udtrack::isPVContributor == true; + using UDtracks = soa::Filtered>; using UDCollisions = soa::Filtered>; // using UDCollision = UDCollisions::iterator; //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -897,10 +902,10 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedTrackVector(selectedTracks[i].px(), selectedTracks[i].py(), selectedTracks[i].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("tpcSignal"), selectedTrackVector.P(), selectedTracks[i].tpcSignal()); histosData.fill(HIST("tofBeta"), selectedTrackVector.P(), selectedTracks[i].beta()); - histosData.fill(HIST("tpcNSigmaPi_WTS"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaPi_WTS"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); - histosData.fill(HIST("pT_track_WTS"), selectedTrackVector.Pt()); - histosData.fill(HIST("rapidity_track_WTS"), selectedTrackVector.Rapidity()); + histosData.fill(HIST("tpcNSigmaPi_all"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaPi_all"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); + histosData.fill(HIST("pT_track_all"), selectedTrackVector.Pt()); + histosData.fill(HIST("rapidity_track_all"), selectedTrackVector.Rapidity()); histosData.fill(HIST("itsChi2NCl"), selectedTracks[i].itsChi2NCl()); histosData.fill(HIST("tpcChi2NCl"), selectedTracks[i].tpcChi2NCl()); histosData.fill(HIST("tpcNClsFindable"), selectedTracks[i].tpcNClsFindable()); @@ -912,24 +917,26 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedPionTrackVector(selectedPionTracks[i].px(), selectedPionTracks[i].py(), selectedPionTracks[i].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("tpcSignal_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].tpcSignal()); histosData.fill(HIST("tofBeta_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].beta()); - histosData.fill(HIST("tpcNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi"), selectedPionTrackVector.Pt()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi"), selectedPionTrackVector.Rapidity()); + histosData.fill(HIST("tpcNSigmaPi_pions"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaKa_pions"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaPr_pions"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaEl_pions"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaMu_pions"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaPi_pions"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaKa_pions"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaPr_pions"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaEl_pions"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaMu_pions"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("pT_track_pions"), selectedPionTrackVector.Pt()); + histosData.fill(HIST("rapidity_track_pions"), selectedPionTrackVector.Rapidity()); } // End of loop over tracks with selection and PID selection of Pions if (numSelectedPionTracks != numFourPionTracks) { return; } + histosData.fill(HIST("EventCounts"), 2); + // Check if there is at least one track with TOF in the selected events, otherwise return bool hasAtleastOneTOF = false; for (int i = 0; i < numPiPlusTracks; i++) { @@ -941,10 +948,13 @@ struct ExclusiveRhoTo4Pi { if (!hasAtleastOneTOF) { return; } + histosData.fill(HIST("EventCounts"), 3); // Selecting Events with net charge = 0 if (numPionMinusTracks == numPiMinus && numPiPlusTracks == numPiPlus) { + histosData.fill(HIST("EventCounts"), 4); + ROOT::Math::PtEtaPhiMVector k1, k2, k3, k4, k1234, k13, k14, k23, k24; ROOT::Math::PxPyPzMVector p1(selectedPionPlusTracks[0].px(), selectedPionPlusTracks[0].py(), selectedPionPlusTracks[0].pz(), o2::constants::physics::MassPionCharged); @@ -952,15 +962,15 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p1.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p2.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p3.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p4.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p1.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p2.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p3.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p4.Pt()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p1.Rapidity()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p2.Rapidity()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p3.Rapidity()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p4.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p1.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p2.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p3.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p4.Rapidity()); k1.SetCoordinates(p1.Pt(), p1.Eta(), p1.Phi(), o2::constants::physics::MassPionCharged); k2.SetCoordinates(p2.Pt(), p2.Eta(), p2.Phi(), o2::constants::physics::MassPionCharged); @@ -1012,31 +1022,34 @@ struct ExclusiveRhoTo4Pi { fourPiPhiPair1, fourPiPhiPair2, fourPiCosThetaPair1, fourPiCosThetaPair2); if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosData.fill(HIST("pT_event_0charge_WTS_PID_Pi"), p1234.Pt()); + histosData.fill(HIST("fourpion_pT_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosData.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainA"), p1234.M()); - histosData.fill(HIST("invMass_pair_1"), (p1 + p3).M()); - histosData.fill(HIST("invMass_pair_2"), (p1 + p4).M()); - histosData.fill(HIST("invMass_pair_3"), (p2 + p3).M()); - histosData.fill(HIST("invMass_pair_4"), (p2 + p4).M()); + histosData.fill(HIST("EventCounts"), 5); + + histosData.fill(HIST("fourpion_rap_0_charge_domA"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_0_charge_domA"), p1234.M()); - histosData.fill(HIST("CS_phi_pair_1"), fourPiPhiPair1); - histosData.fill(HIST("CS_phi_pair_2"), fourPiPhiPair2); - histosData.fill(HIST("CS_costheta_pair_1"), fourPiCosThetaPair1); - histosData.fill(HIST("CS_costheta_pair_2"), fourPiCosThetaPair2); + histosData.fill(HIST("twopion_mass_1"), (p1 + p3).M()); + histosData.fill(HIST("twopion_mass_2"), (p1 + p4).M()); + histosData.fill(HIST("twopion_mass_3"), (p2 + p3).M()); + histosData.fill(HIST("twopion_mass_4"), (p2 + p4).M()); - histosData.fill(HIST("phi_cosTheta_pair_1"), fourPiPhiPair1, fourPiCosThetaPair1); - histosData.fill(HIST("phi_cosTheta_pair_2"), fourPiPhiPair2, fourPiCosThetaPair2); + histosData.fill(HIST("collin_soper_phi_1"), fourPiPhiPair1); + histosData.fill(HIST("collin_soper_phi_2"), fourPiPhiPair2); + histosData.fill(HIST("collin_soper_costheta_1"), fourPiCosThetaPair1); + histosData.fill(HIST("collin_soper_costheta_2"), fourPiCosThetaPair2); + + histosData.fill(HIST("phi_vs_costheta_1"), fourPiPhiPair1, fourPiCosThetaPair1); + histosData.fill(HIST("phi_vs_costheta_2"), fourPiPhiPair2, fourPiCosThetaPair2); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosData.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosData.fill(HIST("fourpion_rap_0_charge_domB"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosData.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosData.fill(HIST("fourpion_rap_0_charge_domC"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection @@ -1045,6 +1058,8 @@ struct ExclusiveRhoTo4Pi { // Selecting Events with net charge != 0 for estimation of background if (numPionMinusTracks != numPiMinus && numPiPlusTracks != numPiPlus) { + histosData.fill(HIST("EventCounts"), 6); + ROOT::Math::PxPyPzMVector p1(selectedPionTracks[0].px(), selectedPionTracks[0].py(), selectedPionTracks[0].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p2(selectedPionTracks[1].px(), selectedPionTracks[1].py(), selectedPionTracks[1].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p3(selectedPionTracks[2].px(), selectedPionTracks[2].py(), selectedPionTracks[2].pz(), o2::constants::physics::MassPionCharged); @@ -1074,19 +1089,20 @@ struct ExclusiveRhoTo4Pi { p1234.Pt(), p1234.Eta(), p1234.Phi(), p1234.Rapidity(), p1234.M()); if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosData.fill(HIST("pT_event_non0charge_WTS_PID_Pi"), p1234.Pt()); + histosData.fill(HIST("fourpion_pT_non_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosData.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainA"), p1234.M()); + histosData.fill(HIST("EventCounts"), 7); + histosData.fill(HIST("fourpion_rap_non_0_charge_domA"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_non_0_charge_domA"), p1234.M()); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosData.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosData.fill(HIST("fourpion_rap_non_0_charge_domB"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_non_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosData.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosData.fill(HIST("fourpion_rap_non_0_charge_domC"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_non_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection } // End of Analysis for non 0 charge events @@ -1186,8 +1202,8 @@ struct ExclusiveRhoTo4Pi { histosMCgen.fill(HIST("fourPion_phi_pair_2"), phiPair2); histosMCgen.fill(HIST("fourPion_costheta_pair_1"), cosThetaPair1); histosMCgen.fill(HIST("fourPion_costheta_pair_2"), cosThetaPair2); - histosMCgen.fill(HIST("phi_cosTheta_pair_1"), phiPair1, cosThetaPair1); - histosMCgen.fill(HIST("phi_cosTheta_pair_2"), phiPair2, cosThetaPair2); + histosMCgen.fill(HIST("phi_vs_costheta_1"), phiPair1, cosThetaPair1); + histosMCgen.fill(HIST("phi_vs_costheta_2"), phiPair2, cosThetaPair2); } // End of 4 Pion MC Generation Process function PROCESS_SWITCH(ExclusiveRhoTo4Pi, processMCgen, "The Process for 4 Pion Analysis from MC Generation", false); @@ -1247,10 +1263,10 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedTrackVector(selectedTracks[i].px(), selectedTracks[i].py(), selectedTracks[i].pz(), o2::constants::physics::MassPionCharged); histosMCreco.fill(HIST("tpcSignal"), selectedTrackVector.P(), selectedTracks[i].tpcSignal()); histosMCreco.fill(HIST("tofBeta"), selectedTrackVector.P(), selectedTracks[i].beta()); - histosMCreco.fill(HIST("tpcNSigmaPi_WTS"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaPi_WTS"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); - histosMCreco.fill(HIST("pT_track_WTS"), selectedTrackVector.Pt()); - histosMCreco.fill(HIST("rapidity_track_WTS"), selectedTrackVector.Rapidity()); + histosMCreco.fill(HIST("tpcNSigmaPi_all"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaPi_all"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); + histosMCreco.fill(HIST("pT_track_all"), selectedTrackVector.Pt()); + histosMCreco.fill(HIST("rapidity_track_all"), selectedTrackVector.Rapidity()); histosMCreco.fill(HIST("itsChi2NCl"), selectedTracks[i].itsChi2NCl()); histosMCreco.fill(HIST("tpcChi2NCl"), selectedTracks[i].tpcChi2NCl()); histosMCreco.fill(HIST("tpcNClsFindable"), selectedTracks[i].tpcNClsFindable()); @@ -1262,18 +1278,18 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedPionTrackVector(selectedPionTracks[i].px(), selectedPionTracks[i].py(), selectedPionTracks[i].pz(), o2::constants::physics::MassPionCharged); histosMCreco.fill(HIST("tpcSignal_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].tpcSignal()); histosMCreco.fill(HIST("tofBeta_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].beta()); - histosMCreco.fill(HIST("tpcNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi"), std::sqrt(selectedPionTracks[i].px() * selectedPionTracks[i].px() + selectedPionTracks[i].py() * selectedPionTracks[i].py())); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi"), selectedPionTrackVector.Rapidity()); + histosMCreco.fill(HIST("tpcNSigmaPi_pions"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaKa_pions"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaPr_pions"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaEl_pions"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaMu_pions"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaPi_pions"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaKa_pions"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaPr_pions"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaEl_pions"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaMu_pions"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("pT_track_pions"), std::sqrt(selectedPionTracks[i].px() * selectedPionTracks[i].px() + selectedPionTracks[i].py() * selectedPionTracks[i].py())); + histosMCreco.fill(HIST("rapidity_track_pions"), selectedPionTrackVector.Rapidity()); } // End of loop over tracks with selection and PID selection of Pions if (numSelectedPionTracks != numFourPionTracks) { @@ -1290,15 +1306,15 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p1.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p2.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p3.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p4.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p1.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p2.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p3.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p4.Pt()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p1.Rapidity()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p2.Rapidity()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p3.Rapidity()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p4.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p1.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p2.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p3.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p4.Rapidity()); k1.SetCoordinates(p1.Pt(), p1.Eta(), p1.Phi(), o2::constants::physics::MassPionCharged); k2.SetCoordinates(p2.Pt(), p2.Eta(), p2.Phi(), o2::constants::physics::MassPionCharged); @@ -1341,30 +1357,30 @@ struct ExclusiveRhoTo4Pi { phiPair1, phiPair2, cosThetaPair1, cosThetaPair2); if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosMCreco.fill(HIST("pT_event_0charge_WTS_PID_Pi"), p1234.Pt()); + histosMCreco.fill(HIST("fourpion_pT_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosMCreco.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainA"), p1234.M()); - - histosMCreco.fill(HIST("invMass_pair_1"), (p1 + p3).M()); - histosMCreco.fill(HIST("invMass_pair_2"), (p1 + p4).M()); - histosMCreco.fill(HIST("invMass_pair_3"), (p2 + p3).M()); - histosMCreco.fill(HIST("invMass_pair_4"), (p2 + p4).M()); - - histosMCreco.fill(HIST("CS_phi_pair_1"), phiPair1); - histosMCreco.fill(HIST("CS_phi_pair_2"), phiPair2); - histosMCreco.fill(HIST("CS_costheta_pair_1"), cosThetaPair1); - histosMCreco.fill(HIST("CS_costheta_pair_2"), cosThetaPair2); - histosMCreco.fill(HIST("phi_cosTheta_pair_1"), phiPair1, cosThetaPair1); - histosMCreco.fill(HIST("phi_cosTheta_pair_2"), phiPair2, cosThetaPair2); + histosMCreco.fill(HIST("fourpion_rap_0_charge_domA"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_0_charge_domA"), p1234.M()); + + histosMCreco.fill(HIST("twopion_mass_1"), (p1 + p3).M()); + histosMCreco.fill(HIST("twopion_mass_2"), (p1 + p4).M()); + histosMCreco.fill(HIST("twopion_mass_3"), (p2 + p3).M()); + histosMCreco.fill(HIST("twopion_mass_4"), (p2 + p4).M()); + + histosMCreco.fill(HIST("collin_soper_phi_1"), phiPair1); + histosMCreco.fill(HIST("collin_soper_phi_2"), phiPair2); + histosMCreco.fill(HIST("collin_soper_costheta_1"), cosThetaPair1); + histosMCreco.fill(HIST("collin_soper_costheta_2"), cosThetaPair2); + histosMCreco.fill(HIST("phi_vs_costheta_1"), phiPair1, cosThetaPair1); + histosMCreco.fill(HIST("phi_vs_costheta_2"), phiPair2, cosThetaPair2); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_0_charge_domB"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_0_charge_domC"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection @@ -1380,19 +1396,19 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector p1234 = p1 + p2 + p3 + p4; if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosMCreco.fill(HIST("pT_event_non0charge_WTS_PID_Pi"), p1234.Pt()); + histosMCreco.fill(HIST("fourpion_pT_non_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosMCreco.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainA"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_non_0_charge_domA"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_non_0_charge_domA"), p1234.M()); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_non_0_charge_domB"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_non_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_non_0_charge_domC"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_non_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection From 826d5673e9d8ad31d5b0f98ee209664bf306cb77 Mon Sep 17 00:00:00 2001 From: Shyam Kumar Date: Tue, 10 Jun 2025 09:14:46 +0200 Subject: [PATCH 16/62] [PWGHF] Selection of prompt and non-prompt scores within a defined range (#11510) --- PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx index 339ab91a27c..834bf4d217c 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx @@ -80,7 +80,8 @@ struct HfTaskCorrelationDplusHadrons { Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for D+"}; // 7 corresponds to topo+PID cuts Configurable selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing"}; Configurable> classMl{"classMl", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; - Configurable> mlScorePromptOrNonPrompt{"mlScorePromptOrNonPrompt", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt or Feed-down"}; + Configurable> mlScorePromptOrNonPromptMin{"mlScorePromptOrNonPromptMin", {0.5, 0.5, 0.5, 0.5}, "Minimum Machine learning scores for prompt or Feed-down"}; + Configurable> mlScorePromptOrNonPromptMax{"mlScorePromptOrNonPromptMax", {1.0, 1.0, 1.0, 1.0}, "Maximum Machine learning scores for prompt or Feed-down"}; Configurable> mlScoreBkg{"mlScoreBkg", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for bkg"}; // pT ranges for correlation plots: the default values are those embedded in hf_cuts_dplus_to_pi_k_pi (i.e. the mass pT bins), but can be redefined via json files Configurable> binsPtCorrelations{"binsPtCorrelations", std::vector{ptBinsCorrelationsVec}, "pT bin limits for correlation plots"}; @@ -315,7 +316,7 @@ struct HfTaskCorrelationDplusHadrons { continue; } - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } double efficiencyWeightD = 1.; @@ -354,7 +355,7 @@ struct HfTaskCorrelationDplusHadrons { continue; } - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { @@ -417,7 +418,7 @@ struct HfTaskCorrelationDplusHadrons { if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) continue; - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } double efficiencyWeightD = 1.; @@ -471,7 +472,7 @@ struct HfTaskCorrelationDplusHadrons { if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) continue; - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { @@ -628,7 +629,7 @@ struct HfTaskCorrelationDplusHadrons { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } - if (outputMl[0] > mlScoreBkg->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] < mlScorePromptOrNonPrompt->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt()))) { + if (outputMl[0] > mlScoreBkg->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] < mlScorePromptOrNonPromptMin->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] > mlScorePromptOrNonPromptMax->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt()))) { continue; } auto collision = candidate.template collision_as>(); From 98fb2bd77acb01644331c45126dc19e60df55a5f Mon Sep 17 00:00:00 2001 From: suyoupeng <109774812+15071832337@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:31:15 +0800 Subject: [PATCH 17/62] [PWGLF] Lambda local polarization induced by jet in pp collision 13.6 TeV (#11529) --- .../Strangeness/lambdaJetpolarization.cxx | 61 ++++++++----------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx index 3acfbad4d10..cca1bdf193e 100644 --- a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx @@ -29,6 +29,9 @@ #include #include "TProfile2D.h" #include "PWGLF/DataModel/lambdaJetpolarization.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "Math/GenVector/Boost.h" #include #include @@ -351,6 +354,8 @@ struct LfMyV0s { } double massPr = o2::constants::physics::MassProton; double massLambda = o2::constants::physics::MassLambda; + double massPi = o2::constants::physics::MassPionCharged; + ROOT::Math::PxPyPzMVector ProtonVec, PionVec, LambdaVec, ProtonBoostedVec, LambdaBoostedVec; TMatrixD LorentzTransInV0frame(double ELambda, double Lambdapx, double Lambdapy, double Lambdapz) { @@ -1233,32 +1238,20 @@ struct LfMyV0s { if (passedLambdaSelection(v0, pos, neg) && ctauLambda < CtauLambda && ifpasslambda) { V0NumbersPerEventsel++; registryLongitudinalPolarization.fill(HIST("hMassVsPtLambda"), v0.pt(), v0.mLambda()); - double PLambda = sqrt(v0.px() * v0.px() + v0.py() * v0.py() + v0.pz() * v0.pz()); - double ELambda = sqrt(v0.mLambda() * v0.mLambda() + PLambda * PLambda); - double protonE = sqrt(massPr * massPr + pos.px() * pos.px() + pos.py() * pos.py() + pos.pz() * pos.pz()); - TMatrixD pLabV0(4, 1); - pLabV0(0, 0) = ELambda; - pLabV0(1, 0) = v0.px(); - pLabV0(2, 0) = v0.py(); - pLabV0(3, 0) = v0.pz(); - TMatrixD pLabproton(4, 1); - pLabproton(0, 0) = protonE; - pLabproton(1, 0) = pos.px(); - pLabproton(2, 0) = pos.py(); - pLabproton(3, 0) = pos.pz(); + ProtonVec = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), massPr); + PionVec = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), massPi); + LambdaVec = ProtonVec + PionVec; + LambdaVec.SetM(massLambda); + ROOT::Math::Boost boost{LambdaVec.BoostToCM()}; + ProtonBoostedVec = boost(ProtonVec); + LambdaBoostedVec = boost(LambdaVec); - TMatrixD V0InV0(4, 1); - V0InV0 = LorentzTransInV0frame(ELambda, v0.px(), v0.py(), v0.pz()) * pLabV0; - registryLongitudinalPolarization.fill(HIST("V0pxInRest_frame"), V0InV0(1, 0)); - registryLongitudinalPolarization.fill(HIST("V0pyInRest_frame"), V0InV0(2, 0)); - registryLongitudinalPolarization.fill(HIST("V0pzInRest_frame"), V0InV0(3, 0)); + registryLongitudinalPolarization.fill(HIST("V0pxInRest_frame"), LambdaBoostedVec.Px()); + registryLongitudinalPolarization.fill(HIST("V0pyInRest_frame"), LambdaBoostedVec.Py()); + registryLongitudinalPolarization.fill(HIST("V0pzInRest_frame"), LambdaBoostedVec.Pz()); - TMatrixD protonInV0(4, 1); - protonInV0 = LorentzTransInV0frame(ELambda, v0.px(), v0.py(), v0.pz()) * pLabproton; - double protonPInV0 = sqrt(protonInV0(1, 0) * protonInV0(1, 0) + protonInV0(2, 0) * protonInV0(2, 0) + protonInV0(3, 0) * protonInV0(3, 0)); - - double protonCosThetainV0 = protonInV0(3, 0) / protonPInV0; + double protonCosThetainV0 = ProtonBoostedVec.Pz() / ProtonBoostedVec.P(); registryLongitudinalPolarization.fill(HIST("hprotoncosthetainV0"), protonCosThetainV0); registryLongitudinalPolarization.fill(HIST("hprotoncosSquarethetainV0"), protonCosThetainV0 * protonCosThetainV0); @@ -1272,21 +1265,15 @@ struct LfMyV0s { if (passedAntiLambdaSelection(v0, pos, neg) && ctauAntiLambda < CtauLambda && ifpasslambda) { registryLongitudinalPolarization.fill(HIST("hMassVsPtAntiLambda"), v0.pt(), v0.mAntiLambda()); - double PLambda = sqrt(v0.px() * v0.px() + v0.py() * v0.py() + v0.pz() * v0.pz()); - double ELambda = sqrt(v0.mAntiLambda() * v0.mAntiLambda() + PLambda * PLambda); - double protonE = sqrt(massPr * massPr + neg.px() * neg.px() + neg.py() * neg.py() + neg.pz() * neg.pz()); - - TMatrixD pLabproton(4, 1); - pLabproton(0, 0) = protonE; - pLabproton(1, 0) = neg.px(); - pLabproton(2, 0) = neg.py(); - pLabproton(3, 0) = neg.pz(); - - TMatrixD protonInV0(4, 1); - protonInV0 = LorentzTransInV0frame(ELambda, v0.px(), v0.py(), v0.pz()) * pLabproton; - double protonPInV0 = sqrt(protonInV0(1, 0) * protonInV0(1, 0) + protonInV0(2, 0) * protonInV0(2, 0) + protonInV0(3, 0) * protonInV0(3, 0)); + ProtonVec = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), massPr); + PionVec = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), massPi); + LambdaVec = ProtonVec + PionVec; + LambdaVec.SetM(massLambda); + ROOT::Math::Boost boost{LambdaVec.BoostToCM()}; + ProtonBoostedVec = boost(ProtonVec); + LambdaBoostedVec = boost(LambdaVec); - double protonCosThetainV0 = protonInV0(3, 0) / protonPInV0; + double protonCosThetainV0 = ProtonBoostedVec.Pz() / ProtonBoostedVec.P(); registryLongitudinalPolarization.fill(HIST("hantiprotoncosthetainV0"), protonCosThetainV0); registryLongitudinalPolarization.fill(HIST("hantiprotoncosSquarethetainV0"), protonCosThetainV0 * protonCosThetainV0); From a53564f72e2af27007de35d769a0362e195a4007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Tue, 10 Jun 2025 12:04:27 +0200 Subject: [PATCH 18/62] [Infrastructure] Configure clang-format to sort and group includes (#11448) --- .clang-format | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++- CPPLINT.cfg | 2 +- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index c5979d77ba1..33e5d4f9d0c 100644 --- a/.clang-format +++ b/.clang-format @@ -39,7 +39,60 @@ PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 -SortIncludes: false +SortIncludes: CaseSensitive +IncludeBlocks: Regroup +IncludeCategories: + # O2Physics, PWG + - Regex: ^(<|")PWG[A-Z]{2}/.*\.h + Priority: 2 + CaseSensitive: true + # O2Physics, non-PWG + - Regex: ^(<|")(Common|ALICE3|DPG|EventFiltering|Tools|Tutorials)/.*\.h + Priority: 3 + CaseSensitive: true + # O2 + - Regex: ^(<|")(Algorithm|CCDB|Common[A-Z]|DataFormats|DCAFitter|Detectors|EMCAL|Field|Framework|FT0|FV0|GlobalTracking|ITS|MathUtils|MFT|MCH|MID|PHOS|PID|ReconstructionDataFormats|SimulationDataFormat|TOF|TPC|ZDC).*/.*\.h + Priority: 4 + CaseSensitive: true + # ROOT + - Regex: ^(<|")(T[A-Z]|Math/|Roo[A-Z])[[:alnum:]/]+\.h + Priority: 5 + CaseSensitive: true + # known third-party: KFParticle + - Regex: ^(<|")KF[A-Z][[:alnum:]]+\.h + Priority: 6 + CaseSensitive: true + # known third-party: FastJet + - Regex: ^(<|")fastjet/ + Priority: 6 + CaseSensitive: true + # known third-party: ONNX runtime + - Regex: ^(<|")onnxruntime + Priority: 6 + CaseSensitive: true + # incomplete path to DataModel + - Regex: ^(<|").*DataModel/ + Priority: 1 + CaseSensitive: true + # other third-party + - Regex: ^(<|")([[:alnum:]_]+/)+[[:alnum:]_]+\.h + Priority: 6 + CaseSensitive: true + # other local-looking file + - Regex: ^".*\. + Priority: 1 + CaseSensitive: true + # C system + - Regex: ^(<|")[[:lower:]_]+\.h(>|") + Priority: 102 + CaseSensitive: true + # C++ system + - Regex: ^(<|")[[:lower:]_/]+(>|") + Priority: 101 + CaseSensitive: true + # rest + - Regex: .* + Priority: 100 SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false diff --git a/CPPLINT.cfg b/CPPLINT.cfg index 7f7d3c357c3..96a8077f685 100644 --- a/CPPLINT.cfg +++ b/CPPLINT.cfg @@ -1 +1 @@ -filter=-build/c++11,-build/namespaces,-readability/fn_size,-readability/todo,-runtime/references,-whitespace/blank_line,-whitespace/braces,-whitespace/comments,-whitespace/indent_namespace,-whitespace/line_length,-whitespace/semicolon,-whitespace/todo +filter=-build/c++11,-build/include_order,-build/namespaces,-readability/fn_size,-readability/todo,-runtime/references,-whitespace/blank_line,-whitespace/braces,-whitespace/comments,-whitespace/indent_namespace,-whitespace/line_length,-whitespace/semicolon,-whitespace/todo From d416e0f1c50cded16e3a5d853293a076ad01ce8c Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Tue, 10 Jun 2025 13:20:52 +0200 Subject: [PATCH 19/62] [PWGHF] Enable ML selection in KF-based LcToPKPi reconstruction (#11489) --- PWGHF/Core/HfMlResponseLcToPKPi.h | 63 +++++++++-- PWGHF/TableProducer/candidateSelectorLc.cxx | 59 +++++++--- PWGHF/TableProducer/treeCreatorLcToPKPi.cxx | 116 +++++++++++++++++--- 3 files changed, 194 insertions(+), 44 deletions(-) diff --git a/PWGHF/Core/HfMlResponseLcToPKPi.h b/PWGHF/Core/HfMlResponseLcToPKPi.h index 405e16cfc42..ae797f32acd 100644 --- a/PWGHF/Core/HfMlResponseLcToPKPi.h +++ b/PWGHF/Core/HfMlResponseLcToPKPi.h @@ -16,8 +16,12 @@ #ifndef PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ #define PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ +#include +#include #include +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + #include "PWGHF/Core/HfMlResponse.h" // Fill the map of available input features @@ -129,10 +133,22 @@ enum class InputFeaturesLcToPKPi : uint8_t { tofNSigmaPrExpPr0, tofNSigmaPiExpPi2, tpcTofNSigmaPrExpPr0, - tpcTofNSigmaPiExpPi2 + tpcTofNSigmaPiExpPi2, + kfChi2PrimProton, + kfChi2PrimKaon, + kfChi2PrimPion, + kfChi2GeoKaonPion, + kfChi2GeoProtonPion, + kfChi2GeoProtonKaon, + kfDcaKaonPion, + kfDcaProtonPion, + kfDcaProtonKaon, + kfChi2Geo, + kfChi2Topo, + kfDecayLengthNormalised }; -template +template class HfMlResponseLcToPKPi : public HfMlResponse { public: @@ -179,8 +195,6 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPr2, nSigTpcPr2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaKa2, nSigTpcKa2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPi2, nSigTpcPi2); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcNSigmaPrExpPr0, tpcNSigmaPr); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcNSigmaPiExpPi2, tpcNSigmaPi); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcNSigmaPrExpPr0, nSigTpcPr0, nSigTpcPr2); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcNSigmaPiExpPi2, nSigTpcPi2, nSigTpcPi0); // TOF PID variables @@ -193,8 +207,6 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPr2, nSigTofPr2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaKa2, nSigTofKa2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPi2, nSigTofPi2); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tofNSigmaPrExpPr0, tofNSigmaPr); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tofNSigmaPiExpPi2, tofNSigmaPi); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tofNSigmaPrExpPr0, nSigTofPr0, nSigTofPr2); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tofNSigmaPiExpPi2, nSigTofPi2, nSigTofPi0); // Combined PID variables @@ -207,13 +219,29 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr0, tpcTofNSigmaPr0); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr1, tpcTofNSigmaPr1); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr2, tpcTofNSigmaPr2); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr0, tpcTofNSigmaPr2); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi2, tpcTofNSigmaPi0); } + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + switch (idx) { + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2PrimProton, kfChi2PrimProng0, kfChi2PrimProng2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, kfChi2PrimKaon, kfChi2PrimProng1); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2PrimPion, kfChi2PrimProng2, kfChi2PrimProng0); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2GeoKaonPion, kfChi2GeoProng1Prong2, kfChi2GeoProng0Prong1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, kfChi2GeoProtonPion, kfChi2GeoProng0Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2GeoProtonKaon, kfChi2GeoProng0Prong1, kfChi2GeoProng1Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfDcaKaonPion, kfDcaProng1Prong2, kfDcaProng0Prong1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, kfDcaProtonPion, kfDcaProng0Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfDcaProtonKaon, kfDcaProng0Prong1, kfDcaProng1Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI(kfChi2Geo); + CHECK_AND_FILL_VEC_LCTOPKPI(kfChi2Topo); + case static_cast(InputFeaturesLcToPKPi::kfDecayLengthNormalised): { + inputFeatures.emplace_back(candidate.kfDecayLength() / candidate.kfDecayLengthError()); + break; + } + } + } } - return inputFeatures; } @@ -273,6 +301,23 @@ class HfMlResponseLcToPKPi : public HfMlResponse FILL_MAP_LCTOPKPI(tpcTofNSigmaPr2), FILL_MAP_LCTOPKPI(tpcTofNSigmaPrExpPr0), FILL_MAP_LCTOPKPI(tpcTofNSigmaPiExpPi2)}; + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + std::map mapKfFeatures{ + // KFParticle variables + FILL_MAP_LCTOPKPI(kfChi2PrimProton), + FILL_MAP_LCTOPKPI(kfChi2PrimKaon), + FILL_MAP_LCTOPKPI(kfChi2PrimPion), + FILL_MAP_LCTOPKPI(kfChi2GeoKaonPion), + FILL_MAP_LCTOPKPI(kfChi2GeoProtonPion), + FILL_MAP_LCTOPKPI(kfChi2GeoProtonKaon), + FILL_MAP_LCTOPKPI(kfDcaKaonPion), + FILL_MAP_LCTOPKPI(kfDcaProtonPion), + FILL_MAP_LCTOPKPI(kfDcaProtonKaon), + FILL_MAP_LCTOPKPI(kfChi2Geo), + FILL_MAP_LCTOPKPI(kfChi2Topo), + FILL_MAP_LCTOPKPI(kfDecayLengthNormalised)}; + MlResponse::mAvailableInputFeatures.insert(mapKfFeatures.begin(), mapKfFeatures.end()); + } } }; diff --git a/PWGHF/TableProducer/candidateSelectorLc.cxx b/PWGHF/TableProducer/candidateSelectorLc.cxx index 93b84c79522..d48cb5f3daa 100644 --- a/PWGHF/TableProducer/candidateSelectorLc.cxx +++ b/PWGHF/TableProducer/candidateSelectorLc.cxx @@ -93,7 +93,8 @@ struct HfCandidateSelectorLc { Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; HfHelper hfHelper; - o2::analysis::HfMlResponseLcToPKPi hfMlResponse; + o2::analysis::HfMlResponseLcToPKPi hfMlResponseDCA; + o2::analysis::HfMlResponseLcToPKPi hfMlResponseKF; std::vector outputMlLcToPKPi = {}; std::vector outputMlLcToPiKP = {}; o2::ccdb::CcdbApi ccdbApi; @@ -142,15 +143,28 @@ struct HfCandidateSelectorLc { } if (applyMl) { - hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); - if (loadModelsFromCCDB) { - ccdbApi.init(ccdbUrl); - hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); - } else { - hfMlResponse.setModelPathsLocal(onnxFileNames); + if (doprocessNoBayesPidWithDCAFitterN || doprocessBayesPidWithDCAFitterN) { + hfMlResponseDCA.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponseDCA.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponseDCA.setModelPathsLocal(onnxFileNames); + } + hfMlResponseDCA.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponseDCA.init(); + } + if (doprocessNoBayesPidWithKFParticle || doprocessBayesPidWithKFParticle) { + hfMlResponseKF.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponseKF.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponseKF.setModelPathsLocal(onnxFileNames); + } + hfMlResponseKF.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponseKF.init(); } - hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); - hfMlResponse.init(); } massK0Star892 = o2::constants::physics::MassK0Star892; @@ -273,7 +287,7 @@ struct HfCandidateSelectorLc { return false; } - float massLc, massKPi; + float massLc{0.f}, massKPi{0.f}; if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { if (trackProton.globalIndex() == candidate.prong0Id()) { massLc = hfHelper.invMassLcToPKPi(candidate); @@ -553,13 +567,24 @@ struct HfCandidateSelectorLc { isSelectedMlLcToPKPi = false; isSelectedMlLcToPiKP = false; - if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { - std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); - isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); - } - if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { - std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); - isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { + if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { + std::vector inputFeaturesLcToPKPi = hfMlResponseDCA.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponseDCA.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); + } + if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { + std::vector inputFeaturesLcToPiKP = hfMlResponseDCA.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponseDCA.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + } + } else { + if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { + std::vector inputFeaturesLcToPKPi = hfMlResponseKF.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponseKF.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); + } + if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { + std::vector inputFeaturesLcToPiKP = hfMlResponseKF.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponseKF.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + } } hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); diff --git a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx index 5ad144e472e..3f53966a973 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -17,7 +17,9 @@ /// \author Nicolo' Jacazio , CERN /// \author Luigi Dello Stritto , CERN +#include #include +#include #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -87,6 +89,9 @@ DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int8_t); DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCand3ProngWPidPiKaPr, "_0"); DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); DECLARE_SOA_COLUMN(Channel, channel, int8_t); // direct or resonant +DECLARE_SOA_COLUMN(MlScoreFirstClass, mlScoreFirstClass, float); +DECLARE_SOA_COLUMN(MlScoreSecondClass, mlScoreSecondClass, float); +DECLARE_SOA_COLUMN(MlScoreThirdClass, mlScoreThirdClass, float); // Events DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int); @@ -238,7 +243,10 @@ DECLARE_SOA_TABLE(HfCandLcLites, "AOD", "HFCANDLCLITE", full::OriginMcRec, full::IsCandidateSwapped, full::Channel, - full::MassKPi); + full::MassKPi, + full::MlScoreFirstClass, + full::MlScoreSecondClass, + full::MlScoreThirdClass); DECLARE_SOA_TABLE(HfCollIdLCLite, "AOD", "HFCOLLIDLCLITE", full::CollisionId); @@ -316,7 +324,10 @@ DECLARE_SOA_TABLE(HfCandLcFulls, "AOD", "HFCANDLCFULL", full::IsCandidateSwapped, full::CandidateId, full::Channel, - full::MassKPi); + full::MassKPi, + full::MlScoreFirstClass, + full::MlScoreSecondClass, + full::MlScoreThirdClass); DECLARE_SOA_TABLE(HfCandLcFullEvs, "AOD", "HFCANDLCFULLEV", full::CollisionId, @@ -374,6 +385,7 @@ struct HfTreeCreatorLcToPKPi { Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; Configurable fillCollIdTable{"fillCollIdTable", false, "Fill a single-column table with collision index"}; Configurable fillCandidateMcTable{"fillCandidateMcTable", false, "Switch to fill a table with MC particles matched to candidates"}; + Configurable applyMl{"applyMl", false, "Whether ML was used in candidateSelectorLc"}; Configurable keepOnlySignalMc{"keepOnlySignalMc", false, "Fill MC tree only with signal candidates"}; Configurable keepOnlyBkg{"keepOnlyBkg", false, "Fill MC tree only with background candidates"}; Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of candidates to store in the tree"}; @@ -553,11 +565,40 @@ struct HfTreeCreatorLcToPKPi { return std::make_pair(invMass, invMassKPi); } + /// \brief function to get ML score values for the current candidate and assign them to input parameters + /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate + /// \param mlScoreFirstClass ML score for belonging to the first class + /// \param mlScoreSecondClass ML score for belonging to the second class + /// \param mlScoreThirdClass ML score for belonging to the third class + /// \param candFlag flag indicating if PKPi (0) or PiKP (1) hypothesis is used + void assignMlScores(aod::HfMlLcToPKPi::iterator const& candidateMlScore, float& mlScoreFirstClass, float& mlScoreSecondClass, float& mlScoreThirdClass, int candFlag) + { + std::vector mlScores; + if (candFlag == 0) { + std::copy(candidateMlScore.mlProbLcToPKPi().begin(), candidateMlScore.mlProbLcToPKPi().end(), std::back_inserter(mlScores)); + } else { + std::copy(candidateMlScore.mlProbLcToPiKP().begin(), candidateMlScore.mlProbLcToPiKP().end(), std::back_inserter(mlScores)); + } + constexpr int IndexFirstClass{0}; + constexpr int IndexSecondClass{1}; + constexpr int IndexThirdClass{2}; + if (mlScores.size() == 0) { + return; // when candidateSelectorLc rejects a candidate by "usual", non-ML cut, the ml score vector remains empty + } + mlScoreFirstClass = mlScores.at(IndexFirstClass); + mlScoreSecondClass = mlScores.at(IndexSecondClass); + if (mlScores.size() > IndexThirdClass) { + mlScoreThirdClass = mlScores.at(IndexThirdClass); + } + } + /// \brief function to fill lite table /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate /// \param candFlag flag indicating if PKPi (0) or PiKP (1) hypothesis is used template - void fillLiteTable(CandType const& candidate, int candFlag) + void fillLiteTable(CandType const& candidate, aod::HfMlLcToPKPi::iterator const& candidateMlScore, int candFlag) { auto [functionInvMass, functionInvMassKPi] = evaluateInvariantMasses(candidate, candFlag); const float functionCt = hfHelper.ctLc(candidate); @@ -575,6 +616,14 @@ struct HfTreeCreatorLcToPKPi { functionFlagMcDecayChanRec = candidate.flagMcDecayChanRec(); } + float mlScoreFirstClass{UndefValueFloat}; + float mlScoreSecondClass{UndefValueFloat}; + float mlScoreThirdClass{UndefValueFloat}; + + if (applyMl) { + assignMlScores(candidateMlScore, mlScoreFirstClass, mlScoreSecondClass, mlScoreThirdClass, candFlag); + } + rowCandidateLite( candidate.posX(), candidate.posY(), @@ -618,7 +667,10 @@ struct HfTreeCreatorLcToPKPi { functionOriginMcRec, functionIsCandidateSwapped, functionFlagMcDecayChanRec, - functionInvMassKPi); + functionInvMassKPi, + mlScoreFirstClass, + mlScoreSecondClass, + mlScoreThirdClass); if (fillCollIdTable) { /// save also candidate collision indices @@ -628,9 +680,10 @@ struct HfTreeCreatorLcToPKPi { /// \brief function to fill lite table /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate /// \param candFlag flag indicating if PKPi (0) or PiKP (1) hypothesis is used template - void fillFullTable(CandType const& candidate, int candFlag) + void fillFullTable(CandType const& candidate, aod::HfMlLcToPKPi::iterator const& candidateMlScore, int candFlag) { auto [functionInvMass, functionInvMassKPi] = evaluateInvariantMasses(candidate, candFlag); const float functionCt = hfHelper.ctLc(candidate); @@ -649,6 +702,14 @@ struct HfTreeCreatorLcToPKPi { functionFlagMcDecayChanRec = candidate.flagMcDecayChanRec(); } + float mlScoreFirstClass{UndefValueFloat}; + float mlScoreSecondClass{UndefValueFloat}; + float mlScoreThirdClass{UndefValueFloat}; + + if (applyMl) { + assignMlScores(candidateMlScore, mlScoreFirstClass, mlScoreSecondClass, mlScoreThirdClass, candFlag); + } + rowCandidateFull( candidate.collisionId(), candidate.posX(), @@ -722,7 +783,10 @@ struct HfTreeCreatorLcToPKPi { functionIsCandidateSwapped, candidate.globalIndex(), functionFlagMcDecayChanRec, - functionInvMassKPi); + functionInvMassKPi, + mlScoreFirstClass, + mlScoreSecondClass, + mlScoreThirdClass); } /// \brief function to fill lite table @@ -839,6 +903,7 @@ struct HfTreeCreatorLcToPKPi { void fillTablesMc(Colls const& collisions, aod::McCollisions const&, CandType const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const&, aod::BCs const&) { @@ -850,7 +915,10 @@ struct HfTreeCreatorLcToPKPi { const size_t candidatesSize = candidates.size(); reserveTables(candidatesSize, IsMc); + int iCand{0}; for (const auto& candidate : candidates) { + auto candidateMlScore = candidateMlScores.rawIteratorAt(iCand); + ++iCand; float ptProng0 = candidate.ptProng0(); auto collision = candidate.template collision_as(); auto fillTable = [&](int candFlag) { @@ -863,9 +931,9 @@ struct HfTreeCreatorLcToPKPi { const bool notSkippedBkg = isMcCandidateSignal || candidate.pt() > downSampleBkgPtMax || pseudoRndm < downSampleBkgFactor; if (passSelection && notSkippedBkg && (keepAll || (keepOnlySignalMc && isMcCandidateSignal) || (keepOnlyBkg && !isMcCandidateSignal))) { if (fillCandidateLiteTable) { - fillLiteTable(candidate, candFlag); + fillLiteTable(candidate, candidateMlScore, candFlag); } else { - fillFullTable(candidate, candFlag); + fillFullTable(candidate, candidateMlScore, candFlag); } if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { @@ -955,10 +1023,11 @@ struct HfTreeCreatorLcToPKPi { void processMcNoCentralityWithDCAFitterN(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcNoCentralityWithDCAFitterN, "Process MC tree writer w/o centrality with DCAFitterN", false); @@ -971,10 +1040,11 @@ struct HfTreeCreatorLcToPKPi { void processMcWithCentralityWithDCAFitterN(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcWithCentralityWithDCAFitterN, "Process MC tree writer with centrality with DCAFitterN", false); @@ -988,10 +1058,11 @@ struct HfTreeCreatorLcToPKPi { void processMcNoCentralityWithKFParticle(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcNoCentralityWithKFParticle, "Process MC tree writer w/o centrality with KFParticle", false); @@ -1004,10 +1075,11 @@ struct HfTreeCreatorLcToPKPi { void processMcWithCentralityWithKFParticle(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcWithCentralityWithKFParticle, "Process MC tree writer with centrality with KFParticle", false); @@ -1017,6 +1089,7 @@ struct HfTreeCreatorLcToPKPi { template void fillTablesData(Colls const& collisions, CandType const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const&, aod::BCs const&) { @@ -1029,7 +1102,10 @@ struct HfTreeCreatorLcToPKPi { // Filling candidate properties + int iCand{0}; for (const auto& candidate : candidates) { + auto candidateMlScore = candidateMlScores.rawIteratorAt(iCand); + ++iCand; float ptProng0 = candidate.ptProng0(); auto collision = candidate.template collision_as(); auto fillTable = [&](int candFlag) { @@ -1037,9 +1113,9 @@ struct HfTreeCreatorLcToPKPi { const int functionSelection = candFlag == 0 ? candidate.isSelLcToPKPi() : candidate.isSelLcToPiKP(); if (functionSelection >= selectionFlagLc && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))) { if (fillCandidateLiteTable) { - fillLiteTable(candidate, candFlag); + fillLiteTable(candidate, candidateMlScore, candFlag); } else { - fillFullTable(candidate, candFlag); + fillFullTable(candidate, candidateMlScore, candFlag); } if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { @@ -1060,9 +1136,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataNoCentralityWithDCAFitterN(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataNoCentralityWithDCAFitterN, "Process data tree writer w/o centrality with DCAFitterN", false); @@ -1073,9 +1150,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataWithCentralityWithDCAFitterN(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataWithCentralityWithDCAFitterN, "Process data tree writer with centrality with DCAFitterN", true); @@ -1086,9 +1164,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataNoCentralityWithKFParticle(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataNoCentralityWithKFParticle, "Process data tree writer w/o centrality with KFParticle", false); @@ -1099,9 +1178,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataWithCentralityWithKFParticle(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataWithCentralityWithKFParticle, "Process data tree writer with centrality with KFParticle", false); }; From 48a7e9ec96ab9600bbca67ebb1be9d791d8bcfd1 Mon Sep 17 00:00:00 2001 From: Zhengqing Wang Date: Tue, 10 Jun 2025 20:29:01 +0800 Subject: [PATCH 20/62] [PWGCF] update on ese (#11530) Co-authored-by: ALICE Action Bot --- PWGCF/Flow/Tasks/flowEsePHe3.cxx | 1564 ++++++++++++++++-------------- 1 file changed, 820 insertions(+), 744 deletions(-) diff --git a/PWGCF/Flow/Tasks/flowEsePHe3.cxx b/PWGCF/Flow/Tasks/flowEsePHe3.cxx index 61582f233b3..624043a2d31 100644 --- a/PWGCF/Flow/Tasks/flowEsePHe3.cxx +++ b/PWGCF/Flow/Tasks/flowEsePHe3.cxx @@ -36,6 +36,8 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/StaticFor.h" +#include "DataFormatsTPC/BetheBlochAleph.h" + #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -51,42 +53,213 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; namespace o2::aod { -namespace flow_ese_p_he3 +namespace ese_var_table { -DECLARE_SOA_COLUMN(NPidFlag, nPidFlag, int8_t); // unqualified -1, hadron 0, proton 1, he3 2, proton+he3 3 -} // namespace flow_ese_p_he3 -DECLARE_SOA_TABLE(PHe3ESEFlags, "AOD", "PHe3ESEFlags", flow_ese_p_he3::NPidFlag); +DECLARE_SOA_COLUMN(EseVtz, eseVtz, float); +DECLARE_SOA_COLUMN(EseCentFT0C, eseCentFT0C, float); +DECLARE_SOA_COLUMN(EsePsi2FT0C, esePsi2FT0C, float); +DECLARE_SOA_COLUMN(Eseq2Tar, eseq2Tar, float); +DECLARE_SOA_COLUMN(Eseq2Ref, eseq2Ref, float); +DECLARE_SOA_COLUMN(EseTarSign, eseTarSign, int8_t); +DECLARE_SOA_COLUMN(EseTarTPCInnerParam, eseTarTPCInnerParam, float); +DECLARE_SOA_COLUMN(EseTarTPCSignal, eseTarTPCSignal, float); +DECLARE_SOA_COLUMN(EseTarPt, eseTarPt, float); +DECLARE_SOA_COLUMN(EseTarEta, eseTarEta, float); +DECLARE_SOA_COLUMN(EseTarPhi, eseTarPhi, float); +DECLARE_SOA_COLUMN(EseTarDCAxy, eseTarDCAxy, float); +DECLARE_SOA_COLUMN(EseTarDCAz, eseTarDCAz, float); +DECLARE_SOA_COLUMN(EseTarTPCNcls, eseTarTPCNcls, uint8_t); +DECLARE_SOA_COLUMN(EseTarITSNcls, eseTarITSNcls, uint8_t); +DECLARE_SOA_COLUMN(EseTarTPCChi2NDF, eseTarTPCChi2NDF, float); +DECLARE_SOA_COLUMN(EseTarITSChi2NDF, eseTarITSChi2NDF, float); +DECLARE_SOA_COLUMN(EseTarTPCNSigma, eseTarTPCNSigma, float); +DECLARE_SOA_COLUMN(EseTarTOFNSigma, eseTarTOFNSigma, float); +DECLARE_SOA_COLUMN(EseTarITSNSigma, eseTarITSNSigma, float); +DECLARE_SOA_COLUMN(EseTarITSClusSize, eseTarITSClusSize, uint32_t); +} // namespace ese_var_table + +DECLARE_SOA_TABLE(ESETable, "AOD", "ESETable", + ese_var_table::EseVtz, + ese_var_table::EseCentFT0C, + ese_var_table::EsePsi2FT0C, + ese_var_table::Eseq2Tar, + ese_var_table::Eseq2Ref, + ese_var_table::EseTarSign, + ese_var_table::EseTarTPCInnerParam, + ese_var_table::EseTarTPCSignal, + ese_var_table::EseTarPt, + ese_var_table::EseTarEta, + ese_var_table::EseTarPhi, + ese_var_table::EseTarDCAxy, + ese_var_table::EseTarDCAz, + ese_var_table::EseTarTPCNcls, + ese_var_table::EseTarITSNcls, + ese_var_table::EseTarTPCChi2NDF, + ese_var_table::EseTarITSChi2NDF, + ese_var_table::EseTarTPCNSigma, + ese_var_table::EseTarTOFNSigma, + ese_var_table::EseTarITSNSigma, + ese_var_table::EseTarITSClusSize); } // namespace o2::aod -namespace pid_flags -{ -// constexpr int8_t kUnqualified = -1; -// constexpr int8_t kUnPOIHadron = 0; -constexpr int8_t kProton = 1; -constexpr int8_t kHe3 = 2; -constexpr int8_t kProtonHe3 = 3; -} // namespace pid_flags - -namespace event_selection -{ -constexpr int kFT0AV0ASigma = 5; -} +struct ESECandidate { + float vtz; + float centFT0C; + float psi2FT0C; + float q2Tar; + float q2Ref; + int8_t signTar; + float tpcInnerParamTar; + float tpcSignalTar; + float ptTar; + float etaTar; + float phiTar; + float dcaXYTar; + float dcaZTar; + uint8_t tpcNclsTar; + uint8_t itsNclsTar; + float tpcChi2NDFTar; + float itsChi2NDFTar; + float tpcNSigmaTar; + float tofNSigmaTar; + float itsNSigmaTar; + uint32_t itsClusSizeTar; +}; -namespace fourier_mode +namespace ese_parameters { -// constexpr int kMode1 = 1; -constexpr int kMode2 = 2; -// constexpr int kMode3 = 3; -} // namespace fourier_mode +constexpr uint8_t kProton = 0; +constexpr uint8_t kDeuteron = 1; +constexpr uint8_t kTriton = 2; +constexpr uint8_t kHe3 = 3; +constexpr uint8_t kAlpha = 4; +constexpr int kFT0AV0ASigma = 5; +constexpr int kRMSMode = 0; +constexpr int kTPCMode = 1; +constexpr int kTOFOnlyMode = 2; +constexpr float Amplitudelow = 1e-8; +constexpr float Charges[5]{1.f, 1.f, 1.f, 2.f, 2.f}; +constexpr float Masses[5]{MassProton, MassDeuteron, MassTriton, MassHelium3, MassAlpha}; +constexpr double BetheBlochDefault[5][6]{ + {-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09}, + {-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09}, + {-239.99, 1.155, 1.099, 1.137, 1.006, 0.09}, + {-321.34, 0.6539, 1.591, 0.8225, 2.363, 0.09}, + {-586.66, 1.859, 4.435, 0.282, 3.201, 0.09}}; +constexpr double BbMomScalingDefault[5][2]{// 0:poscharged 1:negcharged + {1., 1.}, + {1., 1.}, + {1., 1.}, + {1., 1.}, + {1., 1.}}; +constexpr int Open3DPIDPlots[3][1]{ + {0}, + {0}, + {0}}; +constexpr int OpenEvSel[10][1]{ + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {0}, + {1}}; +constexpr int OpenTrackSel[7][1]{ + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {1}}; +constexpr double TPCnSigmaCutDefault[5][2]{ + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}}; +constexpr double ITSnSigmaCutDefault[5][2]{ + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}}; +constexpr double PtPreselection[5][2]{ + {0.15, 99.}, + {0.15, 99.}, + {0.15, 99.}, + {0.15, 99.}, + {0.15, 99.}}; +static const std::vector names{"proton", "deuteron", "triton", "He3", "alpha"}; +static const std::vector chargeLabelNames{"Positive", "Negative"}; +static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; +static const std::vector plot3DPIDNames{"TOF vs ITS", "ITS vs TPC", "TOF vs TPC"}; +static const std::vector openEventSelNames{"EvSelkIsGoodZvtxFT0vsPV", "EvSelkNoSameBunchPileup", "EvSelkNoCollInTimeRangeStandard", "EvSelkIsGoodITSLayersAll", "EvSelkNoCollInRofStandard", "EvSelkNoHighMultCollInPrevRof", "EvSelOccupancy", "EvSelMultCorrelationPVTracks", "EvSelMultCorrelationGlobalTracks", "EvSelV0AT0ACut"}; +static const std::vector openTrackSelNames{"passedITSNCls", "passedITSChi2NDF", "passedITSHits", "passedTPCChi2NDF", "passedTPCCrossedRowsOverNCls", "passedDCAxy", "passedDCAz"}; +static const std::vector plot3DConfigNames{"Open related 3D nSigma plots"}; +static const std::vector openEventSelConfigNames{"Open related event selection options"}; +static const std::vector openTrackSelConfigNames{"Open track selection from TrackSelection table"}; +static const std::vector pidTPCnSigmaNames{"n#sigma_{TPC} Low", "n#sigma_{TPC} High"}; +static const std::vector pidITSnSigmaNames{"n#sigma_{ITS} Low", "n#sigma_{ITS} High"}; +static const std::vector pidPtNames{"p_{T} Low", "p_{T} High"}; +std::vector eseCandidates; +// Tar ptr +std::shared_ptr hPIDQATar1D[12]; +std::shared_ptr hPIDQATar2D[4]; +std::shared_ptr hPIDQATar3D[3]; +std::shared_ptr hv2Tar[2]; +std::shared_ptr hESEQATar1D[2]; +std::shared_ptr hESEQATar2D; +std::shared_ptr hESETar; +// Ref ptr +std::shared_ptr hPIDQARef1D[12]; +std::shared_ptr hPIDQARef2D[4]; +std::shared_ptr hPIDQARef3D[3]; +std::shared_ptr hv2Ref[2]; +std::shared_ptr hESEQARef1D[2]; +std::shared_ptr hESEQARef2D; +} // namespace ese_parameters -using TracksPID = soa::Join; -struct FillPIDcolums { +using TracksPIDFull = soa::Join; - HistogramRegistry histosQA{"histosQAPID", {}, OutputObjHandlingPolicy::AnalysisObject}; +struct FlowEsePHe3 { + EventPlaneHelper helperEP; + o2::aod::ITSResponse itsResponse; + HistogramRegistry histsESE{"histsESE", {}, OutputObjHandlingPolicy::AnalysisObject}; + // process POI control + Configurable cfgTarName{"cfgTarName", "kHe3", "Name of the v2 particle: kProton, kDeuteron, kTriton, kHe3, kAlpha"}; + Configurable cfgRefName{"cfgRefName", "kProton", "Name of the q2 reference particle: kProton, kDeuteron, kTriton, kHe3, kAlpha"}; + // total control config + Configurable cfgOpenAllowCrossTrack{"cfgOpenAllowCrossTrack", false, "Allow one track to be identified as different kind of PID particles"}; + Configurable cfgOpenFullEventQA{"cfgOpenFullEventQA", true, "Open full QA plots for event QA"}; + Configurable cfgOpenPIDQA{"cfgOpenPIDQA", true, "Open PID QA plots"}; + Configurable cfgOpenv2{"cfgOpenv2", true, "Open v2(EP)and q calculation for Proton and He3"}; + Configurable cfgOpenESE{"cfgOpenESE", true, "Open ESE plots"}; + Configurable cfgOpenESEQA{"cfgOpenESEQA", true, "Open ESE QA plots"}; + Configurable> cfgOpen3DPIDPlots{"cfgOpen3DPIDPlots", {ese_parameters::Open3DPIDPlots[0], 3, 1, ese_parameters::plot3DPIDNames, ese_parameters::plot3DConfigNames}, "3D PID QA Plots switch configuration"}; + // Qvec configs + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; + Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; + Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; + // pre event selection(filter) + Configurable cfgVtzCut{"cfgVtzCut", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCentMin{"cfgCentMin", 0.0f, "Centrality min"}; + Configurable cfgCentMax{"cfgCentMax", 100.0f, "Centrality max"}; + // event selection configs + Configurable cfgCutOccupancyLow{"cfgCutOccupancyLow", 0, "Low boundary cut on TPC occupancy"}; + Configurable cfgCutOccupancyHigh{"cfgCutOccupancyHigh", 3000, "High boundary cut on TPC occupancy"}; + Configurable> cfgOpenEvSel{"cfgOpenEvSel", {ese_parameters::OpenEvSel[0], 10, 1, ese_parameters::openEventSelNames, ese_parameters::openEventSelConfigNames}, "Event selection switch configuration"}; + // track selection configs + Configurable> cfgOpenTrackSel{"cfgOpenTrackSel", {ese_parameters::OpenTrackSel[0], 7, 1, ese_parameters::openTrackSelNames, ese_parameters::openTrackSelConfigNames}, "Track selection switch configuration"}; Configurable cfgMinPtPID{"cfgMinPtPID", 0.15, "Minimum track #P_{t} for PID"}; Configurable cfgMaxPtPID{"cfgMaxPtPID", 99.9, "Maximum track #P_{t} for PID"}; Configurable cfgMaxEtaPID{"cfgMaxEtaPID", 0.8, "Maximum track #eta for PID"}; @@ -101,516 +274,152 @@ struct FillPIDcolums { Configurable cfgMaxDCAxy{"cfgMaxDCAxy", 99, "Maxium DCAxy for standard PID tracking"}; Configurable cfgMaxDCAz{"cfgMaxDCAz", 2, "Maxium DCAz for standard PID tracking"}; Configurable cfgPtMaxforTPCOnlyPIDPrton{"cfgPtMaxforTPCOnlyPIDPrton", 0.4, "Maxmium track pt for TPC only PID, at RMS PID mode for proton"}; - Configurable cfgPtMaxforTPCOnlyPIDHe3{"cfgPtMaxforTPCOnlyPIDHe3", 0.5, "Maxmium track pt for TPC only PID, at RMS PID mode for he3"}; - - Configurable cfgProtonPIDMode{"cfgProtonPIDMode", 2, "Proton PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; - Configurable cfgHe3PIDMode{"cfgHe3PIDMode", 1, "He3 PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; - - Configurable cfgOpenpassedITSNCls{"cfgOpenpassedITSNCls", false, "useTrackSelectionTables passedITSNCls for basic track selection"}; - Configurable cfgOpenpassedITSChi2NDF{"cfgOpenpassedITSChi2NDF", false, "useTrackSelectionTables passedITSChi2NDF for basic track selection"}; - Configurable cfgOpenpassedITSHits{"cfgOpenpassedITSHits", false, "useTrackSelectionTables passedITSHits for basic track selection"}; - Configurable cfgOpenpassedTPCChi2NDF{"cfgOpenpassedTPCChi2NDF", false, "useTrackSelectionTables passedTPCChi2NDF for basic track selection"}; - Configurable cfgOpenpassedTPCCrossedRowsOverNCls{"cfgOpenpassedTPCCrossedRowsOverNCls", false, "useTrackSelectionTables passedTPCCrossedRowsOverNCls for basic track selection"}; - Configurable cfgOpenpassedDCAxy{"cfgOpenpassedDCAxy", false, "useTrackSelectionTables passedDCAxy for basic track selection"}; - Configurable cfgOpenpassedDCAz{"cfgOpenpassedDCAz", false, "useTrackSelectionTables passedDCAz for basic track selection"}; - - Configurable cfgQuietMode{"cfgQuietMode", false, "open quiet mode for saving cpu cost and only do some basic QA plots"}; - Configurable cfgOpenPIDITSProton{"cfgOpenPIDITSProton", true, "open ITS assistance cut for proton PID"}; - Configurable cfgOpenPIDITSHe3{"cfgOpenPIDITSHe3", false, "open ITS assistance cut for He3 PID"}; - Configurable cfgOpenPIDByPtProtonMain{"cfgOpenPIDByPtProtonMain", false, "Selection Proton by pt its pt binnings for main selection"}; - Configurable cfgOpenPIDByPtHe3Main{"cfgOpenPIDByPtHe3Main", false, "Selection He3 by pt its pt binnings for main selection"}; - Configurable cfgOpenPIDByPtProtonITS{"cfgOpenPIDByPtProtonITS", false, "Selection Proton by pt its pt binnings for ITS selection"}; - Configurable cfgOpenPIDByPtHe3ITS{"cfgOpenPIDByPtHe3ITS", false, "Selection He3 by pt its pt binnings for ITS selection"}; - Configurable cfgOpenHe3ITSPtCut{"cfgOpenHe3ITSPtCut", true, "Do He3 ITS contamination cut"}; - Configurable cfgOpenAllowCrossTrack{"cfgOpenAllowCrossTrack", false, "Allow one track to be identified as different kind of PID particles"}; - - Configurable cfgOpenPlotnSigmaTOFITSPt{"cfgOpenPlotnSigmaTOFITSPt", true, "plot nSigmaTOF vs nSigmaITS vs Pt"}; - Configurable cfgOpenPlotnSigmaITSTPCPt{"cfgOpenPlotnSigmaITSTPCPt", true, "plot nSigmaITS vs nSigmaTOF vs Pt"}; - Configurable cfgOpenPlotnSigmaTOFTPCPt{"cfgOpenPlotnSigmaTOFTPCPt", true, "plot nSigmaTOF vs nSigmaTPC vs Pt"}; - - Configurable> cfgPtCutProton{"cfgPtCutProton", {0.15, 99.}, "Pt limit for Proton"}; - Configurable> cfgPtCutHe3{"cfgPtCutHe3", {0.15, 99.}, "Pt limit for He3"}; - Configurable> cfgnSigmaCutTPCProton{"cfgnSigmaCutTPCProton", {-3, 3}, "TPC nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutTPCHe3{"cfgnSigmaCutTPCHe3", {-2, 2}, "TPC nsigma cut limit for He3"}; + // PID configs + Configurable> cfgPtPreselection{"cfgPtPreselection", {ese_parameters::PtPreselection[0], 5, 2, ese_parameters::names, ese_parameters::pidPtNames}, "Pt preselection for light nuclei"}; Configurable> cfgnSigmaCutTOFProton{"cfgnSigmaCutTOFProton", {-1.5, 1.5}, "TOF nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutTOFHe3{"cfgnSigmaCutTOFHe3", {-1.5, 1.5}, "TOF nsigma cut limit for He3"}; - Configurable> cfgnSigmaCutITSProton{"cfgnSigmaCutITSProton", {-3, 3}, "ITS nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutITSHe3{"cfgnSigmaCutITSHe3", {-3, 3}, "ITS nsigma cut limit for He3"}; Configurable> cfgnSigmaCutRMSProton{"cfgnSigmaCutRMSProton", {-3, 3}, "RMS nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutRMSHe3{"cfgnSigmaCutRMSHe3", {-3, 3}, "RMS nsigma cut limit for He3"}; - - Configurable> cfgPtBinProtonPID{"cfgPtBinProtonPID", {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0}, "pt bin for pion PIDnsigma"}; - Configurable> cfgPtBinHe3PID{"cfgPtBinHe3PID", {2, 2.2, 2.4, 2.6, 2.8, 3, 3.2, 3.6, 4, 4.4, 4.8, 5.2, 5.6, 6, 6.4, 7.2, 8, 10}, "pt bin for pion PIDnsigma"}; - - Configurable> cfgnSigmaTPCProtonPtUpper{"cfgnSigmaTPCProtonPtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaTPC cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTOFProtonPtUpper{"cfgnSigmaTOFProtonPtUpper", {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, "nSigmaTOF cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaITSProtonPtUpper{"cfgnSigmaITSProtonPtUpper", {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, "nSigmaITS cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaRMSProtonPtUpper{"cfgnSigmaRMSProtonPtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaRMS cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTPCProtonPtLower{"cfgnSigmaTPCProtonPtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaTPC cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTOFProtonPtLower{"cfgnSigmaTOFProtonPtLower", {-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, "nSigmaTOF cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaITSProtonPtLower{"cfgnSigmaITSProtonPtLower", {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, "nSigmaITS cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaRMSProtonPtLower{"cfgnSigmaRMSProtonPtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaRMS cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTPCHe3PtUpper{"cfgnSigmaTPCHe3PtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaTPC cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaTOFHe3PtUpper{"cfgnSigmaTOFHe3PtUpper", {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, "nSigmaTOF cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaITSHe3PtUpper{"cfgnSigmaITSHe3PtUpper", {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, "nSigmaITS cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaRMSHe3PtUpper{"cfgnSigmaRMSHe3PtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaRMS cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaTPCHe3PtLower{"cfgnSigmaTPCHe3PtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaTPC cut lower limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaTOFHe3PtLower{"cfgnSigmaTOFHe3PtLower", {-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, "nSigmaTOF cut lower limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaITSHe3PtLower{"cfgnSigmaITSHe3PtLower", {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, "nSigmaITS cut lower limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaRMSHe3PtLower{"cfgnSigmaRMSHe3PtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaRMS cut lower limit anchored to He3 pt bins"}; - + Configurable cfgUseSelfnSigmaTPCProton{"cfgUseSelfnSigmaTPCProton", false, "Use self nSigma TPC for Proton PID"}; + Configurable cfgProtonPIDMode{"cfgProtonPIDMode", 2, "Proton PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; + Configurable> cfgnSigmaTPC{"cfgnSigmaTPC", {ese_parameters::TPCnSigmaCutDefault[0], 5, 2, ese_parameters::names, ese_parameters::pidTPCnSigmaNames}, "TPC nSigma selection for light nuclei"}; + Configurable> cfgnSigmaITS{"cfgnSigmaITS", {ese_parameters::ITSnSigmaCutDefault[0], 5, 2, ese_parameters::names, ese_parameters::pidITSnSigmaNames}, "ITS nSigma selection for light nuclei"}; + // PID BBself paras config + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {ese_parameters::BetheBlochDefault[0], 5, 6, ese_parameters::names, ese_parameters::betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; + Configurable> cfgMomentumScalingBetheBloch{"cfgMomentumScalingBetheBloch", {ese_parameters::BbMomScalingDefault[0], 5, 2, ese_parameters::names, ese_parameters::chargeLabelNames}, "TPC Bethe-Bloch momentum scaling for light nuclei"}; + Configurable cfgCompensatePIDinTracking{"cfgCompensatePIDinTracking", true, "If true, divide tpcInnerParam by the electric charge"}; + // Axias configs ConfigurableAxis cfgrigidityBins{"cfgrigidityBins", {200, -10.f, 10.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; ConfigurableAxis cfgdedxBins{"cfgdedxBins", {1000, 0.f, 1000.f}, "Binning for dE/dx"}; ConfigurableAxis cfgnSigmaBinsTPC{"cfgnSigmaBinsTPC", {200, -5.f, 5.f}, "Binning for n sigma TPC"}; ConfigurableAxis cfgnSigmaBinsTOF{"cfgnSigmaBinsTOF", {200, -5.f, 5.f}, "Binning for n sigma TOF"}; ConfigurableAxis cfgnSigmaBinsITS{"cfgnSigmaBinsITS", {200, -5.f, 5.f}, "Binning for n sigma ITS"}; - ConfigurableAxis cfgnSigmaBinsRMS{"cfgnSigmaBinsRMS", {100, 0.f, 10.f}, "Combination Binning for TPC&TOF nsigma"}; - ConfigurableAxis cfgaxisptPID{"cfgaxisptPID", {120, 0, 12}, "Binning for P_{t} PID"}; - ConfigurableAxis cfgaxispPID{"cfgaxispPID", {50, 0, 5}, "Binning for P PID"}; + ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, "Binning for P_{t}"}; ConfigurableAxis cfgaxisetaPID{"cfgaxisetaPID", {90, -0.9, 0.9}, "Binning for Pt QA"}; ConfigurableAxis cfgaxisDCAz{"cfgaxisDCAz", {200, -1, 1}, "Binning for DCAz"}; ConfigurableAxis cfgaxisDCAxy{"cfgaxisDCAxy", {100, -0.5, 0.5}, "Binning for DCAxy"}; - ConfigurableAxis cfgaxisChi2Ncls{"cfgaxisChi2Ncls", {100, 0, 100}, "Binning for Chi2Ncls TPC/ITS"}; + ConfigurableAxis cfgaxisChi2Ncls{"cfgaxisChi2Ncls", {100, 0, 30}, "Binning for Chi2Ncls TPC/ITS"}; + ConfigurableAxis cfgaxisQvecF{"cfgaxisQvecF", {300, -1, 1}, ""}; + ConfigurableAxis cfgaxisCent{"cfgaxisCent", {90, 0, 90}, ""}; + ConfigurableAxis cfgaxisNch{"cfgaxisNch", {4000, 0, 4000}, "N_{ch}"}; + ConfigurableAxis cfgaxisT0C{"cfgaxisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; + ConfigurableAxis cfgaxisT0A{"cfgaxisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; + ConfigurableAxis cfgaxisNchPV{"cfgaxisNchPV", {4000, 0, 4000}, "N_{ch} (PV)"}; + ConfigurableAxis cfgaxisq2{"cfgaxisq2", {120, 0, 12}, "Binning for P_{t} PID"}; + ConfigurableAxis cfgaxiscos{"cfgaxiscos", {102, -1.02, 1.02}, ""}; - // Function for He3 TPC-ITS mismatching cuts referd to by chiara's slides - TF1* fNSigmaITSPt = nullptr; + uint8_t poiTar; + uint8_t poiRef; + int detId; + int refAId; + int refBId; + int detInd; + int refAInd; + int refBInd; + // Function for He3 purity cut refered from luca's slides + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; - template - bool trackSelBasic(const TrackType track) - { - if ((track.pt() < cfgMinPtPID) || (track.pt() > cfgMaxPtPID)) - return false; - if (std::abs(track.eta()) > cfgMaxEtaPID) - return false; - if (cfgOpenpassedITSNCls) { - if (!track.passedITSNCls()) - return false; - } else { - if (track.itsNCls() < cfgMinITSCls || track.itsNCls() > cfgMaxITSCls) - return false; - } - if (cfgOpenpassedITSChi2NDF) { - if (!track.passedITSChi2NDF()) - return false; - } else { - if (track.itsChi2NCl() < cfgMinChi2NClITS || track.itsChi2NCl() > cfgMaxChi2NClITS) - return false; - } - if (cfgOpenpassedITSHits) { - if (!track.passedITSHits()) - return false; - } - if (cfgOpenpassedTPCChi2NDF) { - if (!track.passedTPCChi2NDF()) - return false; - } else { - if (track.tpcChi2NCl() < cfgMinTPCChi2NCl || track.tpcChi2NCl() > cfgMaxTPCChi2NCl) - return false; - } - if (cfgOpenpassedTPCCrossedRowsOverNCls) { - if (!track.passedTPCCrossedRowsOverNCls()) - return false; - } - if (cfgOpenpassedDCAxy) { - if (!track.passedDCAxy()) - return false; - } else { - if (std::abs(track.dcaXY()) > cfgMaxDCAxy) - return false; - } - if (cfgOpenpassedDCAz) { - if (!track.passedDCAz()) - return false; - } else { - if (std::abs(track.dcaZ()) > cfgMaxDCAz) - return false; - } - if (track.tpcNClsFound() < cfgMinTPCCls || track.tpcNClsFound() > cfgMaxTPCCls) - return false; - return true; - } + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgVtzCut) && (aod::cent::centFT0C > cfgCentMin) && (aod::cent::centFT0C < cfgCentMax); - template - bool pidProtonSel(const TrackType track, float nSigmaLower, float nSigmaUpper) - { // proton == 1 , He3 == 2 - if (track.pt() < cfgPtCutProton.value[0] || track.pt() > cfgPtCutProton.value[1]) - return false; - float nSigmaUse = -999; - switch (cfgProtonPIDMode) { - case 0: // RMS - nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDPrton) ? std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr()) : track.tpcNSigmaPr(); - break; - case 1: // TPC only - nSigmaUse = track.tpcNSigmaPr(); - break; - case 2: // TOF only - nSigmaUse = track.tofNSigmaPr(); - break; - } - if (nSigmaUse < nSigmaLower || nSigmaUse > nSigmaUpper) { - return false; - } else { - return true; - } - } + Produces eseTable; template - bool pidHe3Sel(const TrackType track, float nSigmaLower, float nSigmaUpper) - { // proton == 1 , He3 == 2 - if (track.pt() < cfgPtCutHe3.value[0] || track.pt() > cfgPtCutHe3.value[1]) - return false; - float nSigmaUse = -999; - switch (cfgHe3PIDMode) { - case 0: // RMS - nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDHe3) ? std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe()) : track.tpcNSigmaHe(); - break; - case 1: // TPC only - nSigmaUse = track.tpcNSigmaHe(); - break; - case 2: // TOF only - nSigmaUse = track.tofNSigmaHe(); - break; - } - if (nSigmaUse < nSigmaLower || nSigmaUse > nSigmaUpper) { - return false; - } else { - return true; + float getNSigmaTPCSelfBB(const TrackType track, uint8_t POI) + { + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + const int iC{track.sign() < 0}; + switch (POI) { + case ese_parameters::kProton: { + const double bgScaling[2]{ese_parameters::Charges[0] * cfgMomentumScalingBetheBloch->get(0u, 0u) / ese_parameters::Masses[0], ese_parameters::Charges[0] * cfgMomentumScalingBetheBloch->get(0u, 1u) / ese_parameters::Masses[0]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(0u, 0u), cfgBetheBlochParams->get(0u, 1u), cfgBetheBlochParams->get(0u, 2u), cfgBetheBlochParams->get(0u, 3u), cfgBetheBlochParams->get(0u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(0u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kDeuteron: { + const double bgScaling[2]{ese_parameters::Charges[1] * cfgMomentumScalingBetheBloch->get(1u, 0u) / ese_parameters::Masses[1], ese_parameters::Charges[1] * cfgMomentumScalingBetheBloch->get(1u, 1u) / ese_parameters::Masses[1]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(1u, 0u), cfgBetheBlochParams->get(1u, 1u), cfgBetheBlochParams->get(1u, 2u), cfgBetheBlochParams->get(1u, 3u), cfgBetheBlochParams->get(1u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(1u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kTriton: { + const double bgScaling[2]{ese_parameters::Charges[2] * cfgMomentumScalingBetheBloch->get(2u, 0u) / ese_parameters::Masses[2], ese_parameters::Charges[2] * cfgMomentumScalingBetheBloch->get(2u, 1u) / ese_parameters::Masses[2]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(2u, 0u), cfgBetheBlochParams->get(2u, 1u), cfgBetheBlochParams->get(2u, 2u), cfgBetheBlochParams->get(2u, 3u), cfgBetheBlochParams->get(2u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(2u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kHe3: { + const double bgScaling[2]{ese_parameters::Charges[3] * cfgMomentumScalingBetheBloch->get(3u, 0u) / ese_parameters::Masses[3], ese_parameters::Charges[3] * cfgMomentumScalingBetheBloch->get(3u, 1u) / ese_parameters::Masses[3]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(3u, 0u), cfgBetheBlochParams->get(3u, 1u), cfgBetheBlochParams->get(3u, 2u), cfgBetheBlochParams->get(3u, 3u), cfgBetheBlochParams->get(3u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(3u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kAlpha: { + const double bgScaling[2]{ese_parameters::Charges[4] * cfgMomentumScalingBetheBloch->get(4u, 0u) / ese_parameters::Masses[4], ese_parameters::Charges[4] * cfgMomentumScalingBetheBloch->get(4u, 1u) / ese_parameters::Masses[4]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(4u, 0u), cfgBetheBlochParams->get(4u, 1u), cfgBetheBlochParams->get(4u, 2u), cfgBetheBlochParams->get(4u, 3u), cfgBetheBlochParams->get(4u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(4u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + default: + return -99.f; } } template - int crossTrackID(const TrackType track) + float getNSigmaTOF(const TrackType track, uint8_t POI) { - if (track.tpcNSigmaPr() < track.tpcNSigmaHe()) { - return 0; - } else { - return 1; + switch (POI) { + case ese_parameters::kProton: { + return track.tofNSigmaPr(); + } + case ese_parameters::kDeuteron: { + return track.tofNSigmaDe(); + } + case ese_parameters::kTriton: { + return track.tofNSigmaTr(); + } + case ese_parameters::kHe3: { + return track.tofNSigmaHe(); + } + case ese_parameters::kAlpha: { + return track.tofNSigmaAl(); + } + default: + return -99.f; } } - void init(InitContext const&) + template + float getNSigmaITS(const TrackType track, uint8_t POI) { - if (cfgOpenHe3ITSPtCut) { - fNSigmaITSPt = new TF1("fNSigmaITSPt", "[0]/pow(x,0.5) - [2]", 0.02, 1000); - fNSigmaITSPt->SetParameters(4.6, 0.5, 4.5); - } - AxisSpec axisITSNcls = {10, -1.5, 8.5, "ITSNcls"}; - AxisSpec axisTPCNcls = {160, 0, 160, "TPCNcls"}; - if (!cfgQuietMode) { - histosQA.add("QA/hist_dEdxTPC_All", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); - histosQA.add("QA/Proton/hist_dEdxTPC_Pr", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); - histosQA.add("QA/He3/hist_dEdxTPC_He3", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); - histosQA.add("QA/hist_pt_All", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); - histosQA.add("QA/Proton/hist_pt_Pr", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); - histosQA.add("QA/He3/hist_pt_He3", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); - histosQA.add("QA/hist_eta_All", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); - histosQA.add("QA/Proton/hist_eta_Pr", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); - histosQA.add("QA/He3/hist_eta_He3", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); - histosQA.add("QA/hist_ITSNcls_All", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); - histosQA.add("QA/Proton/hist_ITSNcls_Pr", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); - histosQA.add("QA/He3/hist_ITSNcls_He3", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); - histosQA.add("QA/hist_TPCNcls_All", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); - histosQA.add("QA/Proton/hist_TPCNcls_Pr", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); - histosQA.add("QA/He3/hist_TPCNcls_He3", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); - histosQA.add("QA/hist_ITSChi2NDF_All", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/Proton/hist_ITSChi2NDF_Pr", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/He3/hist_ITSChi2NDF_He3", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/hist_TPCChi2NDF_All", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/Proton/hist_TPCChi2NDF_Pr", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/He3/hist_TPCChi2NDF_He3", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/hist_DCAxy_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); - histosQA.add("QA/Proton/hist_DCAxy_Pr", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); - histosQA.add("QA/He3/hist_DCAxy_He3", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); - histosQA.add("QA/hist_DCAz_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); - histosQA.add("QA/Proton/hist_DCAz_Pr", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); - histosQA.add("QA/He3/hist_DCAz_He3", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); - histosQA.add("QA/Proton/hist_nSigmaTPC_Pr", ";n_{#sigma}TPC", {HistType::kTH1F, {cfgnSigmaBinsTPC}}); - histosQA.add("QA/Proton/hist_nSigmaTPCPt_Pr", ";#it{p}_{T};n_{#sigma}TPC", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTPC}}); - histosQA.add("QA/Proton/hist_nSigmaTOF_Pr", ";n_{#sigma}TOF", {HistType::kTH1F, {cfgnSigmaBinsTOF}}); - histosQA.add("QA/Proton/hist_nSigmaTOFPt_Pr", ";#it{p}_{T};n_{#sigma}TOF", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTOF}}); - histosQA.add("QA/Proton/hist_nSigmaITS_Pr", ";n_{#sigma}ITS", {HistType::kTH1F, {cfgnSigmaBinsITS}}); - histosQA.add("QA/Proton/hist_nSigmaITSPt_Pr", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); - histosQA.add("QA/Proton/hist_nSigmaRMS_Pr", ";n_{#sigma}RMS", {HistType::kTH1F, {cfgnSigmaBinsRMS}}); - histosQA.add("QA/Proton/hist_nSigmaRMSPt_Pr", ";#it{p}_{T};n_{#sigma}RMS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsRMS}}); - histosQA.add("QA/He3/hist_nSigmaTPC_He3", ";n_{#sigma}TPC", {HistType::kTH1F, {cfgnSigmaBinsTPC}}); - histosQA.add("QA/He3/hist_nSigmaTPCPt_He3", ";#it{p}_{T};n_{#sigma}TPC", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTPC}}); - histosQA.add("QA/He3/hist_nSigmaTOF_He3", ";n_{#sigma}TOF", {HistType::kTH1F, {cfgnSigmaBinsTOF}}); - histosQA.add("QA/He3/hist_nSigmaTOFPt_He3", ";#it{p}_{T};n_{#sigma}TOF", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTOF}}); - histosQA.add("QA/He3/hist_nSigmaITS_He3", ";n_{#sigma}ITS", {HistType::kTH1F, {cfgnSigmaBinsITS}}); - histosQA.add("QA/He3/hist_nSigmaITSPt_He3", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); - histosQA.add("QA/He3/hist_nSigmaRMS_He3", ";n_{#sigma}RMS", {HistType::kTH1F, {cfgnSigmaBinsRMS}}); - histosQA.add("QA/He3/hist_nSigmaRMSPt_He3", ";#it{p}_{T};n_{#sigma}RMS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsRMS}}); - if (cfgOpenHe3ITSPtCut) { - histosQA.add("QA/He3/hist_nSigmaITSPt_He3_unCuted", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); + switch (POI) { + case ese_parameters::kProton: { + return itsResponse.nSigmaITS(track); } - if (cfgOpenPlotnSigmaTOFITSPt) { - histosQA.add("QA/Proton/hist_nSigmaTOFITSPt_Pr", ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxisptPID}}); - histosQA.add("QA/He3/hist_nSigmaTOFITSPt_He3", ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxisptPID}}); + case ese_parameters::kDeuteron: { + return itsResponse.nSigmaITS(track); } - if (cfgOpenPlotnSigmaITSTPCPt) { - histosQA.add("QA/Proton/hist_nSigmaITSTPCPt_Pr", ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxisptPID}}); - histosQA.add("QA/He3/hist_nSigmaITSTPCPt_He3", ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxisptPID}}); + case ese_parameters::kTriton: { + return itsResponse.nSigmaITS(track); } - if (cfgOpenPlotnSigmaTOFTPCPt) { - histosQA.add("QA/Proton/hist_nSigmaTOFTPCPt_Pr", ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxisptPID}}); - histosQA.add("QA/He3/hist_nSigmaTOFTPCPt_He3", ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxisptPID}}); + case ese_parameters::kHe3: { + return itsResponse.nSigmaITS(track); } - } - } - Produces pidEsePHe3Table; - void process(TracksPID const& tracks) - { - auto tracksWithITSPid = soa::Attach(tracks); - int8_t pidFlag; - for (const auto& track : tracksWithITSPid) { - histosQA.fill(HIST("QA/hist_dEdxTPC_All"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); - histosQA.fill(HIST("QA/hist_pt_All"), track.pt()); - histosQA.fill(HIST("QA/hist_eta_All"), track.eta()); - histosQA.fill(HIST("QA/hist_ITSNcls_All"), track.itsNCls()); - histosQA.fill(HIST("QA/hist_TPCNcls_All"), track.tpcNClsFound()); - histosQA.fill(HIST("QA/hist_ITSChi2NDF_All"), track.itsChi2NCl()); - histosQA.fill(HIST("QA/hist_TPCChi2NDF_All"), track.tpcChi2NCl()); - histosQA.fill(HIST("QA/hist_DCAxy_All"), track.dcaXY()); - histosQA.fill(HIST("QA/hist_DCAz_All"), track.dcaZ()); - if (!trackSelBasic(track)) { - pidFlag = -1; - } else { - int currentPtBinPr = -1, currentPtBinHe3 = -1; - if (cfgOpenPIDByPtProtonMain || (cfgOpenPIDByPtProtonITS && cfgOpenPIDITSProton)) { - for (int i = 0; i < static_cast(cfgPtBinProtonPID.value.size()) - 1; ++i) { - if (track.pt() >= cfgPtBinProtonPID.value[i] && track.pt() < cfgPtBinProtonPID.value[i + 1]) { - currentPtBinPr = i; - break; - } - } - } - if (cfgOpenPIDByPtHe3Main || (cfgOpenPIDByPtHe3ITS && cfgOpenPIDITSHe3)) { - for (int i = 0; i < static_cast(cfgPtBinHe3PID.value.size()) - 1; ++i) { - if (track.pt() >= cfgPtBinHe3PID.value[i] && track.pt() < cfgPtBinHe3PID.value[i + 1]) { - currentPtBinHe3 = i; - break; - } - } - } - float nSigmaTPCCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutTPCProton.value[0] : cfgnSigmaTPCProtonPtLower.value[currentPtBinPr]; - float nSigmaTPCCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutTPCProton.value[1] : cfgnSigmaTPCProtonPtUpper.value[currentPtBinPr]; - float nSigmaTOFCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutTOFProton.value[0] : cfgnSigmaTOFProtonPtLower.value[currentPtBinPr]; - float nSigmaTOFCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutTOFProton.value[1] : cfgnSigmaTOFProtonPtUpper.value[currentPtBinPr]; - float nSigmaRMSCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutRMSProton.value[0] : cfgnSigmaRMSProtonPtLower.value[currentPtBinPr]; - float nSigmaRMSCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutRMSProton.value[1] : cfgnSigmaRMSProtonPtUpper.value[currentPtBinPr]; - float nSigmaITSCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutITSProton.value[0] : cfgnSigmaITSProtonPtLower.value[currentPtBinPr]; - float nSigmaITSCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutITSProton.value[1] : cfgnSigmaITSProtonPtUpper.value[currentPtBinPr]; - float nSigmaTPCCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutTPCHe3.value[0] : cfgnSigmaTPCHe3PtLower.value[currentPtBinHe3]; - float nSigmaTPCCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutTPCHe3.value[1] : cfgnSigmaTPCHe3PtUpper.value[currentPtBinHe3]; - float nSigmaTOFCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutTOFHe3.value[0] : cfgnSigmaTOFHe3PtLower.value[currentPtBinHe3]; - float nSigmaTOFCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutTOFHe3.value[1] : cfgnSigmaTOFHe3PtUpper.value[currentPtBinHe3]; - float nSigmaRMSCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutRMSHe3.value[0] : cfgnSigmaRMSHe3PtLower.value[currentPtBinHe3]; - float nSigmaRMSCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutRMSHe3.value[1] : cfgnSigmaRMSHe3PtUpper.value[currentPtBinHe3]; - float nSigmaITSCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutITSHe3.value[0] : cfgnSigmaITSHe3PtLower.value[currentPtBinHe3]; - float nSigmaITSCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutITSHe3.value[1] : cfgnSigmaITSHe3PtUpper.value[currentPtBinHe3]; - float nSigmaMainLowerPr = -999, nSigmaMainUpperPr = -999; - float nSigmaMainLowerHe3 = -999, nSigmaMainUpperHe3 = -999; - switch (cfgProtonPIDMode) { - case 0: - nSigmaMainLowerPr = nSigmaRMSCutPrPtLower; - nSigmaMainUpperPr = nSigmaRMSCutPrPtUpper; - break; - case 1: - nSigmaMainLowerPr = nSigmaTPCCutPrPtLower; - nSigmaMainUpperPr = nSigmaTPCCutPrPtUpper; - break; - case 2: - nSigmaMainLowerPr = nSigmaTOFCutPrPtLower; - nSigmaMainUpperPr = nSigmaTOFCutPrPtUpper; - break; - } - switch (cfgHe3PIDMode) { - case 0: - nSigmaMainLowerHe3 = nSigmaRMSCutHe3PtLower; - nSigmaMainUpperHe3 = nSigmaRMSCutHe3PtUpper; - break; - case 1: - nSigmaMainLowerHe3 = nSigmaTPCCutHe3PtLower; - nSigmaMainUpperHe3 = nSigmaTPCCutHe3PtUpper; - break; - case 2: - nSigmaMainLowerHe3 = nSigmaTOFCutHe3PtLower; - nSigmaMainUpperHe3 = nSigmaTOFCutHe3PtUpper; - break; - } - bool kIsPr = false, kIsHe3 = false; - // Identify Proton - if (pidProtonSel(track, nSigmaMainLowerPr, nSigmaMainUpperPr)) { - kIsPr = true; - if (cfgOpenPIDITSProton) { - if (track.itsNSigmaPr() < nSigmaITSCutPrPtLower || track.itsNSigmaPr() > nSigmaITSCutPrPtUpper) { - kIsPr = false; - } - } - } - // Identify He3 - if (pidHe3Sel(track, nSigmaMainLowerHe3, nSigmaMainUpperHe3)) { - kIsHe3 = true; - if (cfgOpenPIDITSHe3) { - if (track.itsNSigmaHe() < nSigmaITSCutHe3PtLower || track.itsNSigmaHe() > nSigmaITSCutHe3PtUpper) { - kIsHe3 = false; - } - } - } - // Cross track rejection - if (!cfgOpenAllowCrossTrack) { - if (kIsPr && kIsHe3) { - switch (crossTrackID(track)) { - case 0: - kIsPr = true; - kIsHe3 = false; - break; - case 1: - kIsPr = false; - kIsHe3 = true; - break; - } - } - } - // Filter He3 contaimination - if (cfgOpenHe3ITSPtCut && kIsHe3) { - if (!cfgQuietMode) { - histosQA.fill(HIST("QA/He3/hist_nSigmaITSPt_He3_unCuted"), track.pt(), track.itsNSigmaHe()); - } - if (track.itsNSigmaHe() < fNSigmaITSPt->Eval(track.pt())) { - kIsHe3 = false; - } - } - pidFlag = (kIsHe3 << 1) | kIsPr; - // Fill QA histograms - if (!cfgQuietMode) { - if (kIsPr) { - histosQA.fill(HIST("QA/Proton/hist_dEdxTPC_Pr"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); - histosQA.fill(HIST("QA/Proton/hist_pt_Pr"), track.pt()); - histosQA.fill(HIST("QA/Proton/hist_eta_Pr"), track.eta()); - histosQA.fill(HIST("QA/Proton/hist_ITSNcls_Pr"), track.itsNCls()); - histosQA.fill(HIST("QA/Proton/hist_TPCNcls_Pr"), track.tpcNClsFound()); - histosQA.fill(HIST("QA/Proton/hist_ITSChi2NDF_Pr"), track.itsChi2NCl()); - histosQA.fill(HIST("QA/Proton/hist_TPCChi2NDF_Pr"), track.tpcChi2NCl()); - histosQA.fill(HIST("QA/Proton/hist_DCAxy_Pr"), track.dcaXY()); - histosQA.fill(HIST("QA/Proton/hist_DCAz_Pr"), track.dcaZ()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTPC_Pr"), track.tpcNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTPCPt_Pr"), track.pt(), track.tpcNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOF_Pr"), track.tofNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFPt_Pr"), track.pt(), track.tofNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaITS_Pr"), track.itsNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaITSPt_Pr"), track.pt(), track.itsNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaRMS_Pr"), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); - histosQA.fill(HIST("QA/Proton/hist_nSigmaRMSPt_Pr"), track.pt(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); - if (cfgOpenPlotnSigmaTOFITSPt) { - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFITSPt_Pr"), track.tofNSigmaPr(), track.itsNSigmaPr(), track.pt()); - } - if (cfgOpenPlotnSigmaITSTPCPt) { - histosQA.fill(HIST("QA/Proton/hist_nSigmaITSTPCPt_Pr"), track.itsNSigmaPr(), track.tpcNSigmaPr(), track.pt()); - } - if (cfgOpenPlotnSigmaTOFTPCPt) { - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFTPCPt_Pr"), track.tofNSigmaPr(), track.tpcNSigmaPr(), track.pt()); - } - } - if (kIsHe3) { - histosQA.fill(HIST("QA/He3/hist_dEdxTPC_He3"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); - histosQA.fill(HIST("QA/He3/hist_pt_He3"), track.pt()); - histosQA.fill(HIST("QA/He3/hist_eta_He3"), track.eta()); - histosQA.fill(HIST("QA/He3/hist_ITSNcls_He3"), track.itsNCls()); - histosQA.fill(HIST("QA/He3/hist_TPCNcls_He3"), track.tpcNClsFound()); - histosQA.fill(HIST("QA/He3/hist_ITSChi2NDF_He3"), track.itsChi2NCl()); - histosQA.fill(HIST("QA/He3/hist_TPCChi2NDF_He3"), track.tpcChi2NCl()); - histosQA.fill(HIST("QA/He3/hist_DCAxy_He3"), track.dcaXY()); - histosQA.fill(HIST("QA/He3/hist_DCAz_He3"), track.dcaZ()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTPC_He3"), track.tpcNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTPCPt_He3"), track.pt(), track.tpcNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTOF_He3"), track.tofNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTOFPt_He3"), track.pt(), track.tofNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaITS_He3"), track.itsNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaITSPt_He3"), track.pt(), track.itsNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaRMS_He3"), std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe())); - histosQA.fill(HIST("QA/He3/hist_nSigmaRMSPt_He3"), track.pt(), std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe())); - if (cfgOpenPlotnSigmaTOFITSPt) { - histosQA.fill(HIST("QA/He3/hist_nSigmaTOFITSPt_He3"), track.tofNSigmaHe(), track.itsNSigmaHe(), track.pt()); - } - if (cfgOpenPlotnSigmaITSTPCPt) { - histosQA.fill(HIST("QA/He3/hist_nSigmaITSTPCPt_He3"), track.itsNSigmaHe(), track.tpcNSigmaHe(), track.pt()); - } - if (cfgOpenPlotnSigmaTOFTPCPt) { - histosQA.fill(HIST("QA/He3/hist_nSigmaTOFTPCPt_He3"), track.tofNSigmaHe(), track.tpcNSigmaHe(), track.pt()); - } - } - } + case ese_parameters::kAlpha: { + return itsResponse.nSigmaITS(track); } - pidEsePHe3Table(pidFlag); + default: + return -99.f; } } -}; - -struct FlowEsePHe3 { - HistogramRegistry histos{"histosmain", {}, OutputObjHandlingPolicy::AnalysisObject}; - - Configurable> cfgnMods{"cfgnMods", {2}, "Modulation of interest"}; - Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; - Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; - Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; - Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; - - Configurable cfgVtzCut{"cfgVtzCut", 10.0f, "Accepted z-vertex range"}; - Configurable cfgCentMin{"cfgCentMin", 0.0f, "Centrality min"}; - Configurable cfgCentMax{"cfgCentMax", 100.0f, "Centrality max"}; - - Configurable cfgCutOccupancyLow{"cfgCutOccupancyLow", 0, "Low boundary cut on TPC occupancy"}; - Configurable cfgCutOccupancyHigh{"cfgCutOccupancyHigh", 3000, "High boundary cut on TPC occupancy"}; - Configurable cfgUseAdditionalEventCut{"cfgUseAdditionalEventCut", true, "Use additional event cut beyond sel8"}; - Configurable cfgOpenEvSelkIsGoodZvtxFT0vsPV{"cfgOpenEvSelkIsGoodZvtxFT0vsPV", true, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution"}; - Configurable cfgOpenEvSelkNoSameBunchPileup{"cfgOpenEvSelkNoSameBunchPileup", true, "rejects collisions which are associated with the same found-by-T0 bunch crossing"}; - Configurable cfgOpenEvSelkNoCollInTimeRangeStandard{"cfgOpenEvSelkNoCollInTimeRangeStandard", true, "no collisions in specified time range"}; - Configurable cfgOpenEvSelkIsGoodITSLayersAll{"cfgOpenEvSelkIsGoodITSLayersAll", true, "cut time intervals with dead ITS staves"}; - Configurable cfgOpenEvSelkNoCollInRofStandard{"cfgOpenEvSelkNoCollInRofStandard", true, "no other collisions in this Readout Frame with per-collision multiplicity above threshold"}; - Configurable cfgOpenEvSelkNoHighMultCollInPrevRof{"cfgOpenEvSelkNoHighMultCollInPrevRof", true, "veto an event if FT0C amplitude in previous ITS ROF is above threshold"}; - Configurable cfgOpenEvSelOccupancy{"cfgOpenEvSelOccupancy", true, "Occupancy cut"}; - Configurable cfgOpenEvSelMultCorrelationPVTracks{"cfgOpenEvSelMultCorrelationPVTracks", true, "Multiplicity correlation cut for PVtracks vs centrality(FT0C)"}; - Configurable cfgOpenEvSelMultCorrelationGlobalTracks{"cfgOpenEvSelMultCorrelationGlobalTracks", false, "Multiplicity correlation cut for Globaltracks vs centrality(FT0C)"}; - Configurable cfgOpenEvSelV0AT0ACut{"cfgOpenEvSelV0AT0ACut", true, "V0A T0A 5 sigma cut"}; - Configurable cfgOpenFullEventQA{"cfgOpenFullEventQA", true, "Open full QA plots for event QA"}; - Configurable cfgOpenv2q{"cfgOpenv2q", true, "Open v2(EP)and q calculation for Proton and He3"}; - Configurable cfgOpenESE{"cfgOpenESE", true, "Open ESE process"}; - Configurable cfgOpenESEChargeSeperation{"cfgOpenESEChargeSeperation", true, "Open ESE for postive and negative charge repectivily"}; - Configurable cfgOpenESEProton{"cfgOpenESEProton", true, "Open ESE Proton process"}; - Configurable cfgOpenESEHe3{"cfgOpenESEHe3", true, "Open ESE He3 process"}; - - ConfigurableAxis cfgaxisQvecF{"cfgaxisQvecF", {300, -1, 1}, ""}; - ConfigurableAxis cfgaxisCent{"cfgaxisCent", {90, 0, 90}, ""}; - ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, ""}; - ConfigurableAxis cfgaxisCentForQA{"cfgaxisCentForQA", {100, 0, 100}, "centrality for event QA"}; - ConfigurableAxis cfgaxisNch{"cfgaxisNch", {4000, 0, 4000}, "N_{ch}"}; - ConfigurableAxis cfgaxisT0C{"cfgaxisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; - ConfigurableAxis cfgaxisT0A{"cfgaxisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; - ConfigurableAxis cfgaxisNchPV{"cfgaxisNchPV", {4000, 0, 4000}, "N_{ch} (PV)"}; - ConfigurableAxis cfgaxisq2{"cfgaxisq2", {120, 0, 12}, "Binning for P_{t} PID"}; - - EventPlaneHelper helperEP; - SliceCache cache; - - int detId; - int refAId; - int refBId; - // Additional Event selection cuts - Copy from flowGenericFramework.cxx - TF1* fMultPVCutLow = nullptr; - TF1* fMultPVCutHigh = nullptr; - TF1* fMultCutLow = nullptr; - TF1* fMultCutHigh = nullptr; - TF1* fT0AV0AMean = nullptr; - TF1* fT0AV0ASigma = nullptr; - - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgVtzCut) && (aod::cent::centFT0C > cfgCentMin) && (aod::cent::centFT0C < cfgCentMax); - Filter properPIDfilter = aod::flow_ese_p_he3::nPidFlag >= (int8_t)0; // Only POI - - Partition>> protonTrackSet = ((aod::flow_ese_p_he3::nPidFlag == pid_flags::kProton) || (aod::flow_ese_p_he3::nPidFlag == pid_flags::kProtonHe3)); - Partition>> he3TrackSet = ((aod::flow_ese_p_he3::nPidFlag == pid_flags::kHe3) || (aod::flow_ese_p_he3::nPidFlag == pid_flags::kProtonHe3)); template int getDetId(const T& name) @@ -637,160 +446,409 @@ struct FlowEsePHe3 { } } + template + uint8_t getPOI(const T& POI) + { + if (POI.value == "kProton") { + return ese_parameters::kProton; + } else if (POI.value == "kDeuteron") { + return ese_parameters::kDeuteron; + } else if (POI.value == "kTriton") { + return ese_parameters::kTriton; + } else if (POI.value == "kHe3") { + return ese_parameters::kHe3; + } else if (POI.value == "kAlpha") { + return ese_parameters::kAlpha; + } else { + LOGF(warning, "Unknown POI: %s", POI.value.c_str()); + return 0; + } + } + + float calculateq2(const float qx, const float qy, const int multi) + { + if (multi <= 0) { + return 0.f; + } else { + return std::hypot(qx, qy) / std::sqrt(static_cast(multi)); + } + } + template - bool selEvent(const CollType& collision, const int multTrk, const float centrality) + bool eventSelBasic(const CollType& collision, const int64_t multTrk, const float centrality, bool fillQA) { - histos.fill(HIST("QA/histEventCountDetail"), 0.5); - if (cfgOpenEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (!collision.sel8()) + return false; + if (fillQA) { + histsESE.fill(HIST("EventQA/histEventCount"), 0.5); + } + if (cfgOpenEvSel->get(0u) && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; } - if (cfgOpenEvSelkIsGoodZvtxFT0vsPV) { - histos.fill(HIST("QA/histEventCountDetail"), 1.5); + if (fillQA && cfgOpenEvSel->get(0u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 1.5); } - if (cfgOpenEvSelkNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + if (cfgOpenEvSel->get(1u) && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { return false; } - if (cfgOpenEvSelkNoSameBunchPileup) { - histos.fill(HIST("QA/histEventCountDetail"), 2.5); + if (fillQA && cfgOpenEvSel->get(1u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 2.5); } - if (cfgOpenEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + if (cfgOpenEvSel->get(2u) && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { return false; } - if (cfgOpenEvSelkNoCollInTimeRangeStandard) { - histos.fill(HIST("QA/histEventCountDetail"), 3.5); + if (fillQA && cfgOpenEvSel->get(2u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 3.5); } - if (cfgOpenEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (cfgOpenEvSel->get(3u) && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { return false; } - if (cfgOpenEvSelkIsGoodITSLayersAll) { - histos.fill(HIST("QA/histEventCountDetail"), 4.5); + if (fillQA && cfgOpenEvSel->get(3u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 4.5); } - if (cfgOpenEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + if (cfgOpenEvSel->get(4u) && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { return false; } - if (cfgOpenEvSelkNoCollInRofStandard) { - histos.fill(HIST("QA/histEventCountDetail"), 5.5); + if (fillQA && cfgOpenEvSel->get(4u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 5.5); } - if (cfgOpenEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + if (cfgOpenEvSel->get(5u) && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { return false; } - if (cfgOpenEvSelkNoHighMultCollInPrevRof) { - histos.fill(HIST("QA/histEventCountDetail"), 6.5); + if (fillQA && cfgOpenEvSel->get(5u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 6.5); } auto multNTracksPV = collision.multNTracksPV(); auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgOpenEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) { + if (cfgOpenEvSel->get(6u) && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) { return false; } - if (cfgOpenEvSelOccupancy) { - histos.fill(HIST("QA/histEventCountDetail"), 7.5); + if (fillQA && cfgOpenEvSel->get(6u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 7.5); } - if (cfgOpenEvSelMultCorrelationPVTracks) { + if (cfgOpenEvSel->get(7u)) { if (multNTracksPV < fMultPVCutLow->Eval(centrality)) return false; if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) return false; } - if (cfgOpenEvSelMultCorrelationPVTracks) { - histos.fill(HIST("QA/histEventCountDetail"), 8.5); + if (fillQA && cfgOpenEvSel->get(7u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 8.5); } - if (cfgOpenEvSelMultCorrelationGlobalTracks) { + if (cfgOpenEvSel->get(8u)) { if (multTrk < fMultCutLow->Eval(centrality)) return false; if (multTrk > fMultCutHigh->Eval(centrality)) return false; } - if (cfgOpenEvSelMultCorrelationGlobalTracks) { - histos.fill(HIST("QA/histEventCountDetail"), 9.5); + if (fillQA && cfgOpenEvSel->get(8u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 9.5); } - if (cfgOpenEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > event_selection::kFT0AV0ASigma * fT0AV0ASigma->Eval(collision.multFT0A()))) { + if (cfgOpenEvSel->get(9u) && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > ese_parameters::kFT0AV0ASigma * fT0AV0ASigma->Eval(collision.multFT0A()))) { return false; } - if (cfgOpenEvSelV0AT0ACut) { - histos.fill(HIST("QA/histEventCountDetail"), 10.5); + if (fillQA && cfgOpenEvSel->get(9u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 10.5); + } + if (fillQA) { + histsESE.fill(HIST("EventQA/histVtz"), collision.posZ()); + histsESE.fill(HIST("EventQA/histCent"), centrality); } return true; } + template + bool trackSelBasic(const TrackType track) + { + if ((track.pt() < cfgMinPtPID) || (track.pt() > cfgMaxPtPID)) + return false; + if (std::abs(track.eta()) > cfgMaxEtaPID) + return false; + if (cfgOpenTrackSel->get(0u)) { + if (!track.passedITSNCls()) + return false; + } else { + if (track.itsNCls() < cfgMinITSCls || track.itsNCls() > cfgMaxITSCls) + return false; + } + if (cfgOpenTrackSel->get(1u)) { + if (!track.passedITSChi2NDF()) + return false; + } else { + if (track.itsChi2NCl() < cfgMinChi2NClITS || track.itsChi2NCl() > cfgMaxChi2NClITS) + return false; + } + if (cfgOpenTrackSel->get(2u)) { + if (!track.passedITSHits()) + return false; + } + if (cfgOpenTrackSel->get(3u)) { + if (!track.passedTPCChi2NDF()) + return false; + } else { + if (track.tpcChi2NCl() < cfgMinTPCChi2NCl || track.tpcChi2NCl() > cfgMaxTPCChi2NCl) + return false; + } + if (cfgOpenTrackSel->get(4u)) { + if (!track.passedTPCCrossedRowsOverNCls()) + return false; + } + if (cfgOpenTrackSel->get(5u)) { + if (!track.passedDCAxy()) + return false; + } else { + if (std::abs(track.dcaXY()) > cfgMaxDCAxy) + return false; + } + if (cfgOpenTrackSel->get(6u)) { + if (!track.passedDCAz()) + return false; + } else { + if (std::abs(track.dcaZ()) > cfgMaxDCAz) + return false; + } + if (track.tpcNClsFound() < cfgMinTPCCls || track.tpcNClsFound() > cfgMaxTPCCls) + return false; + return true; + } + template - void fillHistosQvec(const CollType& collision, int nmode) + void fillEventQAhistBe(const CollType collision, const int multTrk, const float centrality) { - int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - if (nmode == fourier_mode::kMode2) { - if (collision.qvecAmp()[detId] > 1e-8) { - histos.fill(HIST("QA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); - histos.fill(HIST("QA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); - histos.fill(HIST("QA/histQvec_CorrL2_V2"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.centFT0C()); - histos.fill(HIST("QA/histQvec_CorrL3_V2"), collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL0_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode), collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL1_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], nmode), collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], nmode), collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), collision.centFT0C()); - } - if (collision.qvecAmp()[detId] > 1e-8 && collision.qvecAmp()[refAId] > 1e-8 && collision.qvecAmp()[refBId] > 1e-8) { - histos.fill(HIST("QA/histQvecRes_SigRefAV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), nmode)); - histos.fill(HIST("QA/histQvecRes_SigRefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode)); - histos.fill(HIST("QA/histQvecRes_RefARefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode)); - } + histsESE.fill(HIST("EventQA/hist_globalTracks_centT0C_before"), centrality, multTrk); + histsESE.fill(HIST("EventQA/hist_PVTracks_centT0C_before"), centrality, collision.multNTracksPV()); + histsESE.fill(HIST("EventQA/hist_globalTracks_PVTracks_before"), collision.multNTracksPV(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multT0A_before"), collision.multFT0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multV0A_before"), collision.multFV0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_multV0A_multT0A_before"), collision.multFT0A(), collision.multFV0A()); + histsESE.fill(HIST("EventQA/hist_multT0C_centT0C_before"), centrality, collision.multFT0C()); + } + + template + void fillEventQAhistAf(const CollType collision, const int multTrk, const float centrality) + { + histsESE.fill(HIST("EventQA/hist_globalTracks_centT0C_after"), centrality, multTrk); + histsESE.fill(HIST("EventQA/hist_PVTracks_centT0C_after"), centrality, collision.multNTracksPV()); + histsESE.fill(HIST("EventQA/hist_globalTracks_PVTracks_after"), collision.multNTracksPV(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multT0A_after"), collision.multFT0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multV0A_after"), collision.multFV0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_multV0A_multT0A_after"), collision.multFT0A(), collision.multFV0A()); + histsESE.fill(HIST("EventQA/hist_multT0C_centT0C_after"), centrality, collision.multFT0C()); + } + + template + void fillTrackQAhist(const TrackType track) + { + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + histsESE.fill(HIST("TrackQA/hist_dEdxTPC_All"), track.sign() * correctedTpcInnerParam, track.tpcSignal()); + histsESE.fill(HIST("TrackQA/hist_pt_All"), track.pt()); + histsESE.fill(HIST("TrackQA/hist_eta_All"), track.eta()); + histsESE.fill(HIST("TrackQA/hist_phi_All"), track.phi()); + histsESE.fill(HIST("TrackQA/hist_DCAxy_All"), track.dcaXY()); + histsESE.fill(HIST("TrackQA/hist_DCAz_All"), track.dcaZ()); + histsESE.fill(HIST("TrackQA/hist_ITSNcls_All"), track.itsNCls()); + histsESE.fill(HIST("TrackQA/hist_TPCNcls_All"), track.tpcNClsFound()); + histsESE.fill(HIST("TrackQA/hist_ITSChi2NDF_All"), track.itsChi2NCl()); + histsESE.fill(HIST("TrackQA/hist_TPCChi2NDF_All"), track.tpcChi2NCl()); + } + + template + void fillHistosQvec(const CollType& collision) + { + int detInd = detId * 4 + cfgnTotalSystem * 4 * (2 - 2); + int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (2 - 2); + int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (2 - 2); + if (collision.qvecAmp()[detId] > ese_parameters::Amplitudelow) { + histsESE.fill(HIST("PlanQA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histQvec_CorrL2_V2"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histQvec_CorrL3_V2"), collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL0_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], 2), collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL1_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], 2), collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], 2), collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2), collision.centFT0C()); + } + if (collision.qvecAmp()[detId] > ese_parameters::Amplitudelow && collision.qvecAmp()[refAId] > ese_parameters::Amplitudelow && collision.qvecAmp()[refBId] > ese_parameters::Amplitudelow) { + histsESE.fill(HIST("PlanQA/histQvecRes_SigRefAV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], 2), 2)); + histsESE.fill(HIST("PlanQA/histQvecRes_SigRefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], 2), 2)); + histsESE.fill(HIST("PlanQA/histQvecRes_RefARefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], 2), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], 2), 2)); } } template - float calculateq2(const TrackType tracks, float psi2, float cent, int pidmode) // pidmode 1 for proton , 2 for he3 + bool pidSel(const TrackType& track, uint8_t POI) { - int multi = tracks.size(); - if (multi > 0) { - float q2x = 0, q2y = 0; - for (const auto& track : tracks) { - q2x += std::cos(2 * track.phi()); - q2y += std::sin(2 * track.phi()); - if (pidmode == pid_flags::kProton) { - if (track.sign() > 0) { - histos.fill(HIST("V2/histCosV2EP_Pr_Pos"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); - } else { - histos.fill(HIST("V2/histCosV2EP_Pr_Neg"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + if (track.pt() < cfgPtPreselection->get(POI, 0u) || track.pt() > cfgPtPreselection->get(POI, 1u)) { + return false; + } + float nSigmaTPC = 0.f; + float nSigmaITS = 0.f; + switch (POI) { + case ese_parameters::kProton: + if (cfgProtonPIDMode == ese_parameters::kRMSMode) { // RMS mode + float nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDPrton) ? std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr()) : track.tpcNSigmaPr(); + if (nSigmaUse < cfgnSigmaCutRMSProton.value[0] || nSigmaUse > cfgnSigmaCutRMSProton.value[1]) { + return false; } - } - if (pidmode == pid_flags::kHe3) { - if (track.sign() > 0) { - histos.fill(HIST("V2/histCosV2EP_He3_Pos"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); - } else { - histos.fill(HIST("V2/histCosV2EP_He3_Neg"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + } else if (cfgProtonPIDMode == ese_parameters::kTPCMode) { // TPC mode + nSigmaTPC = (cfgUseSelfnSigmaTPCProton ? getNSigmaTPCSelfBB(track, ese_parameters::kProton) : track.tpcNSigmaPr()); + } else if (cfgProtonPIDMode == ese_parameters::kTOFOnlyMode) { // TOF only mode + if (!track.hasTOF()) + return false; + if (track.tofNSigmaPr() < cfgnSigmaCutTOFProton.value[0] || track.tofNSigmaPr() > cfgnSigmaCutTOFProton.value[1]) { + return false; } } - } - return std::hypot(q2x, q2y) / std::sqrt(multi); - } else { - return 0; + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kDeuteron: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kDeuteron); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kTriton: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kTriton); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kHe3: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kHe3); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kAlpha: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kAlpha); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + default: + LOGF(error, "Unknown POI: %d", POI); + return false; + } + if (nSigmaTPC < cfgnSigmaTPC->get(POI, 0u) || nSigmaTPC > cfgnSigmaTPC->get(POI, 1u)) { + return false; + } + if (nSigmaITS < cfgnSigmaITS->get(POI, 0u) || nSigmaITS > cfgnSigmaITS->get(POI, 1u)) { + return false; } + return true; } - template - void processESE(const TrackType tracks, float psi2, float q2, float cent, int pidmode, bool spcharge) // pidmode 1 for proton , 2 for he3 + template + void fillESECandidates(Tcoll const& collision, Ttrks const& tracks, float& q2Tarx, float& q2Tary, int& multiTar, float& q2Refx, float& q2Refy, int& multiRef) { - for (const auto& track : tracks) { - if (pidmode == pid_flags::kProton) { - if (spcharge) { + float psi2 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2); + float q2Tarinit{0.f}; + float q2Refinit{0.f}; + for (const auto& track : tracks) { // loop on tracks + if (!trackSelBasic(track)) { + continue; + } + // we fill the track info QA in the main process + fillTrackQAhist(track); + bool kIsTar{false}; + bool kIsRef{false}; + kIsTar = pidSel(track, poiTar); + kIsRef = pidSel(track, poiRef); + if (!cfgOpenAllowCrossTrack && kIsTar && kIsRef) { + if (getNSigmaTPCSelfBB(track, poiTar) < getNSigmaTPCSelfBB(track, poiRef)) { + kIsRef = false; + } else { + kIsTar = false; + } + } + if (kIsTar) { + multiTar++; + q2Tarx += std::cos(2 * track.phi()); + q2Tary += std::sin(2 * track.phi()); + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + float nSigmaTPCTar{(poiTar == ese_parameters::kProton && !cfgUseSelfnSigmaTPCProton) ? track.tpcNSigmaPr() : getNSigmaTPCSelfBB(track, poiTar)}; + float nSigmaTOFTar{getNSigmaTOF(track, poiTar)}; + float nSigmaITSTar{getNSigmaITS(track, poiTar)}; + if (cfgOpenPIDQA) { + ese_parameters::hPIDQATar1D[0]->Fill(track.pt()); + ese_parameters::hPIDQATar1D[1]->Fill(track.eta()); + ese_parameters::hPIDQATar1D[2]->Fill(track.phi()); + ese_parameters::hPIDQATar1D[3]->Fill(track.itsNCls()); + ese_parameters::hPIDQATar1D[4]->Fill(track.tpcNClsFound()); + ese_parameters::hPIDQATar1D[5]->Fill(track.itsChi2NCl()); + ese_parameters::hPIDQATar1D[6]->Fill(track.tpcChi2NCl()); + ese_parameters::hPIDQATar1D[7]->Fill(track.dcaXY()); + ese_parameters::hPIDQATar1D[8]->Fill(track.dcaZ()); + ese_parameters::hPIDQATar1D[9]->Fill(nSigmaTPCTar); + ese_parameters::hPIDQATar1D[10]->Fill(nSigmaTOFTar); + ese_parameters::hPIDQATar1D[11]->Fill(nSigmaITSTar); + ese_parameters::hPIDQATar2D[0]->Fill(track.sign() * correctedTpcInnerParam, track.tpcSignal()); + ese_parameters::hPIDQATar2D[1]->Fill(nSigmaTPCTar, track.pt()); + ese_parameters::hPIDQATar2D[2]->Fill(nSigmaTOFTar, track.pt()); + ese_parameters::hPIDQATar2D[3]->Fill(nSigmaITSTar, track.pt()); + if (cfgOpen3DPIDPlots->get(0u)) { + ese_parameters::hPIDQATar3D[0]->Fill(nSigmaTOFTar, nSigmaITSTar, track.pt()); + } + if (cfgOpen3DPIDPlots->get(1u)) { + ese_parameters::hPIDQATar3D[1]->Fill(nSigmaITSTar, nSigmaTPCTar, track.pt()); + } + if (cfgOpen3DPIDPlots->get(2u)) { + ese_parameters::hPIDQATar3D[2]->Fill(nSigmaTOFTar, nSigmaTPCTar, track.pt()); + } + } + if (cfgOpenv2) { if (track.sign() > 0) { - histos.fill(HIST("ESE/hist_v2PosPr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Tar[0]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } else { - histos.fill(HIST("ESE/hist_v2NegPr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Tar[1]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } - } else { - histos.fill(HIST("ESE/hist_v2Pr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); } + ese_parameters::eseCandidates.emplace_back(ESECandidate{ + collision.posZ(), collision.centFT0C(), psi2, q2Tarinit, q2Refinit, static_cast(track.sign()), correctedTpcInnerParam, track.tpcSignal(), track.pt(), track.eta(), track.phi(), + track.dcaXY(), track.dcaZ(), static_cast(track.tpcNClsFound()), track.itsNCls(), track.tpcChi2NCl(), track.itsChi2NCl(), + nSigmaTPCTar, nSigmaTOFTar, nSigmaITSTar, track.itsClusterSizes()}); } - if (pidmode == pid_flags::kHe3) { - if (spcharge) { + if (kIsRef) { + multiRef++; + q2Refx += std::cos(2 * track.phi()); + q2Refy += std::sin(2 * track.phi()); + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + float nSigmaTPCRef{(poiRef == ese_parameters::kProton && !cfgUseSelfnSigmaTPCProton) ? track.tpcNSigmaPr() : getNSigmaTPCSelfBB(track, poiRef)}; + float nSigmaTOFRef{getNSigmaTOF(track, poiRef)}; + float nSigmaITSRef{getNSigmaITS(track, poiRef)}; + if (cfgOpenPIDQA) { + ese_parameters::hPIDQARef1D[0]->Fill(track.pt()); + ese_parameters::hPIDQARef1D[1]->Fill(track.eta()); + ese_parameters::hPIDQARef1D[2]->Fill(track.phi()); + ese_parameters::hPIDQARef1D[3]->Fill(track.itsNCls()); + ese_parameters::hPIDQARef1D[4]->Fill(track.tpcNClsFound()); + ese_parameters::hPIDQARef1D[5]->Fill(track.itsChi2NCl()); + ese_parameters::hPIDQARef1D[6]->Fill(track.tpcChi2NCl()); + ese_parameters::hPIDQARef1D[7]->Fill(track.dcaXY()); + ese_parameters::hPIDQARef1D[8]->Fill(track.dcaZ()); + ese_parameters::hPIDQARef1D[9]->Fill(nSigmaTPCRef); + ese_parameters::hPIDQARef1D[10]->Fill(nSigmaTOFRef); + ese_parameters::hPIDQARef1D[11]->Fill(nSigmaITSRef); + ese_parameters::hPIDQARef2D[0]->Fill(track.sign() * correctedTpcInnerParam, track.tpcSignal()); + ese_parameters::hPIDQARef2D[1]->Fill(nSigmaTPCRef, track.pt()); + ese_parameters::hPIDQARef2D[2]->Fill(nSigmaTOFRef, track.pt()); + ese_parameters::hPIDQARef2D[3]->Fill(nSigmaITSRef, track.pt()); + if (cfgOpen3DPIDPlots->get(0u)) { + ese_parameters::hPIDQARef3D[0]->Fill(nSigmaTOFRef, nSigmaITSRef, track.pt()); + } + if (cfgOpen3DPIDPlots->get(1u)) { + ese_parameters::hPIDQARef3D[1]->Fill(nSigmaITSRef, nSigmaTPCRef, track.pt()); + } + if (cfgOpen3DPIDPlots->get(2u)) { + ese_parameters::hPIDQARef3D[2]->Fill(nSigmaTOFRef, nSigmaTPCRef, track.pt()); + } + } + if (cfgOpenv2) { if (track.sign() > 0) { - histos.fill(HIST("ESE/hist_v2PosHe3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Ref[0]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } else { - histos.fill(HIST("ESE/hist_v2NegHe3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Ref[1]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } - } else { - histos.fill(HIST("ESE/hist_v2He3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); } } } @@ -798,6 +856,8 @@ struct FlowEsePHe3 { void init(InitContext const&) { + poiTar = getPOI(cfgTarName); + poiRef = getPOI(cfgRefName); detId = getDetId(cfgDetName); refAId = getDetId(cfgRefAName); refBId = getDetId(cfgRefBName); @@ -807,169 +867,186 @@ struct FlowEsePHe3 { refAId = 4; refBId = 5; } - if (cfgUseAdditionalEventCut) { - fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); - fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + detInd = detId * 4 + cfgnTotalSystem * 4 * (2 - 2); + refAInd = refAId * 4 + cfgnTotalSystem * 4 * (2 - 2); + refBInd = refBId * 4 + cfgnTotalSystem * 4 * (2 - 2); - fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); - fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); - fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); - fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); - fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); - fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); - } + AxisSpec axisITSNcls = {10, -1.5, 8.5, "ITSNcls"}; + AxisSpec axisTPCNcls = {160, 0, 160, "TPCNcls"}; AxisSpec axisEvtPl = {100, -1.0 * constants::math::PI, constants::math::PI}; - AxisSpec axisvertexz = {100, -15., 15., "vrtx_{Z} [cm]"}; - histos.add("QA/histEventCount", "", {HistType::kTH1F, {{3, 0.0, 3.0}}}); - histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(1, "Filtered event"); - histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(2, "after sel8"); - histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(3, "after additional event cut"); - if (cfgUseAdditionalEventCut) { - histos.add("QA/histEventCountDetail", "Number of Event;; Count", {HistType::kTH1F, {{11, 0, 11}}}); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(1, "after sel8"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(2, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(8, "occupancy"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(9, "MultCorrelationPVTracks"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(10, "MultCorrelationGlobalTracks"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(11, "cfgEvSelV0AT0ACut"); - } + AxisSpec axisPhi = {200, -2.1 * constants::math::PI, 2.1 * constants::math::PI}; + AxisSpec axisCentForQA = {100, 0, 100}; + AxisSpec axisCharge = {4, -2, 2, "Charge"}; + // hists for event level QA + histsESE.add("EventQA/histEventCount", ";Event Count;Counts", {HistType::kTH1F, {{100, 0, 100}}}); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(1, "after sel8"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(2, "kIsGoodZvtxFT0vsPV"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(8, "occupancy"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(9, "MultCorrelationPVTracks"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(10, "MultCorrelationGlobalTracks"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(11, "cfgEvSelV0AT0ACut"); + histsESE.add("EventQA/histVtz", ";#it{Vtz} (cm);Counts", {HistType::kTH1F, {{200, -20., +20.}}}); + histsESE.add("EventQA/histCent", ";Centrality (%);Counts", {HistType::kTH1F, {{100, 0., 100.}}}); if (cfgOpenFullEventQA) { - histos.add("QA/hist_globalTracks_centT0C_before", "before cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNch}}); - histos.add("QA/hist_PVTracks_centT0C_before", "before cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNchPV}}); - histos.add("QA/hist_globalTracks_PVTracks_before", "before cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multT0A_before", "before cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multV0A_before", "before cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_multV0A_multT0A_before", "before cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); - histos.add("QA/hist_multT0C_centT0C_before", "before cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisT0C}}); - histos.add("QA/hist_globalTracks_centT0C_after", "after cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNch}}); - histos.add("QA/hist_PVTracks_centT0C_after", "after cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNchPV}}); - histos.add("QA/hist_globalTracks_PVTracks_after", "after cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multT0A_after", "after cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multV0A_after", "after cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_multV0A_multT0A_after", "after cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); - histos.add("QA/hist_multT0C_centT0C_after", "after cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisT0C}}); - } - histos.add("QA/histVertexZRec", ";vrtx_{Z} [cm];counts", {HistType::kTH1F, {axisvertexz}}); - histos.add("QA/histCentrality", ";Centrality;counts", {HistType::kTH1F, {cfgaxisCentForQA}}); - histos.add("QA/histProtonNum", "ProtonNum;counts", {HistType::kTH1F, {{100, 0, 100}}}); - histos.add("QA/histHe3Num", "He3Num;counts", {HistType::kTH1F, {{20, 0, 20}}}); - histos.add("QA/histQvec_CorrL0_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histQvec_CorrL1_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histQvec_CorrL2_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histQvec_CorrL3_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL0_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL1_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL2_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL3_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histQvecRes_SigRefAV2", ";Centrality;Cos(Sig-RefA)", {HistType::kTProfile, {cfgaxisCent}}); - histos.add("QA/histQvecRes_SigRefBV2", ";Centrality;Cos(Sig-RefB)", {HistType::kTProfile, {cfgaxisCent}}); - histos.add("QA/histQvecRes_RefARefBV2", ";Centrality;Cos(RefA-RefB)", {HistType::kTProfile, {cfgaxisCent}}); - if (cfgOpenv2q) { - histos.add("V2/histCosV2EP_Pr_Pos", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("V2/histCosV2EP_Pr_Neg", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("V2/histCosV2EP_He3_Pos", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("V2/histCosV2EP_He3_Neg", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("q2/hist_q2_Cen_Pr", ";q_{2} (TPC);Centrality", {HistType::kTH2F, {cfgaxisq2, cfgaxisCent}}); - histos.add("q2/hist_q2_Cen_He3", ";q_{2} (TPC);Centrality", {HistType::kTH2F, {cfgaxisq2, cfgaxisCent}}); - histos.add("q2/hist_q2_Pr", ";q_{2} (TPC);counts", {HistType::kTH1F, {cfgaxisq2}}); - histos.add("q2/hist_q2_He3", ";q_{2} (TPC);counts", {HistType::kTH1F, {cfgaxisq2}}); + histsESE.add("EventQA/hist_globalTracks_centT0C_before", "before cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNch}}); + histsESE.add("EventQA/hist_PVTracks_centT0C_before", "before cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNchPV}}); + histsESE.add("EventQA/hist_globalTracks_PVTracks_before", "before cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multT0A_before", "before cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multV0A_before", "before cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_multV0A_multT0A_before", "before cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); + histsESE.add("EventQA/hist_multT0C_centT0C_before", "before cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {axisCentForQA, cfgaxisT0C}}); + histsESE.add("EventQA/hist_globalTracks_centT0C_after", "after cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNch}}); + histsESE.add("EventQA/hist_PVTracks_centT0C_after", "after cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNchPV}}); + histsESE.add("EventQA/hist_globalTracks_PVTracks_after", "after cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multT0A_after", "after cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multV0A_after", "after cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_multV0A_multT0A_after", "after cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); + histsESE.add("EventQA/hist_multT0C_centT0C_after", "after cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {axisCentForQA, cfgaxisT0C}}); } - if (cfgOpenESE) { - if (cfgOpenESEChargeSeperation) { - if (cfgOpenESEProton) { - histos.add("ESE/hist_v2PosPr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - histos.add("ESE/hist_v2NegPr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } - if (cfgOpenESEHe3) { - histos.add("ESE/hist_v2PosHe3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - histos.add("ESE/hist_v2NegHe3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } - } else { - if (cfgOpenESEProton) { - histos.add("ESE/hist_v2Pr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } - if (cfgOpenESEHe3) { - histos.add("ESE/hist_v2He3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } + histsESE.add("PlanQA/histQvec_CorrL0_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histQvec_CorrL1_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histQvec_CorrL2_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histQvec_CorrL3_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL0_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL1_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL2_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL3_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histQvecRes_SigRefAV2", ";Centrality;Cos(Sig-RefA)", {HistType::kTProfile, {cfgaxisCent}}); + histsESE.add("PlanQA/histQvecRes_SigRefBV2", ";Centrality;Cos(Sig-RefB)", {HistType::kTProfile, {cfgaxisCent}}); + histsESE.add("PlanQA/histQvecRes_RefARefBV2", ";Centrality;Cos(RefA-RefB)", {HistType::kTProfile, {cfgaxisCent}}); + // hists for track level QA + histsESE.add("TrackQA/hist_dEdxTPC_All", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); + histsESE.add("TrackQA/hist_pt_All", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxispt}}); + histsESE.add("TrackQA/hist_eta_All", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); + histsESE.add("TrackQA/hist_phi_All", ";#it{#phi};counts", {HistType::kTH1F, {axisPhi}}); + histsESE.add("TrackQA/hist_ITSNcls_All", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); + histsESE.add("TrackQA/hist_TPCNcls_All", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); + histsESE.add("TrackQA/hist_ITSChi2NDF_All", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histsESE.add("TrackQA/hist_TPCChi2NDF_All", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histsESE.add("TrackQA/hist_DCAxy_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); + histsESE.add("TrackQA/hist_DCAz_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); + // v2 and ESEPlots + /// QA plots + if (cfgOpenPIDQA) { + ese_parameters::hPIDQATar2D[0] = histsESE.add(Form("ESE/TrackQA/hist_dEdxTPC_%s", cfgTarName.value.c_str()), ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}); + ese_parameters::hPIDQATar1D[0] = histsESE.add(Form("ESE/TrackQA/hist_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};counts", HistType::kTH1F, {cfgaxispt}); + ese_parameters::hPIDQATar1D[1] = histsESE.add(Form("ESE/TrackQA/hist_eta_%s", cfgTarName.value.c_str()), ";#it{#eta};counts", HistType::kTH1F, {cfgaxisetaPID}); + ese_parameters::hPIDQATar1D[2] = histsESE.add(Form("ESE/TrackQA/hist_phi_%s", cfgTarName.value.c_str()), ";#it{#phi};counts", HistType::kTH1F, {axisPhi}); + ese_parameters::hPIDQATar1D[3] = histsESE.add(Form("ESE/TrackQA/hist_ITSNcls_%s", cfgTarName.value.c_str()), ";ITSNcls;counts", HistType::kTH1F, {axisITSNcls}); + ese_parameters::hPIDQATar1D[4] = histsESE.add(Form("ESE/TrackQA/hist_TPCNcls_%s", cfgTarName.value.c_str()), ";TPCNcls;counts", HistType::kTH1F, {axisTPCNcls}); + ese_parameters::hPIDQATar1D[5] = histsESE.add(Form("ESE/TrackQA/hist_ITSChi2NDF_%s", cfgTarName.value.c_str()), ";ITS#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQATar1D[6] = histsESE.add(Form("ESE/TrackQA/hist_TPCChi2NDF_%s", cfgTarName.value.c_str()), ";TPC#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQATar1D[7] = histsESE.add(Form("ESE/TrackQA/hist_DCAxy_%s", cfgTarName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAxy}); + ese_parameters::hPIDQATar1D[8] = histsESE.add(Form("ESE/TrackQA/hist_DCAz_%s", cfgTarName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAz}); + ese_parameters::hPIDQATar1D[9] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_%s", cfgTarName.value.c_str()), ";n#sigmaTPC;counts", HistType::kTH1F, {cfgnSigmaBinsTPC}); + ese_parameters::hPIDQATar2D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};n#sigmaTPC", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTPC}); + ese_parameters::hPIDQATar1D[10] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_%s", cfgTarName.value.c_str()), ";n#sigmaTOF;counts", HistType::kTH1F, {cfgnSigmaBinsTOF}); + ese_parameters::hPIDQATar2D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};n#sigmaTOF", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTOF}); + ese_parameters::hPIDQATar1D[11] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_%s", cfgTarName.value.c_str()), ";n#sigmaITS;counts", HistType::kTH1F, {cfgnSigmaBinsITS}); + ese_parameters::hPIDQATar2D[3] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};n#sigmaITS", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsITS}); + ese_parameters::hPIDQARef2D[0] = histsESE.add(Form("ESE/TrackQA/hist_dEdxTPC_%s", cfgRefName.value.c_str()), ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}); + ese_parameters::hPIDQARef1D[0] = histsESE.add(Form("ESE/TrackQA/hist_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};counts", HistType::kTH1F, {cfgaxispt}); + ese_parameters::hPIDQARef1D[1] = histsESE.add(Form("ESE/TrackQA/hist_eta_%s", cfgRefName.value.c_str()), ";#it{#eta};counts", HistType::kTH1F, {cfgaxisetaPID}); + ese_parameters::hPIDQARef1D[2] = histsESE.add(Form("ESE/TrackQA/hist_phi_%s", cfgRefName.value.c_str()), ";#it{#phi};counts", HistType::kTH1F, {axisPhi}); + ese_parameters::hPIDQARef1D[3] = histsESE.add(Form("ESE/TrackQA/hist_ITSNcls_%s", cfgRefName.value.c_str()), ";ITSNcls;counts", HistType::kTH1F, {axisITSNcls}); + ese_parameters::hPIDQARef1D[4] = histsESE.add(Form("ESE/TrackQA/hist_TPCNcls_%s", cfgRefName.value.c_str()), ";TPCNcls;counts", HistType::kTH1F, {axisTPCNcls}); + ese_parameters::hPIDQARef1D[5] = histsESE.add(Form("ESE/TrackQA/hist_ITSChi2NDF_%s", cfgRefName.value.c_str()), ";ITS#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQARef1D[6] = histsESE.add(Form("ESE/TrackQA/hist_TPCChi2NDF_%s", cfgRefName.value.c_str()), ";TPC#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQARef1D[7] = histsESE.add(Form("ESE/TrackQA/hist_DCAxy_%s", cfgRefName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAxy}); + ese_parameters::hPIDQARef1D[8] = histsESE.add(Form("ESE/TrackQA/hist_DCAz_%s", cfgRefName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAz}); + ese_parameters::hPIDQARef1D[9] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_%s", cfgRefName.value.c_str()), ";n#sigmaTPC;counts", HistType::kTH1F, {cfgnSigmaBinsTPC}); + ese_parameters::hPIDQARef2D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};n#sigmaTPC", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTPC}); + ese_parameters::hPIDQARef1D[10] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_%s", cfgRefName.value.c_str()), ";n#sigmaTOF;counts", HistType::kTH1F, {cfgnSigmaBinsTOF}); + ese_parameters::hPIDQARef2D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};n#sigmaTOF", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTOF}); + ese_parameters::hPIDQARef1D[11] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_%s", cfgRefName.value.c_str()), ";n#sigmaITS;counts", HistType::kTH1F, {cfgnSigmaBinsITS}); + ese_parameters::hPIDQARef2D[3] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};n#sigmaITS", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsITS}); + if (cfgOpen3DPIDPlots->get(0u)) { + ese_parameters::hPIDQATar3D[0] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFITSPt_%s", cfgTarName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxispt}); + ese_parameters::hPIDQARef3D[0] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFITSPt_%s", cfgRefName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxispt}); } + if (cfgOpen3DPIDPlots->get(1u)) { + ese_parameters::hPIDQATar3D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITSTPCPt_%s", cfgTarName.value.c_str()), ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxispt}); + ese_parameters::hPIDQARef3D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITSTPCPt_%s", cfgRefName.value.c_str()), ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxispt}); + } + if (cfgOpen3DPIDPlots->get(2u)) { + ese_parameters::hPIDQATar3D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFTPCPt_%s", cfgTarName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxispt}); + ese_parameters::hPIDQARef3D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFTPCPt_%s", cfgRefName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxispt}); + } + } + // v2 plots + if (cfgOpenv2) { + ese_parameters::hv2Tar[0] = histsESE.add(Form("ESE/V2/hist_%sPosV2", cfgTarName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + ese_parameters::hv2Tar[1] = histsESE.add(Form("ESE/V2/hist_%sNegV2", cfgTarName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + ese_parameters::hv2Ref[0] = histsESE.add(Form("ESE/V2/hist_%sPosV2", cfgRefName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + ese_parameters::hv2Ref[1] = histsESE.add(Form("ESE/V2/hist_%sNegV2", cfgRefName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + } + // ESE plots + if (cfgOpenESEQA) { + ese_parameters::hESEQATar1D[0] = histsESE.add(Form("ESE/ESEQA/hist_%sNum", cfgTarName.value.c_str()), ";Num_{Proton}/Event;counts", HistType::kTH1F, {{100, 0, 100}}); + ese_parameters::hESEQATar1D[1] = histsESE.add(Form("ESE/ESEQA/hist_%sq2", cfgTarName.value.c_str()), ";#it{q}_{2};counts", HistType::kTH1F, {cfgaxisq2}); + ese_parameters::hESEQATar2D = histsESE.add(Form("ESE/ESEQA/hist_%sq2_Cent", cfgTarName.value.c_str()), ";#it{q}_{2};Centrality (%)", HistType::kTH2F, {cfgaxisq2, cfgaxisCent}); + ese_parameters::hESEQARef1D[0] = histsESE.add(Form("ESE/ESEQA/hist_%sNum", cfgRefName.value.c_str()), ";Num_{He3}/Event;counts", HistType::kTH1F, {{10, 0, 10}}); + ese_parameters::hESEQARef1D[1] = histsESE.add(Form("ESE/ESEQA/hist_%sq2", cfgRefName.value.c_str()), ";#it{q}_{2};counts", HistType::kTH1F, {cfgaxisq2}); + ese_parameters::hESEQARef2D = histsESE.add(Form("ESE/ESEQA/hist_%sq2_Cent", cfgRefName.value.c_str()), ";#it{q}_{2};Centrality (%)", HistType::kTH2F, {cfgaxisq2, cfgaxisCent}); + } + if (cfgOpenESE) { + ese_parameters::hESETar = histsESE.add(Form("ESE/ESE/histESE_%s", cfgTarName.value.c_str()), ";#it{p}_{T};Centrality (%);#it{q}_{2};cos(#phi-#Psi_{2});Charge", HistType::kTHnSparseF, {cfgaxispt, cfgaxisCent, cfgaxisq2, cfgaxiscos, axisCharge}); } } - void process(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks) + void process(soa::Filtered>::iterator const& collision, TracksPIDFull const& tracks) { - const auto cent = collision.centFT0C(); - histos.fill(HIST("QA/histEventCount"), 0.5); - if (!collision.sel8()) - return; - if (tracks.size() < 1) - return; - histos.fill(HIST("QA/histEventCount"), 1.5); - if (cfgOpenFullEventQA) { - histos.fill(HIST("QA/hist_globalTracks_centT0C_before"), cent, tracks.size()); - histos.fill(HIST("QA/hist_PVTracks_centT0C_before"), cent, collision.multNTracksPV()); - histos.fill(HIST("QA/hist_globalTracks_PVTracks_before"), collision.multNTracksPV(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multT0A_before"), collision.multFT0A(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multV0A_before"), collision.multFV0A(), tracks.size()); - histos.fill(HIST("QA/hist_multV0A_multT0A_before"), collision.multFT0A(), collision.multFV0A()); - histos.fill(HIST("QA/hist_multT0C_centT0C_before"), cent, collision.multFT0C()); - } - if (cfgUseAdditionalEventCut && !selEvent(collision, tracks.size(), cent)) { + ese_parameters::eseCandidates.clear(); + const float centrality{collision.centFT0C()}; + const int64_t multTrk{tracks.size()}; + if (cfgOpenFullEventQA) + fillEventQAhistBe(collision, multTrk, centrality); + if (!eventSelBasic(collision, multTrk, centrality, true)) return; + if (cfgOpenFullEventQA) + fillEventQAhistAf(collision, multTrk, centrality); + float q2Tarx{0.}; + float q2Tary{0.}; + float q2Refx{0.}; + float q2Refy{0.}; + int multiTar{0}; + int multiRef{0}; + fillESECandidates(collision, tracks, q2Tarx, q2Tary, multiTar, q2Refx, q2Refy, multiRef); + float q2Tar{calculateq2(q2Tarx, q2Tary, multiTar)}; + float q2Ref{calculateq2(q2Refx, q2Refy, multiRef)}; + if (cfgOpenESEQA) { + ese_parameters::hESEQATar1D[0]->Fill(multiTar); + ese_parameters::hESEQATar1D[1]->Fill(q2Tar); + ese_parameters::hESEQATar2D->Fill(q2Tar, centrality); + ese_parameters::hESEQARef1D[0]->Fill(multiRef); + ese_parameters::hESEQARef1D[1]->Fill(q2Ref); + ese_parameters::hESEQARef2D->Fill(q2Ref, centrality); } - histos.fill(HIST("QA/histEventCount"), 2.5); - histos.fill(HIST("QA/histCentrality"), cent); - histos.fill(HIST("QA/histVertexZRec"), collision.posZ()); - if (cfgOpenFullEventQA) { - histos.fill(HIST("QA/hist_globalTracks_centT0C_after"), cent, tracks.size()); - histos.fill(HIST("QA/hist_PVTracks_centT0C_after"), cent, collision.multNTracksPV()); - histos.fill(HIST("QA/hist_globalTracks_PVTracks_after"), collision.multNTracksPV(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multT0A_after"), collision.multFT0A(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multV0A_after"), collision.multFV0A(), tracks.size()); - histos.fill(HIST("QA/hist_multV0A_multT0A_after"), collision.multFT0A(), collision.multFV0A()); - histos.fill(HIST("QA/hist_multT0C_centT0C_after"), cent, collision.multFT0C()); - } - auto tracksPr = protonTrackSet->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto tracksHe3 = he3TrackSet->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - int multiPr = tracksPr.size(); - int multiHe3 = tracksHe3.size(); - // LOGF(info, Form("Collison ID + 1; Proton Num:%d; He3 Num:%d;\n", multiPr, multiHe3)); - histos.fill(HIST("QA/histProtonNum"), multiPr); - histos.fill(HIST("QA/histHe3Num"), multiHe3); - if (multiPr < 1 && multiHe3 < 1) - return; // Reject Collisions without enough POI - for (auto i = 0; i < static_cast(cfgnMods->size()); i++) { - int detIndGlobal = detId * 4 + cfgnTotalSystem * 4 * (cfgnMods->at(i) - 2); - float psiNGlobal = helperEP.GetEventPlane(collision.qvecRe()[detIndGlobal + 3], collision.qvecIm()[detIndGlobal + 3], cfgnMods->at(i)); - if (cfgnMods->at(i) == fourier_mode::kMode2) { - // LOGF(info, "Process q2\n"); - float q2Proton = calculateq2(tracksPr, psiNGlobal, cent, 1); - float q2He3 = calculateq2(tracksHe3, psiNGlobal, cent, 2); - histos.fill(HIST("q2/hist_q2_Pr"), q2Proton); - histos.fill(HIST("q2/hist_q2_He3"), q2He3); - histos.fill(HIST("q2/hist_q2_Cen_Pr"), q2Proton, cent); - histos.fill(HIST("q2/hist_q2_Cen_He3"), q2He3, cent); - if (cfgOpenESE && multiPr > 0 && multiHe3 > 0) { - // LOGF(info, "Process ESE\n"); - if (cfgOpenESEProton) { - processESE(tracksPr, psiNGlobal, q2Proton, cent, 1, cfgOpenESEChargeSeperation); - } - if (cfgOpenESEHe3) { - processESE(tracksHe3, psiNGlobal, q2He3, cent, 2, cfgOpenESEChargeSeperation); - } - } - // LOGF(info, "Process for this event over\n"); + if (multiTar == 0) + return; + for (const auto& c : ese_parameters::eseCandidates) { + eseTable(c.vtz, c.centFT0C, c.psi2FT0C, q2Tar, q2Ref, c.signTar, c.tpcInnerParamTar, c.tpcSignalTar, c.ptTar, c.etaTar, c.phiTar, c.dcaXYTar, c.dcaZTar, c.tpcNclsTar, c.itsNclsTar, c.tpcChi2NDFTar, c.itsChi2NDFTar, c.tpcNSigmaTar, c.tofNSigmaTar, c.itsNSigmaTar, c.itsClusSizeTar); + if (cfgOpenESE) { + ese_parameters::hESETar->Fill(c.ptTar, c.centFT0C, q2Ref, std::cos(2 * (c.phiTar - c.psi2FT0C)), c.signTar); } - fillHistosQvec(collision, cfgnMods->at(i)); } } }; @@ -977,7 +1054,6 @@ struct FlowEsePHe3 { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), }; } From 9ffd6c7f0f8a45c687efdcc9084d1f5e935e0f26 Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Tue, 10 Jun 2025 15:00:25 +0200 Subject: [PATCH 21/62] [PWGLF] Add new process function to run over strangeness dervide data (#11531) --- .../Tasks/Strangeness/taskLambdaSpinCorr.cxx | 363 ++++++++++++++++++ 1 file changed, 363 insertions(+) diff --git a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx index 0472e380aed..00a2d9707f5 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -50,6 +50,9 @@ using namespace o2::framework::expressions; using std::array; using namespace o2::aod::rctsel; +using dauTracks = soa::Join; +using v0Candidates = soa::Join; + struct LfTaskLambdaSpinCorr { Service ccdb; @@ -375,6 +378,32 @@ struct LfTaskLambdaSpinCorr { return {lambdaTag, aLambdaTag, true}; // Valid candidate } + std::tuple getLambdaTagsDD(const auto& v0, const auto& collision) + { + auto postrack = v0.template posTrackExtra_as(); + auto negtrack = v0.template negTrackExtra_as(); + + int lambdaTag = 0; + int aLambdaTag = 0; + + if (isSelectedV0Daughter(v0, postrack, 0) && isSelectedV0Daughter(v0, negtrack, 1)) { + lambdaTag = 1; + } + if (isSelectedV0Daughter(v0, negtrack, 0) && isSelectedV0Daughter(v0, postrack, 1)) { + aLambdaTag = 1; + } + + if (!lambdaTag && !aLambdaTag) { + return {0, 0, false}; // No valid tags + } + + if (!selectionV0(collision, v0)) { + return {0, 0, false}; // Fails selection + } + + return {lambdaTag, aLambdaTag, true}; // Valid candidate + } + std::tuple getLambdaTagsMC(const auto& v0, const auto& collision) { auto postrack = v0.template posTrack_as(); @@ -766,6 +795,340 @@ struct LfTaskLambdaSpinCorr { } PROCESS_SWITCH(LfTaskLambdaSpinCorr, processME, "Process data ME", true); + void processDerivedData(soa::Join::iterator const& collision, v0Candidates const& V0s, dauTracks const&) + { + histos.fill(HIST("hEvtSelInfo"), 0.5); + if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 1.5); + if (!collision.sel8()) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 2.5); + auto centrality = collision.centFT0C(); + int occupancy = collision.trackOccupancyInTimeRange(); + if (additionalEvSel && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 3.5); + if (additionalEvSel3 && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 4.5); + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 5.5); + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 6.5); + if (occupancy > cfgCutOccupancy) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 7.5); + histos.fill(HIST("hCentrality"), centrality); + + for (const auto& v0 : V0s) { + auto [lambdaTag, aLambdaTag, isValid] = getLambdaTagsDD(v0, collision); + if (!isValid) { + continue; + } + + if (lambdaTag && aLambdaTag) { + continue; + } + + if (lambdaTag) { + proton = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); + lambda = proton + antiPion; + } + if (aLambdaTag) { + antiProton = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda = antiProton + pion; + } + + if (lambdaTag && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } + + // auto postrack1 = v0.template posTrackExtra_as(); + // auto negtrack1 = v0.template negTrackExtra_as(); + + // 2nd loop for combination of lambda lambda + for (const auto& v02 : V0s) { + if (v02.index() <= v0.index()) { + continue; + } + auto [lambdaTag2, aLambdaTag2, isValid2] = getLambdaTagsDD(v02, collision); + if (!isValid2) { + continue; + } + if (lambdaTag2 && aLambdaTag2) { + continue; + } + if (lambdaTag2) { + proton2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassProton); + antiPion2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), o2::constants::physics::MassPionCharged); + lambda2 = proton2 + antiPion2; + } + if (aLambdaTag2) { + antiProton2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), o2::constants::physics::MassProton); + pion2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda2 = antiProton2 + pion2; + } + + if (lambdaTag2 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { + continue; + } + + // auto postrack2 = v02.template posTrackExtra_as(); + // auto negtrack2 = v02.template negTrackExtra_as(); + if (v0.posTrackExtraId() == v02.posTrackExtraId() || v0.negTrackExtraId() == v02.negTrackExtraId()) { + continue; + } + + if (lambdaTag && lambdaTag2) { + fillHistograms(1, 0, 1, 0, lambda, lambda2, proton, proton2, centrality, 0); + } + if (aLambdaTag && aLambdaTag2) { + fillHistograms(0, 1, 0, 1, antiLambda, antiLambda2, antiProton, antiProton2, centrality, 0); + } + if (lambdaTag && aLambdaTag2) { + fillHistograms(1, 0, 0, 1, lambda, antiLambda2, proton, antiProton2, centrality, 0); + } + if (aLambdaTag && lambdaTag2) { + fillHistograms(0, 1, 1, 0, antiLambda, lambda2, antiProton, proton2, centrality, 0); + } + } + } + } + PROCESS_SWITCH(LfTaskLambdaSpinCorr, processDerivedData, "Process derived data", true); + + Preslice tracksPerCollisionV0Mixed = o2::aod::v0data::straCollisionId; // for derived data only + void processDerivedDataMixed(soa::Join const& collisions, v0Candidates const& V0s, dauTracks const&) + + { + + for (auto& [collision1, collision2] : selfCombinations(colBinning, nMix, -1, collisions, collisions)) { + // LOGF(info, "Mixed event collisions: (%d, %d)", collision1.index(), collision2.index()); + if (rctCut.requireRCTFlagChecker && !rctChecker(collision1)) { + continue; + } + if (rctCut.requireRCTFlagChecker && !rctChecker(collision2)) { + continue; + } + int occupancy1 = collision1.trackOccupancyInTimeRange(); + int occupancy2 = collision2.trackOccupancyInTimeRange(); + + if (collision1.index() == collision2.index()) { + continue; + } + if (!collision1.sel8() || !collision2.sel8()) { + continue; + } + if (additionalEvSel && (!collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } + if (occupancy1 > cfgCutOccupancy) { + continue; + } + if (additionalEvSel && (!collision2.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } + if (occupancy2 > cfgCutOccupancy) { + continue; + } + if (additionalEvSel3 && (!collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + continue; + } + if (additionalEvSel4 && !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + if (mixingEvSel && additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + + if (additionalEvSel3 && (!collision2.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + continue; + } + if (additionalEvSel4 && !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + if (mixingEvSel && additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + auto centrality = collision1.centFT0C(); + auto groupV01 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); + auto groupV02 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); + auto groupV03 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision2.globalIndex()); + + size_t rows = groupV03.size() + 20; + size_t cols = groupV01.size() + 20; + std::vector> pairStatus(rows, std::vector(cols, false)); + histos.fill(HIST("hv0Mult"), groupV01.size()); + for (auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02))) { + bool pairfound = false; + if (t2.index() <= t1.index()) { + continue; + } + if (t1.straCollisionId() != t2.straCollisionId()) { + continue; + } + + auto [lambdaTag1, aLambdaTag1, isValid1] = getLambdaTagsDD(t1, collision1); + auto [lambdaTag2, aLambdaTag2, isValid2] = getLambdaTagsDD(t2, collision1); + if (!isValid1) { + continue; + } + if (!isValid2) { + continue; + } + if (lambdaTag1 && aLambdaTag1) { + continue; + } + if (lambdaTag2 && aLambdaTag2) { + continue; + } + // auto postrack1 = t1.template posTrackExtra_as(); + // auto negtrack1 = t1.template negTrackExtra_as(); + // auto postrack2 = t2.template posTrackExtra_as(); + // auto negtrack2 = t2.template negTrackExtra_as(); + if (t1.posTrackExtraId() == t2.posTrackExtraId() || t1.negTrackExtraId() == t2.negTrackExtraId()) { + continue; + } + // auto samePairSumPt = t1.pt() + t2.pt(); + // auto samePairR = TMath::Sqrt(TMath::Power(t1.phi() - t2.phi(), 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + + double deltaPhiSame = RecoDecay::constrainAngle(t1.phi() - t2.phi(), 0.0); + auto samePairR = TMath::Sqrt(TMath::Power(deltaPhiSame, 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + + if (lambdaTag1) { + proton0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassProton); + antiPion0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassPionCharged); + lambda0 = proton0 + antiPion0; + } + if (aLambdaTag1) { + antiProton0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassProton); + pion0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda0 = antiProton0 + pion0; + } + if (lambdaTag1 && (lambda0.M() < lbinIM || lambda0.M() > hbinIM)) { + continue; + } + if (aLambdaTag1 && (antiLambda0.M() < lbinIM || antiLambda0.M() > hbinIM)) { + continue; + } + if (lambdaTag2) { + proton = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassPionCharged); + lambda = proton + antiPion; + } + if (aLambdaTag2) { + antiProton = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda = antiProton + pion; + } + if (lambdaTag2 && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } + + for (const auto& t3 : groupV03) { + if (pairStatus[t3.index()][t2.index()]) { + continue; + } + if (t1.straCollisionId() == t3.straCollisionId()) { + continue; + } + auto [lambdaTag3, aLambdaTag3, isValid3] = getLambdaTagsDD(t3, collision2); + if (!isValid3) { + continue; + } + if (lambdaTag3 && aLambdaTag3) { + continue; + } + if (lambdaTag1 != lambdaTag3 || aLambdaTag1 != aLambdaTag3) { + continue; + } + + if (lambdaTag3) { + proton2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassProton); + antiPion2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassPionCharged); + lambda2 = proton2 + antiPion2; + } + if (aLambdaTag3) { + antiProton2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassProton); + pion2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda2 = antiProton2 + pion2; + } + if (lambdaTag3 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { + continue; + } + + if (aLambdaTag3 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { + continue; + } + + double deltaPhiMix = RecoDecay::constrainAngle(t3.phi() - t2.phi(), 0.0); + auto mixPairR = TMath::Sqrt(TMath::Power(deltaPhiMix, 2.0) + TMath::Power(t3.eta() - t2.eta(), 2.0)); + + auto etaDiff = t1.eta() - t3.eta(); + auto phiDiff = RecoDecay::constrainAngle(t1.phi() - t3.phi(), 0.0); + + histos.fill(HIST("hPtDiff"), t1.pt() - t3.pt()); + histos.fill(HIST("hPhiDiff"), phiDiff); + histos.fill(HIST("hRDiff"), etaDiff); + + if (mixingCombination == 0 && std::abs(t1.pt() - t3.pt()) > ptMix) { + continue; + } + if (mixingCombination == 0 && t1.eta() * t3.eta() > 0 && std::abs(etaDiff) > etaMix) { + continue; + } + if (mixingCombination == 0 && phiDiff > phiMix) { + continue; + } + if (mixingCombination == 1 && std::abs(t1.pt() - t3.pt()) > ptMix) { + continue; + } + if (mixingCombination == 1 && std::abs(mixPairR - samePairR) > etaMix) { + continue; + } + if (lambdaTag2 && lambdaTag3) { + fillHistograms(1, 0, 1, 0, lambda, lambda2, proton, proton2, centrality, 2); + } else if (aLambdaTag2 && aLambdaTag3) { + fillHistograms(0, 1, 0, 1, antiLambda, antiLambda2, antiProton, antiProton2, centrality, 2); + } else if (lambdaTag2 && aLambdaTag3) { + fillHistograms(1, 0, 0, 1, lambda, antiLambda2, proton, antiProton2, centrality, 2); + } else if (aLambdaTag2 && lambdaTag3) { + fillHistograms(0, 1, 1, 0, antiLambda, lambda2, antiProton, proton2, centrality, 2); + } else { + continue; + } + pairfound = true; + pairStatus[t3.index()][t2.index()] = true; + if (pairfound) { + break; + } + } + } + } + } + + PROCESS_SWITCH(LfTaskLambdaSpinCorr, processDerivedDataMixed, "Process mixed derived data", true); + using CollisionMCRecTableCentFT0C = soa::Join; using TrackMCRecTable = soa::Join; using V0TrackCandidatesMC = soa::Join; From 746474edfa905f180d8bb6706f0f91ce29984065 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Tue, 10 Jun 2025 16:03:15 +0200 Subject: [PATCH 22/62] [PWGEM/Dilepton] update in DimuonCut (#11536) --- PWGEM/Dilepton/Core/Dilepton.h | 3 ++- PWGEM/Dilepton/Core/DileptonMC.h | 3 ++- PWGEM/Dilepton/Core/DimuonCut.cxx | 9 ++++++--- PWGEM/Dilepton/Core/DimuonCut.h | 5 +++-- PWGEM/Dilepton/Core/SingleTrackQC.h | 3 ++- PWGEM/Dilepton/Core/SingleTrackQCMC.h | 3 ++- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index 46cecc81c87..33f0ba99718 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -284,6 +284,7 @@ struct Dilepton { Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; @@ -754,7 +755,7 @@ struct Dilepton { fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons - fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 00cec907de5..25ebe949553 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -276,6 +276,7 @@ struct DileptonMC { Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; @@ -720,7 +721,7 @@ struct DileptonMC { fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons - fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template diff --git a/PWGEM/Dilepton/Core/DimuonCut.cxx b/PWGEM/Dilepton/Core/DimuonCut.cxx index 5ee3bf3d3bd..96f00f8b7a5 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.cxx +++ b/PWGEM/Dilepton/Core/DimuonCut.cxx @@ -119,11 +119,14 @@ void DimuonCut::SetMaxPDCARabsDep(std::function RabsDepCut) mMaxPDCARabsDep = RabsDepCut; LOG(info) << "Dimuon Cut, set max pDCA as a function of Rabs: " << mMaxPDCARabsDep(10.0); } -void DimuonCut::SetMFTHitMap(std::vector hitMap) +void DimuonCut::SetMFTHitMap(bool flag, std::vector hitMap) { + mApplyMFTHitMap = flag; mRequiredMFTDisks = hitMap; - for (const auto& iDisk : mRequiredMFTDisks) { - LOG(info) << "Dimuon Cut, require MFT hit on Disk: " << iDisk; + if (mApplyMFTHitMap) { + for (const auto& iDisk : mRequiredMFTDisks) { + LOG(info) << "Dimuon Cut, require MFT hit on Disk: " << iDisk; + } } } void DimuonCut::SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax) diff --git a/PWGEM/Dilepton/Core/DimuonCut.h b/PWGEM/Dilepton/Core/DimuonCut.h index 34d8364f65b..b96afcd7c28 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.h +++ b/PWGEM/Dilepton/Core/DimuonCut.h @@ -156,7 +156,7 @@ class DimuonCut : public TNamed if (!IsSelectedTrack(track, DimuonCuts::kRabs)) { return false; } - if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kMFTHitMap)) { + if (mApplyMFTHitMap && track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kMFTHitMap)) { return false; } if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kDPtDEtaDPhiwrtMCHMID)) { @@ -243,7 +243,7 @@ class DimuonCut : public TNamed void SetDCAxy(float min, float max); // in cm void SetRabs(float min, float max); // in cm void SetMaxPDCARabsDep(std::function RabsDepCut); - void SetMFTHitMap(std::vector hitMap); + void SetMFTHitMap(bool flag, std::vector hitMap); void SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax); // this is relevant for global muons private: @@ -273,6 +273,7 @@ class DimuonCut : public TNamed float mMinRabs{17.6}, mMaxRabs{89.5}; float mMinDcaXY{0.0f}, mMaxDcaXY{1e10f}; float mMaxReldPtwrtMCHMID{1e10f}, mMaxdEtawrtMCHMID{1e10f}, mMaxdPhiwrtMCHMID{1e10f}; + bool mApplyMFTHitMap{false}; std::vector mRequiredMFTDisks{}; ClassDef(DimuonCut, 1); diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 2fc94a8a91c..561e8a2adee 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -204,6 +204,7 @@ struct SingleTrackQC { Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; @@ -458,7 +459,7 @@ struct SingleTrackQC { fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons - fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index 481bb2e9e5e..5fb15b4ec26 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -210,6 +210,7 @@ struct SingleTrackQCMC { Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; @@ -517,7 +518,7 @@ struct SingleTrackQCMC { fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons - fDimuonCut.SetMFTHitMap(dimuoncuts.requiredMFTDisks); + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template From edf0d50d3891f6b3a1269f8dbc5fcdcf9ead7ea4 Mon Sep 17 00:00:00 2001 From: Rrantu <156880782+Rrantu@users.noreply.github.com> Date: Wed, 11 Jun 2025 07:48:54 +0800 Subject: [PATCH 23/62] [PWGHF] Add Xic0 flow task and fix previous O2 linter issues (#11533) --- PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx | 158 +++++++++++++++++------ 1 file changed, 117 insertions(+), 41 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 862b4910c72..03e475bc7ed 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -14,6 +14,7 @@ /// /// \author S. Politanò, INFN Torino, Italy /// \author Wu Chuntai, CUG, China +/// \author Ran Tu, Fudan University, China #include #include @@ -48,7 +49,8 @@ enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, LcToPiKP, XicToPKPi, - XicToPiKP + XicToPiKP, + Xic0ToXiPi }; enum QvecEstimator { FV0A = 0, @@ -75,25 +77,11 @@ struct HfTaskFlowCharmHadrons { Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; - ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; - ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; - ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; - ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; - ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 2. * TMath::Pi(), 2. * TMath::Pi()}, ""}; - ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; - ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; - ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; - ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""}; + HfHelper hfHelper; + EventPlaneHelper epHelper; + HfEventSelection hfEvSel; // event selection and monitoring + o2::framework::Service ccdb; + SliceCache cache; using CandDsDataWMl = soa::Filtered>; using CandDsData = soa::Filtered>; @@ -103,6 +91,8 @@ struct HfTaskFlowCharmHadrons { using CandLcDataWMl = soa::Filtered>; using CandXicData = soa::Filtered>; using CandXicDataWMl = soa::Filtered>; + using CandXic0Data = soa::Filtered>; + using CandXic0DataWMl = soa::Filtered>; using CandD0DataWMl = soa::Filtered>; using CandD0Data = soa::Filtered>; using CollsWithQvecs = soa::Join; @@ -112,6 +102,7 @@ struct HfTaskFlowCharmHadrons { Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; Filter filterSelectLcCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; Filter filterSelectXicCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; + Filter filterSelectXic0Candidates = aod::hf_sel_toxipi::resultSelections >= selectionFlag; Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; @@ -129,12 +120,28 @@ struct HfTaskFlowCharmHadrons { Partition selectedXicToPiKP = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; Partition selectedXicToPKPiWMl = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag; Partition selectedXicToPiKPWMl = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; + Partition selectedXic0 = aod::hf_sel_toxipi::resultSelections >= selectionFlag; + Partition selectedXic0WMl = aod::hf_sel_toxipi::resultSelections >= selectionFlag; - SliceCache cache; - HfHelper hfHelper; - EventPlaneHelper epHelper; - HfEventSelection hfEvSel; // event selection and monitoring - o2::framework::Service ccdb; + ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; + ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; + ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 0, constants::math::TwoPI}, ""}; + ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; + ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; + ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""}; HistogramRegistry registry{"registry", {}}; @@ -231,15 +238,15 @@ struct HfTaskFlowCharmHadrons { } if (storeResoOccu) { - std::vector axes_reso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot}; + std::vector axesReso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot}; if (occEstimator == 1) { - axes_reso.insert(axes_reso.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy, - thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); + axesReso.insert(axesReso.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy, + thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); } else { - axes_reso.insert(axes_reso.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy, - thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); + axesReso.insert(axesReso.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy, + thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); } - registry.add("spReso/hSparseReso", "THn for resolution with occupancy", HistType::kTHnSparseF, axes_reso); + registry.add("spReso/hSparseReso", "THn for resolution with occupancy", HistType::kTHnSparseF, axesReso); } hfEvSel.addHistograms(registry); // collision monitoring @@ -285,6 +292,44 @@ struct HfTaskFlowCharmHadrons { } } + /// Compute the Q vector for the candidate's tracks + /// \param cand is the candidate + /// \param tracksQx is the X component of the Q vector for the tracks + /// \param tracksQy is the Y component of the Q vector for the tracks + /// \param channel is the decay channel + template + void getQvecXic0Tracks(const T1& cand, + std::vector& tracksQx, + std::vector& tracksQy, + float ampl) + { + // add possibility to consider different weights for the tracks, at the moment only pT is considered; + float pXTrack0 = cand.pxPosV0Dau(); + float pYTrack0 = cand.pyPosV0Dau(); + float pTTrack0 = std::hypot(pXTrack0, pYTrack0); + float phiTrack0 = std::atan2(pXTrack0, pYTrack0); + float pXTrack1 = cand.pxNegV0Dau(); + float pYTrack1 = cand.pyNegV0Dau(); + float pTTrack1 = std::hypot(pXTrack1, pYTrack1); + float phiTrack1 = std::atan2(pXTrack1, pYTrack1); + float pYTrack2 = cand.pxBachFromCasc(); + float pXTrack2 = cand.pyBachFromCasc(); + float pTTrack2 = std::hypot(pXTrack2, pYTrack2); + float phiTrack2 = std::atan2(pXTrack2, pYTrack2); + float pXTrack3 = cand.pxBachFromCharmBaryon(); + float pYTrack3 = cand.pyBachFromCharmBaryon(); + float pTTrack3 = std::hypot(pXTrack3, pYTrack3); + float phiTrack3 = std::atan2(pXTrack3, pYTrack3); + + tracksQx.push_back(std::cos(harmonic * phiTrack0) * pTTrack0 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack0) * pTTrack0 / ampl); + tracksQx.push_back(std::cos(harmonic * phiTrack1) * pTTrack1 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack1) * pTTrack1 / ampl); + tracksQx.push_back(std::cos(harmonic * phiTrack2) * pTTrack2 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack2) * pTTrack2 / ampl); + tracksQx.push_back(std::cos(harmonic * phiTrack3) * pTTrack3 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack3) * pTTrack3 / ampl); + } /// Compute the delta psi in the range [0, pi/harmonic] /// \param psi1 is the first angle /// \param psi2 is the second angle @@ -292,12 +337,7 @@ struct HfTaskFlowCharmHadrons { float getDeltaPsiInRange(float psi1, float psi2) { float deltaPsi = psi1 - psi2; - if (std::abs(deltaPsi) > constants::math::PI / harmonic) { - if (deltaPsi > 0.) - deltaPsi -= constants::math::TwoPI / harmonic; - else - deltaPsi += constants::math::TwoPI / harmonic; - } + deltaPsi = RecoDecay::constrainAngle(deltaPsi, -o2::constants::math::PI / harmonic, harmonic); return deltaPsi; } @@ -552,18 +592,36 @@ struct HfTaskFlowCharmHadrons { default: break; } + } else if constexpr (std::is_same_v || std::is_same_v) { + massCand = candidate.invMassCharmBaryon(); + if constexpr (std::is_same_v) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) + outputMl[iclass] = candidate.mlProbToXiPi()[classMl->at(iclass)]; + } } - float ptCand = candidate.pt(); - float phiCand = candidate.phi(); + float ptCand = 0.; + float phiCand = 0.; + + if constexpr (std::is_same_v || std::is_same_v) { + ptCand = candidate.kfptXic(); + phiCand = std::atan2(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()); + } else { + ptCand = candidate.pt(); + phiCand = candidate.phi(); + } // If TPC is used for the SP estimation, the tracks of the hadron candidate must be removed from the TPC Q vector to avoid double counting if (qvecDetector == QvecEstimator::TPCNeg || qvecDetector == QvecEstimator::TPCPos) { float ampl = amplQVec - static_cast(nProngs); std::vector tracksQx = {}; std::vector tracksQy = {}; - - getQvecDtracks(candidate, tracksQx, tracksQy, ampl); + if constexpr (std::is_same_v || std::is_same_v) { + // std::cout<(candidate, tracksQx, tracksQy, ampl); + } for (auto iTrack{0u}; iTrack < tracksQx.size(); ++iTrack) { xQVec -= tracksQx[iTrack]; yQVec -= tracksQy[iTrack]; @@ -683,6 +741,24 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false); + // Xic0 with ML + void processXic0Ml(CollsWithQvecs::iterator const& collision, + CandXic0DataWMl const&) + { + auto candsXic0WMl = selectedXic0WMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsXic0WMl); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0Ml, "Process Xic0 candidates with ML", false); + + // Xic0 + void processXic0(CollsWithQvecs::iterator const& collision, + CandXic0Data const&) + { + auto candsXic0 = selectedXic0->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsXic0); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0, "Process Xic0 candidates", false); + // Resolution void processResolution(CollsWithQvecs::iterator const& collision, aod::BCsWithTimestamps const& bcs) From 5ce067be64486aac37efed3af498a3d61707b75a Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 11 Jun 2025 03:19:37 +0200 Subject: [PATCH 24/62] [ALICE3] do not include internal ITS code (#11539) Co-authored-by: ALICE Action Bot --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 62 +++++++++----------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index ff804b8485a..c858f5a753e 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -23,48 +23,42 @@ /// \author Roberto Preghenella preghenella@bo.infn.it /// -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include "ALICE3/Core/DelphesO2TrackSmearer.h" +#include "ALICE3/Core/DetLayer.h" +#include "ALICE3/Core/FastTracker.h" +#include "ALICE3/Core/TrackUtilities.h" +#include "ALICE3/DataModel/OTFStrangeness.h" +#include "ALICE3/DataModel/collisionAlice3.h" +#include "ALICE3/DataModel/tracksAlice3.h" +#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/runDataProcessing.h" #include "Framework/HistogramRegistry.h" -#include -#include "DCAFitter/DCAFitterN.h" -#include "Common/Core/RecoDecay.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "DetectorsBase/Propagator.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsVertexing/PVertexer.h" -#include "DetectorsVertexing/PVertexerHelpers.h" #include "SimulationDataFormat/InteractionSampler.h" -#include "Field/MagneticField.h" -#include "ITSMFTSimulation/Hit.h" -#include "ITStracking/Configuration.h" -#include "ITStracking/IOUtils.h" -#include "ITStracking/Tracker.h" -#include "ITStracking/Vertexer.h" -#include "ITStracking/VertexerTraits.h" +#include +#include +#include +#include +#include -#include "ALICE3/Core/DelphesO2TrackSmearer.h" -#include "ALICE3/Core/FastTracker.h" -#include "ALICE3/Core/DetLayer.h" -#include "ALICE3/Core/TrackUtilities.h" -#include "ALICE3/DataModel/collisionAlice3.h" -#include "ALICE3/DataModel/tracksAlice3.h" -#include "ALICE3/DataModel/OTFStrangeness.h" +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -808,7 +802,7 @@ struct OnTheFlyTracker { std::array posClusterCandidate; trackParCov.getXYZGlo(posClusterCandidate); float r{std::hypot(posClusterCandidate[0], posClusterCandidate[1])}; - float phi{std::atan2(-posClusterCandidate[1], -posClusterCandidate[0]) + o2::its::constants::math::Pi}; + 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...) From 3317ee43b6ad08d925d6fb0ce3158038bb6974b1 Mon Sep 17 00:00:00 2001 From: aimeric-landou <46970521+aimeric-landou@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:13:34 +0200 Subject: [PATCH 25/62] [Common] Common - add trackdcacov table producer for Run2 converted data (#11434) --- Common/TableProducer/CMakeLists.txt | 5 + .../TableProducer/trackDcaCovFillerRun2.cxx | 179 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 Common/TableProducer/trackDcaCovFillerRun2.cxx diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 042bd643d3e..1d6918d6121 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -62,6 +62,11 @@ o2physics_add_dpl_workflow(track-propagation PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(track-dca-cov-filler-run2 + SOURCES trackDcaCovFillerRun2.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(track-propagation-tester SOURCES trackPropagationTester.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::trackSelectionRequest diff --git a/Common/TableProducer/trackDcaCovFillerRun2.cxx b/Common/TableProducer/trackDcaCovFillerRun2.cxx new file mode 100644 index 00000000000..d07833ae9e0 --- /dev/null +++ b/Common/TableProducer/trackDcaCovFillerRun2.cxx @@ -0,0 +1,179 @@ +// 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 trackDcaCovFillerRun2.cxx +/// \author Aimeric Landou , CERN +/// \brief Fills DCA and DCA Cov tables for Run 2 tracks +// Run 2 AO2Ds cannot have their dcacov filled by the current track-propagation workflow as the workflow isn't designed for them, given Run 2 tracks are already propagated to the PV. +// This task fills the DCA Cov (and DCA) tables for Run 2 tracks by "propagating" the tracks (though given they are already at the PV it doesn't actually do the propagation) and retrieving the DCA and DCA cov given by the propagateToDCABxByBz function + +#include + +#include "TableHelper.h" +#include "Common/Tools/TrackTuner.h" +#include "DataFormatsParameters/GRPObject.h" + +using namespace o2; +using namespace o2::framework; +// using namespace o2::framework::expressions; + +struct TrackDcaCovFillerRun2 { + Produces tracksDCA; + Produces tracksDCACov; + + // Produces tunertable; + + Service ccdb; + + bool fillTracksDCA = false; + bool fillTracksDCACov = false; + int runNumber = -1; + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + + const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; + o2::parameters::GRPMagField* grpmag = nullptr; + o2::base::MatLayerCylSet* lut = nullptr; + + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "CCDB path of the grp file (run2)"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + + HistogramRegistry registry{"registry"}; + + void init(o2::framework::InitContext& initContext) + { + // Checking if the tables are requested in the workflow and enabling them + fillTracksDCA = isTableRequiredInWorkflow(initContext, "TracksDCA"); + fillTracksDCACov = isTableRequiredInWorkflow(initContext, "TracksDCACov"); + + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (runNumber == bc.runNumber()) { + return; + } + + // Run 2 GRP object + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(ccdbPathGrp, bc.timestamp()); + if (grpo == nullptr) { + LOGF(fatal, "Run 2 GRP object (type o2::parameters::GRPObject) is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + o2::base::Propagator::initFieldFromGRP(grpo); + LOGF(info, "Setting magnetic field to %d kG for run %d from its GRP CCDB object (type o2::parameters::GRPObject)", grpo->getNominalL3Field(), bc.runNumber()); + + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + runNumber = bc.runNumber(); + } + + // Running variables + std::array mDcaInfo; + o2::dataformats::DCA mDcaInfoCov; + o2::dataformats::VertexBase mVtx; + o2::track::TrackParametrization mTrackPar; + o2::track::TrackParametrizationWithError mTrackParCov; + + template + void fillTrackTables(TTrack const& tracks, + TParticle const&, + aod::Collisions const&, + aod::BCsWithTimestamps const& bcs) + { + if (bcs.size() == 0) { + return; + } + initCCDB(bcs.begin()); + + if constexpr (fillCovMat) { + if (fillTracksDCACov) { + tracksDCACov.reserve(tracks.size()); + } + } else { + if (fillTracksDCA) { + tracksDCA.reserve(tracks.size()); + } + } + + for (auto const& track : tracks) { + if constexpr (fillCovMat) { + if (fillTracksDCA || fillTracksDCACov) { + mDcaInfoCov.set(999, 999, 999, 999, 999); + } + setTrackParCov(track, mTrackParCov); + } else { + if (fillTracksDCA) { + mDcaInfo[0] = 999; + mDcaInfo[1] = 999; + } + setTrackPar(track, mTrackPar); + } + + if (track.has_collision()) { + auto const& collision = track.collision(); + if constexpr (fillCovMat) { + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); + } else { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); + } + } else { + if constexpr (fillCovMat) { + mVtx.setPos({mMeanVtx->getX(), mMeanVtx->getY(), mMeanVtx->getZ()}); + mVtx.setCov(mMeanVtx->getSigmaX() * mMeanVtx->getSigmaX(), 0.0f, mMeanVtx->getSigmaY() * mMeanVtx->getSigmaY(), 0.0f, 0.0f, mMeanVtx->getSigmaZ() * mMeanVtx->getSigmaZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); + } else { + o2::base::Propagator::Instance()->propagateToDCABxByBz({mMeanVtx->getX(), mMeanVtx->getY(), mMeanVtx->getZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); + } + } + + if constexpr (fillCovMat) { + if (fillTracksDCA) { + tracksDCA(mDcaInfoCov.getY(), mDcaInfoCov.getZ()); + } + if (fillTracksDCACov) { + tracksDCACov(mDcaInfoCov.getSigmaY2(), mDcaInfoCov.getSigmaZ2()); + } + } else { + if (fillTracksDCA) { + tracksDCA(mDcaInfo[0], mDcaInfo[1]); + } + } + } + } + + void processCovariance(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) + { + fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/true>(tracks, tracks, collisions, bcs); + } + PROCESS_SWITCH(TrackDcaCovFillerRun2, processCovariance, "Process with covariance", false); + + void processStandard(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) + { + fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/false>(tracks, tracks, collisions, bcs); + } + PROCESS_SWITCH(TrackDcaCovFillerRun2, processStandard, "Process without covariance", true); +}; + +//**************************************************************************************** +/** + * Workflow definition. + */ +//**************************************************************************************** +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} From dadf0e000c4b2463fc794430edcf62d8ddfb36c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Mart=C3=ADnez=20Garc=C3=ADa?= Date: Wed, 11 Jun 2025 03:32:37 -0600 Subject: [PATCH 26/62] [PWGUD] : Fixing the runtime overhead (#11532) --- PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx | 49 ++++++++++++++-------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx index eb16b83f315..d20a78429dd 100644 --- a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx +++ b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx @@ -100,7 +100,8 @@ struct upcPhotonuclearAnalysisJMG { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // Declare configurables on events/collisions - Configurable nEvenstMixed{"nEvenstMixed", 3, {"Events to be Mixed"}}; + Configurable nEventsMixed{"nEventsMixed", 3, {"Events to be Mixed"}}; + Configurable factorEventsMixed{"factorEventsMixed", 100, {"factorEventsMixed to events mixed"}}; Configurable myZVtxCut{"myZVtxCut", 10., {"My collision cut"}}; Configurable myTimeZNACut{"myTimeZNACut", 2., {"My collision cut"}}; Configurable myTimeZNCCut{"myTimeZNCCut", 2., {"My collision cut"}}; @@ -275,23 +276,18 @@ struct upcPhotonuclearAnalysisJMG { mixedGapSideC.setObject(new CorrelationContainer("mixedEventGapSideC", "mixedEventGapSideC", corrAxis, effAxis, {})); } - std::vector vtxBinsEdges{VARIABLE_WIDTH, -10.0f, -5.0f, 0.0f, 5.0f, 10.0f}; + std::vector vtxBinsEdges{VARIABLE_WIDTH, -10.0f, -7.0f, -5.0f, -2.5f, 0.0f, 2.5f, 5.0f, 7.0f, 10.0f}; std::vector gapSideBinsEdges{VARIABLE_WIDTH, -0.5, 0.5, 1.5}; SliceCache cache; + int countGapA = 0; + int countGapC = 0; // Binning only on PosZ without multiplicity // using BinningType = ColumnBinningPolicy; using BinningType = ColumnBinningPolicy; - BinningType bindingOnVtx{{vtxBinsEdges, {gapSideBinsEdges}}, true}; - SameKindPair pairs{bindingOnVtx, nEvenstMixed, -1, &cache}; - - // ColumnBinningPolicy bindingOnVtx{{vtxBinsEdges, multBinsEdges}, true}; - - // SameKindPair, - // FullUDTracks, - // ColumnBinningPolicy> - // pair{bindingOnVtx, 5, -1, &cache}; + BinningType bindingOnVtx{{vtxBinsEdges, gapSideBinsEdges}, true}; + SameKindPair pairs{bindingOnVtx, nEventsMixed, -1, &cache}; template bool isCollisionCutSG(CSG const& collision, int SideGap) @@ -584,7 +580,8 @@ struct upcPhotonuclearAnalysisJMG { if (fillCollisionUD(sameGapSideC, multiplicity) == false) { return; } - // LOGF(debug, "Filling sameGapSideC events"); + histos.fill(HIST("eventcount"), -1); + // LOGF(info, "Filling sameGapSideC events"); fillCorrelationsUD(sameGapSideC, reconstructedTracks, reconstructedTracks, multiplicity, reconstructedCollision.posZ()); break; default: @@ -601,18 +598,34 @@ struct upcPhotonuclearAnalysisJMG { // int sgSide = reconstructedCollision.gapSide(); // int sgSide = 0; + int maxCountGapA = 0; + int maxCountGapC = 0; + + if (auto histEventCount = histos.get(HIST("eventcount"))) { + int binA = histEventCount->GetXaxis()->FindBin(-2); // Gap A + int binC = histEventCount->GetXaxis()->FindBin(-1); // Gap C + + maxCountGapA = histEventCount->GetBinContent(binA) * factorEventsMixed; + maxCountGapC = histEventCount->GetBinContent(binC) * factorEventsMixed; + } + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { if (collision1.size() == 0 || collision2.size() == 0) { - // LOGF(debug, "One or both collisions are empty."); + // LOGF(info, "One or both collisions are empty."); continue; } + if (countGapA >= maxCountGapA && countGapC >= maxCountGapC) { + break; + } float multiplicity = 0; if (collision1.gapSide() == 0 && collision2.gapSide() == 0) { // gap on side A if (isCollisionCutSG(collision1, 0) == false && isCollisionCutSG(collision2, 0) == false) { continue; } - // LOGF(debug, "In the pairs loop, gap side A"); + // std::cout << "Counts for Gap A: " << countGapA << " Maximum Count for Gap A " << maxCountGapA << std::endl; + ++countGapA; + // LOGF(info, "In the pairs loop, gap side A"); multiplicity = tracks1.size(); if (fillCollisionUD(mixedGapSideA, multiplicity) == false) { return; @@ -620,20 +633,22 @@ struct upcPhotonuclearAnalysisJMG { // histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ()})); histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ(), collision1.gapSide()})); fillCorrelationsUD(mixedGapSideA, tracks1, tracks2, multiplicity, collision1.posZ()); - // LOGF(debug, "Filling mixedGapSideA events, Gap for side A"); + // LOGF(info, "Filling mixedGapSideA events, Gap for side A"); } if (collision1.gapSide() == 1 && collision2.gapSide() == 1) { // gap on side C if (isCollisionCutSG(collision1, 1) == false && isCollisionCutSG(collision2, 1) == false) { continue; } - // LOGF(debug, "In the pairs loop, gap side C"); + // std::cout << "Counts for Gap C: " << countGapC << " Maximum Count for Gap C" << maxCountGapC << std::endl; + ++countGapC; + // LOGF(info, "In the pairs loop, gap side C"); multiplicity = tracks1.size(); if (fillCollisionUD(mixedGapSideC, multiplicity) == false) { return; } fillCorrelationsUD(mixedGapSideC, tracks1, tracks2, multiplicity, collision1.posZ()); - // LOGF(debug, "Filling mixedGapSideC events, Gap for side C"); + // LOGF(info, "Filling mixedGapSideC events, Gap for side C"); } else { continue; } From 6421a35fd5ee10420858011955a2b37e889b47e9 Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Wed, 11 Jun 2025 22:31:36 +0800 Subject: [PATCH 27/62] [Trigger] Add macro to inspect trigger menu per run (#11544) --- EventFiltering/macros/getMenu.C | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 EventFiltering/macros/getMenu.C diff --git a/EventFiltering/macros/getMenu.C b/EventFiltering/macros/getMenu.C new file mode 100644 index 00000000000..692ebe396f3 --- /dev/null +++ b/EventFiltering/macros/getMenu.C @@ -0,0 +1,31 @@ +// 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. + +#include "CCDB/BasicCCDBManager.h" + +#include +#include + +#include + +void getMenu(int runNumber, std::string baseCCDBPath = "Users/m/mpuccio/EventFiltering/OTS/Chunked/") +{ + auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); + TH1* counters = ccdb.getForRun(baseCCDBPath + "FilterCounters", runNumber); + TAxis* axis = counters->GetXaxis(); + + std::vector binLabels(axis->GetNbins() - 2); // skip first and last bins + std::cout << "Menu for run " << runNumber << ":\n"; + for (int i = 2; i < axis->GetNbins(); ++i) { + binLabels[i - 1] = axis->GetBinLabel(i); + std::cout << "Id " << i - 2 << ": " << axis->GetBinLabel(i) << "\n"; + } +} From e06d94e7527b90bea7f8e8eed82cfdff25e68800 Mon Sep 17 00:00:00 2001 From: Sandeep Dudi <69388148+sdudi123@users.noreply.github.com> Date: Wed, 11 Jun 2025 16:36:22 +0200 Subject: [PATCH 28/62] [PWGUD] Updated macro for JIT session error Cannot allocate memory issue (#11490) Co-authored-by: sandeep dudi --- PWGUD/Tasks/sginclusivePhiKstarSD.cxx | 219 +++++++++++++++----------- 1 file changed, 124 insertions(+), 95 deletions(-) diff --git a/PWGUD/Tasks/sginclusivePhiKstarSD.cxx b/PWGUD/Tasks/sginclusivePhiKstarSD.cxx index 20d4f08d1d6..628818bd553 100644 --- a/PWGUD/Tasks/sginclusivePhiKstarSD.cxx +++ b/PWGUD/Tasks/sginclusivePhiKstarSD.cxx @@ -59,6 +59,15 @@ struct SginclusivePhiKstarSD { Configurable zdcCut{"zdcCut", 0., "ZDC threshold"}; Configurable vzCut{"vzCut", 10., "Vz position"}; Configurable occCut{"occCut", 1000., "Occupancy cut"}; + Configurable hadronicRate{"hadronicRate", 1000., "hadronicRate cut"}; + Configurable useTrs{"useTrs", -1, "kNoCollInTimeRangeStandard cut"}; + Configurable useTrofs{"useTrofs", -1, "kNoCollInRofStandard cut"}; + Configurable useHmpr{"useHmpr", -1, "kNoHighMultCollInPrevRof cut"}; + Configurable useTfb{"useTfb", -1, "kNoTimeFrameBorder cut"}; + Configurable useItsrofb{"useItsrofb", -1, "kNoITSROFrameBorder cut"}; + Configurable useSbp{"useSbp", -1, "kNoSameBunchPileup cut"}; + Configurable useZvtxftovpv{"useZvtxftovpv", -1, "kIsGoodZvtxFT0vsPV cut"}; + Configurable useVtxItsTpc{"useVtxItsTpc", -1, "kIsVertexITSTPC cut"}; // Track Selections Configurable pvCut{"pvCut", 1.0, "Use Only PV tracks"}; @@ -395,9 +404,9 @@ struct SginclusivePhiKstarSD { } //_____________________________________________________________________________ - double cosThetaCollinsSoperFrame(TLorentzVector pair1, - TLorentzVector pair2, - TLorentzVector fourpion) + double cosThetaCollinsSoperFrame(ROOT::Math::PxPyPzMVector pair1, + ROOT::Math::PxPyPzMVector pair2, + ROOT::Math::PxPyPzMVector fourpion) { double halfSqrtSnn = 2680.; double massOfLead208 = 193.6823; @@ -483,7 +492,7 @@ struct SginclusivePhiKstarSD { } //------------------------------------------------------------------------------------------------------ - double phiCollinsSoperFrame(TLorentzVector pair1, TLorentzVector pair2, TLorentzVector fourpion) + double phiCollinsSoperFrame(ROOT::Math::PxPyPzMVector pair1, ROOT::Math::PxPyPzMVector pair2, ROOT::Math::PxPyPzMVector fourpion) { // Half of the energy per pair of the colliding nucleons. double halfSqrtSnn = 2680.; @@ -518,24 +527,24 @@ struct SginclusivePhiKstarSD { void process(UDCollisionFull const& collision, UDtracksfull const& tracks) { - TLorentzVector v0; - TLorentzVector v1; - TLorentzVector v01; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector v1; + ROOT::Math::PxPyPzMVector v01; int gapSide = collision.gapSide(); float fitCut[5] = {fv0Cut, ft0aCut, ft0cCut, fddaCut, fddcCut}; std::vector parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut}; int truegapSide = sgSelector.trueGap(collision, fitCut[0], fitCut[1], fitCut[2], zdcCut); - TLorentzVector phiv; - TLorentzVector phiv1; + ROOT::Math::PxPyPzMVector phiv; + ROOT::Math::PxPyPzMVector phiv1; - std::vector onlyPionTracksp; + std::vector onlyPionTracksp; std::vector rawPionTracksp; - std::vector onlyPionTrackspm; + std::vector onlyPionTrackspm; std::vector rawPionTrackspm; - std::vector onlyPionTracksn; + std::vector onlyPionTracksn; std::vector rawPionTracksn; registry.fill(HIST("GapSide"), gapSide); @@ -547,6 +556,25 @@ struct SginclusivePhiKstarSD { return; if (std::abs(collision.occupancyInTime()) > occCut) return; + if (std::abs(collision.hadronicRate()) > hadronicRate) + return; + + if (useTrs != -1 && collision.trs() != useTrs) + return; + if (useTrofs != -1 && collision.trofs() != useTrofs) + return; + if (useHmpr != -1 && collision.hmpr() != useHmpr) + return; + if (useTfb != -1 && collision.tfb() != useTfb) + return; + if (useItsrofb != -1 && collision.itsROFb() != useItsrofb) + return; + if (useSbp != -1 && collision.sbp() != useSbp) + return; + if (useZvtxftovpv != -1 && collision.zVtxFT0vPV() != useZvtxftovpv) + return; + if (useVtxItsTpc != -1 && collision.vtxITSTPC() != useVtxItsTpc) + return; int mult = collision.numContrib(); if (gapSide == 0) { @@ -569,18 +597,19 @@ struct SginclusivePhiKstarSD { int trackextra = 0; int trackextraDG = 0; - Partition pvContributors1 = aod::udtrack::isPVContributor == true; - pvContributors1.bindTable(tracks); - if (gapSide == 0) { - registry.get(HIST("nPVContributors_data"))->Fill(pvContributors1.size(), 1.); - } - if (gapSide == 1) { - registry.get(HIST("nPVContributors_data_1"))->Fill(pvContributors1.size(), 1.); - } + /* Partition pvContributors1 = aod::udtrack::isPVContributor == true; + pvContributors1.bindTable(tracks); + if (gapSide == 0) { + registry.get(HIST("nPVContributors_data"))->Fill(pvContributors1.size(), 1.); + } + if (gapSide == 1) { + registry.get(HIST("nPVContributors_data_1"))->Fill(pvContributors1.size(), 1.); + } + */ for (const auto& track1 : tracks) { if (!trackselector(track1, parameters)) continue; - v0.SetXYZM(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassPionCharged); if (selectionPIDPion1(track1)) { onlyPionTrackspm.push_back(v0); rawPionTrackspm.push_back(track1); @@ -719,8 +748,8 @@ struct SginclusivePhiKstarSD { continue; if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -754,8 +783,8 @@ struct SginclusivePhiKstarSD { continue; if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -790,8 +819,8 @@ struct SginclusivePhiKstarSD { continue; if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -825,8 +854,8 @@ struct SginclusivePhiKstarSD { continue; if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -860,8 +889,8 @@ struct SginclusivePhiKstarSD { continue; if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -895,8 +924,8 @@ struct SginclusivePhiKstarSD { continue; if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -932,8 +961,8 @@ struct SginclusivePhiKstarSD { if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -971,8 +1000,8 @@ struct SginclusivePhiKstarSD { auto rotkaonPx = t0.px() * std::cos(rotangle) - t0.py() * std::sin(rotangle); auto rotkaonPy = t0.px() * std::sin(rotangle) + t0.py() * std::cos(rotangle); - v0.SetXYZM(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; if (t0.sign() != t1.sign()) { if (gapSide == 0) { @@ -995,8 +1024,8 @@ struct SginclusivePhiKstarSD { if (t0.globalIndex() == t1.globalIndex()) continue; if (rho && selectionPIDProton(t0, useTof, nsigmaTpcCut, nsigmaTofCut) && selectionPIDPion1(t1)) { - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassProton); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassProton); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -1025,8 +1054,8 @@ struct SginclusivePhiKstarSD { if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { if (kaoncut && t0.tpcNSigmaPi() < pionNsigmaCut) continue; - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -1062,8 +1091,8 @@ struct SginclusivePhiKstarSD { auto rotkaonPx = t0.px() * std::cos(rotangle) - t0.py() * std::sin(rotangle); auto rotkaonPy = t0.px() * std::sin(rotangle) + t0.py() * std::cos(rotangle); - v0.SetXYZM(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; if (t0.sign() != t1.sign()) { if (gapSide == 0) { @@ -1082,12 +1111,12 @@ struct SginclusivePhiKstarSD { } if (fourpion) { if (gapSide == 2 && mult2 == 4) { - TLorentzVector pair1, pair2, pair3, pair4; + ROOT::Math::PxPyPzMVector pair1, pair2, pair3, pair4; if (onlyPionTracksp.size() == 2 && onlyPionTracksn.size() == 2) { - TLorentzVector k1 = onlyPionTracksp.at(0); - TLorentzVector k2 = onlyPionTracksp.at(1); - TLorentzVector k3 = onlyPionTracksn.at(0); - TLorentzVector k4 = onlyPionTracksn.at(1); + ROOT::Math::PxPyPzMVector k1 = onlyPionTracksp.at(0); + ROOT::Math::PxPyPzMVector k2 = onlyPionTracksp.at(1); + ROOT::Math::PxPyPzMVector k3 = onlyPionTracksn.at(0); + ROOT::Math::PxPyPzMVector k4 = onlyPionTracksn.at(1); phiv = k1 + k2 + k3 + k4; pair1 = k1 + k3; pair2 = k2 + k4; @@ -1112,10 +1141,10 @@ struct SginclusivePhiKstarSD { if (onlyPionTracksp.size() != 2 && onlyPionTracksn.size() != 2) { if (onlyPionTracksp.size() + onlyPionTracksn.size() != 4) return; - TLorentzVector l1 = onlyPionTrackspm.at(0); - TLorentzVector l2 = onlyPionTrackspm.at(1); - TLorentzVector l3 = onlyPionTrackspm.at(2); - TLorentzVector l4 = onlyPionTrackspm.at(3); + ROOT::Math::PxPyPzMVector l1 = onlyPionTrackspm.at(0); + ROOT::Math::PxPyPzMVector l2 = onlyPionTrackspm.at(1); + ROOT::Math::PxPyPzMVector l3 = onlyPionTrackspm.at(2); + ROOT::Math::PxPyPzMVector l4 = onlyPionTrackspm.at(3); phiv1 = l1 + l2 + l3 + l4; registry.fill(HIST("os_pppp_pT_2_ls"), phiv1.M(), phiv1.Pt(), phiv1.Rapidity()); } @@ -1134,9 +1163,9 @@ struct SginclusivePhiKstarSD { using BinningTypeVertexContributor = ColumnBinningPolicy; void mixprocess(UDCollisionsFull1 const& collisions, UDtracksfull const& /*track*/) { - TLorentzVector v0; - TLorentzVector v1; - TLorentzVector v01; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector v1; + ROOT::Math::PxPyPzMVector v01; float fitCut[5] = {fv0Cut, ft0aCut, ft0cCut, fddaCut, fddcCut}; std::vector parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut}; BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass}, true}; @@ -1158,8 +1187,8 @@ struct SginclusivePhiKstarSD { if (!trackselector(track1, parameters) || !trackselector(track2, parameters)) continue; if (phi && selectionPIDKaon1(track1) && selectionPIDKaon1(track2)) { - v0.SetXYZM(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (track1.sign() != track2.sign()) { @@ -1181,8 +1210,8 @@ struct SginclusivePhiKstarSD { if (track1.globalIndex() == track2.globalIndex()) continue; if (kstar && selectionPIDKaon1(track1) && selectionPIDPion1(track2)) { - v0.SetXYZM(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (track1.sign() != track2.sign()) { @@ -1216,11 +1245,11 @@ struct SginclusivePhiKstarSD { void processMCTruth(aod::UDMcCollisions const& mccollisions, CCs const& collisions, aod::UDMcParticles const& McParts, TCs const& tracks) { // number of McCollisions in DF - TLorentzVector v0; - TLorentzVector v1; - TLorentzVector v01; - TLorentzVector vkstar; - TLorentzVector vphi; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector v1; + ROOT::Math::PxPyPzMVector v01; + ROOT::Math::PxPyPzMVector vkstar; + ROOT::Math::PxPyPzMVector vphi; for (const auto& mccollision : mccollisions) { if (mccollision.generatorsID() != generatedId) continue; @@ -1236,11 +1265,11 @@ struct SginclusivePhiKstarSD { for (const auto& [tr1, tr2] : combinations(partSlice, partSlice)) { if ((tr1.pdgCode() == kKPlus && tr2.pdgCode() == kPiMinus) || (tr1.pdgCode() == kKMinus && tr2.pdgCode() == kPiPlus) || (tr1.pdgCode() == kPiPlus && tr2.pdgCode() == kKMinus) || (tr1.pdgCode() == kPiMinus && tr2.pdgCode() == kKPlus)) { if (std::abs(tr1.pdgCode()) == kKPlus) { - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassPionCharged); } else { - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); - v1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); + v1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); } if (!tr1.isPhysicalPrimary() || !tr2.isPhysicalPrimary()) continue; @@ -1255,7 +1284,7 @@ struct SginclusivePhiKstarSD { if (tr1.has_mothers() && tr2.has_mothers()) { for (const auto& mother : tr1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kK0Star892) { - vkstar.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); + vkstar.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); registry.get(HIST("MC/accMPtRap_kstar_G"))->Fill(vkstar.M(), vkstar.Pt(), vkstar.Rapidity(), 1.); flag = true; } @@ -1279,8 +1308,8 @@ struct SginclusivePhiKstarSD { if (std::abs(tr1.pdgCode()) != kKPlus || std::abs(tr2.pdgCode()) != kKPlus) continue; - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); if (tr1.pdgCode() == tr2.pdgCode()) continue; v01 = v0 + v1; @@ -1296,7 +1325,7 @@ struct SginclusivePhiKstarSD { if (tr1.has_mothers() && tr2.has_mothers()) { for (const auto& mother : tr1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kPhi) { - vphi.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); + vphi.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); registry.get(HIST("MC/accMPtRap_phi_G"))->Fill(vphi.M(), vphi.Pt(), vphi.Rapidity(), 1.); flag = true; } @@ -1349,8 +1378,8 @@ struct SginclusivePhiKstarSD { std::vector parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut}; int truegapSide = sgSelector.trueGap(collision, fitCut[0], fitCut[1], fitCut[2], zdcCut); registry.get(HIST("Reco/Stat"))->Fill(4.0, 1.); - Partition pvContributors = aod::udtrack::isPVContributor == true; - pvContributors.bindTable(tracks); + // Partition pvContributors = aod::udtrack::isPVContributor == true; + // pvContributors.bindTable(tracks); if (std::abs(collision.posZ()) > vzCut) return; if (std::abs(collision.occupancyInTime()) > occCut) @@ -1358,16 +1387,16 @@ struct SginclusivePhiKstarSD { registry.get(HIST("Reco/Stat"))->Fill(truegapSide, 1.); if (truegapSide != gapsideMC) return; - registry.get(HIST("Reco/nPVContributors"))->Fill(pvContributors.size(), 1.); - TLorentzVector vphi; - TLorentzVector vkstar; - TLorentzVector v0; - TLorentzVector vr0; - TLorentzVector vr1; - TLorentzVector vr01; - TLorentzVector vr0g; - TLorentzVector vr1g; - TLorentzVector vr01g; + // registry.get(HIST("Reco/nPVContributors"))->Fill(pvContributors.size(), 1.); + ROOT::Math::PxPyPzMVector vphi; + ROOT::Math::PxPyPzMVector vkstar; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector vr0; + ROOT::Math::PxPyPzMVector vr1; + ROOT::Math::PxPyPzMVector vr01; + ROOT::Math::PxPyPzMVector vr0g; + ROOT::Math::PxPyPzMVector vr1g; + ROOT::Math::PxPyPzMVector vr01g; int t1 = 0; if (truegapSide == 0) { registry.fill(HIST("V0A_0_mc"), collision.totalFV0AmplitudeA()); @@ -1401,7 +1430,7 @@ struct SginclusivePhiKstarSD { registry.get(HIST("Reco/tr_chi2ncl_2"))->Fill(tr1.tpcChi2NCl(), 1.); registry.get(HIST("Reco/tr_tpcnclfind_2"))->Fill(tr1.tpcNClsFindable(), 1.); registry.get(HIST("Reco/tr_itsChi2NCl_2"))->Fill(tr1.itsChi2NCl(), 1.); - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); registry.fill(HIST("tpc_dedx_mc"), v0.P(), tr1.tpcSignal()); registry.fill(HIST("tof_beta_mc"), v0.P(), tr1.beta()); @@ -1421,7 +1450,7 @@ struct SginclusivePhiKstarSD { } t1++; - vr0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); + vr0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); registry.get(HIST("Reco/trpt"))->Fill(vr0.Pt(), 1.); registry.get(HIST("Reco/treta_k"))->Fill(vr0.Eta(), 1.); if (!selectionPIDKaon1(tr1)) @@ -1437,7 +1466,7 @@ struct SginclusivePhiKstarSD { if (t2 > t1) { if (!selectionPIDKaon1(tr2)) continue; - vr1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + vr1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); auto mcPart2 = tr2.udMcParticle(); if (std::abs(mcPart2.globalIndex() - mcPart1.globalIndex()) != 1) continue; @@ -1452,7 +1481,7 @@ struct SginclusivePhiKstarSD { if (mcPart1.has_mothers() && mcPart2.has_mothers()) { for (const auto& mother : mcPart1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kPhi) { - vphi.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); + vphi.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); registry.get(HIST("MC/accMPtRap_phi_T"))->Fill(vphi.M(), vphi.Pt(), vphi.Rapidity(), 1.); flag = true; } @@ -1463,8 +1492,8 @@ struct SginclusivePhiKstarSD { } } } - vr0g.SetXYZM(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassKaonCharged); - vr1g.SetXYZM(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); + vr0g.SetCoordinates(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassKaonCharged); + vr1g.SetCoordinates(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); vr01g = vr0g + vr1g; vr01 = vr0 + vr1; @@ -1499,10 +1528,10 @@ struct SginclusivePhiKstarSD { if (tr1.sign() * tr2.sign() > 0) continue; - vr0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); - vr1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); - vr0g.SetXYZM(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassPionCharged); - vr1g.SetXYZM(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); + vr0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); + vr1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + vr0g.SetCoordinates(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassPionCharged); + vr1g.SetCoordinates(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); vr01g = vr0g + vr1g; vr01 = vr0 + vr1; if (!trackselector(tr1, parameters) || !trackselector(tr2, parameters)) { @@ -1514,7 +1543,7 @@ struct SginclusivePhiKstarSD { if (mcPart1.has_mothers() && mcPart2.has_mothers()) { for (const auto& mother : mcPart1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kK0Star892) { - vkstar.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); + vkstar.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); registry.get(HIST("MC/accMPtRap_kstar_T"))->Fill(vkstar.M(), vkstar.Pt(), vkstar.Rapidity(), 1.); flag = true; } From 97f2689ac4b9fa93b75d53b7bef14109aa3e6d85 Mon Sep 17 00:00:00 2001 From: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:01:37 +0200 Subject: [PATCH 29/62] [Trigger,PWGCF] Fix order of enums (#11545) --- EventFiltering/PWGCF/CFFilterAll.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EventFiltering/PWGCF/CFFilterAll.cxx b/EventFiltering/PWGCF/CFFilterAll.cxx index 589228edc5f..efc7625b215 100644 --- a/EventFiltering/PWGCF/CFFilterAll.cxx +++ b/EventFiltering/PWGCF/CFFilterAll.cxx @@ -61,8 +61,8 @@ enum CFTriggers { kPPRho, kPD, kLD, - kRhoD, kPhiD, + kRhoD, kNTriggers }; From bfb7d99c0345676c295689325c2e99a234999525 Mon Sep 17 00:00:00 2001 From: Felix Schlepper Date: Wed, 11 Jun 2025 20:09:12 +0200 Subject: [PATCH 30/62] [PWGLF] do not include ITS internal code (#11540) --- .../Strangeness/Converters/CMakeLists.txt | 10 +++++----- .../Strangeness/Converters/straevselsconverter2.cxx | 11 ++++++----- .../Strangeness/Converters/straevselsconverter3.cxx | 11 ++++++----- .../Strangeness/Converters/straevselsconverter4.cxx | 8 ++++---- .../Strangeness/Converters/straevselsconverter5.cxx | 10 +++++----- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt index 131672fd384..842137dafe1 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt @@ -41,22 +41,22 @@ o2physics_add_dpl_workflow(straevselsconverter o2physics_add_dpl_workflow(straevselsconverter2 SOURCES straevselsconverter2.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ReconstructionDataFormats COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter3 SOURCES straevselsconverter3.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ReconstructionDataFormats COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter4 SOURCES straevselsconverter4.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter5 SOURCES straevselsconverter5.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking O2Physics::AnalysisCCDB + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter2rawcents @@ -117,4 +117,4 @@ o2physics_add_dpl_workflow(stramccollisionconverter2 o2physics_add_dpl_workflow(zdcneutronsconverter SOURCES zdcneutronsconverter.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx index 401b04bbc83..fd3ccad4ee4 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx @@ -8,12 +8,13 @@ // 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. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ITStracking/Vertexer.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Vertex.h" + using namespace o2; using namespace o2::framework; @@ -52,7 +53,7 @@ struct straevselsconverter2 { values.totalFDDAmplitudeC(), values.energyCommonZNA(), values.energyCommonZNC(), - o2::its::Vertex::FlagsMask /*dummy flag value*/); + o2::dataformats::Vertex::FlagsMask /*dummy flag value*/); } } }; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx index ecbd738f5fa..ac209c26fe7 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx @@ -8,12 +8,13 @@ // 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. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ITStracking/Vertexer.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Vertex.h" + using namespace o2; using namespace o2::framework; @@ -53,7 +54,7 @@ struct straevselsconverter3 { values.totalFDDAmplitudeC(), values.energyCommonZNA(), values.energyCommonZNC(), - o2::its::Vertex::FlagsMask /*dummy flag value*/); + o2::dataformats::Vertex::FlagsMask /*dummy flag value*/); } } }; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx index ad988fd93aa..2dc55f365c9 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx @@ -8,12 +8,12 @@ // 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. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ITStracking/Vertexer.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + using namespace o2; using namespace o2::framework; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx index f9617c42a0b..0ba066f99b3 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx @@ -8,13 +8,13 @@ // 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. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/AggregatedRunInfo.h" -#include "ITStracking/Vertexer.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; From e94363c01178285218405e7fbcc7039256fd5f5e Mon Sep 17 00:00:00 2001 From: prottayCMT <61418725+prottayCMT@users.noreply.github.com> Date: Wed, 11 Jun 2025 21:43:09 +0200 Subject: [PATCH 31/62] [PWGLF] removed globalindex to index in addition to filters (#11565) Co-authored-by: Prottay Das --- .../Tasks/Strangeness/taskLambdaSpinCorr.cxx | 87 +++++++++++-------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx index 00a2d9707f5..33157c327bf 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -13,36 +13,41 @@ /// \brief Analysis task for Lambda spin spin correlation /// /// \author prottay.das@cern.ch +/// \author sourav.kundu@cern.ch -#include -#include -#include -#include -#include "Math/Vector2D.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/FT0Corrected.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/TrackSelection.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" -#include "CCDB/BasicCCDBManager.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "Common/DataModel/FT0Corrected.h" -#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table + +#include "Math/GenVector/Boost.h" +#include "Math/Vector2D.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" + +#include + +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -66,7 +71,6 @@ struct LfTaskLambdaSpinCorr { // mixing Configurable cosCalculation{"cosCalculation", 0, "cos calculation"}; Configurable mixingCombination{"mixingCombination", 0, "mixing Combination"}; - Configurable mixingEvSel{"mixingEvSel", false, "mixingEvSel"}; Configurable cfgCutOccupancy{"cfgCutOccupancy", 2000, "Occupancy cut"}; ConfigurableAxis axisVertex{"axisVertex", {5, -10, 10}, "vertex axis for bin"}; ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {8, 0, 80}, "multiplicity percentile for bin"}; @@ -94,13 +98,13 @@ struct LfTaskLambdaSpinCorr { Configurable confV0PtMin{"confV0PtMin", 0.f, "Minimum transverse momentum of V0"}; Configurable confV0PtMax{"confV0PtMax", 0.f, "Maximum transverse momentum of V0"}; Configurable confV0Rap{"confV0Rap", 0.8f, "Rapidity range of V0"}; - Configurable confV0DCADaughMax{"confV0DCADaughMax", 0.2f, "Maximum DCA between the V0 daughters"}; + Configurable confV0DCADaughMax{"confV0DCADaughMax", 0.2f, "Maximum DCA between the V0 daughters"}; Configurable confV0CPAMin{"confV0CPAMin", 0.9998f, "Minimum CPA of V0"}; Configurable confV0TranRadV0Min{"confV0TranRadV0Min", 1.5f, "Minimum transverse radius"}; Configurable confV0TranRadV0Max{"confV0TranRadV0Max", 100.f, "Maximum transverse radius"}; Configurable cMaxV0DCA{"cMaxV0DCA", 1.2, "Maximum V0 DCA to PV"}; - Configurable cMinV0DCAPr{"cMinV0DCAPr", 0.05, "Minimum V0 daughters DCA to PV for Pr"}; - Configurable cMinV0DCAPi{"cMinV0DCAPi", 0.05, "Minimum V0 daughters DCA to PV for Pi"}; + Configurable cMinV0DCAPr{"cMinV0DCAPr", 0.05, "Minimum V0 daughters DCA to PV for Pr"}; + Configurable cMinV0DCAPi{"cMinV0DCAPi", 0.05, "Minimum V0 daughters DCA to PV for Pi"}; Configurable cMaxV0LifeTime{"cMaxV0LifeTime", 20, "Maximum V0 life time"}; // config for V0 daughters @@ -610,7 +614,7 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel4 && !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (mixingEvSel && additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } @@ -620,7 +624,7 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel4 && !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (mixingEvSel && additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } @@ -795,7 +799,11 @@ struct LfTaskLambdaSpinCorr { } PROCESS_SWITCH(LfTaskLambdaSpinCorr, processME, "Process data ME", true); - void processDerivedData(soa::Join::iterator const& collision, v0Candidates const& V0s, dauTracks const&) + Filter v0der = (nabs(aod::v0data::dcapostopv) > cMinV0DCAPr && nabs(aod::v0data::dcanegtopv) > cMinV0DCAPi && nabs(aod::v0data::dcaV0daughters) < confV0DCADaughMax); + using v0Cand = soa::Filtered; + + // void processDerivedData(soa::Join::iterator const& collision, v0Candidates const& V0s, dauTracks const&) + void processDerivedData(soa::Join::iterator const& collision, v0Cand const& V0s, dauTracks const&) { histos.fill(HIST("hEvtSelInfo"), 0.5); if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) { @@ -914,8 +922,10 @@ struct LfTaskLambdaSpinCorr { } PROCESS_SWITCH(LfTaskLambdaSpinCorr, processDerivedData, "Process derived data", true); - Preslice tracksPerCollisionV0Mixed = o2::aod::v0data::straCollisionId; // for derived data only - void processDerivedDataMixed(soa::Join const& collisions, v0Candidates const& V0s, dauTracks const&) + // Preslice tracksPerCollisionV0Mixed = o2::aod::v0data::straCollisionId; // for derived data only + Preslice tracksPerCollisionV0Mixed = o2::aod::v0data::straCollisionId; // for derived data only + // void processDerivedDataMixed(soa::Join const& collisions, v0Candidates const& V0s, dauTracks const&) + void processDerivedDataMixed(soa::Join const& collisions, v0Cand const& V0s, dauTracks const&) { @@ -954,7 +964,7 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel4 && !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (mixingEvSel && additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } @@ -964,13 +974,16 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel4 && !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (mixingEvSel && additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } auto centrality = collision1.centFT0C(); - auto groupV01 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); - auto groupV02 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); - auto groupV03 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision2.globalIndex()); + // auto groupV01 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); + // auto groupV02 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); + // auto groupV03 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision2.globalIndex()); + auto groupV01 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.index()); + auto groupV02 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.index()); + auto groupV03 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision2.index()); size_t rows = groupV03.size() + 20; size_t cols = groupV01.size() + 20; From c3ac5ab526e612df2e8b6f65937c9645a3ad9c41 Mon Sep 17 00:00:00 2001 From: Zhiyong <71517277+Luzhiyongg@users.noreply.github.com> Date: Thu, 12 Jun 2025 07:21:44 +0800 Subject: [PATCH 32/62] [PWGCF] flowtask: ccdb set to now. diHadron: add event weight (#11569) --- PWGCF/Flow/Tasks/flowTask.cxx | 4 +- .../Tasks/diHadronCor.cxx | 155 ++++++++++-------- 2 files changed, 88 insertions(+), 71 deletions(-) diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index 5431a84bd47..4390131be3a 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -132,7 +132,6 @@ struct FlowTask { // Connect to ccdb Service ccdb; - Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; // Define output @@ -196,7 +195,8 @@ struct FlowTask { ccdb->setURL(ccdbUrl.value); ccdb->setCaching(true); - ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); // Add some output objects to the histogram registry // Event QA diff --git a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx index 4a944a4fff0..189e201ef68 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -78,7 +78,6 @@ struct DiHadronCor { O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") O2_DEFINE_CONFIGURABLE(cfgCentTableUnavailable, bool, false, "if a dataset does not provide centrality information") O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") - O2_DEFINE_CONFIGURABLE(cfgUseTentativeEventCounter, bool, false, "After sel8(), count events regardless of real event selection") O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") @@ -93,6 +92,7 @@ struct DiHadronCor { O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") O2_DEFINE_CONFIGURABLE(cfgVerbosity, bool, false, "Verbose output") + O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") SliceCache cache; @@ -184,29 +184,18 @@ struct DiHadronCor { LOGF(info, "Starting init"); // Event Counter - registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{10, 0, 10}}}); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(8, "occupancy"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(9, "MultCorrelation"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "cfgEvSelV0AT0ACut"); - if (cfgUseTentativeEventCounter) { - registry.add("hEventCountTentative", "Number of Event;; Count", {HistType::kTH1D, {{10, 0, 10}}}); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(1, "after sel8"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(8, "occupancy"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(9, "MultCorrelation"); - registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(10, "cfgEvSelV0AT0ACut"); + if (doprocessSame && cfgUseAdditionalEventCut) { + registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{10, 0, 10}}}); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(8, "occupancy"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(9, "MultCorrelation"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "cfgEvSelV0AT0ACut"); } if (cfgUseAdditionalEventCut) { @@ -226,23 +215,24 @@ struct DiHadronCor { fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); } - // Make histograms to check the distributions after cuts - registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); - registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); - registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); - registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); - registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); - registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); - registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); - registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); - registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); - registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); // histogram to see how many events are in the same and mixed event - registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); - registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); - - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + // Make histograms to check the distributions after cuts + if (doprocessSame) { + registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution + registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); + registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); + registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); + registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); + registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event + registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); + registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); // histogram to see how many events are in the same and mixed event + registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); + registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + } registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event if (doprocessMCSame && doprocessOntheflySame) { @@ -263,6 +253,13 @@ struct DiHadronCor { registry.add("MCTrue/MCdeltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution registry.add("MCTrue/MCdeltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); } + if (doprocessMCEfficiency) { + registry.add("MCEffeventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(1, "MC"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(2, "Reco Primary"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(3, "Reco All"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(4, "Fake"); + } std::vector corrAxis = {{axisSample, "Sample"}, {axisVertex, "z-vtx (cm)"}, @@ -424,7 +421,7 @@ struct DiHadronCor { } template - void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int magneticField, float cent) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int magneticField, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { // Cache efficiency for particles (too many FindBin lookups) if (mEfficiency) { @@ -455,7 +452,7 @@ struct DiHadronCor { if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) continue; if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); } for (auto const& track2 : tracks2) { @@ -497,18 +494,18 @@ struct DiHadronCor { // fill the right sparse and histograms if (system == SameEvent) { - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); - registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); } else if (system == MixedEvent) { - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); - registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); } } } } template - void fillMCCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + void fillMCCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); @@ -522,7 +519,7 @@ struct DiHadronCor { continue; if (system == SameEvent && (doprocessMCSame || doprocessOntheflySame)) - registry.fill(HIST("MCTrue/MCTrig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); + registry.fill(HIST("MCTrue/MCTrig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); for (auto const& track2 : tracks2) { @@ -539,13 +536,13 @@ struct DiHadronCor { // fill the right sparse and histograms if (system == SameEvent) { - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); if (doprocessMCSame || doprocessOntheflySame) - registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_same"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); } else if (system == MixedEvent) { - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); if (doprocessMCMixed || doprocessOntheflyMixed) - registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); } } } @@ -652,7 +649,7 @@ struct DiHadronCor { fillYield(collision, tracks); same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); - fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent); + fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, 1.0f); } PROCESS_SWITCH(DiHadronCor, processSame, "Process same event", true); @@ -671,8 +668,9 @@ struct DiHadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; if (!collision1.sel8() || !collision2.sel8()) continue; @@ -702,8 +700,12 @@ struct DiHadronCor { registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin auto bc = collision1.bc_as(); loadEfficiency(bc.timestamp()); + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } - fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp()), cent1); + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp()), cent1, eventWeight); } } @@ -723,7 +725,7 @@ struct DiHadronCor { } } - void processMCEfficiency(FilteredMcCollisions::iterator const& mcCollision, aod::BCsWithTimestamps const&, soa::SmallGroups> const& collisions, FilteredMcParticles const& mcParticles, FilteredTracksWithMCLabels const& tracks) + void processMCEfficiency(FilteredMcCollisions::iterator const& mcCollision, soa::SmallGroups> const& collisions, FilteredMcParticles const& mcParticles, FilteredTracksWithMCLabels const& tracks) { if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { return; @@ -731,6 +733,7 @@ struct DiHadronCor { // Primaries for (const auto& mcParticle : mcParticles) { if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCEffeventcount"), 0.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::MC, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); } } @@ -745,11 +748,14 @@ struct DiHadronCor { if (track.has_mcParticle()) { const auto& mcParticle = track.mcParticle(); if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCEffeventcount"), 1.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoPrimaries, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); } + registry.fill(HIST("MCEffeventcount"), 2.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoAll, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); } else { // fake track + registry.fill(HIST("MCEffeventcount"), 3.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::Fake, track.eta(), track.pt(), 0, 0., mcCollision.posZ()); } } @@ -791,14 +797,15 @@ struct DiHadronCor { } same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); - fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); if (collisions.size() == 0) { return; } + registry.fill(HIST("MCTrue/MCeventcount"), 2.5); same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); - fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); } PROCESS_SWITCH(DiHadronCor, processMCSame, "Process MC same event", false); @@ -815,8 +822,9 @@ struct DiHadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(mcParticles, mcParticles); - Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) continue; @@ -839,14 +847,18 @@ struct DiHadronCor { continue; registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } - fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); if (groupedCollisions.size() == 0) { continue; } - fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); } } PROCESS_SWITCH(DiHadronCor, processMCMixed, "Process MC mixed events", false); @@ -873,10 +885,10 @@ struct DiHadronCor { } same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); - fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); - fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); } PROCESS_SWITCH(DiHadronCor, processOntheflySame, "Process on-the-fly same event", false); @@ -893,8 +905,9 @@ struct DiHadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(mcParticles, mcParticles); - Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) continue; @@ -903,10 +916,14 @@ struct DiHadronCor { continue; registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } - fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); - fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); } } PROCESS_SWITCH(DiHadronCor, processOntheflyMixed, "Process on-the-fly mixed events", false); From e52ac4b35f8ac95dfea65fac8fb4565e63217964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 12 Jun 2025 07:23:03 +0200 Subject: [PATCH 33/62] [PWGHF,Tutorial] Include What You Use (#11553) --- Tutorials/PWGHF/DataModelMini.h | 7 ++++- Tutorials/PWGHF/skimCreatorMini.cxx | 31 +++++++++++++-------- Tutorials/PWGHF/taskMini.cxx | 42 ++++++++++++++++++----------- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/Tutorials/PWGHF/DataModelMini.h b/Tutorials/PWGHF/DataModelMini.h index 7a03f1462b7..720b7207676 100644 --- a/Tutorials/PWGHF/DataModelMini.h +++ b/Tutorials/PWGHF/DataModelMini.h @@ -17,7 +17,12 @@ #ifndef TUTORIALS_PWGHF_DATAMODELMINI_H_ #define TUTORIALS_PWGHF_DATAMODELMINI_H_ -#include "Framework/AnalysisDataModel.h" +#include "Common/Core/RecoDecay.h" + +#include +#include + +#include namespace o2::aod { diff --git a/Tutorials/PWGHF/skimCreatorMini.cxx b/Tutorials/PWGHF/skimCreatorMini.cxx index ac6b12e2004..6fba171cfbf 100644 --- a/Tutorials/PWGHF/skimCreatorMini.cxx +++ b/Tutorials/PWGHF/skimCreatorMini.cxx @@ -14,21 +14,30 @@ /// /// \author Vít Kučera , Inha University -// O2 -#include "CommonConstants/PhysicsConstants.h" -#include "DCAFitter/DCAFitterN.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - -// O2Physics +#include "Tutorials/PWGHF/DataModelMini.h" +// #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/TrackSelectionTables.h" -// PWGHF -#include "Tutorials/PWGHF/DataModelMini.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include using namespace o2; using namespace o2::aod; diff --git a/Tutorials/PWGHF/taskMini.cxx b/Tutorials/PWGHF/taskMini.cxx index 871fe710581..1876d6230cc 100644 --- a/Tutorials/PWGHF/taskMini.cxx +++ b/Tutorials/PWGHF/taskMini.cxx @@ -14,23 +14,33 @@ /// /// \author Vít Kučera , Inha University -// O2 -#include "CommonConstants/PhysicsConstants.h" -#include "DCAFitter/DCAFitterN.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - -// O2Physics +#include "Tutorials/PWGHF/DataModelMini.h" +// +#include "PWGHF/Core/HfHelper.h" +// #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelectorPID.h" #include "Common/Core/trackUtilities.h" -#include "Common/DataModel/PIDResponse.h" - -// PWGHF -#include "PWGHF/Core/HfHelper.h" -#include "Tutorials/PWGHF/DataModelMini.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include using namespace o2; using namespace o2::aod; @@ -314,8 +324,8 @@ struct HfTaskMiniD0 { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"hf-task-mini-candidate-creator-2prong"}), // o2-linter: disable=name/o2-task - adaptAnalysisTask(cfgc, TaskName{"hf-task-mini-candidate-creator-2prong-expressions"}), // o2-linter: disable=name/o2-task + adaptAnalysisTask(cfgc, TaskName{"hf-task-mini-candidate-creator-2prong"}), // o2-linter: disable=name/o2-task (wrong hyphenation) + adaptAnalysisTask(cfgc, TaskName{"hf-task-mini-candidate-creator-2prong-expressions"}), // o2-linter: disable=name/o2-task (wrong hyphenation) adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; } From 1559e85139d3c10dc0861d86fe14e46b65ba6e85 Mon Sep 17 00:00:00 2001 From: Simone Ragoni <47641042+siragoni@users.noreply.github.com> Date: Thu, 12 Jun 2025 08:34:43 +0200 Subject: [PATCH 34/62] [PWGUD] new task for inclusive MC (#11498) --- PWGUD/Tasks/CMakeLists.txt | 7 +- PWGUD/Tasks/analysisMCDPMJetSGv3.cxx | 412 +++++++++++++++++++++++++++ 2 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 PWGUD/Tasks/analysisMCDPMJetSGv3.cxx diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index a193e46587e..d828261167c 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -246,5 +246,10 @@ o2physics_add_dpl_workflow(flow-cumulants-upc o2physics_add_dpl_workflow(flow-correlations-upc SOURCES flowCorrelationsUpc.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGCFCore + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGCFCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(analysis-mc-dpm-jet-sg-v3 + SOURCES analysisMCDPMJetSGv3.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx b/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx new file mode 100644 index 00000000000..4347871377a --- /dev/null +++ b/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx @@ -0,0 +1,412 @@ +// 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 AnalysisMCDPMJetSGv3.cxx +/// \brief Process MC DPMJet events for inclusive studies. +/// +/// \author Simone Ragoni + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/ASoAHelpers.h" +// #include "TDatabasePDG.h" +#include "PWGUD/Core/UPCHelpers.h" +#include "PWGUD/DataModel/UDTables.h" +// #include "TLorentzVector.h" +// #include "TVector3.h" +#include "Math/LorentzVector.h" // ROOT::Math::LorentzVector +#include "Math/PxPyPzM4D.h" // ROOT::Math::PxPyPzM4D +#include "TMath.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct AnalysisMCDPMJetSGv3 { + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + // TDatabasePDG* fPDG = TDatabasePDG::Instance(); + + Configurable nBinsPt{"nBinsPt", 100, "N bins in pT histo"}; + + // using myCompleteTracks = soa::Join; + // using myFilteredTracks = soa::Filtered; + using BCs = soa::Join; + + Preslice perCollision = aod::track::collisionId; + Preslice perMcCollision = o2::aod::mcparticle::mcCollisionId; + // using MCTCs = soa::Join; + // using MCTC = MCTCs::iterator; + // define abbreviations + using CCs = soa::Join; + using CC = CCs::iterator; + using MCparticles = aod::UDMcParticles::iterator; + using TCs = soa::Join; + // using TCs = soa::Join; + using TC = TCs::iterator; + using LorentzVectorM = ROOT::Math::LorentzVector>; + + double massPion = 0.; + double massKaon = 0.; + double massProton = 0.; + const int codePion = 211; + const int codeKaon = 321; + const int codeProton = 2212; + + void init(InitContext const&) + { + // TParticlePDG* pionPDG = fPDG->GetParticle(codePion); + // if (pionPDG != nullptr) { + // massPion = pionPDG->Mass(); + // } + // TParticlePDG* kaonPDG = fPDG->GetParticle(codeKaon); + // if (kaonPDG != nullptr) { + // massKaon = kaonPDG->Mass(); + // } + // TParticlePDG* protonPDG = fPDG->GetParticle(codeProton); + // if (protonPDG != nullptr) { + // massProton = protonPDG->Mass(); + // } + massPion = o2::constants::physics::MassPionCharged; + massKaon = o2::constants::physics::MassKaonCharged; + massProton = o2::constants::physics::MassProton; + + // define axes you want to use + const AxisSpec axisCounter{10, 0, 10, ""}; + const AxisSpec axisEta{100, -1.5, +1.5, "#eta"}; + const AxisSpec axisPt{5000, 0, 5, "p_{T}"}; + const AxisSpec axisPtSmall{1000, 0, 1, "p_{T}"}; + const AxisSpec axisMass{nBinsPt, 0, 5, "m_{#pi#pi}"}; + const AxisSpec axisMassSmall{nBinsPt, 0, 2, "m_{#pi#pi}"}; + const AxisSpec axisDeltaPt{100, -1.0, +1.0, "#Delta(p_{T})"}; + const AxisSpec axisBC{1000, -10000.0, +10000.0, "BCs"}; + const AxisSpec axisBCext{100000, -10000000.0, +10000000.0, "BCs"}; + const AxisSpec axisCosTheta{100, -1.0, +1.0, "cos#theta"}; + const AxisSpec axisPhi{600, -o2::constants::math::PI, -o2::constants::math::PI, "#varphi"}; + + // create histograms + histos.add("hdEdx", "p vs dE/dx Signal", kTH2F, {{100, 0.0, 3.0}, {1000, 0.0, 2000.0}}); + histos.add("hSigmaPion", "p vs dE/dx sigma pion TPC ", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaPionTruth", "p vs dE/dx sigma pion TPC truth", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaPionTOF", "p vs dE/dx sigma pion TOF ", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaPionTruthTOF", "p vs dE/dx sigma pion TOF truth", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaKaon", "p vs dE/dx sigma kaon TPC ", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaKaonTruth", "p vs dE/dx sigma kaon TPC truth", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaKaonTOF", "p vs dE/dx sigma kaon TOF ", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaKaonTruthTOF", "p vs dE/dx sigma kaon TOF truth", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaProton", "p vs dE/dx sigma proton TPC ", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaProtonTruth", "p vs dE/dx sigma proton TPC truth", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaProtonTOF", "p vs dE/dx sigma proton TOF ", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + histos.add("hSigmaProtonTruthTOF", "p vs dE/dx sigma proton TOF truth", kTH2F, {{300, 0.0, 3.0}, {200, -10.0, 10.0}}); + + histos.add("hVisibleMultiVsGeneratedMulti", "Multiplicity correlation", kTH2F, {{10000, -0.5, 9999.5}, {1000, -0.5, 999.5}}); + + histos.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); + histos.add("ptResolution", "ptResolution", kTH2F, {axisPt, axisDeltaPt}); + + histos.add("ptGeneratedPion", "ptGeneratedPion", kTH1F, {axisPt}); + histos.add("ptGeneratedKaon", "ptGeneratedKaon", kTH1F, {axisPt}); + histos.add("ptGeneratedProton", "ptGeneratedProton", kTH1F, {axisPt}); + histos.add("ptGeneratedPionAxE", "ptGeneratedPionAxE", kTH1F, {axisPt}); + histos.add("ptGeneratedKaonAxE", "ptGeneratedKaonAxE", kTH1F, {axisPt}); + histos.add("ptGeneratedProtonAxE", "ptGeneratedProtonAxE", kTH1F, {axisPt}); + histos.add("ptGeneratedProtonAxEPos", "ptGeneratedProtonAxEPos", kTH1F, {axisPt}); + histos.add("ptGeneratedProtonAxENeg", "ptGeneratedProtonAxENeg", kTH1F, {axisPt}); + histos.add("ptReconstructedPion", "ptReconstructedPion", kTH1F, {axisPt}); + histos.add("ptReconstructedKaon", "ptReconstructedKaon", kTH1F, {axisPt}); + histos.add("ptReconstructedProton", "ptReconstructedProton", kTH1F, {axisPt}); + histos.add("ptReconstructedProtonPos", "ptReconstructedProtonPos", kTH1F, {axisPt}); + histos.add("ptReconstructedProtonNeg", "ptReconstructedProtonNeg", kTH1F, {axisPt}); + histos.add("ptReconstructedPionTOF", "ptReconstructedPionTOF", kTH1F, {axisPt}); + histos.add("ptReconstructedKaonTOF", "ptReconstructedKaonTOF", kTH1F, {axisPt}); + histos.add("ptReconstructedProtonTOF", "ptReconstructedProtonTOF", kTH1F, {axisPt}); + + histos.add("allreconstructedPFPion", "allreconstructedPFPion", kTH1F, {axisPt}); + histos.add("allreconstructedPFKaon", "allreconstructedPFKaon", kTH1F, {axisPt}); + histos.add("allreconstructedPFProton", "allreconstructedPFProton", kTH1F, {axisPt}); + histos.add("allreconstructedPFProtonPos", "allreconstructedPFProtonPos", kTH1F, {axisPt}); + histos.add("allreconstructedPFProtonNeg", "allreconstructedPFProtonNeg", kTH1F, {axisPt}); + histos.add("allreconstructedPFPionTOF", "allreconstructedPFPionTOF", kTH1F, {axisPt}); + histos.add("allreconstructedPFKaonTOF", "allreconstructedPFKaonTOF", kTH1F, {axisPt}); + histos.add("allreconstructedPFProtonTOF", "allreconstructedPFProtonTOF", kTH1F, {axisPt}); + + histos.add("numberOfRecoCollisions", "numberOfRecoCollisions", kTH1F, {{100, -0.5f, 99.5f}}); + histos.add("numberOfRecoCollisions2", "numberOfRecoCollisions2", kTH1F, {{100, -0.5f, 99.5f}}); + histos.add("numberOfTracksMC", "numberOfTracksMC", kTH1F, {{100, -0.5f, 99.5f}}); + histos.add("numberOfTracksReco", "numberOfTracksReco", kTH1F, {{100, -0.5f, 99.5f}}); + + histos.add("bcResolution", "bcResolution", kTH1F, {axisBC}); + histos.add("mcbcHistogram", "mcbcHistogram", kTH1F, {axisBCext}); + histos.add("bcHistogram", "bcHistogram", kTH1F, {axisBCext}); + histos.add("mcbcModuloOrbitHistogram", "mcbcModuloOrbitHistogram", kTH1F, {axisBC}); + histos.add("bcModuloOrbitHistogram", "bcModuloOrbitHistogram", kTH1F, {axisBC}); + } + //----------------------------------------------------------------------------------------------------------------------- + void processSim(aod::UDMcCollision const& mcCollision, aod::UDMcParticles const& mcParticles) + { + // histos.fill(HIST("eventCounter"), 0.5); + + // auto massPion = 0.; + // TParticlePDG pionPDG = fPDG->GetParticle(codePion); + // massPion = pionPDG.Mass(); + // auto massKaon = 0.; + // TParticlePDG kaonPDG = fPDG->GetParticle(codeKaon); + // massKaon = kaonPDG.Mass(); + // auto massProton = 0.; + // TParticlePDG protonPDG = fPDG->GetParticle(codeProton); + // massProton = protonPDG.Mass(); + histos.fill(HIST("numberOfTracksMC"), mcParticles.size()); + histos.fill(HIST("eventCounter"), mcCollision.size()); + // LOGF(info, "New event! mcParticles.size() = %d", mcParticles.size()); + + int counterMC = 0; + int counter = 0; + for (const auto& mcParticle : mcParticles) { + if (!mcParticle.isPhysicalPrimary()) + continue; + counterMC += 1; + // if(mcParticle.isPhysicalPrimary()) counterMC += 1; + LorentzVectorM protoMC( + mcParticle.px(), + mcParticle.py(), + mcParticle.pz(), + massPion); + double etaMax = 0.8; + double ptMin = 0.1; + if (std::fabs(protoMC.Eta()) < etaMax && protoMC.Pt() > ptMin) { + counter += 1; + } + if (!mcParticle.isPhysicalPrimary()) + continue; + // if(mcParticle.isPhysicalPrimary() && fabs(mcParticle.eta())<0.9){ // do this in the context of the MC loop ! (context matters!!!) + // LorentzVectorM pMC; + LorentzVectorM pMC(mcParticle.px(), mcParticle.py(), mcParticle.pz(), massPion); + if (std::abs(mcParticle.pdgCode()) == codePion) { + // histos.fill(HIST("ptGeneratedPion"), mcParticle.pt()); + // LorentzVectorM pMC(mcParticle.px(), mcParticle.py(), mcParticle.pz(), massPion); + histos.fill(HIST("ptGeneratedPion"), pMC.Pt()); + } + if (std::abs(mcParticle.pdgCode()) == codeKaon) { + // histos.fill(HIST("ptGenerateKaon"), mcParticle.pt()); + // LorentzVectorM pMC(mcParticle.px(), mcParticle.py(), mcParticle.pz(), massKaon); + pMC.SetM(massKaon); + histos.fill(HIST("ptGeneratedKaon"), pMC.Pt()); + } + if (std::abs(mcParticle.pdgCode()) == codeProton) { + // histos.fill(HIST("ptGeneratedProton"), mcParticle.pt()); + // LorentzVectorM pMC(mcParticle.px(), mcParticle.py(), mcParticle.pz(), massProton); + pMC.SetM(massProton); + histos.fill(HIST("ptGeneratedProton"), pMC.Pt()); + } + double yMax = 0.8; + if (std::abs(pMC.Rapidity()) < yMax) { + if (std::abs(mcParticle.pdgCode()) == codePion) + histos.fill(HIST("ptGeneratedPionAxE"), pMC.Pt()); + if (std::abs(mcParticle.pdgCode()) == codeKaon) + histos.fill(HIST("ptGeneratedKaonAxE"), pMC.Pt()); + if (std::abs(mcParticle.pdgCode()) == codeProton) + histos.fill(HIST("ptGeneratedProtonAxE"), pMC.Pt()); + if (mcParticle.pdgCode() == codeProton) { + histos.fill(HIST("ptGeneratedProtonAxEPos"), pMC.Pt()); + } else { + histos.fill(HIST("ptGeneratedProtonAxENeg"), pMC.Pt()); + } + } + } + histos.fill(HIST("hVisibleMultiVsGeneratedMulti"), counterMC, counter); + } + PROCESS_SWITCH(AnalysisMCDPMJetSGv3, processSim, "processSim", true); + + void processReco(CC const& collision, + TCs const& tracks, + // aod::UDMcCollisions const& /*mccollisions*/, + aod::UDMcParticles const& mcParticles) + { + histos.fill(HIST("numberOfRecoCollisions"), 88.); // number of times coll was reco-ed + histos.fill(HIST("numberOfRecoCollisions"), collision.size()); // number of times coll was reco-ed + histos.fill(HIST("numberOfRecoCollisions2"), mcParticles.size()); + Partition pvContributors = aod::udtrack::isPVContributor == true; + pvContributors.bindTable(tracks); + + // auto massPion = 0.; + // TParticlePDG pionPDG = fPDG->GetParticle(codePion); + // massPion = pionPDG.Mass(); + // auto massKaon = 0.; + // TParticlePDG kaonPDG = fPDG->GetParticle(codeKaon); + // massKaon = kaonPDG.Mass(); + // auto massProton = 0.; + // TParticlePDG protonPDG = fPDG->GetParticle(codeProton); + // massProton = protonPDG.Mass(); + + histos.fill(HIST("numberOfTracksReco"), tracks.size()); + // double etaMax = 0.8; + double yMax = 0.8; + double sigmaMax = 3.; + double ptMin = 0.1; + int nFindableMin = 70; + double dcaZlimit = 2.; + + // int counter = 0; + for (const auto& track : tracks) { + if (track.isPVContributor()) { + int nFindable = track.tpcNClsFindable(); + if (nFindable < nFindableMin) { + continue; + } + // int NMinusFound = track.tpcNClsFindableMinusFound(); + // int NCluster = NFindable - NMinusFound; + // if (NCluster < 70) { + // continue; + // } + if (track.pt() < ptMin) { + continue; + } + if (!(std::abs(track.dcaZ()) < dcaZlimit)) { + continue; + } + double dcaLimit = 0.0105 + 0.035 / std::pow(track.pt(), 1.1); + if (!(std::abs(track.dcaXY()) < dcaLimit)) { + continue; + } + + double momentum = std::sqrt(track.px() * track.px() + track.py() * track.py() + track.pz() * track.pz()); + double dEdx = track.tpcSignal(); + histos.fill(HIST("hdEdx"), momentum, dEdx); + + LorentzVectorM pion(track.px(), track.py(), track.pz(), o2::constants::physics::MassPionCharged); + LorentzVectorM kaon(track.px(), track.py(), track.pz(), o2::constants::physics::MassKaonCharged); + LorentzVectorM proton(track.px(), track.py(), track.pz(), o2::constants::physics::MassProton); + auto nSigmaPi = -999.; + auto nSigmaKa = -999.; + auto nSigmaPr = -999.; + auto nSigmaPiTOF = -999.; + auto nSigmaKaTOF = -999.; + auto nSigmaPrTOF = -999.; + // This section makes templates + if (track.hasTPC()) { + nSigmaPi = track.tpcNSigmaPi(); + nSigmaKa = track.tpcNSigmaKa(); + nSigmaPr = track.tpcNSigmaPr(); + if (std::abs(nSigmaPi) < sigmaMax && std::abs(pion.Rapidity()) < yMax) { + histos.fill(HIST("hSigmaPion"), track.pt(), nSigmaPi); + if (track.has_udMcParticle()) { + auto mcParticle = track.udMcParticle(); + // if(abs(mcParticle.pdgCode())==codePion && mcParticle.isPhysicalPrimary()) howManyPionsHavePionMCandPrimaries += 1; + if (std::abs(mcParticle.pdgCode()) == codePion) { + histos.fill(HIST("hSigmaPionTruth"), track.pt(), nSigmaPi); + histos.fill(HIST("allreconstructedPFPion"), track.pt()); + if (mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("ptReconstructedPion"), track.pt()); + } + } + } + } + if (std::abs(nSigmaKa) < sigmaMax && std::abs(kaon.Rapidity()) < yMax) { + histos.fill(HIST("hSigmaKaon"), track.pt(), nSigmaKa); + if (track.has_udMcParticle()) { + auto mcParticle = track.udMcParticle(); + if (std::abs(mcParticle.pdgCode()) == codeKaon) { + histos.fill(HIST("hSigmaKaonTruth"), track.pt(), nSigmaKa); + histos.fill(HIST("allreconstructedPFKaon"), track.pt()); + if (mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("ptReconstructedKaon"), track.pt()); + } + } + } + } + if (std::abs(nSigmaPr) < sigmaMax && std::abs(proton.Rapidity()) < yMax) { + histos.fill(HIST("hSigmaProton"), track.pt(), nSigmaPr); + if (track.has_udMcParticle()) { + auto mcParticle = track.udMcParticle(); + if (std::abs(mcParticle.pdgCode()) == codeProton) { + histos.fill(HIST("hSigmaProtonTruth"), track.pt(), nSigmaPr); + histos.fill(HIST("allreconstructedPFProton"), track.pt()); + if (mcParticle.pdgCode() == codeProton) { + histos.fill(HIST("allreconstructedPFProtonPos"), track.pt()); + } else { + histos.fill(HIST("allreconstructedPFProtonNeg"), track.pt()); + } + if (mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("ptReconstructedProton"), track.pt()); + if (mcParticle.pdgCode() == codeProton) { + histos.fill(HIST("ptReconstructedProtonPos"), track.pt()); + } else { + histos.fill(HIST("ptReconstructedProtonNeg"), track.pt()); + } + } + } + } + } + } + if (track.hasTPC() && track.hasTOF()) { + // if (track.hasTOF()) { + nSigmaPiTOF = track.tofNSigmaPi(); + nSigmaKaTOF = track.tofNSigmaKa(); + nSigmaPrTOF = track.tofNSigmaPr(); + if (std::abs(nSigmaPiTOF) < sigmaMax && std::abs(pion.Rapidity()) < yMax) { + histos.fill(HIST("hSigmaPionTOF"), track.pt(), nSigmaPiTOF); + if (track.has_udMcParticle()) { + auto mcParticle = track.udMcParticle(); + // if(abs(mcParticle.pdgCode())==codePion && mcParticle.isPhysicalPrimary()) howManyPionsHavePionMCandPrimaries += 1; + if (std::abs(mcParticle.pdgCode()) == codePion) { + histos.fill(HIST("hSigmaPionTruthTOF"), track.pt(), nSigmaPiTOF); + histos.fill(HIST("allreconstructedPFPionTOF"), track.pt()); + if (mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("ptReconstructedPionTOF"), track.pt()); + } + } + } + } + if (std::abs(nSigmaKaTOF) < sigmaMax && std::abs(kaon.Rapidity()) < yMax) { + histos.fill(HIST("hSigmaKaonTOF"), track.pt(), nSigmaKaTOF); + if (track.has_udMcParticle()) { + auto mcParticle = track.udMcParticle(); + if (std::abs(mcParticle.pdgCode()) == codeKaon) { + histos.fill(HIST("hSigmaKaonTruthTOF"), track.pt(), nSigmaKaTOF); + histos.fill(HIST("allreconstructedPFKaonTOF"), track.pt()); + if (mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("ptReconstructedKaonTOF"), track.pt()); + } + } + } + } + if (std::abs(nSigmaPrTOF) < sigmaMax && std::abs(proton.Rapidity()) < yMax) { + histos.fill(HIST("hSigmaProtonTOF"), track.pt(), nSigmaPrTOF); + if (track.has_udMcParticle()) { + auto mcParticle = track.udMcParticle(); + if (std::abs(mcParticle.pdgCode()) == codeProton) { + histos.fill(HIST("hSigmaProtonTruthTOF"), track.pt(), nSigmaPrTOF); + histos.fill(HIST("allreconstructedPFProtonTOF"), track.pt()); + if (mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("ptReconstructedProtonTOF"), track.pt()); + } + } + } + } + } + // counter++; + // histos.fill(HIST("hVisibleMultiVsGeneratedMulti"), counterMC, counter); + // histos.fill(HIST("hVisibleMultiVsGeneratedMulti"), mcParticles.size(), counter); + } + } // track loop + + // } // collision loop + } + PROCESS_SWITCH(AnalysisMCDPMJetSGv3, processReco, "processReco", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} From 41aa1e560cee914dc4735fa6a43f7514b8b54c1e Mon Sep 17 00:00:00 2001 From: Jesper Gumprecht <113693781+jesgum@users.noreply.github.com> Date: Thu, 12 Jun 2025 08:55:36 +0200 Subject: [PATCH 35/62] [ALICE3] Remove subscription to MCharmIndices (#11557) --- ALICE3/Tasks/alice3-multicharm.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ALICE3/Tasks/alice3-multicharm.cxx b/ALICE3/Tasks/alice3-multicharm.cxx index 34276a800b3..2b6ad804ddf 100644 --- a/ALICE3/Tasks/alice3-multicharm.cxx +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -57,7 +57,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using multicharmtracks = soa::Join; +// using multicharmtracks = soa::Join; struct alice3multicharm { SliceCache cache; @@ -134,7 +134,7 @@ struct alice3multicharm { histos.add("h3dXicc", "h3dXicc; Xicc pT (GeV/#it(c)); Xicc #eta; Xicc mass (GeV/#it(c)^{2})", kTH3D, {axisPt, axisEta, axisXiccMass}); } - void processXicc(multicharmtracks const& multiCharmTracks) + void processXicc(aod::MCharmCores const& multiCharmTracks) { for (const auto& xiccCand : multiCharmTracks) { if (xiccCand.xicDauDCA() > xicMaxDauDCA || xiccCand.xiccDauDCA() > xiccMaxDauDCA) From 11b35ea594c99bab6930a5e566da3017520c874a Mon Sep 17 00:00:00 2001 From: yuanzhe <90246048+wang-yuanzhe@users.noreply.github.com> Date: Thu, 12 Jun 2025 09:15:28 +0200 Subject: [PATCH 36/62] [PWGLF] Add option to disable SV radius cut for kink (#11541) --- PWGLF/TableProducer/Common/kinkBuilder.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/PWGLF/TableProducer/Common/kinkBuilder.cxx b/PWGLF/TableProducer/Common/kinkBuilder.cxx index d2b25be26a0..51be861741a 100644 --- a/PWGLF/TableProducer/Common/kinkBuilder.cxx +++ b/PWGLF/TableProducer/Common/kinkBuilder.cxx @@ -106,6 +106,7 @@ struct kinkBuilder { Configurable etaMax{"etaMax", 1., "eta daughter"}; Configurable nTPCClusMinDaug{"nTPCClusMinDaug", 80, "daug NTPC clusters cut"}; Configurable askTOFforDaug{"askTOFforDaug", false, "If true, ask for TOF signal"}; + Configurable doSVRadiusCut{"doSVRadiusCut", true, "If true, apply the cut on the radius of the secondary vertex and tracksIU"}; o2::vertexing::DCAFitterN<2> fitter; o2::base::MatLayerCylSet* lut = nullptr; @@ -329,7 +330,7 @@ struct kinkBuilder { // cut on decay radius to 17 cm float decRad2 = kinkCand.decVtx[0] * kinkCand.decVtx[0] + kinkCand.decVtx[1] * kinkCand.decVtx[1]; - if (decRad2 < LayerRadii[3] * LayerRadii[3]) { + if (doSVRadiusCut && decRad2 < LayerRadii[3] * LayerRadii[3]) { continue; } @@ -348,11 +349,11 @@ struct kinkBuilder { } } - if (lastLayerMoth >= firstLayerDaug) { + if (doSVRadiusCut && lastLayerMoth >= firstLayerDaug) { continue; } - if (decRad2 < LayerRadii[lastLayerMoth] * LayerRadii[lastLayerMoth]) { + if (doSVRadiusCut && decRad2 < LayerRadii[lastLayerMoth] * LayerRadii[lastLayerMoth]) { continue; } From 8193f220828c77547dd047209a3b164a387f718c Mon Sep 17 00:00:00 2001 From: creetz16 <79141119+creetz16@users.noreply.github.com> Date: Thu, 12 Jun 2025 09:15:44 +0200 Subject: [PATCH 37/62] [PWGLF] Update hypertriton 3body decay analysis (#11512) Co-authored-by: ALICE Action Bot --- PWGLF/DataModel/Reduced3BodyTables.h | 28 +- PWGLF/DataModel/Vtx3BodyTables.h | 783 ++-- PWGLF/TableProducer/Nuspex/CMakeLists.txt | 17 +- .../Nuspex/decay3bodybuilder.cxx | 3334 ++++++----------- .../Nuspex/hypertriton3bodyfinder.cxx | 1197 ------ .../Nuspex/reduced3bodyCreator.cxx | 61 +- .../TableProducer/Nuspex/threebodyKFTask.cxx | 488 --- .../Nuspex/threebodyRecoTask.cxx | 909 ----- PWGLF/Tasks/Nuspex/CMakeLists.txt | 10 - PWGLF/Tasks/Nuspex/hypertriton3bodyMcqa.cxx | 908 ----- .../Tasks/Nuspex/hypertriton3bodyanalysis.cxx | 797 ---- PWGLF/Utils/decay3bodyBuilderHelper.h | 838 +++++ 12 files changed, 2219 insertions(+), 7151 deletions(-) delete mode 100644 PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx delete mode 100644 PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx delete mode 100644 PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx delete mode 100644 PWGLF/Tasks/Nuspex/hypertriton3bodyMcqa.cxx delete mode 100644 PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx create mode 100644 PWGLF/Utils/decay3bodyBuilderHelper.h diff --git a/PWGLF/DataModel/Reduced3BodyTables.h b/PWGLF/DataModel/Reduced3BodyTables.h index 51fff63c81d..aeabfb92c0b 100644 --- a/PWGLF/DataModel/Reduced3BodyTables.h +++ b/PWGLF/DataModel/Reduced3BodyTables.h @@ -83,6 +83,7 @@ DECLARE_SOA_TABLE_FULL(StoredRedIUTracks, "RedIUTracks", "AOD", "REDIUTRACK", // // tracks extra track::PIDForTracking, track::IsPVContributor, + track::HasITS, track::HasTPC, track::HasTOF, track::TPCNClsFound, @@ -120,29 +121,22 @@ DECLARE_SOA_INDEX_COLUMN_FULL(Track0, track0, int, RedIUTracks, "_0"); //! DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, RedIUTracks, "_1"); //! Track 1 index DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, RedIUTracks, "_2"); //! Track 2 index DECLARE_SOA_INDEX_COLUMN_FULL(Collision, collision, int, RedCollisions, ""); //! Collision index -DECLARE_SOA_COLUMN(Phi, phi, float); //! decay3body radius -DECLARE_SOA_COLUMN(Radius, radius, float); //! decay3body phi -DECLARE_SOA_COLUMN(PosZ, posz, float); //! decay3body z position +DECLARE_SOA_COLUMN(RadiusKF, radiusKF, float); //! phi of momentum of mother particle calculated by KF +DECLARE_SOA_COLUMN(PhiKF, phiKF, float); //! SV radius in x-y plane calculated by KF +DECLARE_SOA_COLUMN(PosZKF, poszKF, float); //! z position of SV calculated by KF +DECLARE_SOA_COLUMN(RadiusDCA, radiusDCA, float); //! phi of momentum of mother particle calculated by dcaFitter +DECLARE_SOA_COLUMN(PhiDCA, phiDCA, float); //! SV radius in x-y plane calculated by dcaFitter +DECLARE_SOA_COLUMN(PosZDCA, poszDCA, float); //! z position of SV calculated by dcaFitter +DECLARE_SOA_COLUMN(TrackedClSize, trackedClSize, float); //! average ITS cluster size (if tracked) } // namespace reduceddecay3body DECLARE_SOA_TABLE(RedDecay3Bodys, "AOD", "REDDECAY3BODY", //! reduced 3-body decay table o2::soa::Index<>, reduceddecay3body::CollisionId, reduceddecay3body::Track0Id, reduceddecay3body::Track1Id, reduceddecay3body::Track2Id); -using ReducedDecay3BodysLinked = soa::Join; -using ReducedDecay3BodyLinked = ReducedDecay3BodysLinked::iterator; - DECLARE_SOA_TABLE(Red3BodyInfo, "AOD", "RED3BODYINFO", //! joinable with RedDecay3Bodys - reduceddecay3body::Radius, reduceddecay3body::Phi, reduceddecay3body::PosZ); - -namespace dcafittersvinfo -{ -DECLARE_SOA_COLUMN(SVRadius, svRadius, float); //! SV radius in x-y plane calculated by dcaFitter -DECLARE_SOA_COLUMN(MomPhi, momPhi, float); //! phi of momentum of mother particle calculated from dcaFitter -DECLARE_SOA_COLUMN(SVPosZ, svPosZ, float); //! z position of SV calculated by dcaFitter -} // namespace dcafittersvinfo - -DECLARE_SOA_TABLE_FULL(DCAFitterSVInfo, "FitSVInfo", "AOD", "FITSVINFO", //! joinable with RedDecay3Bodys - dcafittersvinfo::SVRadius, dcafittersvinfo::MomPhi, dcafittersvinfo::SVPosZ); + reduceddecay3body::RadiusKF, reduceddecay3body::PhiKF, reduceddecay3body::PosZKF, + reduceddecay3body::RadiusDCA, reduceddecay3body::PhiDCA, reduceddecay3body::PosZDCA, + reduceddecay3body::TrackedClSize); } // namespace o2::aod diff --git a/PWGLF/DataModel/Vtx3BodyTables.h b/PWGLF/DataModel/Vtx3BodyTables.h index 9ae43bb0255..f03dfa8254c 100644 --- a/PWGLF/DataModel/Vtx3BodyTables.h +++ b/PWGLF/DataModel/Vtx3BodyTables.h @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file Vtx3BodyTables.h -/// \brief Definitions of reduced tables for 3body decayed hypertriton +/// \brief Definitions of analysis tables for 3body decayed hypertriton /// \author Yuanzhe Wang /// \author Carolina Reetz @@ -26,48 +26,117 @@ namespace o2::aod { namespace vtx3body { -DECLARE_SOA_INDEX_COLUMN_FULL(Track0, track0, int, Tracks, "_0"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, Tracks, "_1"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, Tracks, "_2"); //! +// indices +DECLARE_SOA_INDEX_COLUMN_FULL(TrackPr, trackPr, int, Tracks, "_pr"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(TrackPi, trackPi, int, Tracks, "_pi"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(TrackDe, trackDe, int, Tracks, "_de"); //! DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! DECLARE_SOA_INDEX_COLUMN(Decay3Body, decay3body); //! -// General 3 body Vtx properties: position, momentum -DECLARE_SOA_COLUMN(PxTrack0, pxtrack0, float); //! track0 px at min -DECLARE_SOA_COLUMN(PyTrack0, pytrack0, float); //! track0 py at min -DECLARE_SOA_COLUMN(PzTrack0, pztrack0, float); //! track0 pz at min -DECLARE_SOA_COLUMN(PxTrack1, pxtrack1, float); //! track1 px at min -DECLARE_SOA_COLUMN(PyTrack1, pytrack1, float); //! track1 py at min -DECLARE_SOA_COLUMN(PzTrack1, pztrack1, float); //! track1 pz at min -DECLARE_SOA_COLUMN(PxTrack2, pxtrack2, float); //! track2 px at min -DECLARE_SOA_COLUMN(PyTrack2, pytrack2, float); //! track2 py at min -DECLARE_SOA_COLUMN(PzTrack2, pztrack2, float); //! track2 pz at min -DECLARE_SOA_COLUMN(X, x, float); //! decay position X -DECLARE_SOA_COLUMN(Y, y, float); //! decay position Y -DECLARE_SOA_COLUMN(Z, z, float); //! decay position Z - -// Saved from finding: DCAs -DECLARE_SOA_COLUMN(DCAVtxDaughters, dcaVtxdaughters, float); //! DCA among daughters -DECLARE_SOA_COLUMN(DCAXYTrack0ToPV, dcaXYtrack0topv, float); //! DCAXY of prong0 to PV -DECLARE_SOA_COLUMN(DCAXYTrack1ToPV, dcaXYtrack1topv, float); //! DCAXY of prong1 to PV -DECLARE_SOA_COLUMN(DCAXYTrack2ToPV, dcaXYtrack2topv, float); //! DCAXY of prong2 to PV -DECLARE_SOA_COLUMN(DCATrack0ToPV, dcatrack0topv, float); //! DCA of prong0 to PV -DECLARE_SOA_COLUMN(DCATrack1ToPV, dcatrack1topv, float); //! DCA of prong1 to PV -DECLARE_SOA_COLUMN(DCATrack2ToPV, dcatrack2topv, float); //! DCA of prong2 to PV - -// Recalculated TOF PID information of bachelor -DECLARE_SOA_COLUMN(TOFNSigmaBachDe, tofNSigmaBachDe, float); //! Recalculated Nsigma seperation with TOF for deuteron +// General 3 body Vtx properties +DECLARE_SOA_COLUMN(Mass, mass, float); //! candidate mass (with H3L or Anti-H3L mass hypothesis depending on deuteron charge) +DECLARE_SOA_COLUMN(Sign, sign, float); //! candidate sign +DECLARE_SOA_COLUMN(X, x, float); //! decay position X +DECLARE_SOA_COLUMN(Y, y, float); //! decay position Y +DECLARE_SOA_COLUMN(Z, z, float); //! decay position Z +DECLARE_SOA_COLUMN(Px, px, float); //! momentum X +DECLARE_SOA_COLUMN(Py, py, float); //! momentum Y +DECLARE_SOA_COLUMN(Pz, pz, float); //! momentum Z +DECLARE_SOA_COLUMN(Chi2, chi2, float); //! KFParticle: chi2geo/ndf or chi2topo/ndf of vertex fit, DCA fitter: Chi2AtPCACandidate value + +// daughter properties +DECLARE_SOA_COLUMN(MassV0, massV0, float); //! V0 mass (with H3L or Anti-H3L mass hypothesis depending on deuteron charge) +DECLARE_SOA_COLUMN(PxTrackPr, pxTrackPr, float); //! track0 px at min +DECLARE_SOA_COLUMN(PyTrackPr, pyTrackPr, float); //! track0 py at min +DECLARE_SOA_COLUMN(PzTrackPr, pzTrackPr, float); //! track0 pz at min +DECLARE_SOA_COLUMN(PxTrackPi, pxTrackPi, float); //! track1 px at min +DECLARE_SOA_COLUMN(PyTrackPi, pyTrackPi, float); //! track1 py at min +DECLARE_SOA_COLUMN(PzTrackPi, pzTrackPi, float); //! track1 pz at min +DECLARE_SOA_COLUMN(PxTrackDe, pxTrackDe, float); //! track2 px at min +DECLARE_SOA_COLUMN(PyTrackDe, pyTrackDe, float); //! track2 py at min +DECLARE_SOA_COLUMN(PzTrackDe, pzTrackDe, float); //! track2 pz at min + +// DCAs to PV +DECLARE_SOA_COLUMN(DCAXYTrackPrToPV, dcaXYtrackPrToPv, float); //! DCAXY of proton to PV +DECLARE_SOA_COLUMN(DCAXYTrackPiToPV, dcaXYtrackPiToPv, float); //! DCAXY of pion to PV +DECLARE_SOA_COLUMN(DCAXYTrackDeToPV, dcaXYtrackDeToPv, float); //! DCAXY of deuteron to PV +DECLARE_SOA_COLUMN(DCAZTrackPrToPV, dcaZtrackPrToPv, float); //! DCAZ of proton to PV +DECLARE_SOA_COLUMN(DCAZTrackPiToPV, dcaZtrackPiToPv, float); //! DCAZ of pion to PV +DECLARE_SOA_COLUMN(DCAZTrackDeToPV, dcaZtrackDeToPv, float); //! DCAZ of deuteron to PV + +// DCAs to SV +DECLARE_SOA_COLUMN(DCATrackPrToSV, dcaTrackPrToSv, float); //! DCA of proton to SV +DECLARE_SOA_COLUMN(DCATrackPiToSV, dcaTrackPiToSv, float); //! DCA of pion to SV +DECLARE_SOA_COLUMN(DCATrackDeToSV, dcaTrackDeToSv, float); //! DCA of deuteron to SV +DECLARE_SOA_COLUMN(DCAVtxDaughters, dcaVtxdaughters, float); //! Quadratic sum of DCA between daughters at SV + +// Strangeness tracking +DECLARE_SOA_COLUMN(TrackedClSize, trackedClSize, float); //! Average ITS cluster size of strangeness tracked 3body + +// PID +DECLARE_SOA_COLUMN(TPCNSigmaPr, tpcNSigmaPr, float); //! nsigma proton of TPC PID of the proton daughter +DECLARE_SOA_COLUMN(TPCNSigmaPi, tpcNSigmaPi, float); //! nsigma pion of TPC PID of the pion daughter +DECLARE_SOA_COLUMN(TPCNSigmaDe, tpcNSigmaDe, float); //! nsigma deuteron of TPC PID of the bachelor daughter +DECLARE_SOA_COLUMN(TPCNSigmaPiBach, tpcNSigmaPiBach, float); //! nsigma pion of TPC PID of the bachelor daughter +DECLARE_SOA_COLUMN(TOFNSigmaDe, tofNSigmaDe, float); //! nsigma deuteron of TOF PID of the bachelor daughter +DECLARE_SOA_COLUMN(PIDTrackingDe, pidTrackingDe, uint32_t); //! PID during tracking of bachelor daughter + +// Daughter track quality +DECLARE_SOA_COLUMN(TPCNClTrackPr, tpcNClTrackPr, int); //! Number of TPC clusters of proton daughter +DECLARE_SOA_COLUMN(TPCNClTrackPi, tpcNClTrackPi, int); //! Number of TPC clusters of pion daughter +DECLARE_SOA_COLUMN(TPCNClTrackDe, tpcNClTrackDe, int); //! Number of TPC clusters of deuteron daughter +DECLARE_SOA_COLUMN(ITSClSizePr, itsClsizePr, double); //! average ITS cluster size of proton daughter +DECLARE_SOA_COLUMN(ITSClSizePi, itsClsizePi, double); //! average ITS cluster size of pion daughter +DECLARE_SOA_COLUMN(ITSClSizeDe, itsClsizeDe, double); //! average ITS cluster size of deuteron daughter + +// Covariance matrices +DECLARE_SOA_COLUMN(CovProton, covProton, float[21]); //! covariance matrix elements of proton daughter track +DECLARE_SOA_COLUMN(CovPion, covPion, float[21]); //! covariance matrix elements of pion daughter track +DECLARE_SOA_COLUMN(CovDeuteron, covDeuteron, float[21]); //! covariance matrix elements of deuteron daughter track +DECLARE_SOA_COLUMN(VtxCovMat, vtxCovMat, float[21]); //! covariance matrix elements of candidate + +// Monte Carlo info +DECLARE_SOA_COLUMN(GenPx, genPx, float); // generated Px of the hypertriton in GeV/c +DECLARE_SOA_COLUMN(GenPy, genPy, float); // generated Py of the hypertriton in GeV/c +DECLARE_SOA_COLUMN(GenPz, genPz, float); // generated Pz of the hypertriton in GeV/c +DECLARE_SOA_COLUMN(GenX, genX, float); // generated decay vtx position X of the hypertriton +DECLARE_SOA_COLUMN(GenY, genY, float); // generated decay vtx position Y of the hypertriton +DECLARE_SOA_COLUMN(GenZ, genZ, float); // generated decay vtx position Z of the hypertriton +DECLARE_SOA_COLUMN(GenCt, genCt, float); // generated Ct of the hypertriton +DECLARE_SOA_COLUMN(GenPhi, genPhi, float); // generated Phi of the hypertriton +DECLARE_SOA_COLUMN(GenEta, genEta, float); // Eta of the hypertriton +DECLARE_SOA_COLUMN(GenRap, genRap, float); // generated rapidity of the hypertriton +DECLARE_SOA_COLUMN(GenPPr, genPPr, float); //! generated momentum proton daughter particle +DECLARE_SOA_COLUMN(GenPPi, genPPi, float); //! generated momentum pion daughter particle +DECLARE_SOA_COLUMN(GenPDe, genPDe, float); //! generated momentum deuteron daughter particle +DECLARE_SOA_COLUMN(GenPtPr, genPtPr, float); //! generated transverse momentum proton daughter particle +DECLARE_SOA_COLUMN(GenPtPi, genPtPi, float); //! generated transverse momentum pion daughter particle +DECLARE_SOA_COLUMN(GenPtDe, genPtDe, float); //! generated transverse momentum deuteron daughter particle +DECLARE_SOA_COLUMN(IsTrueH3L, isTrueH3l, bool); //! flag for true hypertriton candidate +DECLARE_SOA_COLUMN(IsTrueAntiH3L, isTrueAntiH3l, bool); //! flag for true anti-hypertriton candidate +DECLARE_SOA_COLUMN(PrPdgCode, prPdgCode, int); //! MC particle proton PDG code +DECLARE_SOA_COLUMN(PiPdgCode, piPdgCode, int); //! MC particle pion PDG code +DECLARE_SOA_COLUMN(DePdgCode, dePdgCode, int); //! MC particle deuteron PDG code +DECLARE_SOA_COLUMN(IsDePrimary, isDePrimary, bool); //! flag for deuteron daughter primary +DECLARE_SOA_COLUMN(IsSurvEvSel, isSurvEvSel, int); //! flag if reco collision survived event selection +DECLARE_SOA_COLUMN(IsReco, isreco, int); //! flag if candidate was reconstructed // Derived expressions // Momenta -DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! 3 body p - [](float pxtrack0, float pytrack0, float pztrack0, float pxtrack1, float pytrack1, float pztrack1, float pxtrack2, float pytrack2, float pztrack2) -> float { return RecoDecay::sqrtSumOfSquares(pxtrack0 + pxtrack1 + pxtrack2, pytrack0 + pytrack1 + pytrack2, pztrack0 + pztrack1 + pztrack2); }); -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! 3 body pT - [](float pxtrack0, float pytrack0, float pxtrack1, float pytrack1, float pxtrack2, float pytrack2) -> float { return RecoDecay::sqrtSumOfSquares(pxtrack0 + pxtrack1 + pxtrack2, pytrack0 + pytrack1 + pytrack2); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! 3 body pT in GeV/c + [](float px, float py) -> float { return RecoDecay::sqrtSumOfSquares(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! 3 body total momentum in GeV/c + [](float px, float py, float pz) -> float { return RecoDecay::sqrtSumOfSquares(px, py, pz); }); +DECLARE_SOA_DYNAMIC_COLUMN(GenPt, genPt, //! 3 body pT in GeV/c + [](float genPx, float genPy) -> float { return RecoDecay::sqrtSumOfSquares(genPx, genPy); }); +DECLARE_SOA_DYNAMIC_COLUMN(GenP, genP, //! 3 body total momentum in GeV/c + [](float genPx, float genPy, float genPz) -> float { return RecoDecay::sqrtSumOfSquares(genPx, genPy, genPz); }); // Length quantities DECLARE_SOA_DYNAMIC_COLUMN(VtxRadius, vtxradius, //! 3 body decay radius (2D, centered at zero) [](float x, float y) -> float { return RecoDecay::sqrtSumOfSquares(x, y); }); +DECLARE_SOA_DYNAMIC_COLUMN(GenRadius, genRadius, //! 3 body decay radius (2D, centered at zero) + [](float genX, float genY) -> float { return RecoDecay::sqrtSumOfSquares(genX, genY); }); // Distance Over To Mom DECLARE_SOA_DYNAMIC_COLUMN(DistOverTotMom, distovertotmom, //! PV to 3 body decay distance over total momentum @@ -79,6 +148,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(DistOverTotMom, distovertotmom, //! PV to 3 body deca // CosPA DECLARE_SOA_DYNAMIC_COLUMN(VtxCosPA, vtxcosPA, //! 3 body vtx CosPA [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(std::array{pvX, pvY, pvZ}, std::array{X, Y, Z}, std::array{Px, Py, Pz}); }); + // Dca to PV DECLARE_SOA_DYNAMIC_COLUMN(DCAVtxToPV, dcavtxtopv, //! DCA of 3 body vtx to PV [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { return std::sqrt((std::pow((pvY - Y) * Pz - (pvZ - Z) * Py, 2) + std::pow((pvX - X) * Pz - (pvZ - Z) * Px, 2) + std::pow((pvX - X) * Py - (pvY - Y) * Px, 2)) / (Px * Px + Py * Py + Pz * Pz)); }); @@ -89,532 +159,151 @@ DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! 3 body vtx eta DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! 3 body vtx phi [](float Px, float Py) -> float { return RecoDecay::phi(Px, Py); }); -// Calculated on the fly with mother particle hypothesis -DECLARE_SOA_DYNAMIC_COLUMN(MHypertriton, mHypertriton, //! mass under Hypertriton hypothesis - [](float pxtrack0, float pytrack0, float pztrack0, float pxtrack1, float pytrack1, float pztrack1, float pxtrack2, float pytrack2, float pztrack2) -> float { return RecoDecay::m(std::array{std::array{pxtrack0, pytrack0, pztrack0}, std::array{pxtrack1, pytrack1, pztrack1}, std::array{pxtrack2, pytrack2, pztrack2}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); }); -DECLARE_SOA_DYNAMIC_COLUMN(MAntiHypertriton, mAntiHypertriton, //! mass under antiHypertriton hypothesis - [](float pxtrack0, float pytrack0, float pztrack0, float pxtrack1, float pytrack1, float pztrack1, float pxtrack2, float pytrack2, float pztrack2) -> float { return RecoDecay::m(std::array{std::array{pxtrack0, pytrack0, pztrack0}, std::array{pxtrack1, pytrack1, pztrack1}, std::array{pxtrack2, pytrack2, pztrack2}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}); }); - -DECLARE_SOA_DYNAMIC_COLUMN(MHyperHelium4, mHyperHelium4, //! mass under HyperHelium4 hypothesis - [](float pxtrack0, float pytrack0, float pztrack0, float pxtrack1, float pytrack1, float pztrack1, float pxtrack2, float pytrack2, float pztrack2) -> float { return RecoDecay::m(std::array{std::array{pxtrack0, pytrack0, pztrack0}, std::array{pxtrack1, pytrack1, pztrack1}, std::array{pxtrack2, pytrack2, pztrack2}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassHelium3}); }); -DECLARE_SOA_DYNAMIC_COLUMN(MAntiHyperHelium4, mAntiHyperHelium4, //! mass under antiHyperHelium4 hypothesis - [](float pxtrack0, float pytrack0, float pztrack0, float pxtrack1, float pytrack1, float pztrack1, float pxtrack2, float pytrack2, float pztrack2) -> float { return RecoDecay::m(std::array{std::array{pxtrack0, pytrack0, pztrack0}, std::array{pxtrack1, pytrack1, pztrack1}, std::array{pxtrack2, pytrack2, pztrack2}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassHelium3}); }); - -DECLARE_SOA_DYNAMIC_COLUMN(YHypertriton, yHypertriton, //! 3 body vtx y with hypertriton or antihypertriton hypothesis +// Rapidity +DECLARE_SOA_DYNAMIC_COLUMN(Rap, rap, //! 3 body vtx y with hypertriton or antihypertriton hypothesis [](float Px, float Py, float Pz) -> float { return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassHyperTriton); }); -DECLARE_SOA_DYNAMIC_COLUMN(YHyperHelium4, yHyperHelium4, //! 3 body vtx y with hyperhelium4 or antihyperhelium4 hypothesis - [](float Px, float Py, float Pz) -> float { return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassHyperHelium4); }); - -// kinematic information of daughter tracks -DECLARE_SOA_DYNAMIC_COLUMN(Track0Pt, track0pt, //! daughter0 pT - [](float pxtrack0, float pytrack0) -> float { return RecoDecay::sqrtSumOfSquares(pxtrack0, pytrack0); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Pt, track1pt, //! daughter1 pT - [](float pxtrack1, float pytrack1) -> float { return RecoDecay::sqrtSumOfSquares(pxtrack1, pytrack1); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Pt, track2pt, //! daughter2 pT - [](float pxtrack2, float pytrack2) -> float { return RecoDecay::sqrtSumOfSquares(pxtrack2, pytrack2); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track0Eta, track0eta, //! daughter0 eta - [](float pxtrack0, float pytrack0, float pztrack0) -> float { return RecoDecay::eta(std::array{pxtrack0, pytrack0, pztrack0}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track0Phi, track0phi, //! daughter0 phi - [](float pxtrack0, float pytrack0) -> float { return RecoDecay::phi(pxtrack0, pytrack0); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Eta, track1eta, //! daughter1 eta - [](float pxtrack1, float pytrack1, float pztrack1) -> float { return RecoDecay::eta(std::array{pxtrack1, pytrack1, pztrack1}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Phi, track1phi, //! daughter1 phi - [](float pxtrack1, float pytrack1) -> float { return RecoDecay::phi(pxtrack1, pytrack1); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Eta, track2eta, //! daughter2 eta - [](float pxtrack2, float pytrack2, float pztrack2) -> float { return RecoDecay::eta(std::array{pxtrack2, pytrack2, pztrack2}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Phi, track2phi, //! daughter2 phi - [](float pxtrack2, float pytrack2) -> float { return RecoDecay::phi(pxtrack2, pytrack2); }); - -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! 3 body vtx px - float, 1.f * aod::vtx3body::pxtrack0 + 1.f * aod::vtx3body::pxtrack1 + 1.f * aod::vtx3body::pxtrack2); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! 3 body vtx py - float, 1.f * aod::vtx3body::pytrack0 + 1.f * aod::vtx3body::pytrack1 + 1.f * aod::vtx3body::pytrack2); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! 3 body vtx pz - float, 1.f * aod::vtx3body::pztrack0 + 1.f * aod::vtx3body::pztrack1 + 1.f * aod::vtx3body::pztrack2); -} // namespace vtx3body - -DECLARE_SOA_TABLE_FULL(StoredVtx3BodyDatas, "Vtx3BodyDatas", "AOD", "Vtx3BodyDATA", //! - o2::soa::Index<>, vtx3body::Track0Id, vtx3body::Track1Id, vtx3body::Track2Id, vtx3body::CollisionId, vtx3body::Decay3BodyId, - vtx3body::X, vtx3body::Y, vtx3body::Z, - vtx3body::PxTrack0, vtx3body::PyTrack0, vtx3body::PzTrack0, - vtx3body::PxTrack1, vtx3body::PyTrack1, vtx3body::PzTrack1, - vtx3body::PxTrack2, vtx3body::PyTrack2, vtx3body::PzTrack2, - vtx3body::DCAVtxDaughters, - vtx3body::DCAXYTrack0ToPV, vtx3body::DCAXYTrack1ToPV, vtx3body::DCAXYTrack2ToPV, - vtx3body::DCATrack0ToPV, vtx3body::DCATrack1ToPV, vtx3body::DCATrack2ToPV, - vtx3body::TOFNSigmaBachDe, - - // Dynamic columns - vtx3body::P, - vtx3body::Pt, - vtx3body::VtxRadius, - vtx3body::DistOverTotMom, - vtx3body::VtxCosPA, - vtx3body::DCAVtxToPV, - - // Invariant masses - vtx3body::MHypertriton, - vtx3body::MAntiHypertriton, - vtx3body::MHyperHelium4, - vtx3body::MAntiHyperHelium4, - - // Longitudinal - vtx3body::YHypertriton, - vtx3body::YHyperHelium4, - vtx3body::Eta, - vtx3body::Phi, - vtx3body::Track0Pt, - vtx3body::Track0Eta, - vtx3body::Track0Phi, - vtx3body::Track1Pt, - vtx3body::Track1Eta, - vtx3body::Track1Phi, - vtx3body::Track2Pt, - vtx3body::Track2Eta, - vtx3body::Track2Phi); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(Vtx3BodyDatas, StoredVtx3BodyDatas, "Vtx3BodyDATAEXT", //! - vtx3body::Px, vtx3body::Py, vtx3body::Pz); - -using Vtx3BodyData = Vtx3BodyDatas::iterator; -namespace vtx3body -{ -DECLARE_SOA_INDEX_COLUMN(Vtx3BodyData, vtx3BodyData); //! Index to Vtx3BodyData entry -} - -DECLARE_SOA_TABLE(Decay3BodyDataLink, "AOD", "DECAY3BODYLINK", //! Joinable table with Decay3bodys which links to Vtx3BodyData which is not produced for all entries - vtx3body::Vtx3BodyDataId); - -using Decay3BodysLinked = soa::Join; -using Decay3BodyLinked = Decay3BodysLinked::iterator; - -// Definition of labels for Vtx3BodyDatas -namespace mcvtx3bodylabel -{ -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for Vtx3BodyDatas -} // namespace mcvtx3bodylabel - -DECLARE_SOA_TABLE(McVtx3BodyLabels, "AOD", "MCVTXLABEL", //! Table joinable with Vtx3BodyData containing the MC labels - mcvtx3bodylabel::McParticleId); -using McVtx3BodyLabel = McVtx3BodyLabels::iterator; -// Definition of labels for Decay3Bodys // Full table, joinable with Decay3Bodys (CAUTION: NOT WITH Vtx3BodyDATA) -namespace mcfullvtx3bodylabel -{ -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for Decay3Bodys -} // namespace mcfullvtx3bodylabel - -DECLARE_SOA_TABLE(McFullVtx3BodyLabels, "AOD", "MCFULLVTXLABEL", //! Table joinable with Decay3Bodys - mcfullvtx3bodylabel::McParticleId); -using McFullVtx3BodyLabel = McFullVtx3BodyLabels::iterator; +// Kinematic information of daughter tracks +DECLARE_SOA_DYNAMIC_COLUMN(TrackPrPt, trackPrPt, //! daughter0 pT + [](float pxTrackPr, float pyTrackPr) -> float { return RecoDecay::sqrtSumOfSquares(pxTrackPr, pyTrackPr); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackPiPt, trackPiPt, //! daughter1 pT + [](float pxTrackPi, float pyTrackPi) -> float { return RecoDecay::sqrtSumOfSquares(pxTrackPi, pyTrackPi); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackDePt, trackDePt, //! daughter2 pT + [](float pxTrackDe, float pyTrackDe) -> float { return RecoDecay::sqrtSumOfSquares(pxTrackDe, pyTrackDe); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackPrEta, trackPrEta, //! daughter0 eta + [](float pxTrackPr, float pyTrackPr, float pzTrackPr) -> float { return RecoDecay::eta(std::array{pxTrackPr, pyTrackPr, pzTrackPr}); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackPrPhi, trackPrPhi, //! daughter0 phi + [](float pxTrackPr, float pyTrackPr) -> float { return RecoDecay::phi(pxTrackPr, pyTrackPr); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackPiEta, trackPiEta, //! daughter1 eta + [](float pxTrackPi, float pyTrackPi, float pzTrackPi) -> float { return RecoDecay::eta(std::array{pxTrackPi, pyTrackPi, pzTrackPi}); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackPiPhi, trackPiPhi, //! daughter1 phi + [](float pxTrackPi, float pyTrackPi) -> float { return RecoDecay::phi(pxTrackPi, pyTrackPi); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackDeEta, trackDeEta, //! daughter2 eta + [](float pxTrackDe, float pyTrackDe, float pzTrackDe) -> float { return RecoDecay::eta(std::array{pxTrackDe, pyTrackDe, pzTrackDe}); }); +DECLARE_SOA_DYNAMIC_COLUMN(TrackDePhi, trackDePhi, //! daughter2 phi + [](float pxTrackDe, float pyTrackDe) -> float { return RecoDecay::phi(pxTrackDe, pyTrackDe); }); +} // namespace vtx3body -// output table for ML studies -namespace hyp3body -{ -// collision -DECLARE_SOA_COLUMN(Centrality, centrality, float); //! centrality -// reconstruced candidate -DECLARE_SOA_COLUMN(IsMatter, isMatter, bool); //! bool: true for matter -DECLARE_SOA_COLUMN(M, m, float); //! invariant mass -DECLARE_SOA_COLUMN(P, p, float); //! p -DECLARE_SOA_COLUMN(Pt, pt, float); //! pT -DECLARE_SOA_COLUMN(Ct, ct, float); //! ct -DECLARE_SOA_COLUMN(CosPA, cospa, float); -DECLARE_SOA_COLUMN(DCADaughters, dcaDaughters, float); //! DCA among daughters -DECLARE_SOA_COLUMN(DCACandToPV, dcaCandtopv, float); //! DCA of the reconstructed track to pv -DECLARE_SOA_COLUMN(VtxRadius, vtxRadius, float); //! Radius of SV -// kinematic infomation of daughter tracks -DECLARE_SOA_COLUMN(PtProton, ptProton, float); //! pT of the proton daughter -DECLARE_SOA_COLUMN(EtaProton, etaProton, float); //! eta of the proton daughter -DECLARE_SOA_COLUMN(PhiProton, phiProton, float); //! phi of the proton daughter -DECLARE_SOA_COLUMN(RadiusProton, radiusProton, float); //! radius of innermost hit of the proton daughter -DECLARE_SOA_COLUMN(PtPion, ptPion, float); //! pT of the pion daughter -DECLARE_SOA_COLUMN(EtaPion, etaPion, float); //! eta of the pion daughter -DECLARE_SOA_COLUMN(PhiPion, phiPion, float); //! phi of the pion daughter -DECLARE_SOA_COLUMN(RadiusPion, radiusPion, float); //! radius of innermost hit of the pion daughter -DECLARE_SOA_COLUMN(PtBachelor, ptBachelor, float); //! pT of the bachelor daughter -DECLARE_SOA_COLUMN(EtaBachelor, etaBachelor, float); //! eta of the bachelor daughter -DECLARE_SOA_COLUMN(PhiBachelor, phiBachelor, float); //! phi of the bachelor daughter -DECLARE_SOA_COLUMN(RadiusBachelor, radiusBachelor, float); //! radius of innermost hit of the bachelor daughter -// track quality -DECLARE_SOA_COLUMN(TPCNclusProton, tpcNclusProton, uint8_t); //! number of TPC clusters of the proton daughter -DECLARE_SOA_COLUMN(TPCNclusPion, tpcNclusPion, uint8_t); //! number of TPC clusters of the pion daughter -DECLARE_SOA_COLUMN(TPCNclusBachelor, tpcNclusBachelor, uint8_t); //! number of TPC clusters of the bachelor daughter -DECLARE_SOA_COLUMN(ITSNclusSizeProton, itsNclusSizeProton, uint8_t); //! average ITS cluster size of the proton daughter -DECLARE_SOA_COLUMN(ITSNclusSizePion, itsNclusSizePion, uint8_t); //! average ITS cluster size of the pion daughter -DECLARE_SOA_COLUMN(ITSNclusSizeBachelor, itsNclusSizeBachelor, uint8_t); //! average ITS cluster size of the bachelor daughter -// PID -DECLARE_SOA_COLUMN(TPCNSigmaProton, tpcNSigmaProton, float); //! nsigma of TPC PID of the proton daughter -DECLARE_SOA_COLUMN(TPCNSigmaPion, tpcNSigmaPion, float); //! nsigma of TPC PID of the pion daughter -DECLARE_SOA_COLUMN(TPCNSigmaBachelor, tpcNSigmaBachelor, float); //! nsigma of TPC PID of the bachelor daughter -DECLARE_SOA_COLUMN(TOFNSigmaBachelor, tofNSigmaBachelor, float); //! nsigma of TOF PID of the bachelor daughter -// DCA to PV -DECLARE_SOA_COLUMN(DCAXYProtonToPV, dcaxyProtontoPV, float); //! DCAXY of the proton daughter to pv -DECLARE_SOA_COLUMN(DCAXYPionToPV, dcaxyPiontoPV, float); //! DCAXY of the pion daughter to pv -DECLARE_SOA_COLUMN(DCAXYBachelorToPV, dcaxyBachelortoPV, float); //! DCAXY of the bachelor daughter to pv -DECLARE_SOA_COLUMN(DCAProtonToPV, dcaProtontoPV, float); //! DCA of the proton daughter to pv -DECLARE_SOA_COLUMN(DCAPionToPV, dcaPiontoPV, float); //! DCA of the pion daughter to pv -DECLARE_SOA_COLUMN(DCABachelorToPV, dcaBachelortoPV, float); //! DCA of the bachelor daughter to pv -DECLARE_SOA_COLUMN(IsBachPrimary, isbachprimary, bool); //! flag for bachelor daughter primary -// for MC -DECLARE_SOA_COLUMN(GenP, genP, float); // P of the hypertriton -DECLARE_SOA_COLUMN(GenPt, genPt, float); // pT of the hypertriton -DECLARE_SOA_COLUMN(GenCt, genCt, float); // ct of the hypertriton -DECLARE_SOA_COLUMN(GenPhi, genPhi, float); // Phi of the hypertriton -DECLARE_SOA_COLUMN(GenEta, genEta, float); // Eta of the hypertriton -DECLARE_SOA_COLUMN(GenRapidity, genRapidity, float); // Rapidity of the hypertriton -DECLARE_SOA_COLUMN(IsReco, isReco, bool); // bool: true for reco -DECLARE_SOA_COLUMN(IsSignal, isSignal, bool); // bool: true for signal -DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); // pdgCode of the mcparticle, -1 for fake pair -DECLARE_SOA_COLUMN(SurvivedEventSelection, survivedEventSelection, bool); // bool: true for survived event selection -} // namespace hyp3body - -// output table for data -DECLARE_SOA_TABLE(Hyp3BodyCands, "AOD", "HYP3BODYCANDS", - o2::soa::Index<>, - hyp3body::Centrality, - // secondary vertex and reconstruced candidate - hyp3body::IsMatter, - hyp3body::M, - hyp3body::P, - hyp3body::Pt, - hyp3body::Ct, - hyp3body::CosPA, - hyp3body::DCADaughters, - hyp3body::DCACandToPV, - hyp3body::VtxRadius, - // daughter tracks - hyp3body::PtProton, hyp3body::EtaProton, hyp3body::PhiProton, hyp3body::RadiusProton, - hyp3body::PtPion, hyp3body::EtaPion, hyp3body::PhiPion, hyp3body::RadiusPion, - hyp3body::PtBachelor, hyp3body::EtaBachelor, hyp3body::PhiBachelor, hyp3body::RadiusBachelor, - hyp3body::TPCNclusProton, hyp3body::TPCNclusPion, hyp3body::TPCNclusBachelor, - hyp3body::ITSNclusSizeProton, hyp3body::ITSNclusSizePion, hyp3body::ITSNclusSizeBachelor, - hyp3body::TPCNSigmaProton, hyp3body::TPCNSigmaPion, hyp3body::TPCNSigmaBachelor, - hyp3body::TOFNSigmaBachelor, - hyp3body::DCAXYProtonToPV, hyp3body::DCAXYPionToPV, hyp3body::DCAXYBachelorToPV, - hyp3body::DCAProtonToPV, hyp3body::DCAPionToPV, hyp3body::DCABachelorToPV); - -// output table for MC -DECLARE_SOA_TABLE(MCHyp3BodyCands, "AOD", "MCHYP3BODYCANDS", +// index table +DECLARE_SOA_TABLE(Decay3BodyIndices, "AOD", "3BodyINDEX", //! o2::soa::Index<>, - hyp3body::Centrality, - // secondary vertex and reconstruced candidate - hyp3body::IsMatter, - hyp3body::M, - hyp3body::P, - hyp3body::Pt, - hyp3body::Ct, - hyp3body::CosPA, - hyp3body::DCADaughters, - hyp3body::DCACandToPV, - hyp3body::VtxRadius, - // daughter tracks - hyp3body::PtProton, hyp3body::EtaProton, hyp3body::PhiProton, hyp3body::RadiusProton, - hyp3body::PtPion, hyp3body::EtaPion, hyp3body::PhiPion, hyp3body::RadiusPion, - hyp3body::PtBachelor, hyp3body::EtaBachelor, hyp3body::PhiBachelor, hyp3body::RadiusBachelor, - hyp3body::TPCNclusProton, hyp3body::TPCNclusPion, hyp3body::TPCNclusBachelor, - hyp3body::ITSNclusSizeProton, hyp3body::ITSNclusSizePion, hyp3body::ITSNclusSizeBachelor, - hyp3body::TPCNSigmaProton, hyp3body::TPCNSigmaPion, hyp3body::TPCNSigmaBachelor, - hyp3body::TOFNSigmaBachelor, - hyp3body::DCAXYProtonToPV, hyp3body::DCAXYPionToPV, hyp3body::DCAXYBachelorToPV, - hyp3body::DCAProtonToPV, hyp3body::DCAPionToPV, hyp3body::DCABachelorToPV, - hyp3body::IsBachPrimary, - // MC information - hyp3body::GenP, - hyp3body::GenPt, - hyp3body::GenCt, - hyp3body::GenPhi, - hyp3body::GenEta, - hyp3body::GenRapidity, - hyp3body::IsSignal, - hyp3body::IsReco, - hyp3body::PdgCode, - hyp3body::SurvivedEventSelection); - -//______________________________________________________ -// DATAMODEL FOR KFPARTICLE DECAY3BODYS - -namespace kfvtx3body -{ -// General 3 body Vtx properties: mass, momentum, charge -DECLARE_SOA_COLUMN(Mass, mass, float); //! candidate mass (PID hypothesis depending on bachelor charge) -DECLARE_SOA_COLUMN(XErr, xerr, float); //! candidate position x error at decay position -DECLARE_SOA_COLUMN(YErr, yerr, float); //! candidate position y error at decay position -DECLARE_SOA_COLUMN(ZErr, zerr, float); //! candidate position z error at decay position -DECLARE_SOA_COLUMN(Px, px, float); //! candidate px at decay position -DECLARE_SOA_COLUMN(Py, py, float); //! candidate py at decay position -DECLARE_SOA_COLUMN(Pz, pz, float); //! candidate pz at decay position -DECLARE_SOA_COLUMN(Pt, pt, float); //! candidate pt at decay position -DECLARE_SOA_COLUMN(PxErr, pxerr, float); //! candidate px error at decay position -DECLARE_SOA_COLUMN(PyErr, pyerr, float); //! candidate py error at decay position -DECLARE_SOA_COLUMN(PzErr, pzerr, float); //! candidate pz error at decay position -DECLARE_SOA_COLUMN(PtErr, pterr, float); //! candidate pt error at decay position -DECLARE_SOA_COLUMN(Sign, sign, float); //! candidate sign - -// topological properties -DECLARE_SOA_COLUMN(VtxCosPAKF, vtxcospakf, float); //! 3 body vtx CosPA from KFParticle (using kfpPV) -DECLARE_SOA_COLUMN(VtxCosXYPAKF, vtxcosxypakf, float); //! 3 body vtx CosPA from KFParticle (using kfpPV) -DECLARE_SOA_COLUMN(VtxCosPAKFtopo, vtxcospakftopo, float); //! 3 body vtx CosPA from KFParticle after topological constraint (using kfpPV) -DECLARE_SOA_COLUMN(VtxCosXYPAKFtopo, vtxcosxypakftopo, float); //! 3 body vtx CosPA from KFParticle after topological constraint (using kfpPV) -DECLARE_SOA_COLUMN(DCAVtxToPVKF, dcavtxtopvkf, float); //! 3 body vtx DCA to PV from KFParticle (using kfpPV) -DECLARE_SOA_COLUMN(DCAXYVtxToPVKF, dcaxyvtxtopvkf, float); //! 3 body vtx DCAxy to PV from KFParticle (using kfpPV) -DECLARE_SOA_COLUMN(DecayLKF, decaylkf, float); //! 3 body vtx decay length from KFParticle (using kfpPV after topological constraint) -DECLARE_SOA_COLUMN(DecayLXYKF, decaylxykf, float); //! 3 body vtx decay length XY from KFParticle (using kfpPV after topological constraint) -DECLARE_SOA_COLUMN(DecayLDeltaL, decayldeltal, float); //! 3 body vtx l/dl from KFParticle (using kfpPV after topological constraint) -DECLARE_SOA_COLUMN(Chi2geoNDF, chi2geondf, float); //! 3 body vtx chi2geo from geometrical KFParticle fit -DECLARE_SOA_COLUMN(Chi2topoNDF, chi2topondf, float); //! 3 body vtx chi2topo from KFParticle topological constraint to the PV (using kfpPV) -DECLARE_SOA_COLUMN(CTauKFtopo, ctaukftopo, float); //! 3 body vtx ctau from KFParticle after topological constraint - -// Strangeness tracking -DECLARE_SOA_COLUMN(TrackedClSize, trackedclsize, int); //! Cluster size of strangeness tracked 3body - -// daughters -DECLARE_SOA_COLUMN(DCATrack0ToPVKF, dcatrack0topvkf, float); //! DCA of proton prong to PV from KFParticle -DECLARE_SOA_COLUMN(DCATrack1ToPVKF, dcatrack1topvkf, float); //! DCA of pion prong to PV from KFParticle -DECLARE_SOA_COLUMN(DCATrack2ToPVKF, dcatrack2topvkf, float); //! DCA of deuteron prong to PV from KFParticle -DECLARE_SOA_COLUMN(DCAxyTrack0ToPVKF, dcaxytrack0topvkf, float); //! DCAxy of proton prong to PV from KFParticle -DECLARE_SOA_COLUMN(DCAxyTrack1ToPVKF, dcaxytrack1topvkf, float); //! DCAxy of pion prong to PV from KFParticle -DECLARE_SOA_COLUMN(DCAxyTrack2ToPVKF, dcaxytrack2topvkf, float); //! DCAxy of deuteron prong to PV from KFParticle -DECLARE_SOA_COLUMN(DCATrackPosToPV, dcatrackpostopv, float); //! DCA of positive track to PV (propagated before vtx fit) -DECLARE_SOA_COLUMN(DCATrackNegToPV, dcatracknegtopv, float); //! DCA of negative track to PV (propagated before vtx fit) -DECLARE_SOA_COLUMN(DCATrackBachToPV, dcatrackbachtopv, float); //! DCA of bachelor track to PV (propagated before vtx fit) -DECLARE_SOA_COLUMN(DCAxyTrackPosToPV, dcaxytrackpostopv, float); //! DCAxy of positive track to PV (propagated before vtx fit) -DECLARE_SOA_COLUMN(DCAxyTrackNegToPV, dcaxytracknegtopv, float); //! DCAxy of negative track to PV (propagated before vtx fit) -DECLARE_SOA_COLUMN(DCAxyTrackBachToPV, dcaxytrackbachtopv, float); //! DCAxy of bachelor track to PV (propagated before vtx fit) -DECLARE_SOA_COLUMN(DCAxyTrack0ToSVKF, dcaxytrack0tosvkf, float); //! DCAxy of proton prong to SV from KFParticle -DECLARE_SOA_COLUMN(DCAxyTrack1ToSVKF, dcaxytrack1tosvkf, float); //! DCAxy of pion prong to SV from KFParticle -DECLARE_SOA_COLUMN(DCAxyTrack2ToSVKF, dcaxytrack2tosvkf, float); //! DCAxy of deuteron prong to SV from KFParticle -DECLARE_SOA_COLUMN(DCATrack0ToTrack1KF, dcatrack0totrack1kf, float); //! DCAxy of proton prong to pion from KFParticle -DECLARE_SOA_COLUMN(DCATrack0ToTrack2KF, dcatrack0totrack2kf, float); //! DCAxy of proton prong to deuteron from KFParticle -DECLARE_SOA_COLUMN(DCATrack1ToTrack2KF, dcatrack1totrack2kf, float); //! DCAxy of pion prong to deuteron from KFParticle -DECLARE_SOA_COLUMN(DCAVtxDaughtersKF, dcavtxdaughterskf, float); //! sum of DCAs between daughters in 3D from KFParticle -DECLARE_SOA_COLUMN(Track0Sign, track0sign, float); //! sign of proton daughter track -DECLARE_SOA_COLUMN(Track1Sign, track1sign, float); //! sign of pion daughter track -DECLARE_SOA_COLUMN(Track2Sign, track2sign, float); //! sign of deuteron daughter track -DECLARE_SOA_COLUMN(TPCInnerParamTrack0, tpcinnerparamtrack0, float); //! momentum at inner wall of TPC of proton daughter -DECLARE_SOA_COLUMN(TPCInnerParamTrack1, tpcinnerparamtrack1, float); //! momentum at inner wall of TPC of pion daughter -DECLARE_SOA_COLUMN(TPCInnerParamTrack2, tpcinnerparamtrack2, float); //! momentum at inner wall of TPC of deuteron daughter -DECLARE_SOA_COLUMN(TPCNClTrack0, tpcncltrack0, int); //! Number of TPC clusters of proton daughter -DECLARE_SOA_COLUMN(TPCNClTrack1, tpcncltrack1, int); //! Number of TPC clusters of pion daughter -DECLARE_SOA_COLUMN(TPCNClTrack2, tpcncltrack2, int); //! Number of TPC clusters of deuteron daughter -DECLARE_SOA_COLUMN(TPCChi2NClDeuteron, tpcchi2ncldeuteron, float); //! TPC Chi2 / cluster of deuteron daughter -DECLARE_SOA_COLUMN(DeltaPhiDeuteron, deltaphideuteron, float); //! phi before track rotation - phi after track rotation for deuteron track -DECLARE_SOA_COLUMN(DeltaPhiProton, deltaphiproton, float); //! phi before track rotation - phi after track rotation for proton track -// PID -DECLARE_SOA_COLUMN(TPCNSigmaProton, tpcnsigmaproton, float); //! nsigma proton of TPC PID of the proton daughter -DECLARE_SOA_COLUMN(TPCNSigmaPion, tpcnsigmapion, float); //! nsigma pion of TPC PID of the pion daughter -DECLARE_SOA_COLUMN(TPCNSigmaDeuteron, tpcnsigmadeuteron, float); //! nsigma deuteron of TPC PID of the bachelor daughter -DECLARE_SOA_COLUMN(TPCNSigmaPionBach, tpcnsigmapionbach, float); //! nsigma pion of TPC PID of the bachelor daughter -DECLARE_SOA_COLUMN(TPCdEdxProton, tpcdedxproton, float); //! TPC dEdx of the proton daughter -DECLARE_SOA_COLUMN(TPCdEdxPion, tpcdedxpion, float); //! TPC dEdx of the pion daughter -DECLARE_SOA_COLUMN(TPCdEdxDeuteron, tpcdedxdeuteron, float); //! TPC dEdx of the bachelor daughter -DECLARE_SOA_COLUMN(TOFNSigmaDeuteron, tofnsigmadeuteron, float); //! nsigma of TOF PID of the bachelor daughter -DECLARE_SOA_COLUMN(ITSClusSizeDeuteron, itsclussizedeuteron, double); //! average ITS cluster size of bachelor daughter -DECLARE_SOA_COLUMN(PIDTrackingDeuteron, pidtrackingdeuteron, uint32_t); //! PID during tracking of bachelor daughter - -// Monte Carlo -DECLARE_SOA_COLUMN(GenP, genp, float); //! generated momentum -DECLARE_SOA_COLUMN(GenPt, genpt, float); //! generated transverse momentum -DECLARE_SOA_COLUMN(GenDecVtxX, gendecvtxx, double); //! generated decay vertex position x -DECLARE_SOA_COLUMN(GenDecVtxY, gendecvtxy, double); //! generated decay vertex position y -DECLARE_SOA_COLUMN(GenDecVtxZ, gendecvtxz, double); //! generated decay vertex position z -DECLARE_SOA_COLUMN(GenCtau, genctau, double); //! generated ctau -DECLARE_SOA_COLUMN(GenPhi, genphi, float); //! generated phi -DECLARE_SOA_COLUMN(GenEta, geneta, float); //! generated eta -DECLARE_SOA_COLUMN(GenRapidity, genrapidity, float); //! generated rapidity -DECLARE_SOA_COLUMN(GenPosP, genposp, float); //! generated momentum pos daughter particle -DECLARE_SOA_COLUMN(GenPosPt, genpospt, float); //! generated transverse momentum pos daughter particle -DECLARE_SOA_COLUMN(GenNegP, gennegp, float); //! generated momentum neg daughter particle -DECLARE_SOA_COLUMN(GenNegPt, gennegpt, float); //! generated transverse momentum neg daughter particle -DECLARE_SOA_COLUMN(GenBachP, genbachp, float); //! generated momentum bachelor daughter particle -DECLARE_SOA_COLUMN(GenBachPt, genbachpt, float); //! generated transverse momentum bachelor daughter particle -DECLARE_SOA_COLUMN(IsTrueH3L, istrueh3l, bool); //! flag for true hypertriton candidate -DECLARE_SOA_COLUMN(IsTrueAntiH3L, istrueantih3l, bool); //! flag for true anti-hypertriton candidate -DECLARE_SOA_COLUMN(PdgCodeDau0, pdgcodedau0, int); //! MC particle daughter 0 PDG code -DECLARE_SOA_COLUMN(PdgCodeDau1, pdgcodedau1, int); //! MC particle daughter 1 PDG code -DECLARE_SOA_COLUMN(PdgCodeDau2, pdgcodedau2, int); //! MC particle daughter 2 PDG code -DECLARE_SOA_COLUMN(IsBachPrimary, isbachprimary, bool); //! flag for bachelor daughter primary -DECLARE_SOA_COLUMN(SurvEvSel, survevsel, int); //! flag if reco collision survived event selection -DECLARE_SOA_COLUMN(IsReco, isreco, int); //! flag if candidate was reconstructed - -// V0 -DECLARE_SOA_COLUMN(MassV0, massv0, float); //! proton, pion vertex mass -DECLARE_SOA_COLUMN(Chi2MassV0, chi2massv0, float); //! chi2 of proton, pion mass constraint to Lambda mass -DECLARE_SOA_COLUMN(CosPAV0, cospav0, float); //! proton, pion vertex mass - -} // namespace kfvtx3body + vtx3body::Decay3BodyId, + vtx3body::TrackPrId, vtx3body::TrackPiId, vtx3body::TrackDeId, + vtx3body::CollisionId); -DECLARE_SOA_TABLE(KFVtx3BodyDatas, "AOD", "KFVTX3BODYDATA", - o2::soa::Index<>, vtx3body::CollisionId, vtx3body::Track0Id, vtx3body::Track1Id, vtx3body::Track2Id, vtx3body::Decay3BodyId, - - // hypertriton candidate - kfvtx3body::Mass, - vtx3body::X, vtx3body::Y, vtx3body::Z, - kfvtx3body::XErr, kfvtx3body::YErr, kfvtx3body::ZErr, - kfvtx3body::Px, kfvtx3body::Py, kfvtx3body::Pz, kfvtx3body::Pt, - kfvtx3body::PxErr, kfvtx3body::PyErr, kfvtx3body::PzErr, kfvtx3body::PtErr, - kfvtx3body::Sign, - kfvtx3body::DCAVtxToPVKF, kfvtx3body::DCAXYVtxToPVKF, - kfvtx3body::VtxCosPAKF, kfvtx3body::VtxCosXYPAKF, - kfvtx3body::VtxCosPAKFtopo, kfvtx3body::VtxCosXYPAKFtopo, - kfvtx3body::DecayLKF, kfvtx3body::DecayLXYKF, kfvtx3body::DecayLDeltaL, - kfvtx3body::Chi2geoNDF, kfvtx3body::Chi2topoNDF, - kfvtx3body::CTauKFtopo, kfvtx3body::TrackedClSize, - - // V0 - kfvtx3body::MassV0, kfvtx3body::Chi2MassV0, - kfvtx3body::CosPAV0, - - // daughters - vtx3body::PxTrack0, vtx3body::PyTrack0, vtx3body::PzTrack0, // proton - vtx3body::PxTrack1, vtx3body::PyTrack1, vtx3body::PzTrack1, // pion - vtx3body::PxTrack2, vtx3body::PyTrack2, vtx3body::PzTrack2, // deuteron - kfvtx3body::TPCInnerParamTrack0, kfvtx3body::TPCInnerParamTrack1, kfvtx3body::TPCInnerParamTrack2, // proton, pion, deuteron - kfvtx3body::TPCNClTrack0, kfvtx3body::TPCNClTrack1, kfvtx3body::TPCNClTrack2, // proton, pion, deuteron - kfvtx3body::TPCChi2NClDeuteron, - kfvtx3body::DeltaPhiDeuteron, kfvtx3body::DeltaPhiProton, - kfvtx3body::DCATrack0ToPVKF, kfvtx3body::DCATrack1ToPVKF, kfvtx3body::DCATrack2ToPVKF, kfvtx3body::DCAxyTrack0ToPVKF, kfvtx3body::DCAxyTrack1ToPVKF, kfvtx3body::DCAxyTrack2ToPVKF, - kfvtx3body::DCAxyTrack0ToSVKF, kfvtx3body::DCAxyTrack1ToSVKF, kfvtx3body::DCAxyTrack2ToSVKF, - kfvtx3body::DCATrack0ToTrack1KF, kfvtx3body::DCATrack0ToTrack2KF, kfvtx3body::DCATrack1ToTrack2KF, - kfvtx3body::DCAVtxDaughtersKF, - kfvtx3body::DCAxyTrackPosToPV, kfvtx3body::DCAxyTrackNegToPV, kfvtx3body::DCAxyTrackBachToPV, - kfvtx3body::DCATrackPosToPV, kfvtx3body::DCATrackNegToPV, kfvtx3body::DCATrackBachToPV, - kfvtx3body::Track0Sign, kfvtx3body::Track1Sign, kfvtx3body::Track2Sign, // track sing: proton, pion, deuteron - kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, kfvtx3body::TPCNSigmaPionBach, - kfvtx3body::TPCdEdxProton, kfvtx3body::TPCdEdxPion, kfvtx3body::TPCdEdxDeuteron, - kfvtx3body::TOFNSigmaDeuteron, - kfvtx3body::ITSClusSizeDeuteron, - kfvtx3body::PIDTrackingDeuteron); - -using KFVtx3BodyData = KFVtx3BodyDatas::iterator; -namespace kfvtx3body -{ -DECLARE_SOA_INDEX_COLUMN(KFVtx3BodyData, kfvtx3BodyData); //! Index to KFVtx3BodyData entry -} - -DECLARE_SOA_TABLE(KFDecay3BodyDataLink, "AOD", "KF3BODYLINK", //! Joinable table with Decay3bodys which links to KFVtx3BodyData which is not produced for all entries - kfvtx3body::KFVtx3BodyDataId); - -using KFDecay3BodysLinked = soa::Join; -using KFDecay3BodyLinked = KFDecay3BodysLinked::iterator; - -// Lite data candidate table for analysis -DECLARE_SOA_TABLE(KFVtx3BodyDatasLite, "AOD", "KF3BODYLITE", +// reconstructed candidate table for analysis +DECLARE_SOA_TABLE(Vtx3BodyDatas, "AOD", "VTX3BODYDATA", //! o2::soa::Index<>, - // hypertriton candidate - kfvtx3body::Mass, + vtx3body::Sign, + vtx3body::Mass, vtx3body::MassV0, vtx3body::X, vtx3body::Y, vtx3body::Z, - kfvtx3body::Px, kfvtx3body::Py, kfvtx3body::Pz, kfvtx3body::Pt, - kfvtx3body::Sign, - kfvtx3body::DCAVtxToPVKF, kfvtx3body::DCAXYVtxToPVKF, - kfvtx3body::VtxCosPAKF, kfvtx3body::VtxCosXYPAKF, - kfvtx3body::DecayLKF, kfvtx3body::DecayLXYKF, kfvtx3body::DecayLDeltaL, - kfvtx3body::Chi2geoNDF, kfvtx3body::Chi2topoNDF, - kfvtx3body::CTauKFtopo, kfvtx3body::TrackedClSize, - - // V0 - kfvtx3body::MassV0, - kfvtx3body::CosPAV0, - - // daughters - vtx3body::PxTrack0, vtx3body::PyTrack0, vtx3body::PzTrack0, // proton - vtx3body::PxTrack1, vtx3body::PyTrack1, vtx3body::PzTrack1, // pion - vtx3body::PxTrack2, vtx3body::PyTrack2, vtx3body::PzTrack2, // deuteron - kfvtx3body::TPCInnerParamTrack0, kfvtx3body::TPCInnerParamTrack1, kfvtx3body::TPCInnerParamTrack2, // proton, pion, deuteron - kfvtx3body::TPCNClTrack0, kfvtx3body::TPCNClTrack1, kfvtx3body::TPCNClTrack2, // proton, pion, deuteron - kfvtx3body::TPCChi2NClDeuteron, - kfvtx3body::DeltaPhiDeuteron, kfvtx3body::DeltaPhiProton, - kfvtx3body::DCATrack0ToPVKF, kfvtx3body::DCATrack1ToPVKF, kfvtx3body::DCATrack2ToPVKF, kfvtx3body::DCAxyTrack0ToPVKF, kfvtx3body::DCAxyTrack1ToPVKF, kfvtx3body::DCAxyTrack2ToPVKF, - kfvtx3body::DCAxyTrack0ToSVKF, kfvtx3body::DCAxyTrack1ToSVKF, kfvtx3body::DCAxyTrack2ToSVKF, - kfvtx3body::DCATrack0ToTrack1KF, kfvtx3body::DCATrack0ToTrack2KF, kfvtx3body::DCATrack1ToTrack2KF, - kfvtx3body::DCAVtxDaughtersKF, - kfvtx3body::Track0Sign, kfvtx3body::Track1Sign, kfvtx3body::Track2Sign, // track sing: proton, pion, deuteron - kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, kfvtx3body::TPCNSigmaPionBach, - kfvtx3body::TOFNSigmaDeuteron, - kfvtx3body::ITSClusSizeDeuteron, - kfvtx3body::PIDTrackingDeuteron); - -using KFVtx3BodyDataLite = KFVtx3BodyDatasLite::iterator; + vtx3body::Px, vtx3body::Py, vtx3body::Pz, + vtx3body::Chi2, + vtx3body::TrackedClSize, + vtx3body::PxTrackPr, vtx3body::PyTrackPr, vtx3body::PzTrackPr, + vtx3body::PxTrackPi, vtx3body::PyTrackPi, vtx3body::PzTrackPi, + vtx3body::PxTrackDe, vtx3body::PyTrackDe, vtx3body::PzTrackDe, + vtx3body::DCAXYTrackPrToPV, vtx3body::DCAXYTrackPiToPV, vtx3body::DCAXYTrackDeToPV, + vtx3body::DCAZTrackPrToPV, vtx3body::DCAZTrackPiToPV, vtx3body::DCAZTrackDeToPV, + vtx3body::DCATrackPrToSV, vtx3body::DCATrackPiToSV, vtx3body::DCATrackDeToSV, + vtx3body::DCAVtxDaughters, + vtx3body::TPCNSigmaPr, vtx3body::TPCNSigmaPi, vtx3body::TPCNSigmaDe, vtx3body::TPCNSigmaPiBach, + vtx3body::TOFNSigmaDe, + vtx3body::ITSClSizePr, vtx3body::ITSClSizePi, vtx3body::ITSClSizeDe, + vtx3body::TPCNClTrackPr, vtx3body::TPCNClTrackPi, vtx3body::TPCNClTrackDe, + vtx3body::PIDTrackingDe, + + // Dynamic columns + vtx3body::P, + vtx3body::Pt, + vtx3body::VtxRadius, + vtx3body::DistOverTotMom, + vtx3body::VtxCosPA, + vtx3body::DCAVtxToPV, + + // Longitudinal + vtx3body::Rap, + vtx3body::Eta, + vtx3body::Phi, + vtx3body::TrackPrPt, + vtx3body::TrackPrEta, + vtx3body::TrackPrPhi, + vtx3body::TrackPiPt, + vtx3body::TrackPiEta, + vtx3body::TrackPiPhi, + vtx3body::TrackDePt, + vtx3body::TrackDeEta, + vtx3body::TrackDePhi); + +// covariance matrix table +DECLARE_SOA_TABLE(Vtx3BodyCovs, "AOD", "VTX3BODYCOV", //! + vtx3body::CovProton, vtx3body::CovPion, vtx3body::CovDeuteron, + vtx3body::VtxCovMat); // MC candidate table for analysis -DECLARE_SOA_TABLE(McKFVtx3BodyDatas, "AOD", "MCKF3BODYDATAS", +DECLARE_SOA_TABLE(McVtx3BodyDatas, "AOD", "MC3BODYDATA", //! o2::soa::Index<>, - // hypertriton candidate - kfvtx3body::Mass, + vtx3body::Sign, + vtx3body::Mass, vtx3body::MassV0, vtx3body::X, vtx3body::Y, vtx3body::Z, - kfvtx3body::XErr, kfvtx3body::YErr, kfvtx3body::ZErr, - kfvtx3body::Px, kfvtx3body::Py, kfvtx3body::Pz, kfvtx3body::Pt, - kfvtx3body::PxErr, kfvtx3body::PyErr, kfvtx3body::PzErr, kfvtx3body::PtErr, - kfvtx3body::Sign, - kfvtx3body::DCAVtxToPVKF, kfvtx3body::DCAXYVtxToPVKF, - kfvtx3body::VtxCosPAKF, kfvtx3body::VtxCosXYPAKF, - kfvtx3body::VtxCosPAKFtopo, kfvtx3body::VtxCosXYPAKFtopo, - kfvtx3body::DecayLKF, kfvtx3body::DecayLXYKF, kfvtx3body::DecayLDeltaL, - kfvtx3body::Chi2geoNDF, kfvtx3body::Chi2topoNDF, - kfvtx3body::CTauKFtopo, kfvtx3body::TrackedClSize, - - // V0 - kfvtx3body::MassV0, kfvtx3body::Chi2MassV0, - kfvtx3body::CosPAV0, - - // daughters - vtx3body::PxTrack0, vtx3body::PyTrack0, vtx3body::PzTrack0, // proton - vtx3body::PxTrack1, vtx3body::PyTrack1, vtx3body::PzTrack1, // pion - vtx3body::PxTrack2, vtx3body::PyTrack2, vtx3body::PzTrack2, // deuteron - kfvtx3body::TPCInnerParamTrack0, kfvtx3body::TPCInnerParamTrack1, kfvtx3body::TPCInnerParamTrack2, // proton, pion, deuteron - kfvtx3body::TPCNClTrack0, kfvtx3body::TPCNClTrack1, kfvtx3body::TPCNClTrack2, // proton, pion, deuteron - kfvtx3body::TPCChi2NClDeuteron, - kfvtx3body::DeltaPhiDeuteron, kfvtx3body::DeltaPhiProton, - kfvtx3body::DCATrack0ToPVKF, kfvtx3body::DCATrack1ToPVKF, kfvtx3body::DCATrack2ToPVKF, kfvtx3body::DCAxyTrack0ToPVKF, kfvtx3body::DCAxyTrack1ToPVKF, kfvtx3body::DCAxyTrack2ToPVKF, - kfvtx3body::DCAxyTrack0ToSVKF, kfvtx3body::DCAxyTrack1ToSVKF, kfvtx3body::DCAxyTrack2ToSVKF, - kfvtx3body::DCATrack0ToTrack1KF, kfvtx3body::DCATrack0ToTrack2KF, kfvtx3body::DCATrack1ToTrack2KF, - kfvtx3body::DCAVtxDaughtersKF, - kfvtx3body::DCAxyTrackPosToPV, kfvtx3body::DCAxyTrackNegToPV, kfvtx3body::DCAxyTrackBachToPV, - kfvtx3body::DCATrackPosToPV, kfvtx3body::DCATrackNegToPV, kfvtx3body::DCATrackBachToPV, - kfvtx3body::Track0Sign, kfvtx3body::Track1Sign, kfvtx3body::Track2Sign, // track sing: proton, pion, deuteron - kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, kfvtx3body::TPCNSigmaPionBach, - kfvtx3body::TPCdEdxProton, kfvtx3body::TPCdEdxPion, kfvtx3body::TPCdEdxDeuteron, - kfvtx3body::TOFNSigmaDeuteron, - kfvtx3body::ITSClusSizeDeuteron, - kfvtx3body::PIDTrackingDeuteron, - - // MC information - kfvtx3body::GenP, - kfvtx3body::GenPt, - kfvtx3body::GenDecVtxX, kfvtx3body::GenDecVtxY, kfvtx3body::GenDecVtxZ, - kfvtx3body::GenCtau, - kfvtx3body::GenPhi, - kfvtx3body::GenEta, - kfvtx3body::GenRapidity, - kfvtx3body::GenPosP, kfvtx3body::GenPosPt, - kfvtx3body::GenNegP, kfvtx3body::GenNegPt, - kfvtx3body::GenBachP, kfvtx3body::GenBachPt, - kfvtx3body::IsTrueH3L, kfvtx3body::IsTrueAntiH3L, - kfvtx3body::PdgCodeDau0, kfvtx3body::PdgCodeDau1, kfvtx3body::PdgCodeDau2, - kfvtx3body::IsBachPrimary, - kfvtx3body::IsReco, - kfvtx3body::SurvEvSel); - -// Definition of labels for KFVtx3BodyDatas -namespace mckfvtx3bodylabel -{ -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for KF Vtx3BodyDatas -} // namespace mckfvtx3bodylabel - -DECLARE_SOA_TABLE(McKFVtx3BodyLabels, "AOD", "MCKFVTXLABEL", //! Table joinable with KFVtx3BodyData containing the MC labels - mckfvtx3bodylabel::McParticleId); -using McKFVtx3BodyLabel = McKFVtx3BodyLabels::iterator; - -// Definition of labels for KFDecay3Bodys // Full table, joinable with KFDecay3Bodys (CAUTION: NOT WITH Vtx3BodyDATA) -namespace mcfullkfvtx3bodylabel -{ -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for Decay3Bodys -} // namespace mcfullkfvtx3bodylabel + vtx3body::Px, vtx3body::Py, vtx3body::Pz, + vtx3body::Chi2, + vtx3body::TrackedClSize, + vtx3body::PxTrackPr, vtx3body::PyTrackPr, vtx3body::PzTrackPr, + vtx3body::PxTrackPi, vtx3body::PyTrackPi, vtx3body::PzTrackPi, + vtx3body::PxTrackDe, vtx3body::PyTrackDe, vtx3body::PzTrackDe, + vtx3body::DCAXYTrackPrToPV, vtx3body::DCAXYTrackPiToPV, vtx3body::DCAXYTrackDeToPV, + vtx3body::DCAZTrackPrToPV, vtx3body::DCAZTrackPiToPV, vtx3body::DCAZTrackDeToPV, + vtx3body::DCATrackPrToSV, vtx3body::DCATrackPiToSV, vtx3body::DCATrackDeToSV, + vtx3body::DCAVtxDaughters, + vtx3body::TPCNSigmaPr, vtx3body::TPCNSigmaPi, vtx3body::TPCNSigmaDe, vtx3body::TPCNSigmaPiBach, + vtx3body::TOFNSigmaDe, + vtx3body::ITSClSizePr, vtx3body::ITSClSizePi, vtx3body::ITSClSizeDe, + vtx3body::TPCNClTrackPr, vtx3body::TPCNClTrackPi, vtx3body::TPCNClTrackDe, + vtx3body::PIDTrackingDe, + + // Monte Carlo information + vtx3body::GenPx, vtx3body::GenPy, vtx3body::GenPz, + vtx3body::GenX, vtx3body::GenY, vtx3body::GenZ, + vtx3body::GenCt, + vtx3body::GenPhi, vtx3body::GenEta, vtx3body::GenRap, + vtx3body::GenPPr, vtx3body::GenPPi, vtx3body::GenPDe, + vtx3body::GenPtPr, vtx3body::GenPtPi, vtx3body::GenPtDe, + vtx3body::IsTrueH3L, vtx3body::IsTrueAntiH3L, + vtx3body::IsReco, + vtx3body::PrPdgCode, vtx3body::PiPdgCode, vtx3body::DePdgCode, + vtx3body::IsDePrimary, + vtx3body::IsSurvEvSel, + + // Dynamic columns + vtx3body::P, + vtx3body::Pt, + vtx3body::GenP, + vtx3body::GenPt, + vtx3body::VtxRadius, + vtx3body::GenRadius, + vtx3body::DistOverTotMom, + vtx3body::VtxCosPA, + vtx3body::DCAVtxToPV, + + // Longitudinal + vtx3body::Rap, + vtx3body::Eta, + vtx3body::Phi, + vtx3body::TrackPrPt, + vtx3body::TrackPrEta, + vtx3body::TrackPrPhi, + vtx3body::TrackPiPt, + vtx3body::TrackPiEta, + vtx3body::TrackPiPhi, + vtx3body::TrackDePt, + vtx3body::TrackDeEta, + vtx3body::TrackDePhi); + +// Define joins +using Vtx3BodyDatasCovs = soa::Join; +using Vtx3BodyDatasCovsIndexed = soa::Join; -DECLARE_SOA_TABLE(McFullKFVtx3BodyLabels, "AOD", "MCFULLKFLABEL", //! Table joinable with Decay3Bodys (CAUTION: NOT WITH Vtx3BodyDATA) - mcfullkfvtx3bodylabel::McParticleId); -using McFullKFVtx3BodyLabel = McFullKFVtx3BodyLabels::iterator; } // namespace o2::aod #endif // PWGLF_DATAMODEL_VTX3BODYTABLES_H_ diff --git a/PWGLF/TableProducer/Nuspex/CMakeLists.txt b/PWGLF/TableProducer/Nuspex/CMakeLists.txt index f8f62f22925..7138fe9ded7 100644 --- a/PWGLF/TableProducer/Nuspex/CMakeLists.txt +++ b/PWGLF/TableProducer/Nuspex/CMakeLists.txt @@ -11,7 +11,7 @@ o2physics_add_dpl_workflow(decay3bodybuilder SOURCES decay3bodybuilder.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter KFParticle::KFParticle O2Physics::AnalysisCore O2::TOFBase O2Physics::EventFilteringUtils O2::DetectorsVertexing + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter KFParticle::KFParticle O2::TOFBase O2Physics::EventFilteringUtils O2::DetectorsVertexing COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(hyhefour-builder @@ -29,11 +29,6 @@ o2physics_add_dpl_workflow(lnn-reco-task PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(hypertriton3bodyfinder - SOURCES hypertriton3bodyfinder.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(nucleustreecreator SOURCES LFTreeCreatorNuclei.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -59,11 +54,6 @@ o2physics_add_dpl_workflow(threebodymcfinder PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(threebody-reco-task - SOURCES threebodyRecoTask.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore O2Physics::EventFilteringUtils - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(ebye-maker SOURCES ebyeMaker.cxx PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore @@ -79,11 +69,6 @@ o2physics_add_dpl_workflow(pidtof-generic PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::TOFBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(threebody-kf-task - SOURCES threebodyKFTask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(hypernuclei-kf-reco-task SOURCES hypKfRecoTask.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore KFParticle::KFParticle diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index b7b643bca21..77c3e5668a7 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -9,10 +9,12 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +// ======================== /// \file decay3bodybuilder.cxx -/// \brief Builder task for 3-body decay reconstruction (p + pion + bachelor) +/// \brief Builder task for 3-body hypertriton decay reconstruction (proton + pion + deuteron) /// \author Yuanzhe Wang -/// \author Carolina Reetz (KFParticle specific part) +/// \author Carolina Reetz +// ======================== #include #include @@ -20,25 +22,20 @@ #include #include #include -#include #include - -#include -#include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" -#include "DCAFitter/DCAFitterN.h" #include "ReconstructionDataFormats/Track.h" -#include "DetectorsVertexing/SVertexHypothesis.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/Reduced3BodyTables.h" #include "PWGLF/DataModel/Vtx3BodyTables.h" #include "PWGLF/DataModel/pidTOFGeneric.h" +#include "PWGLF/Utils/decay3bodyBuilderHelper.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" #include "Common/Core/PID/PIDTOF.h" @@ -53,8 +50,6 @@ #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" -#include "DataFormatsTPC/BetheBlochAleph.h" -#include "DataFormatsCalibration/MeanVertexObject.h" #ifndef HomogeneousField #define HomogeneousField @@ -70,308 +65,207 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using std::array; - -using FullTracksExtIU = soa::Join; -using FullTracksExtPIDIU = soa::Join; - -using ColwithEvTimes = o2::soa::Join; -using ColwithEvTimesMults = o2::soa::Join; -using TrackExtIUwithEvTimes = soa::Join; -using TrackExtPIDIUwithEvTimes = soa::Join; - -using MCLabeledTracksIU = soa::Join; - -using ReducedCollisionsMults = soa::Join; -using ReducedCollisionsMultsCents = soa::Join; - -namespace -{ -const float pidCutsLambda[o2::vertexing::SVertexHypothesis::NPIDParams] = {0., 20, 0., 5.0, 0.0, 1.09004e-03, 2.62291e-04, 8.93179e-03, 2.83121}; // Lambda -} // namespace - -struct VtxCandidate { - int track0Id; - int track1Id; - int track2Id; - int collisionId; - int decay3bodyId; - float vtxPos[3]; - float track0P[3]; - float track1P[3]; - float track2P[3]; - float dcadaughters; - float daudcaxytopv[3]; // 0 - proton, 1 - pion, 2 - bachelor - float daudcatopv[3]; // 0 - proton, 1 - pion, 2 - bachelor - float bachelortofNsigma; -}; -struct kfCandidate { - // hypertriton - int collisionID; - int trackPosID; - int trackNegID; - int trackBachID; - int decay3bodyID; - float mass; - float pos[3]; - float posErr[3]; - float mom[4]; - float momErr[4]; - float charge; - float dcaToPV[2]; // 3D, xy - float cpaToPV[2]; // 3D, xy - float cpaToPVtopo[2]; // 3D, xy - float decLen[2]; // 3D, xy - float ldl; - float chi2geoNDF; - float chi2topoNDF; - float ctau; - float trackedClSize; - float DeltaPhiRotDeuteron; - float DeltaPhiRotProton; - // V0 - float massV0; - float chi2massV0; - float cpaV0ToPV; - // daughter momenta - float protonMom[3]; - float pionMom[3]; - float deuteronMom[3]; - float tpcInnerParam[3]; // proton, pion, deuteron - // daughter track quality - int tpcNClDaughters[3]; // proton, pion, deuteron - float tpcChi2NClDeuteron; - // daughter DCAs KF - float DCAdaughterToPV[3]; // proton, pion, deuteron - float DCAdaughterToPVxy[3]; // proton, pion, deuteron - float DCAdaughterToSVxy[3]; // proton, pion, deuteron - float DCAprotonToPion; - float DCAprotonToDeuteron; - float DCApionToDeuteron; - float DCAvtxDaughters3D; - // daughter DCAs to PV propagated with material - float trackDCAxy[3]; // pos, neg, bach - float trackDCA[3]; // pos, neg, bach - // daughter signs - float daughterCharge[3]; // proton, pion, deuteron - // daughter PID - float tpcNsigma[4]; // proton, pion, deuteron, bach with pion hyp - float tpcdEdx[3]; // proton, pion, deuteron - float tofNsigmaDeuteron; - float averageClusterSizeDeuteron; - float pidForTrackingDeuteron; +static constexpr int nParameters = 1; +static const std::vector tableNames{ + "Decay3BodyIndices", + "Vtx3BodyDatas", + "Vtx3BodyCovs", + "McVtx3BodyDatas"}; + +static constexpr int nTablesConst = 4; + +static const std::vector parameterNames{"enable"}; +static const int defaultParameters[nTablesConst][nParameters]{ + {0}, // Decay3BodyIndices + {0}, // Vtx3BodyDatas + {0}, // Vtx3BodyCovs + {0} // McVtx3BodyDatas }; -struct decay3bodyBuilder { - - Produces vtx3bodydata; - Produces kfvtx3bodydata; - Produces kfvtx3bodydatalite; - Service ccdb; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - std::vector VtxCandidates; +using TracksExtPIDIUwithEvTimes = soa::Join; +using TracksExtPIDIUwithEvTimesLabeled = soa::Join; - std::unordered_map ccdbCache; // Maps runNumber -> d_bz - std::unordered_map> grpMagCache; // Maps runNumber -> grpmap +using ColswithEvTimes = o2::soa::Join; +using ColswithEvTimesLabeled = o2::soa::Join; - Zorro zorro; - OutputObj zorroSummary{"zorroSummary"}; +struct decay3bodyBuilder { - std::vector fTrackedClSizeVector; + // helper object + o2::pwglf::decay3bodyBuilderHelper helper; + + // table index : match order above + enum tableIndex { kDecay3BodyIndices = 0, + kVtx3BodyDatas, + kVtx3BodyCovs, + kMcVtx3BodyDatas, + nTables }; + + struct : ProducesGroup { + Produces decay3bodyindices; + Produces vtx3bodydatas; + Produces vtx3bodycovs; + Produces mcvtx3bodydatas; + } products; + + // enablde tables + Configurable> enabledTables{"enabledTables", + {defaultParameters[0], nTables, nParameters, tableNames, parameterNames}, + "Produce this table: 0 - false, 1 - true"}; + std::vector mEnabledTables; // Vector of enabled tables + + // general options + Configurable useMatCorrType{"useMatCorrType", 0, "0: none, 1: TGeo, 2: LUT"}; + Configurable doTrackQA{"doTrackQA", false, "Flag to fill QA histograms for daughter tracks of (selected) decay3body candidates."}; + Configurable doVertexQA{"doVertexQA", false, "Flag to fill QA histograms for PV of (selected) events."}; + Configurable doSel8selection{"doSel8selection", true, "flag for sel8 event selection"}; + Configurable doPosZselection{"doPosZselection", true, "flag for posZ event selection"}; - // Configurables - Configurable d_UseAbsDCA{"d_UseAbsDCA", true, "Use Abs DCAs"}; - - enum Hyp3Body { kH3L = 0, - kH4L, - kHe4L, - kHe5L, - kNHyp3body }; - - enum VtxStep { kVtxAll = 0, - kVtxTPCNcls, - kVtxPIDCut, - kVtxhasSV, - kVtxDcaDau, - kVtxCosPA, - kNVtxSteps }; - - enum kfvtxstep { kKfVtxAll = 0, - kKfVtxCharge, - kKfVtxEta, - kKfVtxTPCNcls, - kKfVtxTPCRows, - kKfVtxTPCPID, - kKfVtxDCAxyPV, - kKfVtxDCAzPV, - kKfVtxV0MassConst, - kKfVtxhasSV, - kKfVtxDcaDau, - kKfVtxDcaDauVtx, - kKfVtxDauPt, - kKfVtxRap, - kKfVtxPt, - kKfVtxMass, - kKfVtxCosPA, - kKfVtxCosPAXY, - kKfVtxChi2geo, - kKfVtxTopoConstr, - kKfVtxChi2topo, - kKfNVtxSteps }; - - HistogramRegistry registry{"registry", {}}; - - // hypothesis - Configurable motherhyp{"motherhyp", 0, "hypothesis of the 3body decayed particle"}; // corresponds to Hyp3Body - int bachelorcharge = 1; // to be updated in Init base on the hypothesis - o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; // to be updated in Init base on the hypothesis - - // Selection criteria - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - Configurable mintpcNCls{"mintpcNCls", 70, "min tpc Nclusters"}; - Configurable minCosPA3body{"minCosPA3body", 0.9, "minCosPA3body"}; - Configurable dcavtxdau{"dcavtxdau", 1.0, "DCA Vtx Daughters"}; - Configurable enablePidCut{"enablePidCut", 0, "enable function checkPIDH3L"}; - Configurable TofPidNsigmaMin{"TofPidNsigmaMin", -5, "TofPidNsigmaMin"}; - Configurable TofPidNsigmaMax{"TofPidNsigmaMax", 5, "TofPidNsigmaMax"}; - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable minBachPUseTOF{"minBachPUseTOF", 1, "minBachP Enable TOF PID"}; + // data processing options + Configurable doSkimmedProcessing{"doSkimmedProcessing", false, "Apply Zoroo counting in case of skimmed data input"}; + Configurable triggerList{"triggerList", "fTriggerEventF1Proton, fTrackedOmega, fTrackedXi, fOmegaLargeRadius, fDoubleOmega, fOmegaHighMult, fSingleXiYN, fQuadrupleXi, fDoubleXi, fhadronOmega, fOmegaXi, fTripleXi, fOmega, fGammaVeryLowPtEMCAL, fGammaVeryLowPtDCAL, fGammaHighPtEMCAL, fGammaLowPtEMCAL, fGammaVeryHighPtDCAL, fGammaVeryHighPtEMCAL, fGammaLowPtDCAL, fJetNeutralLowPt, fJetNeutralHighPt, fGammaHighPtDCAL, fJetFullLowPt, fJetFullHighPt, fEMCALReadout, fPCMandEE, fPHOSnbar, fPCMHighPtPhoton, fPHOSPhoton, fLD, fPPPHI, fPD, fLLL, fPLL, fPPL, fPPP, fLeadingPtTrack, fHighFt0cFv0Flat, fHighFt0cFv0Mult, fHighFt0Flat, fHighFt0Mult, fHighMultFv0, fHighTrackMult, fHfSingleNonPromptCharm3P, fHfSingleNonPromptCharm2P, fHfSingleCharm3P, fHfPhotonCharm3P, fHfHighPt2P, fHfSigmaC0K0, fHfDoubleCharm2P, fHfBeauty3P, fHfFemto3P, fHfFemto2P, fHfHighPt3P, fHfSigmaCPPK, fHfDoubleCharm3P, fHfDoubleCharmMix, fHfPhotonCharm2P, fHfV0Charm2P, fHfBeauty4P, fHfV0Charm3P, fHfSingleCharm2P, fHfCharmBarToXiBach, fSingleMuHigh, fSingleMuLow, fLMeeHMR, fDiMuon, fDiElectron, fLMeeIMR, fSingleE, fTrackHighPt, fTrackLowPt, fJetChHighPt, fJetChLowPt, fUDdiffLarge, fUDdiffSmall, fITSextremeIonisation, fITSmildIonisation, fH3L3Body, fHe, fH2", "List of triggers used to select events"}; + Configurable onlyKeepInterestedTrigger{"onlyKeepInterestedTrigger", false, "Flag to keep only interested trigger"}; - Configurable useMatCorrType{"useMatCorrType", 0, "0: none, 1: TGeo, 2: LUT"}; // CCDB options - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - // CCDB TOF PID paras - Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; - Configurable paramFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; - Configurable parametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; - Configurable passName{"passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; - Configurable timeShiftCCDBPath{"timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; - Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; - Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; - // for KFParticle reconstruction struct : ConfigurableGroup { - Configurable cfgSkimmedProcessing{"kfparticleConfigurations.cfgSkimmedProcessing", false, "Flag for skimmed dataset processing"}; - Configurable triggerList{"kfparticleConfigurations.triggerList", "fH3L3Body", "List of triggers used to select events"}; - Configurable cfgOnlyKeepInterestedTrigger{"kfparticleConfigurations.cfgOnlyKeepInterestedTrigger", false, "Flag to keep only interested trigger"}; - Configurable fillCandidateFullTable{"kfparticleConfigurations.fillCandidateFullTable", false, "Switch to fill full table with candidate properties"}; - Configurable doSel8selection{"kfparticleConfigurations.doSel8selection", true, "flag for sel8 event selection"}; - Configurable doPosZselection{"kfparticleConfigurations.doPosZselection", true, "flag for posZ event selection"}; - Configurable doDCAFitterPreMinimum{"kfparticleConfigurations.doDCAFitterPreMinimum", false, "do DCAFitter pre-optimization before KF fit to include material corrections for decay3body vertex"}; - Configurable doTrackQA{"kfparticleConfigurations.doTrackQA", false, "Flag to fill QA histograms for daughter tracks."}; - Configurable doVertexQA{"kfparticleConfigurations.doVertexQA", false, "Flag to fill QA histograms for KFParticle PV."}; - Configurable useLambdaMassConstraint{"kfparticleConfigurations.useLambdaMassConstraint", false, "Apply Lambda mass constraint on proton-pion vertex"}; - Configurable doDCAPreSel{"kfparticleConfigurations.doDCAPreSel", false, "Apply selection on DCA of daughter tracks to PV"}; - Configurable maxEta{"kfparticleConfigurations.maxEta", 1.0, "Maximum eta for proton and pion daughter tracks"}; - Configurable maxEtaDeuteron{"kfparticleConfigurations.maxEtaDeuteron", 0.9, "Maximum eta for deuteron daughter track"}; - Configurable useTPCforPion{"kfparticleConfigurations.useTPCforPion", true, "Flag to ask for TPC info for pion track (PID, nClusters), false: pion track can be ITS only"}; - Configurable mintpcNClsProton{"kfparticleConfigurations.mintpcNClsProton", 70, "Minimum number of TPC clusters for proton track"}; - Configurable mintpcNClsPion{"kfparticleConfigurations.mintpcNClsPion", 70, "Minimum number of TPC clusters for pion track"}; - Configurable mintpcNClsBach{"kfparticleConfigurations.mintpcNClsBach", 70, "Minimum number of TPC clusters for bachelor track"}; - Configurable mintpcCrossedRows{"kfparticleConfigurations.mintpcCrossedRows", 70, "Minimum number of TPC crossed rows for proton and deuteron track"}; - Configurable mintpcCrossedRowsPion{"kfparticleConfigurations.mintpcCrossedRowsPion", 70, "Minimum number of TPC crossed rows for pion track"}; - Configurable minPtProton{"kfparticleConfigurations.minPtProton", 0.1, "Minimum pT of proton track"}; - Configurable maxPtProton{"kfparticleConfigurations.maxPtProton", 10, "Maximum pT of proton track"}; - Configurable minPtPion{"kfparticleConfigurations.minPtPion", 0.1, "Minimum pT of pion track"}; - Configurable maxPtPion{"kfparticleConfigurations.maxPtPion", 10, "Maximum pT of pion track"}; - Configurable minPtDeuteron{"kfparticleConfigurations.minPtDeuteron", 0.1, "Minimum pT of deuteron track"}; - Configurable maxPtDeuteron{"kfparticleConfigurations.maxPtDeuteron", 10, "Maximum pT of deuteron track"}; - Configurable mindcaXYPionPV{"kfparticleConfigurations.mindcaXYPionPV", 0.1, "Minimum DCA XY of the pion daughter track to the PV"}; - Configurable mindcaXYProtonPV{"kfparticleConfigurations.mindcaXYProtonPV", 0.1, "Minimum DCA XY of the proton daughter track to the PV"}; - Configurable mindcaZPionPV{"kfparticleConfigurations.mindcaZPionPV", 0.1, "Minimum DCA Z of the pion daughter track to the PV"}; - Configurable mindcaZProtonPV{"kfparticleConfigurations.mindcaZProtonPV", 0.1, "Minimum DCA Z of the proton daughter track to the PV"}; - Configurable maxtpcnSigma{"kfparticleConfigurations.maxtpcnSigma", 5., "Maximum nSigma TPC for daughter tracks"}; - Configurable maxDcaProDeu{"kfparticleConfigurations.maxDcaProDeu", 1000., "Maximum geometrical distance between proton and deuteron at the SV in 3D with KFParticle"}; - Configurable maxDcaProPi{"kfparticleConfigurations.maxDcaProPi", 1000., "Maximum geometrical distance between proton and pion at the SV in 3D with KFParticle"}; - Configurable maxDcaPiDe{"kfparticleConfigurations.maxDcaPiDe", 1000., "Maximum geometrical distance between pion and deuteron at the SV in 3D with KFParticle"}; - Configurable maxDcaXYSVDau{"kfparticleConfigurations.maxDcaXYSVDau", 1.0, "Maximum geometrical distance of daughter tracks from the SV in XY with KFParticle"}; - Configurable maxRapidityHt{"kfparticleConfigurations.maxRapidityHt", 1., "Maximum rapidity for Hypertriton candidates with KFParticle"}; - Configurable minPtHt{"kfparticleConfigurations.minPtHt", 0.01, "Minimum momentum for Hypertriton candidates with KFParticle (0.01 applied in SVertexer)"}; - Configurable maxPtHt{"kfparticleConfigurations.maxPtHt", 36., "Maximum momentum for Hypertriton candidates with KFParticle"}; - Configurable minMassHt{"kfparticleConfigurations.minMassHt", 2.96, "Minimum candidate mass with KFParticle"}; - Configurable maxMassHt{"kfparticleConfigurations.maxMassHt", 3.05, "Maximum candidate mass with KFParticle"}; - Configurable maxctauHt{"kfparticleConfigurations.maxctauHt", 40., "Maximum candidate ctau with KFParticle before topological constraint"}; - Configurable maxChi2geo{"kfparticleConfigurations.maxChi2geo", 1000., "Maximum chi2 geometrical with KFParticle"}; - Configurable minCosPA{"kfparticleConfigurations.minCosPA", 0.8, "Minimum cosine pointing angle with KFParticle (0.8 applied in SVertexer)"}; - Configurable minCosPAxy{"kfparticleConfigurations.minCosPAxy", 0.8, "Minimum cosine pointing angle in xy with KFParticle"}; - Configurable applyTopoSel{"kfparticleConfigurations.applyTopoSel", false, "Apply selection constraining the mother to the PV with KFParticle"}; - Configurable maxChi2topo{"kfparticleConfigurations.maxChi2topo", 1000., "Maximum chi2 topological with KFParticle"}; - Configurable nEvtMixing{"kfparticleConfigurations.nEvtMixing", 5, "Number of events to mix"}; - ConfigurableAxis binsVtxZ{"kfparticleConfigurations.binsVtxZ", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis binsMultiplicity{"kfparticleConfigurations.binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 1.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Mixing bins - multiplicity"}; - // 3body mixing - Configurable mixingType{"kfparticleConfigurations.mixingType", 0, "0: mix V0 from one event with bachelor from another, 1: mix pion and bachelor from one event with proton from another "}; - Configurable applySVertexerV0Cuts{"kfparticleConfigurations.applySVertexerV0Cuts", false, "Apply virtual V0 cuts applied in SVertexer in case of proton mixing"}; - ConfigurableAxis bins3BodyRadius{"kfparticleConfigurations.bins3BodyRadius", {VARIABLE_WIDTH, 0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, 16.0f, 18.0f, 20.0f, 30.0f, 1000.0}, "Mixing bins - 3body radius"}; - // ConfigurableAxis bins3BodyPhi{"kfparticleConfigurations.bins3BodyPhi", {VARIABLE_WIDTH, -180.0f*TMath::Pi()/180, -170.0f*TMath::Pi()/180, -160.0f*TMath::Pi()/180, -150.0f*TMath::Pi()/180, -140.0f*TMath::Pi()/180, -130.0f*TMath::Pi()/180, -120.0f*TMath::Pi()/180, -110.0f*TMath::Pi()/180, -100.0f*TMath::Pi()/180, -90.0f*TMath::Pi()/180, -80.0f*TMath::Pi()/180, -70.0f*TMath::Pi()/180, -60.0f*TMath::Pi()/180, -50.0f*TMath::Pi()/180, -40.0f*TMath::Pi()/180, -30.0f*TMath::Pi()/180, -20.0f*TMath::Pi()/180, -10.0f*TMath::Pi()/180, 0.0f, 10.0f*TMath::Pi()/180, 20.0f*TMath::Pi()/180, 30.0f*TMath::Pi()/180, 40.0f*TMath::Pi()/180, 50.0f*TMath::Pi()/180, 60.0f*TMath::Pi()/180, 70.0f*TMath::Pi()/180, 80.0f*TMath::Pi()/180, 90.0f*TMath::Pi()/180, 100.0f*TMath::Pi()/180, 110.0f*TMath::Pi()/180, 120.0f*TMath::Pi()/180, 130.0f*TMath::Pi()/180, 140.0f*TMath::Pi()/180, 150.0f*TMath::Pi()/180, 160.0f*TMath::Pi()/180, 170.0f*TMath::Pi()/180, 180.0f*TMath::Pi()/180}, "Mixing bins - 3body phi"}; - ConfigurableAxis bins3BodyPhi{"kfparticleConfigurations.bins3BodyPhi", {VARIABLE_WIDTH, -180.0f * TMath::Pi() / 180, -160.0f * TMath::Pi() / 180, -140.0f * TMath::Pi() / 180, -120.0f * TMath::Pi() / 180, -100.0f * TMath::Pi() / 180, -80.0f * TMath::Pi() / 180, -60.0f * TMath::Pi() / 180, -40.0f * TMath::Pi() / 180, -20.0f * TMath::Pi() / 180, 0.0f, 20.0f * TMath::Pi() / 180, 40.0f * TMath::Pi() / 180, 60.0f * TMath::Pi() / 180, 80.0f * TMath::Pi() / 180, 100.0f * TMath::Pi() / 180, 120.0f * TMath::Pi() / 180, 140.0f * TMath::Pi() / 180, 160.0f * TMath::Pi() / 180, 180.0f * TMath::Pi() / 180}, "Mixing bins - 3body phi"}; - ConfigurableAxis bins3BodyPosZ{"kfparticleConfigurations.bins3BodyPosZ", {VARIABLE_WIDTH, -300.0f, -42.0f, -13.0f, -6.0f, -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 13.0f, 42.0f, 300.0f}, "Mixing bins - 3body z position"}; - Configurable selectVtxZ3bodyMixing{"kfparticleConfigurations.selectVtxZ3bodyMixing", true, "Select same VtxZ events in case of 3body mixing"}; - Configurable VtxZBin3bodyMixing{"kfparticleConfigurations.VtxZBin3bodyMixing", 1., "Bin width for event vtx z position in case of 3body mixing"}; - } kfparticleConfigurations; - - //------------------------------------------------------------------ - // Sets for DCAFitter event mixing + std::string prefix = "ccdb"; + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + } ccdbConfigurations; + + // Decay3body building options struct : ConfigurableGroup { - Configurable nUseMixed{"dcaFitterEMSel.nUseMixed", 5, "nUseMixed"}; - Configurable mMinPt2V0{"dcaFitterEMSel.mMinPt2V0", 0.5, "mMinPt2V0"}; // minimum pT^2 of V0 - Configurable mMaxTgl2V0{"dcaFitterEMSel.mMaxTgl2V0", 4, "mMaxTgl2V0"}; // maximum tgLambda^2 of V0 - Configurable mMaxDCAXY2ToMeanVertex3bodyV0{"dcaFitterEMSel.mMaxDCAXY2ToMeanVertex3bodyV0", 4, "mMaxDCAXY2ToMeanVertex3bodyV0"}; // max DCA^2 of 2 body decay to mean vertex of 3 body decay in XY - Configurable minCosPAXYMeanVertex3bodyV0{"dcaFitterEMSel.minCosPAXYMeanVertex3bodyV0", 0.9, "minCosPAXYMeanVertex3bodyV0"}; // min CosPA of 2 body decay to mean vertex of 3 body decay in XY - Configurable minCosPA3bodyV0{"dcaFitterEMSel.minCosPA3bodyV0", 0.8, "minCosPA3bodyV0"}; // min CosPA of 3 body decay to PV - Configurable maxRDiffV03body{"dcaFitterEMSel.maxRDiffV03body", 3, "maxRDiffV03body"}; // Maximum difference between virtual V0 and 3body radius - Configurable minPt3Body = {"dcaFitterEMSel.minPt3Body", 0.01, ""}; // minimum pT of 3body Vertex - Configurable maxTgl3Body = {"dcaFitterEMSel.maxTgl3Body", 2, ""}; // maximum tgLambda of 3body Vertex - Configurable maxDCAXY3Body{"dcaFitterEMSel.maxDCAXY3Body", 0.5, "DCAXY H3L to PV"}; // max DCA of 3 body decay to PV in XY - Configurable maxDCAZ3Body{"dcaFitterEMSel.maxDCAZ3Body", 1.0, "DCAZ H3L to PV"}; // max DCA of 3 body decay to PV in Z - // Binning for mixing events - ConfigurableAxis binsVtxZ{"dcaFitterEMSel.binsVtxZ", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis binsMultiplicity{"dcaFitterEMSel.binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 1.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Mixing bins - multiplicity"}; - Configurable maxDeltaRadiusColMixing{"dcaFitterEMSel.maxDeltaRadiusColMixing", 2., "max difference between pv z position in case of collision mixing"}; - Configurable maxDeltaPhiColMixing{"dcaFitterEMSel.maxDeltaPhiColMixing", 30., "max difference between Phi of monther particle in case of collision mixing (degree)"}; - // Configurations for mixing decay3bodys - // Configurable cfgUseDCAFitterInfo{"dcaFitterEMSel.cfgUseDCAFitterInfo", true, ""}; // if use information from dcatFitter while mixing reduced 3bodys - Configurable cfgMix3BodyMethod{"dcaFitterEMSel.cfgMix3BodyMethod", 0, ""}; // 0: bachelor, 1: pion, 2: proton - Configurable cfgApplyV0Cut{"dcaFitterEMSel.cfgApplyV0Cut", true, "if apply V0 cut while performing event-mixing"}; - ConfigurableAxis bins3BodyRadius{"dcaFitterEMSel.bins3BodyRadius", {VARIABLE_WIDTH, 0.0f, 2.0f, 4.0f, 7.0f, 10.0f, 14.0f, 18.0f, 22.0f, 30.0f, 40.0f}, "Mixing bins - 3body radius"}; - ConfigurableAxis bins3BodyPhi{"dcaFitterEMSel.bins3BodyPhi", {VARIABLE_WIDTH, -3.15, -2.15, -1, 0, 1, 2.15, 3.15}, "Mixing bins - 3body phi"}; - ConfigurableAxis bins3BodyPhiDegree{"dcaFitterEMSel.bins3BodyPhiDegree", {VARIABLE_WIDTH, -180, -120, -60, 0, 60, 120, 180}, "Mixing bins - 3body phi"}; - ConfigurableAxis bins3BodyPosZ{"dcaFitterEMSel.bins3BodyPosZ", {VARIABLE_WIDTH, -500.0f, -200.0f, -100.0f, -70.0f, -60.0f, -50.0f, -40.0f, -35.0f, -30.0f, -25.0f, -20.0f, -15.0f, -13.0f, -10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 13.0f, 15.0f, 20.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f, 60.0f, 70.0f, 100.0f, 200.0f, 500.0f}, "3body SV z position"}; - Configurable selectPVPosZ3bodyMixing{"dcaFitterEMSel.selectPVPosZ3bodyMixing", true, "Select same pvPosZ events in case of 3body mixing"}; - Configurable maxDeltaPVPosZ3bodyMixing{"dcaFitterEMSel.maxDeltaPVPosZ3bodyMixing", 1., "max difference between pv z position in case of 3body mixing"}; - } dcaFitterEMSel; - - SliceCache cache; - using BinningTypeColEM = ColumnBinningPolicy; - using Binning3BodyDCAFitter = ColumnBinningPolicy; - using Binning3BodyKFInfo = ColumnBinningPolicy; - - // KF event mixing - using BinningTypeKF = ColumnBinningPolicy; + std::string prefix = "decay3bodyBuilderOpts"; + // building options + Configurable useKFParticle{"useKFParticle", false, "Use KFParticle for decay3body building"}; + Configurable kfSetTopologicalConstraint{"kfSetTopologicalConstraint", false, "Set topological vertex constraint in case of KFParticle reconstruction"}; + Configurable useSelections{"useSelections", true, "Apply selections during decay3body building"}; + Configurable useTPCforPion{"useTPCforPion", false, "Flag to ask for TPC info for pion track (PID, nClusters), false: pion track can be ITS only"}; + Configurable acceptTPCOnly{"acceptTPCOnly", false, "Accept TPC only tracks as daughters"}; + Configurable calculateCovariance{"calculateCovariance", true, "Calculate candidate and daughter covariance matrices"}; + // daughter track selections + Configurable maxEtaDaughters{"maxEtaDaughters", 0.9, "Max eta of daughters"}; + Configurable minTPCNClProton{"minTPCNClProton", 90, "Min TPC NClusters of proton daughter"}; + Configurable minTPCNClPion{"minTPCNClPion", 70, "Min TPC NClusters of pion daughter"}; + Configurable minTPCNClDeuteron{"minTPCNClDeuteron", 100, "Min TPC NClusters of deuteron daughter"}; + Configurable minDCAProtonToPV{"minDCAProtonToPV", 0.1, "Min DCA of proton to PV"}; + Configurable minDCAPionToPV{"minDCAPionToPV", 0.1, "Min DCA of pion to PV"}; + Configurable minDCADeuteronToPV{"minDCADeuteronToPV", 0.1, "Min DCA of deuteron to PV"}; + Configurable minPtProton{"minPtProton", 0.3, "Min Pt of proton daughter"}; + Configurable minPtPion{"minPtPion", 0.1, "Min Pt of pion daughter"}; + Configurable minPtDeuteron{"minPtDeuteron", 0.6, "Min Pt of deuteron daughter"}; + Configurable maxPtProton{"maxPtProton", 5.0, "Max Pt of proton daughter"}; + Configurable maxPtPion{"maxPtPion", 1.2, "Max Pt of pion daughter"}; + Configurable maxPtDeuteron{"maxPtDeuteron", 10.0, "Max Pt of deuteron daughter"}; + Configurable maxTPCnSigma{"maxTPCnSigma", 5.0, "Min/max TPC nSigma of daughter tracks"}; + Configurable minTOFnSigmaDeuteron{"minTOFnSigmaDeuteron", -5.0, "Min TOF nSigma of deuteron daughter"}; + Configurable maxTOFnSigmaDeuteron{"maxTOFnSigmaDeuteron", 5.0, "Max TOF nSigma of deuteron daughter"}; + Configurable minPDeuteronUseTOF{"minPDeuteronUseTOF", 1.0, "Min P of deuteron to use TOF PID"}; + Configurable maxDCADauAtSV{"maxDCADauAtSV", 0.5, "Max DCA of daughters at SV (quadratic sum of daughter DCAs between each other)"}; + // candidate selections + Configurable maxRapidity{"maxRapidity", 1.0, "Max rapidity of decay3body vertex"}; + Configurable minPt{"minPt", 2.0, "Min Pt of decay3body candidate"}; + Configurable maxPt{"maxPt", 5.0, "Max Pt of decay3body candidate"}; + Configurable minMass{"minMass", 2.96, "Min mass of decay3body candidate"}; + Configurable maxMass{"maxMass", 3.04, "Max mass of decay3body candidate"}; + Configurable minCtau{"minCtau", 0.0, "Min ctau of decay3body candidate"}; + Configurable maxCtau{"maxCtau", 100.0, "Max ctau of decay3body candidate"}; + Configurable minCosPA{"minCosPA", 0.9, "Min cosPA of decay3body candidate"}; + Configurable maxChi2{"maxChi2", 100.0, "Max chi2 of decay3body candidate"}; + } decay3bodyBuilderOpts; - // 3body mixing - // using Binning3Body = ColumnBinningPolicy; - using Binning3Body = ColumnBinningPolicy; + struct : ConfigurableGroup { + std::string prefix = "mixingOpts"; + Configurable n3bodyMixing{"n3bodyMixing", 0, "Number of decay3bodys to mix: 0 - value set to maximum bin entry in hDecay3BodyRadiusPhi, > 0 - manual setting"}; + Configurable mixingType{"mixingType", 0, "0: mix V0 from one event with bachelor from another, 1: mix pion and bachelor from one event with proton from another, 1: mix proton and bachelor from one event with pion from another "}; + ConfigurableAxis bins3BodyRadius{"mixingOpts.bins3BodyRadius", {VARIABLE_WIDTH, 0.0f, 2.0f, 4.0f, 7.0f, 10.0f, 14.0f, 18.0f, 22.0f, 30.0f, 40.0f}, "Mixing bins - 3body radius"}; + ConfigurableAxis bins3BodyPhi{"mixingOpts.bins3BodyPhi", {VARIABLE_WIDTH, -180 * TMath::Pi() / 180, -120 * TMath::Pi() / 180, -60 * TMath::Pi() / 180, 0, 60 * TMath::Pi() / 180, 120 * TMath::Pi() / 180, 180 * TMath::Pi() / 180}, "Mixing bins - 3body phi (rad)"}; + ConfigurableAxis bins3BodyPhiDegree{"mixingOpts.bins3BodyPhiDegree", {VARIABLE_WIDTH, -180, -120, -60, 0, 60, 120, 180}, "Mixing bins - 3body phi (degree)"}; + ConfigurableAxis bins3BodyPosZ{"mixingOpts.bins3BodyPosZ", {VARIABLE_WIDTH, -500.0f, -200.0f, -100.0f, -70.0f, -60.0f, -50.0f, -40.0f, -35.0f, -30.0f, -25.0f, -20.0f, -15.0f, -13.0f, -10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 13.0f, 15.0f, 20.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f, 60.0f, 70.0f, 100.0f, 200.0f, 500.0f}, "3body SV z position"}; + Configurable selectPVPosZ3bodyMixing{"selectPVPosZ3bodyMixing", true, "Select same pvPosZ events in case of 3body mixing"}; + Configurable maxDeltaPVPosZ3bodyMixing{"maxDeltaPVPosZ3bodyMixing", 1., "max difference between PV z position in case of 3body mixing"}; + // SVertexer selections + Configurable minPt2V0{"minPt2V0", 0.5, "Min Pt squared of V0"}; + Configurable maxTgl2V0{"maxTgl2V0", 4, "Max tgl squared of V0"}; + Configurable maxDCAXY2ToMeanVertex3bodyV0{"maxDCAXY2ToMeanVertex3bodyV0", 4, "Max DCA XY squared of V0 to mean vertex"}; + Configurable minCosPAXYMeanVertex3bodyV0{"minCosPAXYMeanVertex3bodyV0", 0.9, "Min cosPA XY of V0 to mean vertex"}; + Configurable minCosPA3bodyV0{"minCosPA3bodyV0", 0.8, "Min cosPA of V0"}; + Configurable maxRDiffV03body{"maxRDiffV03body", 3, "Max RDiff of V0 to 3body"}; + Configurable minPt3Body{"minPt3Body", 0.5, "Min Pt of 3body"}; + Configurable maxTgl3Body{"maxTgl3Body", 0.01, "Max tgl of 3body"}; + Configurable maxDCAXY3Body{"maxDCAXY3Body", 0.5, "Max DCA XY of 3body"}; + Configurable maxDCAZ3Body{"maxDCAZ3Body", 1.0, "Max DCA Z of 3body"}; + } mixingOpts; - // Filters and slices - Preslice perCollision = o2::aod::decay3body::collisionId; - Preslice perReducedCollision = o2::aod::reduceddecay3body::collisionId; + struct : ConfigurableGroup { + std::string prefix = "tofPIDOpts"; + Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; + Configurable paramFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; + Configurable parametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; + Configurable passName{"passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; + Configurable timeShiftCCDBPath{"timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; + Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; + Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; + } tofPIDOpts; + + // Helper struct to contain MC information prior to filling + struct mc3Bodyinfo { + int label; + std::array genDecVtx{0.f}; + std::array genMomentum{0.f}; + float genCt; + float genPhi; + float genEta; + float genRapidity; + float genMomProton; + float genMomPion; + float genMomDeuteron; + float genPtProton; + float genPtPion; + float genPtDeuteron; + bool isTrueH3L; + bool isTrueAntiH3L; + bool isReco; + int daughterPrPdgCode; + int daughterPiPdgCode; + int daughterDePdgCode; + bool isDeuteronPrimary; + bool survivedEventSel; + }; + mc3Bodyinfo this3BodyMCInfo; + // CCDB and magnetic field int mRunNumber; float d_bz; - float maxSnp; // max sine phi for propagation - float maxStep; // max step size (cm) for propagation + Service ccdb; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + std::unordered_map ccdbCache; // Maps runNumber -> d_bz o2::base::MatLayerCylSet* lut = nullptr; - o2::vertexing::DCAFitterN<2> fitterV0; - o2::vertexing::DCAFitterN<3> fitter3body; + + // histogram registry + HistogramRegistry registry{"Registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // bachelor TOF PID + o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; // to be updated in Init based on the hypothesis + o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPIDLabeled; // to be updated in Init based on the hypothesis o2::pid::tof::TOFResoParamsV2 mRespParamsV2; - std::array mV0Hyps; // 0 - Lambda, 1 - AntiLambda - bool doUpdateGRPMagField = false; // if initialize magnetic field for each bc - o2::dataformats::VertexBase mMeanVertex{{0., 0., 0.}, {0.1 * 0.1, 0., 0.1 * 0.1, 0., 0., 6. * 6.}}; + + // 3body mixing + using Binning3BodyKF = ColumnBinningPolicy; + using Binning3BodyDCAfitter = ColumnBinningPolicy; + + // skimmed processing + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + + // tracked cluster size + std::vector fTrackedClSizeVector; + + // MC info + std::vector isGoodCollision; void init(InitContext&) { @@ -379,276 +273,238 @@ struct decay3bodyBuilder { mRunNumber = 0; d_bz = 0; - maxSnp = 0.85f; // could be changed later - maxStep = 2.00f; // could be changed later - - // set hypothesis corresponds to Hyp3Body, tpcpid to be implemented - switch (motherhyp) { - case Hyp3Body::kH3L: - bachelorcharge = 1; - bachelorTOFPID.SetPidType(o2::track::PID::Deuteron); - break; - case Hyp3Body::kH4L: - bachelorcharge = 1; - bachelorTOFPID.SetPidType(o2::track::PID::Triton); - break; - case Hyp3Body::kHe4L: - bachelorcharge = 2; - bachelorTOFPID.SetPidType(o2::track::PID::Helium3); - break; - case Hyp3Body::kHe5L: - bachelorcharge = 2; - bachelorTOFPID.SetPidType(o2::track::PID::Alpha); - break; - default: - LOG(fatal) << "Wrong hypothesis for decay3body"; - return; - } - fitterV0.setPropagateToPCA(true); - fitterV0.setMaxR(200.); - fitterV0.setMinParamChange(1e-3); - fitterV0.setMinRelChi2Change(0.9); - fitterV0.setMaxDZIni(1e9); - fitterV0.setMaxChi2(1e9); - fitterV0.setUseAbsDCA(d_UseAbsDCA); - - fitter3body.setPropagateToPCA(true); - fitter3body.setMaxR(200.); //->maxRIni3body - fitter3body.setMinParamChange(1e-3); - fitter3body.setMinRelChi2Change(0.9); - fitter3body.setMaxDZIni(1e9); - fitter3body.setMaxChi2(1e9); - fitter3body.setUseAbsDCA(d_UseAbsDCA); - - // Material correction in the DCA fitter - ccdb->setURL(ccdburl); + mEnabledTables.resize(nTables, 0); + + // CCDB options + ccdb->setURL(ccdbConfigurations.ccdburl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); + // Set material correction if (useMatCorrType == 1) { LOGF(info, "TGeo correction requested, loading geometry"); if (!o2::base::GeometryManager::isGeometryLoaded()) { - ccdb->get(geoPath); + ccdb->get(ccdbConfigurations.geoPath); } + matCorr = o2::base::Propagator::MatCorrType::USEMatCorrTGeo; } if (useMatCorrType == 2) { LOGF(info, "LUT correction requested, loading LUT"); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); - } - - // Material correction in the DCA fitter - if (useMatCorrType == 1) - matCorr = o2::base::Propagator::MatCorrType::USEMatCorrTGeo; - if (useMatCorrType == 2) + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbConfigurations.lutPath)); matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - - fitterV0.setMatCorrType(matCorr); - fitter3body.setMatCorrType(matCorr); - - // Add histograms separately for different process functions - if (doprocessRun3 == true || doprocessRun3Reduced) { - registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{1, 0.0f, 1.0f}}); - } - - if (doprocessRun3 == true || doprocessRun3Reduced || doprocessRun3ReducedEM == true || doprocessRun3Reduced3bodyMixing == true || doprocessRun3Reduced3bodyMixingKFInfo == true) { - auto hVtx3BodyCounter = registry.add("hVtx3BodyCounter", "hVtx3BodyCounter", HistType::kTH1D, {{6, 0.0f, 6.0f}}); - hVtx3BodyCounter->GetXaxis()->SetBinLabel(1, "Total"); - hVtx3BodyCounter->GetXaxis()->SetBinLabel(2, "TPCNcls"); - hVtx3BodyCounter->GetXaxis()->SetBinLabel(3, "PIDCut"); - hVtx3BodyCounter->GetXaxis()->SetBinLabel(4, "HasSV"); - hVtx3BodyCounter->GetXaxis()->SetBinLabel(5, "DcaDau"); - hVtx3BodyCounter->GetXaxis()->SetBinLabel(6, "CosPA"); - registry.add("hBachelorTOFNSigmaDe", "", HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}); } - if (doprocessRun3ReducedEM == true) { - registry.add("hEventCount", "hEventCount", HistType::kTH2F, {dcaFitterEMSel.binsVtxZ, dcaFitterEMSel.binsMultiplicity}); - registry.add("hEventPairs", "hEventPairs", HistType::kTH2F, {dcaFitterEMSel.binsVtxZ, dcaFitterEMSel.binsMultiplicity}); - registry.add("hDecay3BodyPairsBeforeCut", "hDecay3BodyPairsBeforeCut", HistType::kTH2F, {dcaFitterEMSel.binsVtxZ, dcaFitterEMSel.binsMultiplicity}); - registry.add("hDecay3BodyPairsAfterCut", "hDecay3BodyPairsAfterCut", HistType::kTH2F, {dcaFitterEMSel.binsVtxZ, dcaFitterEMSel.binsMultiplicity}); - registry.add("hRadius0", "hRadius0", HistType::kTH1F, {{200, 0.0f, 20.0f, "Radius (cm)"}}); - registry.add("hRadius1", "hRadius1", HistType::kTH1F, {{200, 0.0f, 20.0f, "Radius (cm)"}}); - registry.add("hDeltaRadius", "hDeltaRadius", HistType::kTH1F, {{400, -20.0f, 20.0f, "#Delta Radius (cm)"}}); - registry.add("hPhi0", "hPhi0", HistType::kTH1F, {{360, -180.0f, 180.0f, "#phi (degree)"}}); - registry.add("hPhi1", "hPhi1", HistType::kTH1F, {{360, -180.0f, 180.0f, "#phi (degree)"}}); - registry.add("hDeltaPhi", "hDeltaPhi", HistType::kTH1F, {{360, -180.0f, 180.0f, "#Delta #phi (degree)"}}); + helper.fitterV0.setMatCorrType(matCorr); + helper.fitter3body.setMatCorrType(matCorr); + + // set bachelor PID + bachelorTOFPID.SetPidType(o2::track::PID::Deuteron); + bachelorTOFPIDLabeled.SetPidType(o2::track::PID::Deuteron); + + // set decay3body parameters in the helper + helper.decay3bodyselections.maxEtaDaughters = decay3bodyBuilderOpts.maxEtaDaughters; + helper.decay3bodyselections.minTPCNClProton = decay3bodyBuilderOpts.minTPCNClProton; + helper.decay3bodyselections.minTPCNClPion = decay3bodyBuilderOpts.minTPCNClPion; + helper.decay3bodyselections.minTPCNClDeuteron = decay3bodyBuilderOpts.minTPCNClDeuteron; + helper.decay3bodyselections.minDCAProtonToPV = decay3bodyBuilderOpts.minDCAProtonToPV; + helper.decay3bodyselections.minDCAPionToPV = decay3bodyBuilderOpts.minDCAPionToPV; + helper.decay3bodyselections.minDCADeuteronToPV = decay3bodyBuilderOpts.minDCADeuteronToPV; + helper.decay3bodyselections.minPtProton = decay3bodyBuilderOpts.minPtProton; + helper.decay3bodyselections.minPtPion = decay3bodyBuilderOpts.minPtPion; + helper.decay3bodyselections.minPtDeuteron = decay3bodyBuilderOpts.minPtDeuteron; + helper.decay3bodyselections.maxPtProton = decay3bodyBuilderOpts.maxPtProton; + helper.decay3bodyselections.maxPtPion = decay3bodyBuilderOpts.maxPtPion; + helper.decay3bodyselections.maxPtDeuteron = decay3bodyBuilderOpts.maxPtDeuteron; + helper.decay3bodyselections.maxTPCnSigma = decay3bodyBuilderOpts.maxTPCnSigma; + helper.decay3bodyselections.minTOFnSigmaDeuteron = decay3bodyBuilderOpts.minTOFnSigmaDeuteron; + helper.decay3bodyselections.maxTOFnSigmaDeuteron = decay3bodyBuilderOpts.maxTOFnSigmaDeuteron; + helper.decay3bodyselections.minPDeuteronUseTOF = decay3bodyBuilderOpts.minPDeuteronUseTOF; + helper.decay3bodyselections.maxDCADauAtSV = decay3bodyBuilderOpts.maxDCADauAtSV; + helper.decay3bodyselections.maxRapidity = decay3bodyBuilderOpts.maxRapidity; + helper.decay3bodyselections.minPt = decay3bodyBuilderOpts.minPt; + helper.decay3bodyselections.maxPt = decay3bodyBuilderOpts.maxPt; + helper.decay3bodyselections.minMass = decay3bodyBuilderOpts.minMass; + helper.decay3bodyselections.maxMass = decay3bodyBuilderOpts.maxMass; + helper.decay3bodyselections.minCtau = decay3bodyBuilderOpts.minCtau; + helper.decay3bodyselections.maxCtau = decay3bodyBuilderOpts.maxCtau; + helper.decay3bodyselections.minCosPA = decay3bodyBuilderOpts.minCosPA; + helper.decay3bodyselections.maxChi2 = decay3bodyBuilderOpts.maxChi2; + + // set SVertexer selection parameters in the helper + helper.svertexerselections.minPt2V0 = mixingOpts.minPt2V0; + helper.svertexerselections.maxTgl2V0 = mixingOpts.maxTgl2V0; + helper.svertexerselections.maxDCAXY2ToMeanVertex3bodyV0 = mixingOpts.maxDCAXY2ToMeanVertex3bodyV0; + helper.svertexerselections.minCosPAXYMeanVertex3bodyV0 = mixingOpts.minCosPAXYMeanVertex3bodyV0; + helper.svertexerselections.minCosPA3bodyV0 = mixingOpts.minCosPA3bodyV0; + helper.svertexerselections.maxRDiffV03body = mixingOpts.maxRDiffV03body; + helper.svertexerselections.minPt3Body = mixingOpts.minPt3Body; + helper.svertexerselections.maxTgl3Body = mixingOpts.maxTgl3Body; + helper.svertexerselections.maxDCAXY3Body = mixingOpts.maxDCAXY3Body; + helper.svertexerselections.maxDCAZ3Body = mixingOpts.maxDCAZ3Body; + + // list enabled process functions + LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"); + LOGF(info, " Decay3body builder: basic configuration listing"); + LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"); + + if (doprocessRealData) { + LOGF(info, " ===> process function enabled: processRealData"); + } + if (doprocessRealDataReduced) { + LOGF(info, " ===> process function enabled: processRealDataReduced"); + } + if (doprocessRealDataReduced3bodyMixing) { + LOGF(info, " ===> process function enabled: processRealDataReduced3bodyMixing"); + } + if (doprocessMonteCarlo) { + LOGF(info, " ===> process function enabled: processMonteCarlo"); + } + + // list enabled tables + for (int i = 0; i < nTables; i++) { + if (mEnabledTables[i]) { + LOGF(info, " -~> Table enabled: %s", tableNames[i]); + } + } + + // print base cuts + LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"); + LOGF(info, "-~> max daughter eta ..............: %f", decay3bodyBuilderOpts.maxEtaDaughters.value); + LOGF(info, "-~> min TPC ncls proton ...........: %i", decay3bodyBuilderOpts.minTPCNClProton.value); + LOGF(info, "-~> min TPC ncls pion .............: %i", decay3bodyBuilderOpts.minTPCNClPion.value); + LOGF(info, "-~> min TPC ncls bach .............: %i", decay3bodyBuilderOpts.minTPCNClDeuteron.value); + LOGF(info, "-~> min DCA proton to PV ..........: %f", decay3bodyBuilderOpts.minDCAProtonToPV.value); + LOGF(info, "-~> min DCA pion to PV ............: %f", decay3bodyBuilderOpts.minDCAPionToPV.value); + LOGF(info, "-~> min DCA bach to PV ............: %f", decay3bodyBuilderOpts.minDCADeuteronToPV.value); + LOGF(info, "-~> min pT proton .................: %f", decay3bodyBuilderOpts.minPtProton.value); + LOGF(info, "-~> min pT pion ...................: %f", decay3bodyBuilderOpts.minPtPion.value); + LOGF(info, "-~> min pT bach ...................: %f", decay3bodyBuilderOpts.minPtDeuteron.value); + LOGF(info, "-~> max pT proton .................: %f", decay3bodyBuilderOpts.maxPtProton.value); + LOGF(info, "-~> max pT pion ...................: %f", decay3bodyBuilderOpts.maxPtPion.value); + LOGF(info, "-~> max pT bach ...................: %f", decay3bodyBuilderOpts.maxPtDeuteron.value); + LOGF(info, "-~> max TPC nSigma ...............: %f", decay3bodyBuilderOpts.maxTPCnSigma.value); + LOGF(info, "-~> min TOF nSigma deuteron ......: %f", decay3bodyBuilderOpts.minTOFnSigmaDeuteron.value); + LOGF(info, "-~> max TOF nSigma deuteron ......: %f", decay3bodyBuilderOpts.maxTOFnSigmaDeuteron.value); + LOGF(info, "-~> min p bach use TOF ...........: %f", decay3bodyBuilderOpts.minPDeuteronUseTOF.value); + LOGF(info, "-~> max DCA dau at SV ............: %f", decay3bodyBuilderOpts.maxDCADauAtSV.value); + LOGF(info, "-~> max rapidity .................: %f", decay3bodyBuilderOpts.maxRapidity.value); + LOGF(info, "-~> min pT .......................: %f", decay3bodyBuilderOpts.minPt.value); + LOGF(info, "-~> max pT .......................: %f", decay3bodyBuilderOpts.maxPt.value); + LOGF(info, "-~> min mass .....................: %f", decay3bodyBuilderOpts.minMass.value); + LOGF(info, "-~> max mass .....................: %f", decay3bodyBuilderOpts.maxMass.value); + LOGF(info, "-~> min ctau .....................: %f", decay3bodyBuilderOpts.minCtau.value); + LOGF(info, "-~> max ctau .....................: %f", decay3bodyBuilderOpts.maxCtau.value); + LOGF(info, "-~> min cosPA ....................: %f", decay3bodyBuilderOpts.minCosPA.value); + LOGF(info, "-~> max chi2 .....................: %f", decay3bodyBuilderOpts.maxChi2.value); + LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"); + + // bookkeeping histograms + auto h = registry.add("Counters/hTableBuildingStatistics", "hTableBuildingStatistics", kTH1D, {{nTablesConst, -0.5f, static_cast(nTablesConst)}}); + auto h2 = registry.add("Counters/hInputStatistics", "hInputStatistics", kTH1D, {{nTablesConst, -0.5f, static_cast(nTablesConst)}}); + h2->SetTitle("Input table sizes"); + + // configure tables to generate + for (int i = 0; i < nTables; i++) { + h->GetXaxis()->SetBinLabel(i + 1, tableNames[i].c_str()); + h2->GetXaxis()->SetBinLabel(i + 1, tableNames[i].c_str()); + h->SetBinContent(i + 1, 0); // mark all as disabled to start + + int f = enabledTables->get(tableNames[i].c_str(), "enable"); + if (f == 1) { + mEnabledTables[i] = 1; + h->SetBinContent(i + 1, 1); // mark enabled + } + } + + if (mEnabledTables[kVtx3BodyDatas] && mEnabledTables[kMcVtx3BodyDatas]) { + LOG(fatal) << "Tables Vtx3BodyDatas and McVtx3BodyDatas cannot both be enabled at the same time. Choose one!"; } - if (doprocessRun3Reduced3bodyMixing == true || doprocessRun3Reduced3bodyMixingKFInfo == true) { - registry.add("hDecay3BodyRadiusPhi", "hDecay3BodyRadiusPhi", HistType::kTH2F, {dcaFitterEMSel.bins3BodyRadius, dcaFitterEMSel.bins3BodyPhi}); - registry.add("hDecay3BodyPosZ", "hDecay3BodyPosZ", HistType::kTH1F, {dcaFitterEMSel.bins3BodyPosZ}); - auto h3bodyCombinationCounter = registry.add("h3bodyCombinationCounter", "h3bodyCombinationCounter", HistType::kTH1D, {{4, 0.0f, 4.0f}}); - h3bodyCombinationCounter->GetXaxis()->SetBinLabel(1, "total"); - h3bodyCombinationCounter->GetXaxis()->SetBinLabel(2, "bach sign/ID"); - h3bodyCombinationCounter->GetXaxis()->SetBinLabel(3, "not same collision"); - h3bodyCombinationCounter->GetXaxis()->SetBinLabel(4, "collision VtxZ"); - } - - if (doprocessRun3ReducedEM == true || doprocessRun3Reduced3bodyMixing == true || doprocessRun3Reduced3bodyMixingKFInfo == true) { - doUpdateGRPMagField = true; - registry.add("h3bodyEMCutCounter", "h3bodyEMCutCounter", HistType::kTH1D, {{14, 0.0f, 14.0f}}); - } - - if (doprocessRun3withKFParticle == true || doprocessRun3withKFParticleStrangenessTracking == true || doprocessRun3withKFParticleReduced == true || doprocessRun3withKFParticleReducedEM == true || doprocessRun3withKFParticleReduced3bodyMixing == true) { - auto hEventCounterZorro = registry.add("Counters/hEventCounterZorro", "hEventCounterZorro", HistType::kTH1D, {{2, -0.5, 1.5}}); - hEventCounterZorro->GetXaxis()->SetBinLabel(1, "Zorro before evsel"); - hEventCounterZorro->GetXaxis()->SetBinLabel(2, "Zorro after evsel"); - auto hEventCounterKFParticle = registry.add("Counters/hEventCounterKFParticle", "hEventCounterKFParticle", HistType::kTH1D, {{4, 0.0f, 4.0f}}); - hEventCounterKFParticle->GetXaxis()->SetBinLabel(1, "total"); - hEventCounterKFParticle->GetXaxis()->SetBinLabel(2, "sel8"); - hEventCounterKFParticle->GetXaxis()->SetBinLabel(3, "vertexZ"); - hEventCounterKFParticle->GetXaxis()->SetBinLabel(4, "has candidate"); - hEventCounterKFParticle->LabelsOption("v"); - auto hVtx3BodyCounterKFParticle = registry.add("Counters/hVtx3BodyCounterKFParticle", "hVtx3BodyCounterKFParticle", HistType::kTH1D, {{21, 0.0f, 21.0f}}); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(1, "Total"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(2, "Charge"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(3, "Eta"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(4, "TPCNcls"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(5, "TPCRows"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(6, "TPCpid"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(7, "DCAxyPV"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(8, "DCAzPV"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(9, "V0MassConst"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(10, "HasSV"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(11, "DcaDau"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(12, "DCADauVtx"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(13, "DauPt"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(14, "Rapidity"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(15, "Pt"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(16, "Mass"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(17, "CosPA"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(18, "CosPAXY"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(19, "Chi2geo"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(20, "TopoConstr"); - hVtx3BodyCounterKFParticle->GetXaxis()->SetBinLabel(21, "Chi2topo"); - hVtx3BodyCounterKFParticle->LabelsOption("v"); - - registry.add("QA/Tracks/hTrackPosTPCNcls", "hTrackPosTPCNcls", HistType::kTH1F, {{152, 0, 152, "# TPC clusters"}}); - registry.add("QA/Tracks/hTrackNegTPCNcls", "hTrackNegTPCNcls", HistType::kTH1F, {{152, 0, 152, "# TPC clusters"}}); - registry.add("QA/Tracks/hTrackBachTPCNcls", "hTrackBachTPCNcls", HistType::kTH1F, {{152, 0, 152, "# TPC clusters"}}); - registry.add("QA/Tracks/hTrackPosHasTPC", "hTrackPosHasTPC", HistType::kTH1F, {{2, -0.5, 1.5, "has TPC"}}); - registry.add("QA/Tracks/hTrackNegHasTPC", "hTrackNegHasTPC", HistType::kTH1F, {{2, -0.5, 1.5, "has TPC"}}); - registry.add("QA/Tracks/hTrackBachHasTPC", "hTrackBachHasTPC", HistType::kTH1F, {{2, -0.5, 1.5, "has TPC"}}); - registry.add("QA/Tracks/hTrackBachITSClusSizes", "hTrackBachITSClusSizes", HistType::kTH1F, {{10, 0., 10., "ITS cluster sizes"}}); - registry.add("QA/Tracks/hTrackProtonTPCPID", "hTrackProtonTPCPID", HistType::kTH2F, {{100, -10.0f, 10.0f, "p/z (GeV/c)"}, {100, -10.0f, 10.0f, "TPC n#sigma"}}); - registry.add("QA/Tracks/hTrackPionTPCPID", "hTrackPionTPCPID", HistType::kTH2F, {{100, -10.0f, 10.0f, "p/z (GeV/c)"}, {100, -10.0f, 10.0f, "TPC n#sigma"}}); - registry.add("QA/Tracks/hTrackBachTPCPID", "hTrackBachTPCPID", HistType::kTH2F, {{100, -10.0f, 10.0f, "p/z (GeV/c)"}, {100, -10.0f, 10.0f, "TPC n#sigma"}}); - registry.add("QA/Tracks/hTrackProtonPt", "hTrackProtonPt", HistType::kTH1F, {{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}); - registry.add("QA/Tracks/hTrackPionPt", "hTrackPionPt", HistType::kTH1F, {{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}); - registry.add("QA/Tracks/hTrackBachPt", "hTrackBachPt", HistType::kTH1F, {{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}); - registry.add("QA/Event/hAllSelEventsVtxZ", "hAllSelEventsVtxZ", HistType::kTH1F, {{500, -15.0f, 15.0f, "PV Z (cm)"}}); - registry.add("QA/Event/hVtxXKF", "hVtxXKF", HistType::kTH1F, {{500, -0.1f, 0.1f, "PV X (cm)"}}); - registry.add("QA/Event/hVtxYKF", "hVtxYKF", HistType::kTH1F, {{500, -0.1f, 0.1f, "PV Y (cm)"}}); - registry.add("QA/Event/hVtxZKF", "hVtxZKF", HistType::kTH1F, {{500, -15.0f, 15.0f, "PV Z (cm)"}}); - registry.add("QA/Event/hVtxCovXXKF", "hVtxCovXXKF", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XX) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovYYKF", "hVtxCovYYKF", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(YY) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovZZKF", "hVtxCovZZKF", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(ZZ) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovXYKF", "hVtxCovXYKF", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XY) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovXZKF", "hVtxCovXZKF", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XZ) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovYZKF", "hVtxCovYZKF", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(YZ) (cm^{2})"}}); - registry.add("QA/Event/hVtxX", "hVtxX", HistType::kTH1F, {{500, -0.1f, 0.1f, "PV X (cm)"}}); - registry.add("QA/Event/hVtxY", "hVtxY", HistType::kTH1F, {{500, -0.1f, 0.1f, "PV Y (cm)"}}); - registry.add("QA/Event/hVtxZ", "hVtxZ", HistType::kTH1F, {{500, -15.0f, 15.0f, "PV Z (cm)"}}); - registry.add("QA/Event/hVtxCovXX", "hVtxCovXX", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XX) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovYY", "hVtxCovYY", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(YY) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovZZ", "hVtxCovZZ", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(ZZ) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovXY", "hVtxCovXY", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XY) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovXZ", "hVtxCovXZ", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XZ) (cm^{2})"}}); - registry.add("QA/Event/hVtxCovYZ", "hVtxCovYZ", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(YZ) (cm^{2})"}}); - } - - if (doprocessRun3withKFParticleReducedEM == true) { - registry.add("QA/EM/hPairCounterMixing", "hPairCounterMixing", HistType::kTH1D, {{1, 0.0f, 1.0f}}); - auto hCombinationCounterMixing = registry.add("QA/EM/hCombinationCounterMixing", "hCombinationCounterMixing", HistType::kTH1D, {{3, 0.0f, 3.0f}}); - hCombinationCounterMixing->GetXaxis()->SetBinLabel(1, "total"); - hCombinationCounterMixing->GetXaxis()->SetBinLabel(2, "bach sign/ID"); - hCombinationCounterMixing->GetXaxis()->SetBinLabel(3, "radius, phi"); - hCombinationCounterMixing->LabelsOption("v"); - - registry.add("QA/EM/hEventBinCounts", "hEventBinCounts", HistType::kTH2D, {{10, 0, 10, "bins VtxZ"}, {13, 0, 13, "bins mult"}}); - registry.add("QA/EM/h3bodyBinCounts", "h3bodyBinCounts", HistType::kTH2D, {{10, 0, 10, "bins VtxZ"}, {13, 0, 13, "bins mult"}}); - registry.add("QA/EM/hPairBinCounts", "hPairBinCounts", HistType::kTH2D, {{10, 0, 10, "bins VtxZ"}, {13, 0, 13, "bins mult"}}); - - registry.add("QA/EM/hRadius1", "hRadius1", HistType::kTH1F, {{200, 0.0f, 20.0f, "Radius (cm)"}}); - registry.add("QA/EM/hRadius2", "hRadius2", HistType::kTH1F, {{200, 0.0f, 20.0f, "Radius (cm)"}}); - registry.add("QA/EM/hPhi1", "hPhi1", HistType::kTH1F, {{360, 0.0f, 360.0f, "#phi (degree)"}}); - registry.add("QA/EM/hPhi2", "hPhi2", HistType::kTH1F, {{360, 0.0f, 360.0f, "#phi (degree)"}}); - registry.add("QA/EM/hDeltaRadius", "hDeltaRadius", HistType::kTH1F, {{200, 0.0f, 10.0f, "#Delta Radius (cm)"}}); - registry.add("QA/EM/hDeltaPhi", "hDeltaPhi", HistType::kTH1F, {{360, 0.0f, 360.0f, "#Delta #phi (degree)"}}); - } - - if (doprocessRun3withKFParticleReduced3bodyMixing == true) { - auto h3bodyCombinationCounter = registry.add("QA/EM/h3bodyCombinationCounter", "h3bodyCombinationCounter", HistType::kTH1D, {{4, 0.0f, 4.0f}}); + // Add histograms separately for different process functions + if (doprocessRealData == true || doprocessMonteCarlo == true) { + auto hEventCounter = registry.add("Counters/hEventCounter", "hEventCounter", HistType::kTH1D, {{3, 0.0f, 3.0f}}); + hEventCounter->GetXaxis()->SetBinLabel(1, "total"); + hEventCounter->GetXaxis()->SetBinLabel(2, "sel8"); + hEventCounter->GetXaxis()->SetBinLabel(3, "vertexZ"); + hEventCounter->LabelsOption("v"); + } + + if (doprocessRealData == true || doprocessRealDataReduced == true || doprocessMonteCarlo == true) { + if (doTrackQA) { // histograms for all daughter tracks of (selected) 3body candidates + registry.add("QA/Tracks/hTrackProtonTPCNcls", "hTrackProtonTPCNcls", HistType::kTH1F, {{152, 0, 152, "# TPC clusters"}}); + registry.add("QA/Tracks/hTrackPionTPCNcls", "hTrackPionTPCNcls", HistType::kTH1F, {{152, 0, 152, "# TPC clusters"}}); + registry.add("QA/Tracks/hTrackDeuteronTPCNcls", "hTrackDeuteronTPCNcls", HistType::kTH1F, {{152, 0, 152, "# TPC clusters"}}); + registry.add("QA/Tracks/hTrackProtonHasTPC", "hTrackProtonHasTPC", HistType::kTH1F, {{2, -0.5, 1.5, "has TPC"}}); + registry.add("QA/Tracks/hTrackPionHasTPC", "hTrackPionHasTPC", HistType::kTH1F, {{2, -0.5, 1.5, "has TPC"}}); + registry.add("QA/Tracks/hTrackDeuteronHasTPC", "hTrackDeuteronHasTPC", HistType::kTH1F, {{2, -0.5, 1.5, "has TPC"}}); + registry.add("QA/Tracks/hTrackDeuteronITSClusSizes", "hTrackDeuteronITSClusSizes", HistType::kTH1F, {{10, 0., 10., "ITS cluster sizes"}}); + registry.add("QA/Tracks/hTrackProtonTPCPID", "hTrackProtonTPCPID", HistType::kTH2F, {{100, -10.0f, 10.0f, "p/z (GeV/c)"}, {100, -10.0f, 10.0f, "TPC n#sigma"}}); + registry.add("QA/Tracks/hTrackPionTPCPID", "hTrackPionTPCPID", HistType::kTH2F, {{100, -10.0f, 10.0f, "p/z (GeV/c)"}, {100, -10.0f, 10.0f, "TPC n#sigma"}}); + registry.add("QA/Tracks/hTrackDeuteronTPCPID", "hTrackDeuteronTPCPID", HistType::kTH2F, {{100, -10.0f, 10.0f, "p/z (GeV/c)"}, {100, -10.0f, 10.0f, "TPC n#sigma"}}); + registry.add("QA/Tracks/hTrackProtonPt", "hTrackProtonPt", HistType::kTH1F, {{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}); + registry.add("QA/Tracks/hTrackPionPt", "hTrackPionPt", HistType::kTH1F, {{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}); + registry.add("QA/Tracks/hTrackDeuteronPt", "hTrackDeuteronPt", HistType::kTH1F, {{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}); + } + if (doVertexQA) { + registry.add("QA/Event/hAllSelEventsVtxZ", "hAllSelEventsVtxZ", HistType::kTH1F, {{500, -15.0f, 15.0f, "PV Z (cm)"}}); + registry.add("QA/Event/hVtxX", "hVtxX", HistType::kTH1F, {{500, -0.1f, 0.1f, "PV X (cm)"}}); + registry.add("QA/Event/hVtxY", "hVtxY", HistType::kTH1F, {{500, -0.1f, 0.1f, "PV Y (cm)"}}); + registry.add("QA/Event/hVtxZ", "hVtxZ", HistType::kTH1F, {{500, -15.0f, 15.0f, "PV Z (cm)"}}); + registry.add("QA/Event/hVtxCovXX", "hVtxCovXX", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XX) (cm^{2})"}}); + registry.add("QA/Event/hVtxCovYY", "hVtxCovYY", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(YY) (cm^{2})"}}); + registry.add("QA/Event/hVtxCovZZ", "hVtxCovZZ", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(ZZ) (cm^{2})"}}); + registry.add("QA/Event/hVtxCovXY", "hVtxCovXY", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XY) (cm^{2})"}}); + registry.add("QA/Event/hVtxCovXZ", "hVtxCovXZ", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(XZ) (cm^{2})"}}); + registry.add("QA/Event/hVtxCovYZ", "hVtxCovYZ", HistType::kTH1F, {{200, -0.0001f, 0.0001f, "PV cov(YZ) (cm^{2})"}}); + } + } + + if (doprocessRealDataReduced3bodyMixing == true) { + auto h3bodyCombinationCounter = registry.add("Mixing/h3bodyCombinationCounter", "h3bodyCombinationCounter", HistType::kTH1D, {{4, 0.0f, 4.0f}}); h3bodyCombinationCounter->GetXaxis()->SetBinLabel(1, "total"); h3bodyCombinationCounter->GetXaxis()->SetBinLabel(2, "not same collision"); h3bodyCombinationCounter->GetXaxis()->SetBinLabel(3, "collision VtxZ"); h3bodyCombinationCounter->GetXaxis()->SetBinLabel(4, "bach sign/ID"); h3bodyCombinationCounter->LabelsOption("v"); - // registry.add("QA/EM/h3bodyBinCounts", "h3bodyBinCounts", HistType::kTH3D, {{16, 0, 16, "bins radius"}, {36, 0, 36, "bins phi"}, {12, 0, 12, "bins pos Z"}}); - registry.add("QA/EM/h3bodyBinCounts", "h3bodyBinCounts", HistType::kTH2D, {{16, 0, 16, "bins radius"}, {18, 0, 18, "bins phi"}}); - - AxisSpec radiusAxis = {kfparticleConfigurations.bins3BodyRadius, "Radius (cm)"}; - AxisSpec phiAxis = {kfparticleConfigurations.bins3BodyPhi, "#phi (degree)"}; - AxisSpec posZAxis = {kfparticleConfigurations.bins3BodyPosZ, "position in z (cm)"}; - - registry.add("QA/EM/hRadius", "hRadius", HistType::kTH1F, {radiusAxis}); - registry.add("QA/EM/hPhi", "hPhi", HistType::kTH1F, {phiAxis}); - registry.add("QA/EM/hPosZ", "hPosZ", HistType::kTH1F, {posZAxis}); + registry.add("Mixing/hDecay3BodyRadiusPhi", "hDecay3BodyRadiusPhi", HistType::kTH2F, {mixingOpts.bins3BodyRadius, mixingOpts.bins3BodyPhi}); + registry.add("Mixing/hDecay3BodyPosZ", "hDecay3BodyPosZ", HistType::kTH1F, {mixingOpts.bins3BodyPosZ}); } } - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + template + bool initCCDB(aod::BCsWithTimestamps const& bcs, TCollisions const& collisions) { - if (mRunNumber == bc.runNumber()) { - return; + auto bc = collisions.size() ? collisions.begin().template bc_as() : bcs.begin(); + if (!bcs.size()) { + LOGF(warn, "No BC found, skipping this DF."); + return false; // signal to skip this DF } - if (kfparticleConfigurations.cfgSkimmedProcessing) { - zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), kfparticleConfigurations.triggerList); - zorro.populateHistRegistry(registry, bc.runNumber()); + + if (mRunNumber == bc.runNumber()) { + return true; } - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - fitterV0.setBz(d_bz); - fitter3body.setBz(d_bz); -#ifdef HomogeneousField - KFParticle::SetField(d_bz); -#endif - o2::parameters::GRPMagField grpmag; - if (std::fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = bc.runNumber(); - return; + if (doSkimmedProcessing) { + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), triggerList); + zorro.populateHistRegistry(registry, bc.runNumber()); } - auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + auto timestamp = bc.timestamp(); o2::parameters::GRPMagField* grpmag = 0x0; - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - // d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - d_bz = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } - mRunNumber = bc.runNumber(); - // Set magnetic field value once known - fitterV0.setBz(d_bz); - fitter3body.setBz(d_bz); + grpmag = ccdb->getForTimeStamp(ccdbConfigurations.grpmagPath, timestamp); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << ccdbConfigurations.grpmagPath << " of object GRPMagField for timestamp " << timestamp; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + // Fetch magnetic field from ccdb for current collision + auto d_bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << "Retrieved GRP for timestamp " << timestamp << " with magnetic field of " << d_bz << " kG"; + + // set magnetic field value for DCA fitter + helper.fitterV0.setBz(d_bz); + helper.fitter3body.setBz(d_bz); // Set magnetic field for KF vertexing #ifdef HomogeneousField KFParticle::SetField(d_bz); @@ -657,1853 +513,849 @@ struct decay3bodyBuilder { if (useMatCorrType == 2) { // setMatLUT only after magfield has been initalized // (setMatLUT has implicit and problematic init field call if not) + LOG(info) << "Loading material look-up table for timestamp: " << timestamp; + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->getForTimeStamp(ccdbConfigurations.lutPath, timestamp)); o2::base::Propagator::Instance()->setMatLUT(lut); } + // mark run as configured + mRunNumber = bc.runNumber(); + // Initial TOF PID Paras, copied from PIDTOF.h - timestamp.value = bc.timestamp(); - ccdb->setTimestamp(timestamp.value); + tofPIDOpts.timestamp.value = bc.timestamp(); + ccdb->setTimestamp(tofPIDOpts.timestamp.value); // Not later than now objects ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); // TODO: implement the automatic pass name detection from metadata - if (passName.value == "") { - passName.value = "unanchored"; // temporary default - LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << passName.value << "'"; + if (tofPIDOpts.passName.value == "") { + tofPIDOpts.passName.value = "unanchored"; // temporary default + LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << tofPIDOpts.passName.value << "'"; } - LOG(info) << "Using parameter collection, starting from pass '" << passName.value << "'"; + LOG(info) << "Using parameter collection, starting from pass '" << tofPIDOpts.passName.value << "'"; - const std::string fname = paramFileName.value; + const std::string fname = tofPIDOpts.paramFileName.value; if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << parametrizationPath.value; + LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << tofPIDOpts.parametrizationPath.value; if (1) { o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, parametrizationPath.value); + paramCollection.loadParamFromFile(fname, tofPIDOpts.parametrizationPath.value); LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV2, passName.value)) { - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + if (!paramCollection.retrieveParameters(mRespParamsV2, tofPIDOpts.passName.value)) { + if (tofPIDOpts.fatalOnPassNotAvailable) { + LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); } } else { - mRespParamsV2.setShiftParameters(paramCollection.getPars(passName.value)); + mRespParamsV2.setShiftParameters(paramCollection.getPars(tofPIDOpts.passName.value)); mRespParamsV2.printShiftParameters(); } } else { - mRespParamsV2.loadParamFromFile(fname.data(), parametrizationPath.value); + mRespParamsV2.loadParamFromFile(fname.data(), tofPIDOpts.parametrizationPath.value); } - } else if (loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << parametrizationPath.value << " for timestamp " << timestamp.value; - o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(parametrizationPath.value, timestamp.value); + } else if (tofPIDOpts.loadResponseFromCCDB) { // Loading it from CCDB + LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << tofPIDOpts.parametrizationPath.value << " for timestamp " << tofPIDOpts.timestamp.value; + o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(tofPIDOpts.parametrizationPath.value, tofPIDOpts.timestamp.value); paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV2, passName.value)) { // Attempt at loading the parameters with the pass defined - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + if (!paramCollection->retrieveParameters(mRespParamsV2, tofPIDOpts.passName.value)) { // Attempt at loading the parameters with the pass defined + if (tofPIDOpts.fatalOnPassNotAvailable) { + LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); } } else { // Pass is available, load non standard parameters - mRespParamsV2.setShiftParameters(paramCollection->getPars(passName.value)); + mRespParamsV2.setShiftParameters(paramCollection->getPars(tofPIDOpts.passName.value)); mRespParamsV2.printShiftParameters(); } } mRespParamsV2.print(); - if (timeShiftCCDBPath.value != "") { - if (timeShiftCCDBPath.value.find(".root") != std::string::npos) { - mRespParamsV2.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Pos", true); - mRespParamsV2.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Neg", false); + if (tofPIDOpts.timeShiftCCDBPath.value != "") { + if (tofPIDOpts.timeShiftCCDBPath.value.find(".root") != std::string::npos) { + mRespParamsV2.setTimeShiftParameters(tofPIDOpts.timeShiftCCDBPath.value, "gmean_Pos", true); + mRespParamsV2.setTimeShiftParameters(tofPIDOpts.timeShiftCCDBPath.value, "gmean_Neg", false); } else { - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/pos", timeShiftCCDBPath.value.c_str()), timestamp.value), true); - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/neg", timeShiftCCDBPath.value.c_str()), timestamp.value), false); + mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/pos", tofPIDOpts.timeShiftCCDBPath.value.c_str()), tofPIDOpts.timestamp.value), true); + mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/neg", tofPIDOpts.timeShiftCCDBPath.value.c_str()), tofPIDOpts.timestamp.value), false); } } bachelorTOFPID.SetParams(mRespParamsV2); + bachelorTOFPIDLabeled.SetParams(mRespParamsV2); + + return true; } - void initCCDBfromRunNumber(int runNumber) + float getMagFieldFromRunNumber(int runNumber) { - // set magnetic field only when run number changes - if (mRunNumber == runNumber) { - LOG(debug) << "CCDB initialized for run " << mRunNumber; - return; - } - mRunNumber = runNumber; // Update the last run number - + float magField; // Check if the CCDB data for this run is already cached if (ccdbCache.find(runNumber) != ccdbCache.end()) { LOG(debug) << "CCDB data already cached for run " << runNumber; - d_bz = ccdbCache[runNumber]; - if (doUpdateGRPMagField == true) { - o2::base::Propagator::initFieldFromGRP(grpMagCache[runNumber].get()); - } + magField = ccdbCache[runNumber]; + // if not, retrieve it from CCDB } else { - std::shared_ptr grpmag = std::make_shared(*ccdb->getForRun(grpmagPath, runNumber)); + std::shared_ptr grpmag = std::make_shared(*ccdb->getForRun(ccdbConfigurations.grpmagPath, runNumber)); if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for run number " << runNumber; + LOG(fatal) << "Got nullptr from CCDB for path " << ccdbConfigurations.grpmagPath << " of object GRPMagField and " << ccdbConfigurations.grpPath << " of object GRPObject for run number " << runNumber; } o2::base::Propagator::initFieldFromGRP(grpmag.get()); // Fetch magnetic field from ccdb for current collision - d_bz = o2::base::Propagator::Instance()->getNominalBz(); + magField = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << "Retrieved GRP for run number " << runNumber << " with magnetic field of " << d_bz << " kZG"; - ccdbCache[runNumber] = d_bz; - grpMagCache[runNumber] = grpmag; + // cache magnetic field info + ccdbCache[runNumber] = magField; + } + return magField; + } + + void initFittersWithMagField(int runNumber, float magField) + { + // set magnetic field only when run number changes + if (mRunNumber == runNumber) { + LOG(debug) << "CCDB initialized for run " << mRunNumber; + return; } + mRunNumber = runNumber; // Update the last run number + + // update propagator + o2::base::Propagator::Instance()->setNominalBz(magField); // Set magnetic field for KF vertexing #ifdef HomogeneousField - KFParticle::SetField(d_bz); + KFParticle::SetField(magField); #endif // Set field for DCAfitter - fitterV0.setBz(d_bz); - fitter3body.setBz(d_bz); - - mV0Hyps[0].set(o2::track::PID::Lambda, o2::track::PID::Proton, o2::track::PID::Pion, pidCutsLambda, d_bz); - mV0Hyps[1].set(o2::track::PID::Lambda, o2::track::PID::Pion, o2::track::PID::Proton, pidCutsLambda, d_bz); + helper.fitterV0.setBz(magField); + helper.fitter3body.setBz(magField); if (useMatCorrType == 2) { - // setMatLUT only after magfield has been initalized + // setMatLUT only after magfield has been initalized (setMatLUT has implicit and problematic init field call if not) o2::base::Propagator::Instance()->setMatLUT(lut); } - - // cache magnetic field info - ccdbCache[runNumber] = d_bz; } - //------------------------------------------------------------------ - //-------------------- DCA fitter reconstruction ------------------- - //------------------------------------------------------------------ - // Select decay3body candidate based on daughter track PID - template - bool checkPID(TTrack const& trackProton, TTrack const& trackPion, TTrack const& trackBachelor, const double& tofNSigmaBach) - { - if ((tofNSigmaBach < TofPidNsigmaMin || tofNSigmaBach > TofPidNsigmaMax) && trackBachelor.p() > minBachPUseTOF) { - return false; - } - if (std::abs(trackProton.tpcNSigmaPr()) > TpcPidNsigmaCut) { - return false; - } - if (std::abs(trackPion.tpcNSigmaPi()) > TpcPidNsigmaCut) { - return false; - } - return true; - } - // PID check for H3L - template - bool checkPIDH3L(TTrack const& trackProton, TTrack const& trackPion, TTrack const& trackBachelor, const double& tofNSigmaBach) + // ______________________________________________________________ + // function to build decay3body candidates + template + void buildCandidates(TBCs const&, + TCollisions const& collisions, + T3Bodys const& decay3bodys, + TMCParticles const& mcParticles, + TMCCollisions const& mcCollisions) { - if ((std::abs(trackBachelor.tpcNSigmaDe()) > TpcPidNsigmaCut) || !checkPID(trackProton, trackPion, trackBachelor, tofNSigmaBach)) { - return false; + if (!(mEnabledTables[kVtx3BodyDatas] || mEnabledTables[kMcVtx3BodyDatas])) { + LOG(info) << "No request for candidate analysis table in place, skipping candidate building." << std::endl; + return; // don't do if no request for decay3bodys in place } - return true; - } - //------------------------------------------------------------------ - // 3body candidate builder - template - void fillVtxCand(TCollisionTable const& collision, TTrackTable const& t0, TTrackTable const& t1, TTrackTable const& t2, int64_t decay3bodyId, int bachelorcharge = 1, double tofNSigmaBach = -999, bool saveInTable = true) - { - registry.fill(HIST("hVtx3BodyCounter"), kVtxAll); + // prepare MC container (not necessarily used) + std::vector mcParticleIsReco; - if (t0.tpcNClsFound() < mintpcNCls || t1.tpcNClsFound() < mintpcNCls || t2.tpcNClsFound() < mintpcNCls) { - return; + // clear and reserve size for MC info vectors + if constexpr (soa::is_table) { + isGoodCollision.resize(mcCollisions.size(), false); + mcParticleIsReco.resize(mcParticles.size(), false); } - registry.fill(HIST("hVtx3BodyCounter"), kVtxTPCNcls); - if (enablePidCut) { - if (t2.sign() > 0) { - if (!checkPIDH3L(t0, t1, t2, tofNSigmaBach)) - return; - } else { - if (!checkPIDH3L(t1, t0, t2, tofNSigmaBach)) - return; - } - } + // Loop over collisions for vertex QA + for (const auto& collision : collisions) { + if constexpr (soa::is_table) { // only do if NOT running over reduced data (already done in reducedCreator) + // Zorro event counting + bool isZorroSelected = false; + if (doSkimmedProcessing) { + isZorroSelected = zorro.isSelected(collision.template bc_as().globalBC()); + if (!isZorroSelected && onlyKeepInterestedTrigger) { + continue; + } + } - registry.fill(HIST("hVtx3BodyCounter"), kVtxPIDCut); + // event counting + registry.fill(HIST("Counters/hEventCounter"), 0.5); + if (doSel8selection && !collision.sel8()) { + continue; + } + registry.fill(HIST("Counters/hEventCounter"), 1.5); + if (doPosZselection && (collision.posZ() >= 10.0f || collision.posZ() <= -10.0f)) { + continue; + } + registry.fill(HIST("Counters/hEventCounter"), 2.5); + } + + // vertex QA and counting + if (doVertexQA) { + registry.fill(HIST("QA/Event/hAllSelEventsVtxZ"), collision.posZ()); + registry.fill(HIST("QA/Event/hVtxX"), collision.posX()); + registry.fill(HIST("QA/Event/hVtxY"), collision.posY()); + registry.fill(HIST("QA/Event/hVtxZ"), collision.posZ()); + registry.fill(HIST("QA/Event/hVtxCovXX"), collision.covXX()); + registry.fill(HIST("QA/Event/hVtxCovYY"), collision.covYY()); + registry.fill(HIST("QA/Event/hVtxCovZZ"), collision.covZZ()); + registry.fill(HIST("QA/Event/hVtxCovXY"), collision.covXY()); + registry.fill(HIST("QA/Event/hVtxCovXZ"), collision.covXZ()); + registry.fill(HIST("QA/Event/hVtxCovYZ"), collision.covYZ()); + } + + // In case of MC: reco collision survived event selection filter --> fill value for MC collision if collision is "true" MC collision + if constexpr (soa::is_table) { + if (collision.mcCollisionId() >= 0) { + isGoodCollision[collision.mcCollisionId()] = true; + } + } + } // loop over collisions - // Calculate DCA with respect to the collision associated to the V0, not individual tracks - std::array dcaInfo; + // Loop over all decay3bodys in same time frame + registry.fill(HIST("Counters/hInputStatistics"), kVtx3BodyDatas, decay3bodys.size()); + int lastRunNumber = -1; + for (const auto& decay3body : decay3bodys) { + // skip decay3body without assigned collision + /// TODO: do we want this?? + if (decay3body.collisionId() < 0) { + return; + } - auto Track0Par = getTrackPar(t0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track0dcaXY = dcaInfo[0]; - auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]); + // aquire collision + auto const& collision = collisions.rawIteratorAt(decay3body.collisionId()); - auto Track1Par = getTrackPar(t1); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track1dcaXY = dcaInfo[0]; - auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]); + // initialise CCDB from run number saved in reduced collisions table when running over reduced data + if constexpr (!soa::is_table) { // only do if running over reduced data (otherwise CCDB is initialised in process function) + if (collision.runNumber() != lastRunNumber) { + initFittersWithMagField(collision.runNumber(), getMagFieldFromRunNumber(collision.runNumber())); + lastRunNumber = collision.runNumber(); // Update the last run number + LOG(debug) << "CCDB initialized for run " << lastRunNumber; + } + } - auto Track2Par = getTrackPar(t2); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track2dcaXY = dcaInfo[0]; - auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]); + // event selection + if constexpr (soa::is_table) { + if (doSel8selection && !collision.sel8()) { // only when NOT running over reduced data + continue; + } + } + if (doPosZselection && (collision.posZ() >= 10.0f || collision.posZ() <= -10.0f)) { + continue; + } - auto Track0 = getTrackParCov(t0); - auto Track1 = getTrackParCov(t1); - auto Track2 = getTrackParCov(t2); - int n3bodyVtx = fitter3body.process(Track0, Track1, Track2); - if (n3bodyVtx == 0) { // discard this pair - return; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxhasSV); + // aquire tracks + auto trackPos = decay3body.template track0_as(); + auto trackNeg = decay3body.template track1_as(); + auto trackDeuteron = decay3body.template track2_as(); + auto trackProton = trackPos; + auto trackPion = trackNeg; + if (trackDeuteron.sign() < 0) { + trackProton = trackNeg; + trackPion = trackPos; + } + + // get deuteron TOF PID + float tofNSigmaDeuteron; + if constexpr (!soa::is_table) { // running over derived data + tofNSigmaDeuteron = trackDeuteron.tofNSigmaDe(); + } else if constexpr (soa::is_table) { // running over AO2Ds + if constexpr (soa::is_table) { // running over MC (track table with labels) + tofNSigmaDeuteron = getTOFnSigma(collision, trackDeuteron); + } else { // running over real data + tofNSigmaDeuteron = getTOFnSigma(collision, trackDeuteron); + } + } - std::array pos = {0.}; - const auto& vtxXYZ = fitter3body.getPCACandidate(); - for (int i = 0; i < 3; i++) { - pos[i] = vtxXYZ[i]; - } + /// build Decay3body candidate + if (!helper.buildDecay3BodyCandidate(collision, + trackProton, + trackPion, + trackDeuteron, + decay3body.globalIndex(), + tofNSigmaDeuteron, + fTrackedClSizeVector[decay3body.globalIndex()], + decay3bodyBuilderOpts.useKFParticle, + decay3bodyBuilderOpts.kfSetTopologicalConstraint, + decay3bodyBuilderOpts.useSelections, + decay3bodyBuilderOpts.useTPCforPion, + decay3bodyBuilderOpts.acceptTPCOnly, + decay3bodyBuilderOpts.calculateCovariance, + false /*isEventMixing*/)) { + continue; + } - std::array p0 = {0.}, p1 = {0.}, p2{0.}; - const auto& propagatedTrack0 = fitter3body.getTrack(0); - const auto& propagatedTrack1 = fitter3body.getTrack(1); - const auto& propagatedTrack2 = fitter3body.getTrack(2); - propagatedTrack0.getPxPyPzGlo(p0); - propagatedTrack1.getPxPyPzGlo(p1); - propagatedTrack2.getPxPyPzGlo(p2); - for (int i = 0; i < 3; i++) { - p2[i] *= bachelorcharge; - } - std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; + // fill QA histograms + if (doTrackQA) { // histograms filled for daughter tracks of (selected) 3body candidates + registry.fill(HIST("QA/Tracks/hTrackProtonTPCNcls"), trackProton.tpcNClsFound()); + registry.fill(HIST("QA/Tracks/hTrackPionTPCNcls"), trackPion.tpcNClsFound()); + registry.fill(HIST("QA/Tracks/hTrackDeuteronTPCNcls"), trackDeuteron.tpcNClsFound()); + registry.fill(HIST("QA/Tracks/hTrackProtonHasTPC"), trackProton.hasTPC()); + registry.fill(HIST("QA/Tracks/hTrackPionHasTPC"), trackPion.hasTPC()); + registry.fill(HIST("QA/Tracks/hTrackDeuteronHasTPC"), trackDeuteron.hasTPC()); + registry.fill(HIST("QA/Tracks/hTrackDeuteronITSClusSizes"), trackDeuteron.itsClusterSizes()); + registry.fill(HIST("QA/Tracks/hTrackProtonTPCPID"), trackProton.sign() * trackProton.tpcInnerParam(), trackProton.tpcNSigmaPr()); + registry.fill(HIST("QA/Tracks/hTrackPionTPCPID"), trackPion.sign() * trackPion.tpcInnerParam(), trackPion.tpcNSigmaPi()); + registry.fill(HIST("QA/Tracks/hTrackDeuteronTPCPID"), trackDeuteron.sign() * trackDeuteron.tpcInnerParam(), trackDeuteron.tpcNSigmaDe()); + registry.fill(HIST("QA/Tracks/hTrackProtonPt"), trackProton.pt()); + registry.fill(HIST("QA/Tracks/hTrackPionPt"), trackPion.pt()); + registry.fill(HIST("QA/Tracks/hTrackDeuteronPt"), trackDeuteron.pt()); + } + + // generate analysis tables with current candidate (only Vtx3BodyDatas is filled here, McVtx3BodyDatas table is filled later) + if (!mEnabledTables[kMcVtx3BodyDatas]) { + fillAnalysisTables(); + } + + // ___________________________________________________________ + // MC handling part: matching of reconstructed candidates + // ___________________________________________________________ + // fill MC table with reco MC candidate information and gen information if matched to MC particle + if constexpr (soa::is_table) { + // MC info + resetMCInfo(this3BodyMCInfo); + this3BodyMCInfo.isReco = true; + + // check if daughters have MC particle + if (!trackProton.has_mcParticle() || !trackPion.has_mcParticle() || !trackDeuteron.has_mcParticle()) { + continue; + } - if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { - return; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxDcaDau); + // get MC daughter particles + auto mcTrackProton = trackProton.template mcParticle_as(); + auto mcTrackPion = trackPion.template mcParticle_as(); + auto mcTrackDeuteron = trackDeuteron.template mcParticle_as(); + + // set daughter MC info (also for non-matched candidates) + this3BodyMCInfo.daughterPrPdgCode = mcTrackProton.pdgCode(); + this3BodyMCInfo.daughterPiPdgCode = mcTrackPion.pdgCode(); + this3BodyMCInfo.daughterDePdgCode = mcTrackDeuteron.pdgCode(); + this3BodyMCInfo.isDeuteronPrimary = mcTrackDeuteron.isPhysicalPrimary(); + this3BodyMCInfo.genMomProton = mcTrackProton.p(); + this3BodyMCInfo.genMomPion = mcTrackPion.p(); + this3BodyMCInfo.genMomDeuteron = mcTrackDeuteron.p(); + this3BodyMCInfo.genPtProton = mcTrackProton.pt(); + this3BodyMCInfo.genPtPion = mcTrackPion.pt(); + this3BodyMCInfo.genPtDeuteron = mcTrackDeuteron.pt(); + + // check if reco mother is true H3L/Anti-H3l + bool isMuonReco; + int motherID = checkH3LTruth(mcTrackProton, mcTrackPion, mcTrackDeuteron, isMuonReco); + + // get generated mother MC info + if (motherID > 0) { + auto mcTrackH3L = mcParticles.rawIteratorAt(motherID); + int chargeFactor = mcTrackH3L.pdgCode() > 0 ? 1 : -1; + this3BodyMCInfo.label = motherID; + this3BodyMCInfo.genMomentum = {mcTrackH3L.px(), mcTrackH3L.py(), mcTrackH3L.pz()}; + this3BodyMCInfo.genDecVtx = {mcTrackProton.vx(), mcTrackProton.vy(), mcTrackProton.vz()}; + this3BodyMCInfo.genCt = RecoDecay::sqrtSumOfSquares(mcTrackProton.vx() - mcTrackH3L.vx(), mcTrackProton.vy() - mcTrackH3L.vy(), mcTrackProton.vz() - mcTrackH3L.vz()) * o2::constants::physics::MassHyperTriton / mcTrackH3L.p(); + this3BodyMCInfo.genPhi = mcTrackH3L.phi(); + this3BodyMCInfo.genEta = mcTrackH3L.eta(); + this3BodyMCInfo.genRapidity = mcTrackH3L.y(); + this3BodyMCInfo.isTrueH3L = chargeFactor > 0; + this3BodyMCInfo.isTrueAntiH3L = chargeFactor < 0; + } - float VtxcosPA = RecoDecay::cpa(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{pos[0], pos[1], pos[2]}, std::array{p3B[0], p3B[1], p3B[2]}); - if (VtxcosPA < minCosPA3body) { - return; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxCosPA); - registry.fill(HIST("hBachelorTOFNSigmaDe"), t2.sign() * t2.p(), tofNSigmaBach); - - // additional cut for EM - if (decay3bodyId == -1) { - registry.fill(HIST("h3bodyEMCutCounter"), 0.5); - auto v0Track0 = getTrackParCov(t0); - auto v0Track1 = getTrackParCov(t1); - int nV0 = fitterV0.process(v0Track0, v0Track1); - if (nV0 == 0) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 1.5); + // fill analysis tables (only McVtx3BodyDatas is filled here) + fillAnalysisTables(); - std::array v0pos = {0.}; - const auto& v0vtxXYZ = fitterV0.getPCACandidate(); - for (int i = 0; i < 3; i++) { - v0pos[i] = v0vtxXYZ[i]; - } - const int cand = 0; - if (!fitterV0.isPropagateTracksToVertexDone(cand) && !fitterV0.propagateTracksToVertex(cand)) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 2.5); - - const auto& trPProp = fitterV0.getTrack(0, cand); - const auto& trNProp = fitterV0.getTrack(1, cand); - std::array pP{}, pN{}; - trPProp.getPxPyPzGlo(pP); - trNProp.getPxPyPzGlo(pN); - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - // Cut for Virtual V0 - float dxv0 = v0pos[0] - mMeanVertex.getX(), dyv0 = v0pos[1] - mMeanVertex.getY(), r2v0 = dxv0 * dxv0 + dyv0 * dyv0; - float rv0 = std::sqrt(r2v0); - float pt2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1], prodXYv0 = dxv0 * pV0[0] + dyv0 * pV0[1], tDCAXY = prodXYv0 / pt2V0; - if (dcaFitterEMSel.cfgApplyV0Cut && pt2V0 <= dcaFitterEMSel.mMinPt2V0) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 3.5); - if (dcaFitterEMSel.cfgApplyV0Cut && pV0[2] * pV0[2] / pt2V0 > dcaFitterEMSel.mMaxTgl2V0) { // tgLambda cut - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 4.5); - - float p2V0 = pt2V0 + pV0[2] * pV0[2], ptV0 = std::sqrt(pt2V0); - // apply mass selections - float p2Pos = pP[0] * pP[0] + pP[1] * pP[1] + pP[2] * pP[2], p2Neg = pN[0] * pN[0] + pN[1] * pN[1] + pN[2] * pN[2]; - bool good3bodyV0Hyp = false; - for (int ipid = 0; ipid < 2; ipid++) { - float massForLambdaHyp = mV0Hyps[ipid].calcMass(p2Pos, p2Neg, p2V0); - if (massForLambdaHyp - mV0Hyps[ipid].getMassV0Hyp() < mV0Hyps[ipid].getMargin(ptV0)) { - good3bodyV0Hyp = true; - break; + // mark mcParticle as reconstructed + if (this3BodyMCInfo.label > -1) { + mcParticleIsReco[this3BodyMCInfo.label] = true; + } + } // constexpr requires mcParticles check + } // decay3body loop + + // ____________________________________________________________________ + // MC handling part: generated information of non-reco candidates + // ____________________________________________________________________ + if constexpr (soa::is_table) { + for (auto& mcparticle : mcParticles) { + // MC info + resetMCInfo(this3BodyMCInfo); + this3BodyMCInfo.isReco = false; + + // skip MC particle if reconstructed and already filled previously + if (mcParticleIsReco[mcparticle.globalIndex()] == true) { + continue; } - } - if (dcaFitterEMSel.cfgApplyV0Cut && !good3bodyV0Hyp) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 5.5); - float dcaX = dxv0 - pV0[0] * tDCAXY, dcaY = dyv0 - pV0[1] * tDCAXY, dca2 = dcaX * dcaX + dcaY * dcaY; - float cosPAXY = prodXYv0 / rv0 * ptV0; - if (dcaFitterEMSel.cfgApplyV0Cut && dca2 > dcaFitterEMSel.mMaxDCAXY2ToMeanVertex3bodyV0) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 6.5); - // FIXME: V0 cosPA cut to be investigated - if (dcaFitterEMSel.cfgApplyV0Cut && cosPAXY < dcaFitterEMSel.minCosPAXYMeanVertex3bodyV0) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 7.5); - // Check: CosPA Cut of Virtual V0 may not be used since the V0 may be based on another PV - float dx = v0pos[0] - collision.posX(), dy = v0pos[1] - collision.posY(), dz = v0pos[2] - collision.posZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; - float v0CosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); - if (dcaFitterEMSel.cfgApplyV0Cut && v0CosPA < dcaFitterEMSel.minCosPA3bodyV0) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 8.5); + // set flag if corresponding MC collision has matched reconstructed collision which passed event selection + this3BodyMCInfo.survivedEventSel = isGoodCollision[mcparticle.mcCollisionId()]; - float r3body = std::hypot(pos[0], pos[1]); - if (r3body < 0.5) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 9.5); + // check if MC particle is hypertriton + if (std::abs(mcparticle.pdgCode()) != 1010010030) { + continue; + } - // Cut for the compatibility of V0 and 3body vertex - float deltaR = std::abs(rv0 - r3body); - if (deltaR > dcaFitterEMSel.maxRDiffV03body) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 10.5); + // check daughter identities + bool haveProton = false, havePion = false, haveDeuteron = false; + bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; + for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { + if (mcparticleDaughter.pdgCode() == PDG_t::kProton) + haveProton = true; + if (mcparticleDaughter.pdgCode() == PDG_t::kProtonBar) + haveAntiProton = true; + if (mcparticleDaughter.pdgCode() == PDG_t::kPiPlus) + havePion = true; + if (mcparticleDaughter.pdgCode() == PDG_t::kPiMinus) + haveAntiPion = true; + if (mcparticleDaughter.pdgCode() == 1000010020) + haveDeuteron = true; + if (mcparticleDaughter.pdgCode() == -1000010020) + haveAntiDeuteron = true; + } - float pt3B = std::hypot(p3B[0], p3B[1]); - if (pt3B < dcaFitterEMSel.minPt3Body) { // pt cut - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 11.5); - if (p3B[2] / pt3B > dcaFitterEMSel.maxTgl3Body) { // tgLambda cut - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 12.5); - - // H3L DCA Check - const auto& vertexXYZ = fitter3body.getPCACandidatePos(); - auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, t2.sign()); - o2::dataformats::DCA dca; - if (!track3B.propagateToDCA({{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}, fitter3body.getBz(), &dca, 5.) || - std::abs(dca.getY()) > dcaFitterEMSel.maxDCAXY3Body || std::abs(dca.getZ()) > dcaFitterEMSel.maxDCAZ3Body) { - return; - } - registry.fill(HIST("h3bodyEMCutCounter"), 13.5); - } + // check if hypertriton decayed via 3-body decay and is particle or anti-particle + if ((haveProton && haveAntiPion && haveDeuteron) || (haveAntiProton && havePion && haveAntiDeuteron)) { + if (mcparticle.pdgCode() > 0) { + this3BodyMCInfo.isTrueH3L = true; + } else if (mcparticle.pdgCode() < 0) { + this3BodyMCInfo.isTrueAntiH3L = true; + } + // get daughters + for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { + if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kProton) { // proton + this3BodyMCInfo.genMomProton = mcparticleDaughter.p(); + this3BodyMCInfo.genPtProton = mcparticleDaughter.pt(); + this3BodyMCInfo.daughterPrPdgCode = mcparticleDaughter.pdgCode(); + this3BodyMCInfo.genDecVtx = {mcparticleDaughter.vx(), mcparticleDaughter.vy(), mcparticleDaughter.vz()}; + } else if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kPiPlus) { // pion + this3BodyMCInfo.genMomPion = mcparticleDaughter.p(); + this3BodyMCInfo.genPtPion = mcparticleDaughter.pt(); + this3BodyMCInfo.daughterPiPdgCode = mcparticleDaughter.pdgCode(); + } else if (std::abs(mcparticleDaughter.pdgCode()) == 1000010020) { // deuteron + this3BodyMCInfo.genMomDeuteron = mcparticleDaughter.p(); + this3BodyMCInfo.genPtDeuteron = mcparticleDaughter.pt(); + this3BodyMCInfo.daughterDePdgCode = mcparticleDaughter.pdgCode(); + this3BodyMCInfo.isDeuteronPrimary = mcparticleDaughter.isPhysicalPrimary(); + } + } + } else { + continue; // stop if particle is not decayed via 3-body decay + } - VtxCandidate candVtx; - candVtx.track0Id = t0.globalIndex(); - candVtx.track1Id = t1.globalIndex(); - candVtx.track2Id = t2.globalIndex(); - candVtx.collisionId = collision.globalIndex(); - candVtx.decay3bodyId = decay3bodyId; - candVtx.vtxPos[0] = pos[0]; - candVtx.vtxPos[1] = pos[1]; - candVtx.vtxPos[2] = pos[2]; - candVtx.track0P[0] = p0[0]; - candVtx.track0P[1] = p0[1]; - candVtx.track0P[2] = p0[2]; - candVtx.track1P[0] = p1[0]; - candVtx.track1P[1] = p1[1]; - candVtx.track1P[2] = p1[2]; - candVtx.track2P[0] = p2[0]; - candVtx.track2P[1] = p2[1]; - candVtx.track2P[2] = p2[2]; - candVtx.dcadaughters = fitter3body.getChi2AtPCACandidate(); - candVtx.daudcaxytopv[0] = Track0dcaXY; - candVtx.daudcaxytopv[1] = Track1dcaXY; - candVtx.daudcaxytopv[2] = Track2dcaXY; - candVtx.daudcatopv[0] = Track0dca; - candVtx.daudcatopv[1] = Track1dca; - candVtx.daudcatopv[2] = Track2dca; - candVtx.bachelortofNsigma = tofNSigmaBach; - if (saveInTable) { - fillVtx3BodyTable(candVtx); - } else { - VtxCandidates.push_back(candVtx); - } + // calculate ctau + this3BodyMCInfo.genCt = RecoDecay::sqrtSumOfSquares(this3BodyMCInfo.genDecVtx[0] - mcparticle.vx(), this3BodyMCInfo.genDecVtx[1] - mcparticle.vy(), this3BodyMCInfo.genDecVtx[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); + + // fill MCDecay3BodyCores table if requested + if (mEnabledTables[kMcVtx3BodyDatas]) { + products.mcvtx3bodydatas(-1, // sign + -1., -1., // mass, massV0 + -1., -1., -1., // position + -1., -1., -1., // momentum + -1., // chi2 + -1., // trackedClSize + -1., -1., -1., // momProton + -1., -1., -1., // momPion + -1., -1., -1., // momDeuteron + -1., -1., -1., // trackDCAxyToPV: 0 - proton, 1 - pion, 2 - deuteron + -1., -1., -1., // trackDCAzToPV: 0 - proton, 1 - pion, 2 - deuteron + -1., -1., -1., // daughterDCAtoSV: 0 - proton, 1 - pion, 2 - deuteron + -1., // daughterDCAatSV + -1., -1., -1., -1., // tpcNsigma: 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp + -1., // tofNsigmaDeuteron + -1., -1., -1., // average ITS cluster sizes: proton, pion, deuteron + -1., -1., -1., // TPCNCl: proton, pion, deuteron + -1., // pidForTrackingDeuteron + // MC information + mcparticle.px(), mcparticle.py(), mcparticle.pz(), + this3BodyMCInfo.genDecVtx[0], this3BodyMCInfo.genDecVtx[1], this3BodyMCInfo.genDecVtx[2], + this3BodyMCInfo.genCt, + mcparticle.phi(), mcparticle.eta(), mcparticle.y(), + this3BodyMCInfo.genMomProton, this3BodyMCInfo.genMomPion, this3BodyMCInfo.genMomDeuteron, + this3BodyMCInfo.genPtProton, this3BodyMCInfo.genPtPion, this3BodyMCInfo.genPtDeuteron, + this3BodyMCInfo.isTrueH3L, this3BodyMCInfo.isTrueAntiH3L, + this3BodyMCInfo.isReco, + this3BodyMCInfo.daughterPrPdgCode, this3BodyMCInfo.daughterPiPdgCode, this3BodyMCInfo.daughterDePdgCode, + this3BodyMCInfo.isDeuteronPrimary, + this3BodyMCInfo.survivedEventSel); + } // enabled table check + } // mcParticles loop + } // constexpr requires mcParticles check } - //------------------------------------------------------------------ - // event mixing - template - void doMixed3Body(TMixed3bodys decay3bodys, TBinningType binningType) + + // ______________________________________________________________ + // function to build mixed decay3body candidates + template + void buildMixedCandidates(TRedDecay3Bodys const& decay3bodys, TBinningType const& binningType) { + if (!mEnabledTables[kVtx3BodyDatas]) { + return; // don't do if no request for decay3bodys in place + } + // Strictly upper index policy for decay3body objects binned by radius, phi - for (const auto& [decay3body0, decay3body1] : selfCombinations(binningType, dcaFitterEMSel.nUseMixed, -1, decay3bodys, decay3bodys)) { - auto tpos0 = decay3body0.template track0_as(); - auto tneg0 = decay3body0.template track1_as(); - auto tbach0 = decay3body0.template track2_as(); - auto tpos1 = decay3body1.template track0_as(); - auto tneg1 = decay3body1.template track1_as(); - auto tbach1 = decay3body1.template track2_as(); - - registry.fill(HIST("h3bodyCombinationCounter"), 0.5); - - // ---------- selections ---------- - if ((tbach0.sign() > 0 && !(tbach1.sign() > 0)) || (tbach0.sign() < 0 && !(tbach1.sign() < 0)) || tbach0.globalIndex() == tbach1.globalIndex()) { // only combine if tbach1 has correct sign and is not same as tbach0 + for (const auto& [decay3body0, decay3body1] : selfPairCombinations(binningType, mixingOpts.n3bodyMixing, -1, decay3bodys)) { + auto trackPos0 = decay3body0.template track0_as(); + auto trackNeg0 = decay3body0.template track1_as(); + auto trackDeuteron0 = decay3body0.template track2_as(); + auto trackPos1 = decay3body1.template track0_as(); + auto trackNeg1 = decay3body1.template track1_as(); + auto trackDeuteron1 = decay3body1.template track2_as(); + + // assign tracks + auto trackProton0 = trackPos0; + auto trackPion0 = trackNeg0; + auto trackProton1 = trackPos1; + auto trackPion1 = trackNeg1; + if (trackDeuteron0.sign() < 0) { + trackProton0 = trackNeg0; + trackPion0 = trackPos0; + } + if (trackDeuteron1.sign() < 0) { + trackProton1 = trackNeg1; + trackPion1 = trackPos1; + } + + registry.fill(HIST("Mixing/h3bodyCombinationCounter"), 0.5); + + // only combine if from different event + if (decay3body0.collisionId() == decay3body1.collisionId()) { continue; } - registry.fill(HIST("h3bodyCombinationCounter"), 1.5); + registry.fill(HIST("Mixing/h3bodyCombinationCounter"), 1.5); + + // collision vertex selection + auto collision0 = decay3body0.template collision_as(); + auto collision1 = decay3body1.template collision_as(); + + // get b_z value for each collision (from CCDB or cache) and cache it for that run number + float magFieldCol0 = getMagFieldFromRunNumber(collision0.runNumber()); + float magFieldCol1 = getMagFieldFromRunNumber(collision1.runNumber()); - if (decay3body0.collisionId() == decay3body1.collisionId()) { // only combine if from different event + // only combine if collision similar in VtxZ + if (mixingOpts.selectPVPosZ3bodyMixing && std::abs(collision0.posZ() - collision1.posZ()) > mixingOpts.maxDeltaPVPosZ3bodyMixing) { continue; } - registry.fill(HIST("h3bodyCombinationCounter"), 2.5); + registry.fill(HIST("Mixing/h3bodyCombinationCounter"), 2.5); - auto c0 = decay3body0.template collision_as(); - auto c1 = decay3body1.template collision_as(); + // Charge selections + // same magnetic fields --> mix matter with matter + if ((magFieldCol0 / std::abs(magFieldCol0)) == (magFieldCol1 / std::abs(magFieldCol1))) { + if (trackDeuteron0.sign() != trackDeuteron1.sign()) { + continue; + } + } + // opposite magnetic fields --> mix matter with anti-matter + if ((magFieldCol0 / std::abs(magFieldCol0)) != (magFieldCol1 / std::abs(magFieldCol1))) { + if (trackDeuteron0.sign() == trackDeuteron1.sign()) { + continue; + } + } - if (dcaFitterEMSel.selectPVPosZ3bodyMixing && std::abs(c0.posZ() - c1.posZ()) > dcaFitterEMSel.maxDeltaPVPosZ3bodyMixing) { // only combine if collision similar in PV posZ + // don't mix 3body with itself + if ((trackDeuteron0.globalIndex() == trackDeuteron1.globalIndex()) || (trackProton0.globalIndex() == trackProton1.globalIndex()) || (trackPion0.globalIndex() == trackPion1.globalIndex())) { continue; } - registry.fill(HIST("h3bodyCombinationCounter"), 3.5); - - initCCDBfromRunNumber(c0.runNumber()); - - if (dcaFitterEMSel.cfgMix3BodyMethod == 0) { // mix bachelor (deuteron) - fillVtxCand(c0, tpos0, tneg0, tbach1, -1, bachelorcharge, tbach1.tofNSigmaDe()); - fillVtxCand(c1, tpos1, tneg1, tbach0, -1, bachelorcharge, tbach0.tofNSigmaDe()); - } else if ((dcaFitterEMSel.cfgMix3BodyMethod == 1 && tbach0.sign() > 0) || (dcaFitterEMSel.cfgMix3BodyMethod == 2 && tbach0.sign() < 0)) { // mix piMinus or proton - fillVtxCand(c0, tpos0, tneg1, tbach0, -1, bachelorcharge, tbach0.tofNSigmaDe()); - fillVtxCand(c1, tpos1, tneg0, tbach1, -1, bachelorcharge, tbach1.tofNSigmaDe()); - } else if ((dcaFitterEMSel.cfgMix3BodyMethod == 1 && tbach0.sign() < 0) || (dcaFitterEMSel.cfgMix3BodyMethod == 2 && tbach0.sign() > 0)) { // mix piPlus or anti-proton - fillVtxCand(c0, tpos1, tneg0, tbach0, -1, bachelorcharge, tbach0.tofNSigmaDe()); - fillVtxCand(c1, tpos0, tneg1, tbach1, -1, bachelorcharge, tbach1.tofNSigmaDe()); - } + registry.fill(HIST("Mixing/h3bodyCombinationCounter"), 3.5); - VtxCandidates.clear(); + // candidate analysis + // mix deuteron + if (mixingOpts.mixingType == 0) { + doMixing(collision0, trackProton0, trackPion0, trackDeuteron1, magFieldCol0); + doMixing(collision1, trackProton1, trackPion1, trackDeuteron0, magFieldCol1); + } + // mix proton + if (mixingOpts.mixingType == 1) { + doMixing(collision0, trackProton1, trackPion0, trackDeuteron0, magFieldCol0); + doMixing(collision1, trackProton0, trackPion1, trackDeuteron1, magFieldCol1); + } + // mix pion + if (mixingOpts.mixingType == 2) { + doMixing(collision0, trackProton0, trackPion1, trackDeuteron0, magFieldCol0); + doMixing(collision1, trackProton1, trackPion0, trackDeuteron1, magFieldCol1); + } } // end decay3body combinations loop } - //------------------------------------------------------------------ - // fill the StoredVtx3BodyDatas table - void fillVtx3BodyTable(VtxCandidate const& candVtx) + + // ______________________________________________________________ + // function to calculate correct TOF nSigma for deuteron track + template + double getTOFnSigma(TCollision const& collision, TTrack const& track) { - vtx3bodydata( - candVtx.track0Id, candVtx.track1Id, candVtx.track2Id, candVtx.collisionId, candVtx.decay3bodyId, - candVtx.vtxPos[0], candVtx.vtxPos[1], candVtx.vtxPos[2], - candVtx.track0P[0], candVtx.track0P[1], candVtx.track0P[2], candVtx.track1P[0], candVtx.track1P[1], candVtx.track1P[2], candVtx.track2P[0], candVtx.track2P[1], candVtx.track2P[2], - candVtx.dcadaughters, - candVtx.daudcaxytopv[0], candVtx.daudcaxytopv[1], candVtx.daudcaxytopv[2], - candVtx.daudcatopv[0], candVtx.daudcatopv[1], candVtx.daudcatopv[2], - candVtx.bachelortofNsigma); + // TOF PID of deuteron + if (track.has_collision() && track.hasTOF()) { + auto originalcol = track.template collision_as(); + if constexpr (isMC) { + return bachelorTOFPIDLabeled.GetTOFNSigma(track, originalcol, collision); + } else { + return bachelorTOFPID.GetTOFNSigma(track, originalcol, collision); + } + } + return -999; } - //------------------------------------------------------------------ - //-------------------- KFParticle reconstruction ------------------- - //------------------------------------------------------------------ - // function to select daughter track PID - template - bool selectTPCPID(TTrack const& trackProton, TTrack const& trackPion, TTrack const& trackDeuteron) + // ______________________________________________________________ + // function to fill analysis tables + void fillAnalysisTables() { - if (std::abs(trackProton.tpcNSigmaPr()) > kfparticleConfigurations.maxtpcnSigma) { - return false; - } - if (std::abs(trackDeuteron.tpcNSigmaDe()) > kfparticleConfigurations.maxtpcnSigma) { - return false; + // generate analysis tables + if (mEnabledTables[kDecay3BodyIndices]) { + products.decay3bodyindices(helper.decay3body.decay3bodyID, + helper.decay3body.protonID, helper.decay3body.pionID, helper.decay3body.deuteronID, + helper.decay3body.collisionID); + registry.fill(HIST("Counters/hTableBuildingStatistics"), kDecay3BodyIndices); + } + if (mEnabledTables[kVtx3BodyDatas]) { + products.vtx3bodydatas(helper.decay3body.sign, + helper.decay3body.mass, helper.decay3body.massV0, + helper.decay3body.position[0], helper.decay3body.position[1], helper.decay3body.position[2], + helper.decay3body.momentum[0], helper.decay3body.momentum[1], helper.decay3body.momentum[2], + helper.decay3body.chi2, + helper.decay3body.trackedClSize, + helper.decay3body.momProton[0], helper.decay3body.momProton[1], helper.decay3body.momProton[2], + helper.decay3body.momPion[0], helper.decay3body.momPion[1], helper.decay3body.momPion[2], + helper.decay3body.momDeuteron[0], helper.decay3body.momDeuteron[1], helper.decay3body.momDeuteron[2], + helper.decay3body.trackDCAxyToPV[0], helper.decay3body.trackDCAxyToPV[1], helper.decay3body.trackDCAxyToPV[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.trackDCAzToPV[0], helper.decay3body.trackDCAzToPV[1], helper.decay3body.trackDCAzToPV[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.daughterDCAtoSV[0], helper.decay3body.daughterDCAtoSV[1], helper.decay3body.daughterDCAtoSV[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.daughterDCAatSV, + helper.decay3body.tpcNsigma[0], helper.decay3body.tpcNsigma[1], helper.decay3body.tpcNsigma[2], helper.decay3body.tpcNsigma[2], // 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp + helper.decay3body.tofNsigmaDeuteron, + helper.decay3body.averageITSClSize[0], helper.decay3body.averageITSClSize[1], helper.decay3body.averageITSClSize[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.tpcNCl[0], helper.decay3body.tpcNCl[1], helper.decay3body.tpcNCl[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.pidForTrackingDeuteron); + registry.fill(HIST("Counters/hTableBuildingStatistics"), kVtx3BodyDatas); + } + if (mEnabledTables[kVtx3BodyCovs]) { + products.vtx3bodycovs(helper.decay3body.covProton, + helper.decay3body.covPion, + helper.decay3body.covDeuteron, + helper.decay3body.covariance); + registry.fill(HIST("Counters/hTableBuildingStatistics"), kVtx3BodyCovs); + } + if (mEnabledTables[kMcVtx3BodyDatas]) { + products.mcvtx3bodydatas(helper.decay3body.sign, + helper.decay3body.mass, helper.decay3body.massV0, + helper.decay3body.position[0], helper.decay3body.position[1], helper.decay3body.position[2], + helper.decay3body.momentum[0], helper.decay3body.momentum[1], helper.decay3body.momentum[2], + helper.decay3body.chi2, + helper.decay3body.trackedClSize, + helper.decay3body.momProton[0], helper.decay3body.momProton[1], helper.decay3body.momProton[2], + helper.decay3body.momPion[0], helper.decay3body.momPion[1], helper.decay3body.momPion[2], + helper.decay3body.momDeuteron[0], helper.decay3body.momDeuteron[1], helper.decay3body.momDeuteron[2], + helper.decay3body.trackDCAxyToPV[0], helper.decay3body.trackDCAxyToPV[1], helper.decay3body.trackDCAxyToPV[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.trackDCAzToPV[0], helper.decay3body.trackDCAzToPV[1], helper.decay3body.trackDCAzToPV[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.daughterDCAtoSV[0], helper.decay3body.daughterDCAtoSV[1], helper.decay3body.daughterDCAtoSV[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.daughterDCAatSV, + helper.decay3body.tpcNsigma[0], helper.decay3body.tpcNsigma[1], helper.decay3body.tpcNsigma[2], helper.decay3body.tpcNsigma[2], // 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp + helper.decay3body.tofNsigmaDeuteron, + helper.decay3body.averageITSClSize[0], helper.decay3body.averageITSClSize[1], helper.decay3body.averageITSClSize[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.tpcNCl[0], helper.decay3body.tpcNCl[1], helper.decay3body.tpcNCl[2], // 0 - proton, 1 - pion, 2 - deuteron + helper.decay3body.pidForTrackingDeuteron, + // MC information + this3BodyMCInfo.genMomentum[0], this3BodyMCInfo.genMomentum[1], this3BodyMCInfo.genMomentum[2], + this3BodyMCInfo.genDecVtx[0], this3BodyMCInfo.genDecVtx[1], this3BodyMCInfo.genDecVtx[2], + this3BodyMCInfo.genCt, + this3BodyMCInfo.genPhi, this3BodyMCInfo.genEta, this3BodyMCInfo.genRapidity, + this3BodyMCInfo.genMomProton, this3BodyMCInfo.genMomPion, this3BodyMCInfo.genMomDeuteron, + this3BodyMCInfo.genPtProton, this3BodyMCInfo.genPtPion, this3BodyMCInfo.genPtDeuteron, + this3BodyMCInfo.isTrueH3L, this3BodyMCInfo.isTrueAntiH3L, + this3BodyMCInfo.isReco, + this3BodyMCInfo.daughterPrPdgCode, this3BodyMCInfo.daughterPiPdgCode, this3BodyMCInfo.daughterDePdgCode, + this3BodyMCInfo.isDeuteronPrimary, + this3BodyMCInfo.survivedEventSel); + registry.fill(HIST("Counters/hTableBuildingStatistics"), kMcVtx3BodyDatas); } - if (kfparticleConfigurations.useTPCforPion && std::abs(trackPion.tpcNSigmaPi()) > kfparticleConfigurations.maxtpcnSigma) { - return false; + } + + // ______________________________________________________________ + // function to build mixed 3body candidate from selected tracks + template + void doMixing(TCollision const& collision, TTrack const& trackProton, TTrack const& trackPion, TTrack const& trackDeuteron, float magField) + { + // set vertexers and propagator with correct mag field of this collision (only if run number changed compared to previous candidate build) + initFittersWithMagField(collision.runNumber(), magField); + if (helper.buildDecay3BodyCandidate(collision, trackProton, trackPion, trackDeuteron, + -1 /*decay3bodyIndex*/, + trackDeuteron.tofNSigmaDe(), + 0 /*trackedClSize*/, + decay3bodyBuilderOpts.useKFParticle, + decay3bodyBuilderOpts.kfSetTopologicalConstraint, + decay3bodyBuilderOpts.useSelections, + decay3bodyBuilderOpts.useTPCforPion, + decay3bodyBuilderOpts.acceptTPCOnly, + decay3bodyBuilderOpts.calculateCovariance, + true /*isEventMixing*/)) { + // fill analysis tables with built candidate + fillAnalysisTables(); + return; + } else { + return; } - return true; } - template - double getTOFnSigma(TCollision const& collision, TTrack const& track, bool isEventMixing) + // ______________________________________________________________ + // function to check if a reconstructed mother is a true H3L/Anti-H3L (returns -1 if not) + template + int checkH3LTruth(MCTrack3B const& mcParticlePr, MCTrack3B const& mcParticlePi, MCTrack3B const& mcParticleDe, bool& isMuonReco) { - // TOF PID of deuteron (set motherhyp correctly) - double tofNSigmaDeuteron = -999; - if (track.has_collision() && track.hasTOF()) { - if (isEventMixing) { - tofNSigmaDeuteron = bachelorTOFPID.GetTOFNSigma(track, collision, collision); - } else { - auto originalcol = track.template collision_as(); - tofNSigmaDeuteron = bachelorTOFPID.GetTOFNSigma(track, originalcol, collision); + if (std::abs(mcParticlePr.pdgCode()) != 2212 || std::abs(mcParticleDe.pdgCode()) != 1000010020) { + return -1; + } + // check proton and deuteron mother + int prDeMomID = -1; + for (const auto& motherPr : mcParticlePr.template mothers_as()) { + for (const auto& motherDe : mcParticleDe.template mothers_as()) { + if (motherPr.globalIndex() == motherDe.globalIndex() && std::abs(motherPr.pdgCode()) == 1010010030) { + prDeMomID = motherPr.globalIndex(); + break; + } + } + } + if (prDeMomID == -1) { + return -1; + } + if (std::abs(mcParticlePi.pdgCode()) != 211 && std::abs(mcParticlePi.pdgCode()) != 13) { + return -1; + } + // check if the pion track is a muon coming from a pi -> mu + vu decay, if yes, take the mother pi + auto mcParticlePiTmp = mcParticlePi; + if (std::abs(mcParticlePiTmp.pdgCode()) == 13) { + for (const auto& motherPi : mcParticlePiTmp.template mothers_as()) { + if (std::abs(motherPi.pdgCode()) == 211) { + mcParticlePiTmp = motherPi; + isMuonReco = true; + break; + } + } + } + // now loop over the pion mother + for (const auto& motherPi : mcParticlePiTmp.template mothers_as()) { + if (motherPi.globalIndex() == prDeMomID) { + return motherPi.globalIndex(); } } - return tofNSigmaDeuteron; + return -1; } - //------------------------------------------------------------------ - // function to fill candidate table - template - void fillCandidateTable(TCandidate const& candidate) + // ______________________________________________________________ + // function to reset MCInfo + void resetMCInfo(mc3Bodyinfo mcInfo) { - kfvtx3bodydatalite( - // hypertriton - candidate.mass, - candidate.pos[0], candidate.pos[1], candidate.pos[2], - candidate.mom[0], candidate.mom[1], candidate.mom[2], candidate.mom[3], - candidate.charge, - candidate.dcaToPV[0], candidate.dcaToPV[1], // 3D, xy - candidate.cpaToPV[0], candidate.cpaToPV[1], // 3D, xy - candidate.decLen[0], candidate.decLen[1], // 3D, xy - candidate.ldl, - candidate.chi2geoNDF, candidate.chi2topoNDF, - candidate.ctau, - candidate.trackedClSize, - // V0 - candidate.massV0, - candidate.cpaV0ToPV, - // daughter momenta at vertex - candidate.protonMom[0], candidate.protonMom[1], candidate.protonMom[2], - candidate.pionMom[0], candidate.pionMom[1], candidate.pionMom[2], - candidate.deuteronMom[0], candidate.deuteronMom[1], candidate.deuteronMom[2], - candidate.tpcInnerParam[0], candidate.tpcInnerParam[1], candidate.tpcInnerParam[2], // proton, pion, deuteron - // daughter track quality - candidate.tpcNClDaughters[0], candidate.tpcNClDaughters[1], candidate.tpcNClDaughters[2], // proton, pion, deuteron - candidate.tpcChi2NClDeuteron, - candidate.DeltaPhiRotDeuteron, candidate.DeltaPhiRotProton, - // daughter DCAs KF - candidate.DCAdaughterToPV[0], candidate.DCAdaughterToPV[1], candidate.DCAdaughterToPV[2], // proton, pion, deuteron - candidate.DCAdaughterToPVxy[0], candidate.DCAdaughterToPVxy[1], candidate.DCAdaughterToPVxy[2], // proton, pion, deuteron - candidate.DCAdaughterToSVxy[0], candidate.DCAdaughterToSVxy[1], candidate.DCAdaughterToSVxy[2], // proton, pion, deuteron - candidate.DCAprotonToPion, candidate.DCAprotonToDeuteron, candidate.DCApionToDeuteron, - candidate.DCAvtxDaughters3D, - // daughter signs - candidate.daughterCharge[0], candidate.daughterCharge[1], candidate.daughterCharge[2], // proton, pion, deuteron - // daughter PID - candidate.tpcNsigma[0], candidate.tpcNsigma[1], candidate.tpcNsigma[2], candidate.tpcNsigma[3], // proton, pion, deuteron, bach with pion hyp - candidate.tofNsigmaDeuteron, - candidate.averageClusterSizeDeuteron, - candidate.pidForTrackingDeuteron); - - if (kfparticleConfigurations.fillCandidateFullTable) { - kfvtx3bodydata( - candidate.collisionID, candidate.trackPosID, candidate.trackNegID, candidate.trackBachID, candidate.decay3bodyID, - // hypertriton - candidate.mass, - candidate.pos[0], candidate.pos[1], candidate.pos[2], - candidate.posErr[0], candidate.posErr[1], candidate.posErr[2], - candidate.mom[0], candidate.mom[1], candidate.mom[2], candidate.mom[3], - candidate.momErr[0], candidate.momErr[1], candidate.momErr[2], candidate.momErr[3], - candidate.charge, - candidate.dcaToPV[0], candidate.dcaToPV[1], // 3D, xy - candidate.cpaToPV[0], candidate.cpaToPV[1], // 3D, xy - candidate.cpaToPVtopo[0], candidate.cpaToPVtopo[1], // 3D, xy - candidate.decLen[0], candidate.decLen[1], // 3D, xy - candidate.ldl, - candidate.chi2geoNDF, candidate.chi2topoNDF, - candidate.ctau, - candidate.trackedClSize, - // V0 - candidate.massV0, candidate.chi2massV0, - candidate.cpaV0ToPV, - // daughter momenta (at vertex and TPC) - candidate.protonMom[0], candidate.protonMom[1], candidate.protonMom[2], - candidate.pionMom[0], candidate.pionMom[1], candidate.pionMom[2], - candidate.deuteronMom[0], candidate.deuteronMom[1], candidate.deuteronMom[2], - candidate.tpcInnerParam[0], candidate.tpcInnerParam[1], candidate.tpcInnerParam[2], // proton, pion, deuteron - // daughter track quality - candidate.tpcNClDaughters[0], candidate.tpcNClDaughters[1], candidate.tpcNClDaughters[2], // proton, pion, deuteron - candidate.tpcChi2NClDeuteron, - candidate.DeltaPhiRotDeuteron, candidate.DeltaPhiRotProton, - // daughter DCAs KF - candidate.DCAdaughterToPV[0], candidate.DCAdaughterToPV[1], candidate.DCAdaughterToPV[2], // proton, pion, deuteron - candidate.DCAdaughterToPVxy[0], candidate.DCAdaughterToPVxy[1], candidate.DCAdaughterToPVxy[2], // proton, pion, deuteron - candidate.DCAdaughterToSVxy[0], candidate.DCAdaughterToSVxy[1], candidate.DCAdaughterToSVxy[2], // proton, pion, deuteron - candidate.DCAprotonToPion, candidate.DCAprotonToDeuteron, candidate.DCApionToDeuteron, - candidate.DCAvtxDaughters3D, - // daughter DCAs to PV propagated with material - candidate.trackDCAxy[0], candidate.trackDCAxy[1], candidate.trackDCAxy[2], // pos, neg, bach - candidate.trackDCA[0], candidate.trackDCA[1], candidate.trackDCA[2], // pos, neg, bach - // daughter signs - candidate.daughterCharge[0], candidate.daughterCharge[1], candidate.daughterCharge[2], // proton, pion, deuteron - // daughter PID - candidate.tpcNsigma[0], candidate.tpcNsigma[1], candidate.tpcNsigma[2], candidate.tpcNsigma[3], // proton, pion, deuteron, bach with pion hyp - candidate.tpcdEdx[0], candidate.tpcdEdx[1], candidate.tpcdEdx[2], // proton, pion, deuteron - candidate.tofNsigmaDeuteron, - candidate.averageClusterSizeDeuteron, - candidate.pidForTrackingDeuteron); - } - LOG(debug) << "Table filled."; + mcInfo.label = -1; + mcInfo.genMomentum[0] = -1., mcInfo.genMomentum[1] = -1., mcInfo.genMomentum[2] = -1.; + mcInfo.genDecVtx[0] = -1., mcInfo.genDecVtx[1] = -1., mcInfo.genDecVtx[2] = -1.; + mcInfo.genCt = -1.; + mcInfo.genPhi = -1., mcInfo.genEta = -1., mcInfo.genRapidity = -1.; + mcInfo.genMomProton = -1., mcInfo.genMomPion = -1., mcInfo.genMomDeuteron = -1.; + mcInfo.genPtProton = -1., mcInfo.genPtPion = -1., mcInfo.genPtDeuteron = -1.; + mcInfo.isTrueH3L = false, mcInfo.isTrueAntiH3L = false; + mcInfo.isReco = false; + mcInfo.daughterPrPdgCode = -1, mcInfo.daughterPiPdgCode = -1, mcInfo.daughterDePdgCode = -1; + mcInfo.isDeuteronPrimary = false; + mcInfo.survivedEventSel = false; + return; } - //------------------------------------------------------------------ - // function to fit KFParticle 3body vertex - template - void fit3bodyVertex(TKFParticle& kfpProton, TKFParticle& kfpPion, TKFParticle& kfpDeuteron, TKFParticle& KFHt) + // ______________________________________________________________ + // process functions + void processRealData(ColswithEvTimes const& collisions, + aod::Decay3Bodys const& decay3bodys, + aod::Tracked3Bodys const& tracked3bodys, + TracksExtPIDIUwithEvTimes const&, + aod::BCsWithTimestamps const& bcs) { - // Construct 3body vertex - int nDaughters3body = 3; - const KFParticle* Daughters3body[3] = {&kfpProton, &kfpPion, &kfpDeuteron}; - KFHt.SetConstructMethod(2); - try { - KFHt.Construct(Daughters3body, nDaughters3body); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to create Hyper triton 3-body vertex." << e.what(); + // initialise CCDB from BCs + if (!initCCDB(bcs, collisions)) { + LOG(info) << "CCDB initialisation failed, skipping candidate building." << std::endl; return; } - // transport all daughter tracks to hypertriton vertex - float HtVtx[3] = {0.}; - HtVtx[0] = KFHt.GetX(); - HtVtx[1] = KFHt.GetY(); - HtVtx[2] = KFHt.GetZ(); - kfpProton.TransportToPoint(HtVtx); - kfpPion.TransportToPoint(HtVtx); - kfpDeuteron.TransportToPoint(HtVtx); - LOG(debug) << "Hypertriton vertex constructed."; + + // get tracked cluster size info + fTrackedClSizeVector.clear(); + fTrackedClSizeVector.resize(decay3bodys.size(), 0); + for (const auto& tvtx3body : tracked3bodys) { + fTrackedClSizeVector[tvtx3body.decay3BodyId()] = tvtx3body.itsClsSize(); + } + + // do candidate analysis without MC processing + buildCandidates(bcs, // bc table + collisions, // collision table + decay3bodys, // decay3body table + static_cast(nullptr), // MC particle table + static_cast(nullptr)); // MC collision table } - //------------------------------------------------------------------ - // 3body candidate builder with KFParticle - template - void buildVtx3BodyDataTableKFParticle(TCollision const& collision, TTrack const& trackPos, TTrack const& trackNeg, TTrack const& trackBach, int64_t decay3bodyID, int bachelorcharge, double tofNSigmaDeuteron) + void processRealDataReduced(aod::RedCollisions const& collisions, + soa::Join const& decay3bodys, + aod::RedIUTracks const&) { - gROOT->SetBatch(true); - gRandom->SetSeed(42); - - // initialise KF primary vertex - KFPVertex kfpVertex = createKFPVertexFromCollision(collision); - KFParticle kfpv(kfpVertex); - LOG(debug) << "Created KF PV."; - - // fill event QA histograms --> only for events with a decay3body! - if (kfparticleConfigurations.doVertexQA) { - registry.fill(HIST("QA/Event/hVtxXKF"), kfpv.GetX()); - registry.fill(HIST("QA/Event/hVtxYKF"), kfpv.GetY()); - registry.fill(HIST("QA/Event/hVtxZKF"), kfpv.GetZ()); - registry.fill(HIST("QA/Event/hVtxCovXXKF"), kfpv.GetCovariance(0)); - registry.fill(HIST("QA/Event/hVtxCovYYKF"), kfpv.GetCovariance(2)); - registry.fill(HIST("QA/Event/hVtxCovZZKF"), kfpv.GetCovariance(5)); - registry.fill(HIST("QA/Event/hVtxCovXYKF"), kfpv.GetCovariance(1)); - registry.fill(HIST("QA/Event/hVtxCovXZKF"), kfpv.GetCovariance(3)); - registry.fill(HIST("QA/Event/hVtxCovYZKF"), kfpv.GetCovariance(4)); - registry.fill(HIST("QA/Event/hVtxX"), collision.posX()); - registry.fill(HIST("QA/Event/hVtxY"), collision.posY()); - registry.fill(HIST("QA/Event/hVtxZ"), collision.posZ()); - registry.fill(HIST("QA/Event/hVtxCovXX"), collision.covXX()); - registry.fill(HIST("QA/Event/hVtxCovYY"), collision.covYY()); - registry.fill(HIST("QA/Event/hVtxCovZZ"), collision.covZZ()); - registry.fill(HIST("QA/Event/hVtxCovXY"), collision.covXY()); - registry.fill(HIST("QA/Event/hVtxCovXZ"), collision.covXZ()); - registry.fill(HIST("QA/Event/hVtxCovYZ"), collision.covYZ()); + // get tracked cluster size info (saved in aod::Red3BodyInfo) + fTrackedClSizeVector.clear(); + fTrackedClSizeVector.resize(decay3bodys.size(), 0); + for (const auto& vtx3body : decay3bodys) { + fTrackedClSizeVector[vtx3body.globalIndex()] = vtx3body.trackedClSize(); } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxAll); - - auto trackParCovPos = getTrackParCov(trackPos); - auto trackParCovNeg = getTrackParCov(trackNeg); - auto trackParCovBach = getTrackParCov(trackBach); - LOG(debug) << "Got all daughter tracks."; - - bool isMatter = trackBach.sign() > 0 ? true : false; - - // ---------- fill track QA histograms ---------- - if (kfparticleConfigurations.doTrackQA) { - registry.fill(HIST("QA/Tracks/hTrackPosTPCNcls"), trackPos.tpcNClsFound()); - registry.fill(HIST("QA/Tracks/hTrackNegTPCNcls"), trackNeg.tpcNClsFound()); - registry.fill(HIST("QA/Tracks/hTrackBachTPCNcls"), trackBach.tpcNClsFound()); - registry.fill(HIST("QA/Tracks/hTrackPosHasTPC"), trackPos.hasTPC()); - registry.fill(HIST("QA/Tracks/hTrackNegHasTPC"), trackNeg.hasTPC()); - registry.fill(HIST("QA/Tracks/hTrackBachHasTPC"), trackBach.hasTPC()); - registry.fill(HIST("QA/Tracks/hTrackBachITSClusSizes"), trackBach.itsClusterSizes()); - if (isMatter) { - registry.fill(HIST("QA/Tracks/hTrackProtonTPCPID"), trackPos.sign() * trackPos.tpcInnerParam(), trackPos.tpcNSigmaPr()); - registry.fill(HIST("QA/Tracks/hTrackPionTPCPID"), trackNeg.sign() * trackNeg.tpcInnerParam(), trackNeg.tpcNSigmaPi()); - registry.fill(HIST("QA/Tracks/hTrackProtonPt"), trackPos.pt()); - registry.fill(HIST("QA/Tracks/hTrackPionPt"), trackNeg.pt()); + // do candidate analysis without MC processing + buildCandidates(static_cast(nullptr), // bc table + collisions, // collision table + decay3bodys, // decay3body table + static_cast(nullptr), // MC particle table + static_cast(nullptr)); // MC collision table + } + + void processRealDataReduced3bodyMixing(aod::RedCollisions const&, + soa::Join const& decay3bodys, + aod::RedIUTracks const&) + { + auto xAxis = registry.get(HIST("Mixing/hDecay3BodyRadiusPhi"))->GetXaxis(); + auto yAxis = registry.get(HIST("Mixing/hDecay3BodyRadiusPhi"))->GetYaxis(); + + for (const auto& decay3body : decay3bodys) { + int bin_Radius, bin_Phi; + if (decay3bodyBuilderOpts.useKFParticle) { + bin_Radius = xAxis->FindBin(decay3body.radiusKF()); + bin_Phi = yAxis->FindBin(decay3body.phiKF()); + registry.fill(HIST("Mixing/hDecay3BodyPosZ"), decay3body.poszKF()); } else { - registry.fill(HIST("QA/Tracks/hTrackProtonTPCPID"), trackNeg.sign() * trackNeg.tpcInnerParam(), trackNeg.tpcNSigmaPr()); - registry.fill(HIST("QA/Tracks/hTrackPionTPCPID"), trackPos.sign() * trackPos.tpcInnerParam(), trackPos.tpcNSigmaPi()); - registry.fill(HIST("QA/Tracks/hTrackProtonPt"), trackNeg.pt()); - registry.fill(HIST("QA/Tracks/hTrackPionPt"), trackPos.pt()); + bin_Radius = xAxis->FindBin(decay3body.radiusDCA()); + bin_Phi = yAxis->FindBin(decay3body.phiDCA()); + registry.fill(HIST("Mixing/hDecay3BodyPosZ"), decay3body.poszDCA()); } - registry.fill(HIST("QA/Tracks/hTrackBachTPCPID"), trackBach.sign() * trackBach.tpcInnerParam(), trackBach.tpcNSigmaDe()); - registry.fill(HIST("QA/Tracks/hTrackBachPt"), trackBach.pt()); + registry.fill(HIST("Mixing/hDecay3BodyRadiusPhi"), xAxis->GetBinCenter(bin_Radius), yAxis->GetBinCenter(bin_Phi)); } - // -------- STEP 1: track selection -------- - // collision ID --> not correct? tracks can have different collisions, but belong to one 3prong vertex! - // if (trackPos.collisionId() != trackNeg.collisionId() || trackPos.collisionId() != trackBach.collisionId() || trackNeg.collisionId() != trackBach.collisionId()) { - // continue; - // } - // track IDs --> already checked in SVertexer! + if (decay3bodyBuilderOpts.useKFParticle) { + Binning3BodyKF binningOnRadPhiKF{{mixingOpts.bins3BodyRadius, mixingOpts.bins3BodyPhi}, true}; + buildMixedCandidates(decay3bodys, binningOnRadPhiKF); + } else { + Binning3BodyDCAfitter binningOnRadPhiDCA{{mixingOpts.bins3BodyRadius, mixingOpts.bins3BodyPhi}, true}; + buildMixedCandidates(decay3bodys, binningOnRadPhiDCA); + } + } - // track signs (pos, neg, bach) --> sanity check, should already be in SVertexer - if (trackPos.sign() != +1 || trackNeg.sign() != -1) { + void processMonteCarlo(ColswithEvTimesLabeled const& collisions, + aod::Decay3Bodys const& decay3bodys, + aod::Tracked3Bodys const& tracked3bodys, + TracksExtPIDIUwithEvTimesLabeled const&, + aod::BCsWithTimestamps const& bcs, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions) + { + // initialise CCDB from BCs + if (!initCCDB(bcs, collisions)) { + LOG(info) << "CCDB initialisation failed, skipping candidate building." << std::endl; return; } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxCharge); - // track eta - if (std::abs(trackPos.eta()) > kfparticleConfigurations.maxEta || std::abs(trackNeg.eta()) > kfparticleConfigurations.maxEta || std::abs(trackBach.eta()) > kfparticleConfigurations.maxEtaDeuteron) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxEta); - - // number of TPC clusters - if (trackBach.tpcNClsFound() <= kfparticleConfigurations.mintpcNClsBach) { - return; - } - if (isMatter && ((kfparticleConfigurations.useTPCforPion && trackNeg.tpcNClsFound() <= kfparticleConfigurations.mintpcNClsPion) || trackPos.tpcNClsFound() <= kfparticleConfigurations.mintpcNClsProton)) { - return; - } else if (!isMatter && ((kfparticleConfigurations.useTPCforPion && trackPos.tpcNClsFound() <= kfparticleConfigurations.mintpcNClsPion) || trackNeg.tpcNClsFound() <= kfparticleConfigurations.mintpcNClsProton)) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxTPCNcls); - - // number of TPC crossed rows - if (trackBach.tpcNClsCrossedRows() <= kfparticleConfigurations.mintpcCrossedRows) { - return; - } - if (isMatter && ((kfparticleConfigurations.useTPCforPion && trackNeg.tpcNClsCrossedRows() <= kfparticleConfigurations.mintpcCrossedRowsPion) || trackPos.tpcNClsCrossedRows() <= kfparticleConfigurations.mintpcCrossedRows)) { - return; - } else if (!isMatter && ((kfparticleConfigurations.useTPCforPion && trackPos.tpcNClsCrossedRows() <= kfparticleConfigurations.mintpcCrossedRowsPion) || trackNeg.tpcNClsCrossedRows() <= kfparticleConfigurations.mintpcCrossedRows)) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxTPCRows); - - // TPC PID - float tpcNsigmaProton; - float tpcNsigmaPion; - float dEdxProton; - float dEdxPion; - float tpcNsigmaDeuteron = trackBach.tpcNSigmaDe(); - float tpcNsigmaPionBach = trackBach.tpcNSigmaPi(); - float dEdxDeuteron = trackBach.tpcSignal(); - if (isMatter) { // hypertriton (proton, pi-, deuteron) - tpcNsigmaProton = trackPos.tpcNSigmaPr(); - tpcNsigmaPion = trackNeg.tpcNSigmaPi(); - dEdxProton = trackPos.tpcSignal(); - dEdxPion = trackNeg.tpcSignal(); - if (!selectTPCPID(trackPos, trackNeg, trackBach)) { - return; - } - } else if (!isMatter) { // anti-hypertriton (anti-proton, pi+, deuteron) - tpcNsigmaProton = trackNeg.tpcNSigmaPr(); - tpcNsigmaPion = trackPos.tpcNSigmaPi(); - dEdxProton = trackNeg.tpcSignal(); - dEdxPion = trackPos.tpcSignal(); - if (!selectTPCPID(trackNeg, trackPos, trackBach)) { - return; - } - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxTPCPID); - LOG(debug) << "Basic track selections done."; - - // Average ITS cluster size of deuteron track - double averageClusterSizeDeuteron(0); - int nCls(0); - for (int i = 0; i < 7; i++) { - int clusterSize = trackBach.itsClsSizeInLayer(i); - averageClusterSizeDeuteron += static_cast(clusterSize); - if (clusterSize > 0) - nCls++; - } - averageClusterSizeDeuteron = averageClusterSizeDeuteron / static_cast(nCls); - - // track DCAxy and DCAz to PV associated with decay3body - o2::dataformats::VertexBase mPV; - o2::dataformats::DCA mDcaInfoCovPos; - o2::dataformats::DCA mDcaInfoCovNeg; - o2::dataformats::DCA mDcaInfoCovBach; - auto trackParCovPVPos = trackParCovPos; - auto trackParCovPVNeg = trackParCovNeg; - auto trackParCovPVBach = trackParCovBach; - mPV.setPos({collision.posX(), collision.posY(), collision.posZ()}); - mPV.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mPV, trackParCovPVPos, 2.f, matCorr, &mDcaInfoCovPos); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mPV, trackParCovPVNeg, 2.f, matCorr, &mDcaInfoCovNeg); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mPV, trackParCovPVBach, 2.f, matCorr, &mDcaInfoCovBach); - auto TrackPosDcaXY = mDcaInfoCovPos.getY(); - auto TrackNegDcaXY = mDcaInfoCovNeg.getY(); - auto TrackBachDcaXY = mDcaInfoCovBach.getY(); - auto TrackPosDcaZ = mDcaInfoCovPos.getZ(); - auto TrackNegDcaZ = mDcaInfoCovNeg.getZ(); - auto TrackBachDcaZ = mDcaInfoCovBach.getZ(); - // calculate 3D track DCA - auto TrackPosDca = std::sqrt(TrackPosDcaXY * TrackPosDcaXY + TrackPosDcaZ * TrackPosDcaZ); - auto TrackNegDca = std::sqrt(TrackNegDcaXY * TrackNegDcaXY + TrackNegDcaZ * TrackNegDcaZ); - auto TrackBachDca = std::sqrt(TrackBachDcaXY * TrackBachDcaXY + TrackBachDcaZ * TrackBachDcaZ); - // selection - if (kfparticleConfigurations.doDCAPreSel && isMatter && (std::fabs(TrackNegDcaXY) <= kfparticleConfigurations.mindcaXYPionPV || std::fabs(TrackPosDcaXY) <= kfparticleConfigurations.mindcaXYProtonPV)) { - return; - } else if (kfparticleConfigurations.doDCAPreSel && !isMatter && (std::fabs(TrackPosDcaXY) <= kfparticleConfigurations.mindcaXYPionPV || std::fabs(TrackNegDcaXY) <= kfparticleConfigurations.mindcaXYProtonPV)) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxDCAxyPV); - if (kfparticleConfigurations.doDCAPreSel && isMatter && (std::fabs(TrackNegDcaZ) <= kfparticleConfigurations.mindcaZPionPV || std::fabs(TrackPosDcaZ) <= kfparticleConfigurations.mindcaZProtonPV)) { - return; - } else if (kfparticleConfigurations.doDCAPreSel && !isMatter && (std::fabs(TrackPosDcaZ) <= kfparticleConfigurations.mindcaZPionPV || std::fabs(TrackNegDcaZ) <= kfparticleConfigurations.mindcaZProtonPV)) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxDCAzPV); - - // daughter track momentum at inner wall of TPC - float tpcInnerParamProton; - float tpcInnerParamPion; - float tpcInnerParamDeuteron = trackBach.tpcInnerParam(); - if (isMatter) { // hypertriton (proton, pi-, deuteron) - tpcInnerParamProton = trackPos.tpcInnerParam(); - tpcInnerParamPion = trackNeg.tpcInnerParam(); - } else if (!isMatter) { // anti-hypertriton (anti-proton, pi+, deuteron) - tpcInnerParamProton = trackNeg.tpcInnerParam(); - tpcInnerParamPion = trackPos.tpcInnerParam(); - } - - // -------- STEP 2: fit vertex with proton and pion -------- - // Fit vertex with DCA fitter to find minimization point --> uses material corrections implicitly - if (kfparticleConfigurations.doDCAFitterPreMinimum) { - try { - fitter3body.process(trackParCovPos, trackParCovNeg, trackParCovBach); - } catch (std::runtime_error& e) { - LOG(error) << "Exception caught in DCA fitter process call: Not able to fit decay3body vertex!"; - return; - } - // re-acquire tracks at vertex position from DCA fitter - trackParCovPos = fitter3body.getTrack(0); - trackParCovNeg = fitter3body.getTrack(1); - trackParCovBach = fitter3body.getTrack(2); - - LOG(debug) << "Minimum found with DCA fitter for decay3body."; - } - - // create KFParticle objects from tracks - KFParticle kfpProton, kfpPion; - if (isMatter) { - kfpProton = createKFParticleFromTrackParCov(trackParCovPos, trackPos.sign(), constants::physics::MassProton); - kfpPion = createKFParticleFromTrackParCov(trackParCovNeg, trackNeg.sign(), constants::physics::MassPionCharged); - } else if (!isMatter) { - kfpProton = createKFParticleFromTrackParCov(trackParCovNeg, trackNeg.sign(), constants::physics::MassProton); - kfpPion = createKFParticleFromTrackParCov(trackParCovPos, trackPos.sign(), constants::physics::MassPionCharged); - } - LOG(debug) << "KFParticle objects created from daughter tracks."; - - // Construct V0 as intermediate step - KFParticle KFV0; - int nDaughtersV0 = 2; - const KFParticle* DaughtersV0[2] = {&kfpProton, &kfpPion}; - KFV0.SetConstructMethod(2); - try { - KFV0.Construct(DaughtersV0, nDaughtersV0); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to create V0 vertex from daughter tracks." << e.what(); - return; - } - KFV0.TransportToDecayVertex(); - LOG(debug) << "V0 constructed."; - - // check V0 mass and set mass constraint - float massV0, sigmaMassV0; - KFV0.GetMass(massV0, sigmaMassV0); - KFParticle KFV0Mass = KFV0; - KFV0Mass.SetNonlinearMassConstraint(o2::constants::physics::MassLambda); - float chi2massV0 = KFV0Mass.GetChi2() / KFV0Mass.GetNDF(); - if (kfparticleConfigurations.useLambdaMassConstraint) { - LOG(debug) << "V0 mass constraint applied."; - KFV0 = KFV0Mass; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxV0MassConst); - - // apply virtual V0 cuts used in SVertexer in case of 3body mixing with proton track - if (kfparticleConfigurations.mixingType == 1 && kfparticleConfigurations.applySVertexerV0Cuts) { - // V0 radius - if (std::sqrt(KFV0.GetX() * KFV0.GetX() + KFV0.GetY() * KFV0.GetY()) <= 0.5) { - return; - } - // pT - if (KFV0.GetPt() <= 0.01) { - return; - } - // pz/pT - if (KFV0.GetPz() / KFV0.GetPt() >= 2) { - return; - } - // cos(PA) - if (cpaXYFromKF(KFV0, kfpv) <= 0.9 || cpaFromKF(KFV0, kfpv) <= 0.8) { - return; - } - } - - // -------- STEP 3: fit three body vertex -------- - // Create KFParticle object from deuteron track - KFParticle kfpDeuteron; - kfpDeuteron = createKFParticleFromTrackParCov(trackParCovBach, trackBach.sign() * bachelorcharge, constants::physics::MassDeuteron); - LOG(debug) << "KFParticle created from deuteron track."; - - // Construct vertex - KFParticle KFHt; - fit3bodyVertex(kfpProton, kfpPion, kfpDeuteron, KFHt); - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxhasSV); - - // -------- STEP 4: daughter selections after geometrical vertex fit -------- - // daughter DCAs with KF - if ((kfpProton.GetDistanceFromParticle(kfpPion) >= kfparticleConfigurations.maxDcaProPi) || (kfpProton.GetDistanceFromParticle(kfpDeuteron) >= kfparticleConfigurations.maxDcaProDeu) || (kfpPion.GetDistanceFromParticle(kfpDeuteron) >= kfparticleConfigurations.maxDcaPiDe)) { - return; - } - float DCAvtxDaughters3D = kfpProton.GetDistanceFromParticle(kfpPion) + kfpProton.GetDistanceFromParticle(kfpDeuteron) + kfpPion.GetDistanceFromParticle(kfpDeuteron); - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxDcaDau); - LOG(debug) << "DCA selection after vertex fit applied."; - - // daughter DCAs to vertex - if (kfpProton.GetDistanceFromVertexXY(KFHt) >= kfparticleConfigurations.maxDcaXYSVDau || kfpPion.GetDistanceFromVertexXY(KFHt) >= kfparticleConfigurations.maxDcaXYSVDau || kfpDeuteron.GetDistanceFromVertexXY(KFHt) >= kfparticleConfigurations.maxDcaXYSVDau) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxDcaDauVtx); - LOG(debug) << "DCA to vertex selection after vertex fit applied."; - - // daughter pT - if (kfpProton.GetPt() < kfparticleConfigurations.minPtProton || kfpProton.GetPt() > kfparticleConfigurations.maxPtProton || kfpPion.GetPt() < kfparticleConfigurations.minPtPion || kfpPion.GetPt() > kfparticleConfigurations.maxPtPion || kfpDeuteron.GetPt() < kfparticleConfigurations.minPtDeuteron || kfpDeuteron.GetPt() > kfparticleConfigurations.maxPtDeuteron) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxDauPt); - LOG(debug) << "Daughter pT selection applied."; - - // -------- STEP 5: candidate selection and constraint after geometrical vertex fit -------- - // Rapidity - float rapHt = RecoDecay::y(std::array{KFHt.GetPx(), KFHt.GetPy(), KFHt.GetPz()}, o2::constants::physics::MassHyperTriton); - if (std::abs(rapHt) > kfparticleConfigurations.maxRapidityHt) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxRap); - - // Pt selection - if (KFHt.GetPt() <= kfparticleConfigurations.minPtHt || KFHt.GetPt() >= kfparticleConfigurations.maxPtHt) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxPt); - - // Mass window - float massHt, sigmaMassHt; - KFHt.GetMass(massHt, sigmaMassHt); - if (massHt <= kfparticleConfigurations.minMassHt || massHt >= kfparticleConfigurations.maxMassHt) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxMass); - - // cos(PA) to PV - if (std::abs(cpaFromKF(KFHt, kfpv)) <= kfparticleConfigurations.minCosPA) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxCosPA); - - // cos(PA) xy to PV - if (std::abs(cpaXYFromKF(KFHt, kfpv)) <= kfparticleConfigurations.minCosPAxy) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxCosPAXY); - - // chi2 geometrical - float chi2geoNDF = KFHt.GetChi2() / KFHt.GetNDF(); - if (kfparticleConfigurations.applyTopoSel && chi2geoNDF >= kfparticleConfigurations.maxChi2geo) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxChi2geo); - LOG(debug) << "Basic selections after vertex fit done."; - - // ctau before topo constraint - if (KFHt.GetLifeTime() > kfparticleConfigurations.maxctauHt) { - return; - } - - // Set vertex constraint and topological selection - KFParticle KFHtPV = KFHt; - try { - KFHtPV.SetProductionVertex(kfpv); - } catch (std::runtime_error& e) { - LOG(error) << "Exception caught KFParticle process call: Topological constraint failed"; - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxTopoConstr); // to check if topo constraint fails - // get topological chi2 - float chi2topoNDF = KFHtPV.GetChi2() / KFHtPV.GetNDF(); - KFHtPV.TransportToDecayVertex(); - if (kfparticleConfigurations.applyTopoSel && chi2topoNDF >= kfparticleConfigurations.maxChi2topo) { - return; - } - registry.fill(HIST("Counters/hVtx3BodyCounterKFParticle"), kKfVtxChi2topo); - - // -------- STEP 6: collect and fill candidate info -------- - // get cluster size of strangeness tracked 3bodies - float trackedClSize; - if (decay3bodyID == -1) { - trackedClSize = 0; - } else { - trackedClSize = !fTrackedClSizeVector.empty() ? fTrackedClSizeVector[decay3bodyID] : 0; - } - - // candidate filling - kfCandidate candidate; - candidate.collisionID = collision.globalIndex(); - candidate.trackPosID = trackPos.globalIndex(); - candidate.trackNegID = trackNeg.globalIndex(); - candidate.trackBachID = trackBach.globalIndex(); - candidate.decay3bodyID = decay3bodyID; - // hypertriton - candidate.mass = massHt; - candidate.pos[0] = KFHt.GetX(); - candidate.pos[1] = KFHt.GetY(); - candidate.pos[2] = KFHt.GetZ(); - candidate.posErr[0] = KFHt.GetErrX(); - candidate.posErr[1] = KFHt.GetErrY(); - candidate.posErr[2] = KFHt.GetErrZ(); - candidate.mom[0] = KFHt.GetPx(); - candidate.mom[1] = KFHt.GetPy(); - candidate.mom[2] = KFHt.GetPz(); - candidate.mom[3] = KFHt.GetPt(); - candidate.momErr[0] = KFHt.GetErrPx(); - candidate.momErr[1] = KFHt.GetErrPy(); - candidate.momErr[2] = KFHt.GetErrPz(); - candidate.momErr[3] = KFHt.GetErrPt(); - candidate.charge = KFHt.GetQ(); - candidate.dcaToPV[0] = KFHt.GetDistanceFromVertex(kfpv); - candidate.dcaToPV[1] = KFHt.GetDistanceFromVertexXY(kfpv); - candidate.cpaToPV[0] = cpaFromKF(KFHt, kfpv); - candidate.cpaToPV[1] = cpaXYFromKF(KFHt, kfpv); - candidate.cpaToPVtopo[0] = cpaFromKF(KFHtPV, kfpv); - candidate.cpaToPVtopo[1] = cpaXYFromKF(KFHtPV, kfpv); - candidate.decLen[0] = KFHtPV.GetDecayLength(); - candidate.decLen[1] = KFHtPV.GetDecayLengthXY(); - candidate.ldl = KFHtPV.GetDecayLength() / KFHtPV.GetErrDecayLength(); - candidate.chi2geoNDF = chi2geoNDF; - candidate.chi2topoNDF = chi2topoNDF; - candidate.ctau = KFHtPV.GetLifeTime(); - candidate.trackedClSize = trackedClSize; - // V0 - candidate.massV0 = massV0; - candidate.chi2massV0 = chi2massV0; - candidate.cpaV0ToPV = cpaFromKF(KFV0, kfpv); - // daughter momenta - candidate.protonMom[0] = kfpProton.GetPx(); - candidate.protonMom[1] = kfpProton.GetPy(); - candidate.protonMom[2] = kfpProton.GetPz(); - candidate.pionMom[0] = kfpPion.GetPx(); - candidate.pionMom[1] = kfpPion.GetPy(); - candidate.pionMom[2] = kfpPion.GetPz(); - candidate.deuteronMom[0] = kfpDeuteron.GetPx(); - candidate.deuteronMom[1] = kfpDeuteron.GetPy(); - candidate.deuteronMom[2] = kfpDeuteron.GetPz(); - candidate.tpcInnerParam[0] = tpcInnerParamProton; - candidate.tpcInnerParam[1] = tpcInnerParamPion; - candidate.tpcInnerParam[2] = tpcInnerParamDeuteron; - // daughter DCAs with KF - candidate.DCAdaughterToPV[0] = kfpProton.GetDistanceFromVertex(kfpv); - candidate.DCAdaughterToPV[1] = kfpPion.GetDistanceFromVertex(kfpv); - candidate.DCAdaughterToPV[2] = kfpDeuteron.GetDistanceFromVertex(kfpv); - candidate.DCAdaughterToPVxy[0] = kfpProton.GetDistanceFromVertexXY(kfpv); - candidate.DCAdaughterToPVxy[1] = kfpPion.GetDistanceFromVertexXY(kfpv); - candidate.DCAdaughterToPVxy[2] = kfpDeuteron.GetDistanceFromVertexXY(kfpv); - candidate.DCAdaughterToSVxy[0] = kfpProton.GetDistanceFromVertexXY(KFHt); - candidate.DCAdaughterToSVxy[1] = kfpPion.GetDistanceFromVertexXY(KFHt); - candidate.DCAdaughterToSVxy[2] = kfpDeuteron.GetDistanceFromVertexXY(KFHt); - candidate.DCAprotonToPion = kfpProton.GetDistanceFromParticle(kfpPion); - candidate.DCAprotonToDeuteron = kfpProton.GetDistanceFromParticle(kfpDeuteron); - candidate.DCApionToDeuteron = kfpPion.GetDistanceFromParticle(kfpDeuteron); - candidate.DCAvtxDaughters3D = DCAvtxDaughters3D; - // daughter DCAs with material corrections - candidate.trackDCAxy[0] = TrackPosDcaXY; - candidate.trackDCAxy[1] = TrackNegDcaXY; - candidate.trackDCAxy[2] = TrackBachDcaXY; - candidate.trackDCA[0] = TrackPosDca; - candidate.trackDCA[1] = TrackNegDca; - candidate.trackDCA[2] = TrackBachDca; - // daughter signs - candidate.daughterCharge[0] = kfpProton.GetQ(); - candidate.daughterCharge[1] = kfpPion.GetQ(); - candidate.daughterCharge[2] = trackBach.sign(); - // daughter PID - candidate.tpcNsigma[0] = tpcNsigmaProton; - candidate.tpcNsigma[1] = tpcNsigmaPion; - candidate.tpcNsigma[2] = tpcNsigmaDeuteron; - candidate.tpcNsigma[3] = tpcNsigmaPionBach; - candidate.tpcdEdx[0] = dEdxProton; - candidate.tpcdEdx[1] = dEdxPion; - candidate.tpcdEdx[2] = dEdxDeuteron; - candidate.tofNsigmaDeuteron = tofNSigmaDeuteron; - candidate.averageClusterSizeDeuteron = averageClusterSizeDeuteron; - candidate.pidForTrackingDeuteron = trackBach.pidForTracking(); - - //------------------------------------------------------------------ - // table filling - fillCandidateTable(candidate); - LOG(debug) << "Table filled."; - - // fill event counter hist (has selected candidate) --> only filled once per vertex - registry.fill(HIST("Counters/hEventCounterKFParticle"), 3.5); - } // end buildVtx3BodyDataTableKFParticle - - //------------------------------------------------------------------ - void processRun3(ColwithEvTimes const& collisions, aod::Decay3Bodys const& decay3bodys, TrackExtPIDIUwithEvTimes const&, aod::BCsWithTimestamps const&) - { - VtxCandidates.clear(); - - registry.fill(HIST("hEventCounter"), 0.5, collisions.size()); - - for (const auto& d3body : decay3bodys) { - auto t0 = d3body.track0_as(); - auto t1 = d3body.track1_as(); - auto t2 = d3body.track2_as(); - auto collision = d3body.collision_as(); - auto bc = collision.bc_as(); - initCCDB(bc); - - // Recalculate the TOF PID - double tofNSigmaBach = -999; - if (t2.has_collision() && t2.hasTOF()) { - auto originalcol = t2.template collision_as(); - tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(t2, originalcol, collision); - } - - fillVtxCand(collision, t0, t1, t2, d3body.globalIndex(), bachelorcharge, tofNSigmaBach); - } - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3, "Produce DCA fitter decay3body tables", true); - - //------------------------------------------------------------------ - void processRun3Reduced(aod::RedCollisions const& collisions, aod::RedDecay3Bodys const& decay3bodys, aod::RedIUTracks const&) - { - VtxCandidates.clear(); - - registry.fill(HIST("hEventCounter"), 0.5, collisions.size()); - - for (const auto& d3body : decay3bodys) { - auto t0 = d3body.track0_as(); - auto t1 = d3body.track1_as(); - auto t2 = d3body.track2_as(); - auto collision = d3body.collision_as(); - - initCCDBfromRunNumber(collision.runNumber()); - fillVtxCand(collision, t0, t1, t2, d3body.globalIndex(), bachelorcharge, t2.tofNSigmaDe()); - } - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3Reduced, "Produce DCA fitter decay3body tables with reduced data", false); - - //------------------------------------------------------------------ - // Event-mixing background - void processRun3ReducedEM(ReducedCollisionsMultsCents const& collisions, aod::RedDecay3Bodys const& decay3bodys, aod::RedIUTracks const&) - { - auto xAxis = registry.get(HIST("hEventPairs"))->GetXaxis(); - auto yAxis = registry.get(HIST("hEventPairs"))->GetYaxis(); - - // fill collisions counter - for (const auto& collision : collisions) { - int bin_PosZ = xAxis->FindBin(collision.posZ()); - int bin_Mult = yAxis->FindBin(collision.multNTracksPV()); - registry.fill(HIST("hEventCount"), xAxis->GetBinCenter(bin_PosZ), yAxis->GetBinCenter(bin_Mult)); - } - VtxCandidates.clear(); - - auto tuple = std::make_tuple(decay3bodys); - BinningTypeColEM binningEvent{{dcaFitterEMSel.binsVtxZ, dcaFitterEMSel.binsMultiplicity}, true}; - SameKindPair pair{binningEvent, dcaFitterEMSel.nUseMixed, -1, collisions, tuple, &cache}; - - for (const auto& [c0, decay3bodys0, c1, decay3bodys1] : pair) { - // LOG(info) << "Processing event mixing with collisions " << c0.globalIndex() << " and " << c1.globalIndex(); - initCCDBfromRunNumber(c0.runNumber()); - - int bin_PosZ = xAxis->FindBin(c0.posZ()); - int bin_Mult = yAxis->FindBin(c0.multNTracksPV()); - registry.fill(HIST("hEventPairs"), xAxis->GetBinCenter(bin_PosZ), yAxis->GetBinCenter(bin_Mult)); - - for (const auto& [d3body0, d3body1] : combinations(soa::CombinationsFullIndexPolicy(decay3bodys0, decay3bodys1))) { - - registry.fill(HIST("hDecay3BodyPairsBeforeCut"), xAxis->GetBinCenter(bin_PosZ), yAxis->GetBinCenter(bin_Mult)); - - auto tpos0 = d3body0.track0_as(); - auto tneg0 = d3body0.track1_as(); - auto tbach0 = d3body0.track2_as(); - auto tpos1 = d3body1.track0_as(); - auto tneg1 = d3body1.track1_as(); - auto tbach1 = d3body1.track2_as(); - - // try to fit the vertex for decay3body0 - auto Trackpos0 = getTrackParCov(tpos0); - auto Trackneg0 = getTrackParCov(tneg0); - auto Trackbach0 = getTrackParCov(tbach0); - int nVtx0 = fitter3body.process(Trackpos0, Trackneg0, Trackbach0); - if (nVtx0 == 0) { - continue; - ; - } - - if ((tbach0.sign() > 0 && !(tbach1.sign() > 0)) || (tbach0.sign() < 0 && !(tbach1.sign() < 0)) || tbach0.globalIndex() == tbach1.globalIndex()) { // only combine if tbach1 has correct sign and is not same as tbach0 - continue; - } - - const auto& vtx0XYZ = fitter3body.getPCACandidate(); - float rVtx0 = std::hypot(vtx0XYZ[0], vtx0XYZ[1]); - registry.fill(HIST("hRadius0"), rVtx0); - - std::array ppos0 = {0.}, pneg0 = {0.}, pbach0{0.}; - const auto& propagatedtpos0 = fitter3body.getTrack(0); - const auto& propagatedtneg0 = fitter3body.getTrack(1); - const auto& propagatedtbach0 = fitter3body.getTrack(2); - propagatedtpos0.getPxPyPzGlo(ppos0); - propagatedtneg0.getPxPyPzGlo(pneg0); - propagatedtbach0.getPxPyPzGlo(pbach0); - for (int i = 0; i < 3; i++) { - pbach0[i] *= bachelorcharge; - } - std::array p3B0 = {ppos0[0] + pneg0[0] + pbach0[0], ppos0[1] + pneg0[1] + pbach0[1], ppos0[2] + pneg0[2] + pbach0[2]}; - float phiVtx0 = std::atan2(p3B0[1], p3B0[0]); - - // try to fit the vertex for decay3body1 - auto Trackpos1 = getTrackParCov(tpos1); - auto Trackneg1 = getTrackParCov(tneg1); - auto Trackbach1 = getTrackParCov(tbach1); - int nVtx1 = fitter3body.process(Trackpos1, Trackneg1, Trackbach1); - if (nVtx1 == 0) { - continue; - } - - const auto& vtx1XYZ = fitter3body.getPCACandidate(); - float rVtx1 = std::hypot(vtx1XYZ[0], vtx1XYZ[1]); - registry.fill(HIST("hRadius1"), rVtx1); - - std::array ppos1 = {0.}, pneg1 = {0.}, pbach1{0.}; - const auto& propagatedtpos1 = fitter3body.getTrack(0); - const auto& propagatedtneg1 = fitter3body.getTrack(1); - const auto& propagatedtbach1 = fitter3body.getTrack(2); - propagatedtpos1.getPxPyPzGlo(ppos1); - propagatedtneg1.getPxPyPzGlo(pneg1); - propagatedtbach1.getPxPyPzGlo(pbach1); - for (int i = 0; i < 3; i++) { - pbach1[i] *= bachelorcharge; - } - std::array p3B1 = {ppos1[0] + pneg1[0] + pbach1[0], ppos1[1] + pneg1[1] + pbach1[1], ppos1[2] + pneg1[2] + pbach1[2]}; - float phiVtx1 = std::atan2(p3B1[1], p3B1[0]); - registry.fill(HIST("hPhi0"), phiVtx0 * o2::constants::math::Rad2Deg); - registry.fill(HIST("hPhi1"), phiVtx1 * o2::constants::math::Rad2Deg); - // convert deltaPhi to range [-pi, pi] - float deltaPhi = RecoDecay::constrainAngle(phiVtx1 - phiVtx0, -o2::constants::math::PI); - // check if radius and phi of the two vertices are compatible - registry.fill(HIST("hDeltaRadius"), rVtx1 - rVtx0); - registry.fill(HIST("hDeltaPhi"), deltaPhi * o2::constants::math::Rad2Deg); - if (std::abs(deltaPhi) * o2::constants::math::Rad2Deg > dcaFitterEMSel.maxDeltaPhiColMixing || std::abs(rVtx1 - rVtx0) > dcaFitterEMSel.maxDeltaRadiusColMixing) { - continue; - } - registry.fill(HIST("hDecay3BodyPairsAfterCut"), xAxis->GetBinCenter(bin_PosZ), yAxis->GetBinCenter(bin_Mult)); - - fillVtxCand(c0, tpos0, tneg0, tbach1, -1, bachelorcharge, tbach1.tofNSigmaDe()); - // initCCDBfromRunNumber(c1.runNumber()); - fillVtxCand(c1, tpos1, tneg1, tbach0, -1, bachelorcharge, tbach0.tofNSigmaDe()); - } - } - - // Aviod break of preslice in following workflow - /*std::sort(VtxCandidates.begin(), VtxCandidates.end(), [](const VtxCandidate a, const VtxCandidate b) { - return a.collisionId < b.collisionId; - });*/ - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3ReducedEM, "Produce event-mixing background", false); - - void processRun3Reduced3bodyMixing(ReducedCollisionsMults const&, aod::RedIUTracks const&, soa::Join const& decay3bodys) - { - VtxCandidates.clear(); - - auto xAxis = registry.get(HIST("hDecay3BodyRadiusPhi"))->GetXaxis(); - auto yAxis = registry.get(HIST("hDecay3BodyRadiusPhi"))->GetYaxis(); - - for (const auto& decay3body : decay3bodys) { - int bin_Radius = xAxis->FindBin(decay3body.svRadius()); - int bin_Phi = yAxis->FindBin(decay3body.momPhi()); - registry.fill(HIST("hDecay3BodyRadiusPhi"), xAxis->GetBinCenter(bin_Radius), yAxis->GetBinCenter(bin_Phi)); - registry.fill(HIST("hDecay3BodyPosZ"), decay3body.svPosZ()); - } - - Binning3BodyDCAFitter binningOnRadiusPhi{{dcaFitterEMSel.bins3BodyRadius, dcaFitterEMSel.bins3BodyPhiDegree}, true}; - doMixed3Body(decay3bodys, binningOnRadiusPhi); - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3Reduced3bodyMixing, "Produce mixing background directly from mixed decay3bodys based on DCAFitter Info", false); - - void processRun3Reduced3bodyMixingKFInfo(ReducedCollisionsMults const&, aod::RedIUTracks const&, soa::Join const& decay3bodys) - { - VtxCandidates.clear(); - - auto xAxis = registry.get(HIST("hDecay3BodyRadiusPhi"))->GetXaxis(); - auto yAxis = registry.get(HIST("hDecay3BodyRadiusPhi"))->GetYaxis(); - - for (const auto& decay3body : decay3bodys) { - int bin_Radius = xAxis->FindBin(decay3body.radius()); - int bin_Phi = yAxis->FindBin(decay3body.phi()); - registry.fill(HIST("hDecay3BodyRadiusPhi"), xAxis->GetBinCenter(bin_Radius), yAxis->GetBinCenter(bin_Phi)); - registry.fill(HIST("hDecay3BodyPosZ"), decay3body.posz()); - } - - Binning3BodyKFInfo binningOnRadiusPhi{{dcaFitterEMSel.bins3BodyRadius, dcaFitterEMSel.bins3BodyPhi}, true}; - doMixed3Body(decay3bodys, binningOnRadiusPhi); - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3Reduced3bodyMixingKFInfo, "Produce mixing background directly from mixed decay3bodys based on KF Info", false); - - //------------------------------------------------------------------ - void processRun3withKFParticle(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const&, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) - { - for (const auto& collision : collisions) { - - auto bc = collision.bc_as(); - initCCDB(bc); - LOG(debug) << "CCDB initialised."; - - // Zorro event counting - bool isZorroSelected = false; - if (kfparticleConfigurations.cfgSkimmedProcessing) { - isZorroSelected = zorro.isSelected(collision.template bc_as().globalBC()); - if (isZorroSelected) { - registry.fill(HIST("Counters/hEventCounterZorro"), 0.); - } else { - if (kfparticleConfigurations.cfgOnlyKeepInterestedTrigger) { - continue; - } - } - } - - // event selection - registry.fill(HIST("Counters/hEventCounterKFParticle"), 0.5); - if (kfparticleConfigurations.doSel8selection && !collision.sel8()) { - continue; - } - registry.fill(HIST("Counters/hEventCounterKFParticle"), 1.5); - if (kfparticleConfigurations.doPosZselection && (collision.posZ() >= 10.0f || collision.posZ() <= -10.0f)) { - continue; - } - registry.fill(HIST("Counters/hEventCounterKFParticle"), 2.5); - registry.fill(HIST("QA/Event/hAllSelEventsVtxZ"), collision.posZ()); - - if (isZorroSelected) { - registry.fill(HIST("Counters/hEventCounterZorro"), 1.); - } - - // slice Decay3Body table by collision - const uint64_t collIdx = collision.globalIndex(); - auto Decay3BodyTable_thisCollision = decay3bodys.sliceBy(perCollision, collIdx); - for (auto& vtx3body : Decay3BodyTable_thisCollision) { - auto trackPos = vtx3body.template track0_as(); - auto trackNeg = vtx3body.template track1_as(); - auto trackBach = vtx3body.template track2_as(); - buildVtx3BodyDataTableKFParticle(collision, trackPos, trackNeg, trackBach, vtx3body.globalIndex(), bachelorcharge, getTOFnSigma(collision, trackBach, false /*isEventMixing*/)); - LOG(debug) << "End of processKFParticle."; - } - } - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3withKFParticle, "Produce KFParticle decay3body tables", false); - - void processRun3withKFParticleStrangenessTracking(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const& tracks, aod::Decay3Bodys const& decay3bodys, aod::Tracked3Bodys const& tracked3bodys, aod::BCsWithTimestamps const& bcs) - { + // get tracked cluster size info fTrackedClSizeVector.clear(); fTrackedClSizeVector.resize(decay3bodys.size(), 0); for (const auto& tvtx3body : tracked3bodys) { fTrackedClSizeVector[tvtx3body.decay3BodyId()] = tvtx3body.itsClsSize(); } - processRun3withKFParticle(collisions, tracks, decay3bodys, bcs); - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3withKFParticleStrangenessTracking, "Produce KFParticle strangeness tracked decay3body tables", false); - - void processRun3withKFParticleReduced(aod::RedCollisions const& collisions, aod::RedIUTracks const&, aod::RedDecay3Bodys const& decay3bodys) - { - int lastRunNumber = -1; - - for (const auto& collision : collisions) { - // set magnetic field only when run number changes - if (collision.runNumber() != lastRunNumber) { - initCCDBfromRunNumber(collision.runNumber()); - lastRunNumber = collision.runNumber(); // Update the last run number - LOG(debug) << "CCDB initialized for run " << lastRunNumber; - } - - // event selection - registry.fill(HIST("Counters/hEventCounterKFParticle"), 2.5); - registry.fill(HIST("QA/Event/hAllSelEventsVtxZ"), collision.posZ()); - - // slice Decay3Body table by collision - const uint64_t collIdx = collision.globalIndex(); - auto Decay3BodyTable_thisCollision = decay3bodys.sliceBy(perReducedCollision, collIdx); - for (auto& vtx3body : Decay3BodyTable_thisCollision) { - auto trackPos = vtx3body.template track0_as(); - auto trackNeg = vtx3body.template track1_as(); - auto trackBach = vtx3body.template track2_as(); - buildVtx3BodyDataTableKFParticle(collision, trackPos, trackNeg, trackBach, vtx3body.globalIndex(), bachelorcharge, trackBach.tofNSigmaDe()); - } - LOG(debug) << "End of processKFParticleDerived."; - } - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3withKFParticleReduced, "Produce KFParticle decay3body tables from derived decay3body data", false); - - void processRun3withKFParticleReducedEM(ReducedCollisionsMults const& collisions, aod::RedIUTracks const&, aod::RedDecay3Bodys const& decay3bodys) - { - // ------------- Check number of events in bins -------------- - // Define a 2D array to count events and pairs per bin - std::vector> binEventCounts(10, std::vector(13, 0)); // 10 vtxZ bins, 13 multiplicity bins - std::vector> binPairCounts(10, std::vector(13, 0)); - - // Function to find bin index (returns -1 if out of range) - auto findBin = [](float value, const std::vector& binEdges) -> int { - for (size_t i = 0; i < binEdges.size() - 1; ++i) { - if (value > binEdges[i] && value <= binEdges[i + 1]) { - return i; - } - } - return -1; // Shouldn't happen if events are within range - }; - // Loop over all collisions to count them in bins - for (auto& collision : collisions) { - float vtxZ = collision.posZ(); - float mult = collision.multNTracksPV(); - - // Determine bin indices - int vtxZBin = findBin(vtxZ, {-10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}); - int multBin = findBin(mult, {0.0f, 1.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}); - - if (vtxZBin >= 0 && multBin >= 0) { - binEventCounts[vtxZBin][multBin]++; - } - } - // Print out the number of events per bin - LOG(info) << "Event count per bin (vtxZ, mult):"; - for (size_t i = 0; i < binEventCounts.size(); ++i) { - for (size_t j = 0; j < binEventCounts[i].size(); ++j) { - LOG(info) << "Bin (" << i << ", " << j << "): " << binEventCounts[i][j] << " events"; - } - } - // Fill histogram with numbers per bin - for (size_t i = 0; i < binEventCounts.size(); ++i) { - for (size_t j = 0; j < binEventCounts[i].size(); ++j) { - registry.fill(HIST("QA/EM/hEventBinCounts"), i, j, binEventCounts[i][j]); - } - } - LOG(info) << "Integral of hEventBinCounts:" << registry.get(HIST("QA/EM/hEventBinCounts"))->Integral(); - - // ------------- Check number of decay3bodys in bins ------------- - // Define a 2D array to count events and pairs per bin - std::vector> binDecay3BodyCounts(10, std::vector(13, 0)); // 10 vtxZ bins, 13 multiplicity bins - // Loop over all decay3bodys to count them in bins - for (auto& decay3body : decay3bodys) { - auto collision = decay3body.template collision_as(); - float vtx3bodyZ = collision.posZ(); - float mult3body = collision.multNTracksPV(); - - // Determine bin indices - int vtx3bodyZBin = findBin(vtx3bodyZ, {-10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}); - int mult3bodyBin = findBin(mult3body, {0.0f, 1.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}); - - if (vtx3bodyZBin >= 0 && mult3bodyBin >= 0) { - binDecay3BodyCounts[vtx3bodyZBin][mult3bodyBin]++; - } - } - // Print out the number of events per bin - LOG(debug) << "Event count per bin (vtxZ, mult):"; - for (size_t i = 0; i < binDecay3BodyCounts.size(); ++i) { - for (size_t j = 0; j < binDecay3BodyCounts[i].size(); ++j) { - LOG(debug) << "Bin (" << i << ", " << j << "): " << binDecay3BodyCounts[i][j] << " events"; - } - } - // Fill histogram with numbers per bin - for (size_t i = 0; i < binDecay3BodyCounts.size(); ++i) { - for (size_t j = 0; j < binDecay3BodyCounts[i].size(); ++j) { - registry.fill(HIST("QA/EM/h3bodyBinCounts"), i, j, binDecay3BodyCounts[i][j]); - } - } - LOG(info) << "Integral of h3bodyBinCounts:" << registry.get(HIST("QA/EM/h3bodyBinCounts"))->Integral(); - - // ------------- Do event mixing -------------- - auto tuple = std::make_tuple(decay3bodys); - BinningTypeKF binningOnPosAndMult{{kfparticleConfigurations.binsVtxZ, kfparticleConfigurations.binsMultiplicity}, true}; // ignore over-/underflow - SameKindPair pair{binningOnPosAndMult, kfparticleConfigurations.nEvtMixing, -1, collisions, tuple, &cache}; // indicates that under/overflow (-1) to be ignored - - int lastRunNumber = -1; - - for (auto& [c1, decays3body1, c2, decays3body2] : pair) { - registry.fill(HIST("QA/EM/hPairCounterMixing"), 0.5); - - // event selection already applied in reducer task - - // set magnetic field only when run number changes - if (c1.runNumber() != lastRunNumber) { - initCCDBfromRunNumber(c1.runNumber()); - lastRunNumber = c1.runNumber(); // Update the last run number - LOG(debug) << "CCDB initialized for run " << lastRunNumber; - } - - // Get vtxZ and multiplicity from collision - float vtxZpair = c1.posZ(); - float multpair = c1.multNTracksPV(); - // Find the bin index - int vtxZpairBin = findBin(vtxZpair, {-10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}); - int multpairBin = findBin(multpair, {0.0f, 1.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}); - if (vtxZpairBin >= 0 && multpairBin >= 0) { - binPairCounts[vtxZpairBin][multpairBin]++; // Count the pair - } - - for (auto& [decay3body1, decay3body2] : soa::combinations(soa::CombinationsFullIndexPolicy(decays3body1, decays3body2))) { - auto trackPos1 = decay3body1.template track0_as(); - auto trackNeg1 = decay3body1.template track1_as(); - auto trackBach1 = decay3body1.template track2_as(); - auto trackPos2 = decay3body2.template track0_as(); - auto trackNeg2 = decay3body2.template track1_as(); - auto trackBach2 = decay3body2.template track2_as(); - - registry.fill(HIST("QA/EM/hCombinationCounterMixing"), 0.5); - - // ---------- selections bachelor track ---------- - if ((trackBach1.sign() > 0 && !(trackBach2.sign() > 0)) || (trackBach1.sign() < 0 && !(trackBach2.sign() < 0)) || trackBach1.globalIndex() == trackBach2.globalIndex()) { // only combine if trackBach2 has correct sign and is not same as trackBach1 - continue; - } - registry.fill(HIST("QA/EM/hCombinationCounterMixing"), 1.5); - - // ---------- check radius and phi of decay3bodys ---------- - auto trackParCovPos1 = getTrackParCov(trackPos1); - auto trackParCovNeg1 = getTrackParCov(trackNeg1); - auto trackParCovBach1 = getTrackParCov(trackBach1); - auto trackParCovPos2 = getTrackParCov(trackPos2); - auto trackParCovNeg2 = getTrackParCov(trackNeg2); - auto trackParCovBach2 = getTrackParCov(trackBach2); - // create KFParticle objects from tracks - KFParticle kfpProton1, kfpPion1, kfpDeuteron1; - if (trackBach1.sign() > 0) { - kfpProton1 = createKFParticleFromTrackParCov(trackParCovPos1, trackPos1.sign(), constants::physics::MassProton); - kfpPion1 = createKFParticleFromTrackParCov(trackParCovNeg1, trackNeg1.sign(), constants::physics::MassPionCharged); - } else if (!(trackBach1.sign() > 0)) { - kfpProton1 = createKFParticleFromTrackParCov(trackParCovNeg1, trackNeg1.sign(), constants::physics::MassProton); - kfpPion1 = createKFParticleFromTrackParCov(trackParCovPos1, trackPos1.sign(), constants::physics::MassPionCharged); - } - kfpDeuteron1 = createKFParticleFromTrackParCov(trackParCovBach1, trackBach1.sign() * bachelorcharge, constants::physics::MassDeuteron); - KFParticle kfpProton2, kfpPion2, kfpDeuteron2; - if (trackBach2.sign() > 0) { - kfpProton2 = createKFParticleFromTrackParCov(trackParCovPos2, trackPos2.sign(), constants::physics::MassProton); - kfpPion2 = createKFParticleFromTrackParCov(trackParCovNeg2, trackNeg2.sign(), constants::physics::MassPionCharged); - } else if (!(trackBach2.sign() > 0)) { - kfpProton2 = createKFParticleFromTrackParCov(trackParCovNeg2, trackNeg2.sign(), constants::physics::MassProton); - kfpPion2 = createKFParticleFromTrackParCov(trackParCovPos2, trackPos2.sign(), constants::physics::MassPionCharged); - } - kfpDeuteron2 = createKFParticleFromTrackParCov(trackParCovBach2, trackBach2.sign() * bachelorcharge, constants::physics::MassDeuteron); - // fit vertices - KFParticle KFHt1, KFHt2; - fit3bodyVertex(kfpProton1, kfpPion1, kfpDeuteron1, KFHt1); - fit3bodyVertex(kfpProton2, kfpPion2, kfpDeuteron2, KFHt2); - - // ---------- select common radius and phi region ---------- - auto radius1 = std::sqrt(KFHt1.GetX() * KFHt1.GetX() + KFHt1.GetY() * KFHt1.GetY()); - auto radius2 = std::sqrt(KFHt2.GetX() * KFHt2.GetX() + KFHt2.GetY() * KFHt2.GetY()); - registry.fill(HIST("QA/EM/hRadius1"), radius1); - registry.fill(HIST("QA/EM/hRadius2"), radius2); - registry.fill(HIST("QA/EM/hPhi1"), KFHt1.GetPhi() * (180.0 / TMath::Pi())); - registry.fill(HIST("QA/EM/hPhi2"), KFHt2.GetPhi() * (180.0 / TMath::Pi())); - registry.fill(HIST("QA/EM/hDeltaRadius"), std::abs(radius1 - radius2)); - registry.fill(HIST("QA/EM/hDeltaPhi"), std::abs(KFHt1.GetPhi() - KFHt2.GetPhi()) * (180.0 / TMath::Pi())); - if (std::abs(KFHt1.GetPhi() - KFHt2.GetPhi()) * (180.0 / TMath::Pi()) > 10 || std::abs(radius1 - radius2) > 2) { - continue; - } - registry.fill(HIST("QA/EM/hCombinationCounterMixing"), 2.5); - - // fill 2D pair counter per bin - registry.fill(HIST("QA/EM/hPairBinCounts"), vtxZpairBin, multpairBin, 1); - - // ---------- do candidate analysis ---------- - buildVtx3BodyDataTableKFParticle(c1, trackPos1, trackNeg1, trackBach2, -1 /*vtx3bodyID*/, bachelorcharge, trackBach2.tofNSigmaDe()); - } // end decay3body combinations loop - } // end pairing loop - } // end process - PROCESS_SWITCH(decay3bodyBuilder, processRun3withKFParticleReducedEM, "Produce KFParticle event mixing decay3body tables from derived decay3body data", false); - - void processRun3withKFParticleReduced3bodyMixing(ReducedCollisionsMults const&, aod::RedIUTracks const&, soa::Join const& decay3bodys) - { - // Define a 2D array to count 3bodies per bin (radius, phi, posZ) - std::vector> bin3bodyCounts(16, std::vector(36, 0)); - - // Function to find bin index (returns -1 if out of range) - auto findBin = [](float value, const std::vector& binEdges) -> int { - for (size_t i = 0; i < binEdges.size() - 1; ++i) { - if (value > binEdges[i] && value <= binEdges[i + 1]) { - return i; - } - } - return -1; // Out of range - }; - - int counter = 0; - // Loop over all collisions to count them in bins - for (auto& decay3body : decay3bodys) { - counter++; - float radius = decay3body.radius(); - float phi = decay3body.phi(); - float posZ = decay3body.posz(); - - registry.fill(HIST("QA/EM/hRadius"), radius); - registry.fill(HIST("QA/EM/hPhi"), phi); - registry.fill(HIST("QA/EM/hPosZ"), posZ); - - // float degToRad = TMath::Pi()/180; - - // Determine bin indices - int radiusBin = findBin(radius, {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, 16.0f, 18.0f, 20.0f, 30.0f, 1000.0}); - int phiBin = findBin(phi, {-180.0f * TMath::Pi() / 180, -160.0f * TMath::Pi() / 180, -140.0f * TMath::Pi() / 180, -120.0f * TMath::Pi() / 180, -100.0f * TMath::Pi() / 180, -80.0f * TMath::Pi() / 180, -60.0f * TMath::Pi() / 180, -40.0f * TMath::Pi() / 180, -20.0f * TMath::Pi() / 180, 0.0f, 20.0f * TMath::Pi() / 180, 40.0f * TMath::Pi() / 180, 60.0f * TMath::Pi() / 180, 80.0f * TMath::Pi() / 180, 100.0f * TMath::Pi() / 180, 120.0f * TMath::Pi() / 180, 140.0f * TMath::Pi() / 180, 160.0f * TMath::Pi() / 180, 180.0f * TMath::Pi() / 180}); - if (radiusBin >= 0 && phiBin >= 0) { // && posZBin >= 0) { - bin3bodyCounts[radiusBin][phiBin]++; //[posZBin]++; - } - } - LOG(info) << "3body counter: " << counter; - - // Print out the number of 3-body decays per bin - LOG(info) << "3body count per bin (radius, phi, posZ):"; - for (size_t i = 0; i < bin3bodyCounts.size(); ++i) { - for (size_t j = 0; j < bin3bodyCounts[i].size(); ++j) { - LOG(info) << "Bin (" << i << ", " << j << "): " << bin3bodyCounts[i][j] << " 3bodies"; - } - } - // Fill 3D histogram with numbers per bin - for (size_t i = 0; i < bin3bodyCounts.size(); ++i) { - for (size_t j = 0; j < bin3bodyCounts[i].size(); ++j) { - registry.fill(HIST("QA/EM/h3bodyBinCounts"), i, j, bin3bodyCounts[i][j]); - } - } - LOG(info) << "Integral of h3bodyBinCounts: " << registry.get(HIST("QA/EM/h3bodyBinCounts"))->Integral(); - - Binning3Body binningOnRadPhi{{kfparticleConfigurations.bins3BodyRadius, kfparticleConfigurations.bins3BodyPhi}, true}; - - // Strictly upper index policy for decay3body objects binned by radius, phi and z position - for (auto& [decay3body1, decay3body2] : selfPairCombinations(binningOnRadPhi, kfparticleConfigurations.nEvtMixing, -1, decay3bodys)) { - auto trackPos1 = decay3body1.template track0_as(); - auto trackNeg1 = decay3body1.template track1_as(); - auto trackBach1 = decay3body1.template track2_as(); - auto trackPos2 = decay3body2.template track0_as(); - auto trackNeg2 = decay3body2.template track1_as(); - auto trackBach2 = decay3body2.template track2_as(); - - registry.fill(HIST("QA/EM/h3bodyCombinationCounter"), 0.5); - - // collision vertex selections - auto collision1 = decay3body1.template collision_as(); - auto collision2 = decay3body2.template collision_as(); - initCCDBfromRunNumber(collision2.runNumber()); - initCCDBfromRunNumber(collision1.runNumber()); - - if (decay3body1.collisionId() == decay3body2.collisionId()) { // only combine if from different event - continue; - } - registry.fill(HIST("QA/EM/h3bodyCombinationCounter"), 1.5); - if (kfparticleConfigurations.selectVtxZ3bodyMixing && std::abs(collision1.posZ() - collision2.posZ()) > kfparticleConfigurations.VtxZBin3bodyMixing) { // only combine if collision similar in VtxZ - continue; - } - registry.fill(HIST("QA/EM/h3bodyCombinationCounter"), 2.5); - - // ---------- selections ---------- - if ((trackBach1.sign() > 0 && !(trackBach2.sign() > 0)) || (trackBach1.sign() < 0 && !(trackBach2.sign() < 0)) || trackBach1.globalIndex() == trackBach2.globalIndex()) { // only combine if trackBach2 has correct sign and is not same as trackBach1 - continue; - } - registry.fill(HIST("QA/EM/h3bodyCombinationCounter"), 3.5); - - // ---------- do candidate analysis ---------- - bool isMatter1 = false; - if (trackBach1.sign() > 0) { - isMatter1 = true; - } - if (kfparticleConfigurations.mixingType == 0) { // mix deuteron - buildVtx3BodyDataTableKFParticle(collision1, trackPos1, trackNeg1, trackBach2, -1 /*vtx3bodyID*/, bachelorcharge, trackBach2.tofNSigmaDe()); - buildVtx3BodyDataTableKFParticle(collision2, trackPos2, trackNeg2, trackBach1, -1 /*vtx3bodyID*/, bachelorcharge, trackBach1.tofNSigmaDe()); - } else if (kfparticleConfigurations.mixingType == 1) { // mix proton - if (isMatter1 == true) { - buildVtx3BodyDataTableKFParticle(collision1, trackPos2, trackNeg1, trackBach1, -1 /*vtx3bodyID*/, bachelorcharge, trackBach1.tofNSigmaDe()); - buildVtx3BodyDataTableKFParticle(collision2, trackPos1, trackNeg2, trackBach2, -1 /*vtx3bodyID*/, bachelorcharge, trackBach2.tofNSigmaDe()); - } else if (isMatter1 == false) { - buildVtx3BodyDataTableKFParticle(collision1, trackPos1, trackNeg2, trackBach1, -1 /*vtx3bodyID*/, bachelorcharge, trackBach1.tofNSigmaDe()); - buildVtx3BodyDataTableKFParticle(collision2, trackPos2, trackNeg1, trackBach2, -1 /*vtx3bodyID*/, bachelorcharge, trackBach2.tofNSigmaDe()); - } - } - } // end decay3body combinations loop - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3withKFParticleReduced3bodyMixing, "Produce KFParticle mixed decay3body tables from derived decay3body data", false); -}; - -// build link from decay3body -> vtx3body -struct decay3bodyDataLinkBuilder { - Produces VtxDataLink; - - void init(InitContext const&) {} - - template - void buildDecay3BodyLabel(TDecay3Bodys const& decay3bodytable, TVtx3BodyDatas const& vtxdatatable) - { - std::vector lIndices; - lIndices.reserve(decay3bodytable.size()); - for (int ii = 0; ii < decay3bodytable.size(); ii++) - lIndices[ii] = -1; - for (const auto& vtxdata : vtxdatatable) { - if (vtxdata.decay3bodyId() != -1) { - lIndices[vtxdata.decay3bodyId()] = vtxdata.globalIndex(); - } - } - for (int ii = 0; ii < decay3bodytable.size(); ii++) { - VtxDataLink(lIndices[ii]); - } - } - - void processStandard(aod::Decay3Bodys const& decay3bodytable, aod::Vtx3BodyDatas const& vtxdatatable) - { - buildDecay3BodyLabel(decay3bodytable, vtxdatatable); - } - PROCESS_SWITCH(decay3bodyDataLinkBuilder, processStandard, "Produce label from decay3body to vtx3body", true); - - void processReduced(aod::RedDecay3Bodys const& decay3bodytable, aod::Vtx3BodyDatas const& vtxdatatable) - { - buildDecay3BodyLabel(decay3bodytable, vtxdatatable); - } - PROCESS_SWITCH(decay3bodyDataLinkBuilder, processReduced, "Produce label from reducedDecay3body to vtx3body", false); -}; - -struct kfdecay3bodyDataLinkBuilder { - Produces kfvtxdataLink; - - void init(InitContext const&) {} - - template - void buildDataLink(TDecay3Bodys const& decay3bodytable, TVtx3BodyDatas const& vtxdatatable) - { - std::vector lIndices; - lIndices.reserve(decay3bodytable.size()); - for (int ii = 0; ii < decay3bodytable.size(); ii++) - lIndices[ii] = -1; - for (auto& vtxdata : vtxdatatable) { - if (vtxdata.decay3bodyId() != -1) { - lIndices[vtxdata.decay3bodyId()] = vtxdata.globalIndex(); - } - } - for (int ii = 0; ii < decay3bodytable.size(); ii++) { - kfvtxdataLink(lIndices[ii]); - } - } - - void processStandard(aod::Decay3Bodys const& decay3bodytable, aod::KFVtx3BodyDatas const& vtxdatatable) - { - buildDataLink(decay3bodytable, vtxdatatable); // build Decay3Body -> KFDecay3BodyData link table - } - PROCESS_SWITCH(kfdecay3bodyDataLinkBuilder, processStandard, "Build data link table.", true); - - void processReduced(aod::RedDecay3Bodys const& decay3bodytable, aod::KFVtx3BodyDatas const& vtxdatatable) - { - buildDataLink(decay3bodytable, vtxdatatable); // build ReducedDecay3Body -> KFDecay3BodyData link table - } - PROCESS_SWITCH(kfdecay3bodyDataLinkBuilder, processReduced, "Build data link table for reduced data.", false); -}; - -struct decay3bodyLabelBuilder { - - Produces vtxlabels; - Produces vtxfulllabels; - - HistogramRegistry registry{"registry", {}}; - - void init(InitContext const&) - { - if (doprocessDoNotBuildLabels == false) { - auto hLabelCounter = registry.add("hLabelCounter", "hLabelCounter", HistType::kTH1D, {{3, 0.0f, 3.0f}}); - hLabelCounter->GetXaxis()->SetBinLabel(1, "Total"); - hLabelCounter->GetXaxis()->SetBinLabel(2, "Have Same MotherTrack"); - hLabelCounter->GetXaxis()->SetBinLabel(3, "True H3L"); - - registry.add("hHypertritonMCPt", "hHypertritonMCPt", HistType::kTH1F, {{100, 0.0f, 10.0f}}); - registry.add("hAntiHypertritonMCPt", "hAntiHypertritonMCPt", HistType::kTH1F, {{100, 0.0f, 10.0f}}); - registry.add("hHypertritonMCMass", "hHypertritonMCMass", HistType::kTH1F, {{40, 2.95f, 3.05f, "Inv. Mass (GeV/c^{2})"}}); - registry.add("hAntiHypertritonMCMass", "hAntiHypertritonMCMass", HistType::kTH1F, {{40, 2.95f, 3.05f, "Inv. Mass (GeV/c^{2})"}}); - registry.add("hHypertritonMCLifetime", "hHypertritonMCLifetime", HistType::kTH1F, {{50, 0.0f, 50.0f, "ct(cm)"}}); - registry.add("hAntiHypertritonMCLifetime", "hAntiHypertritonMCLifetime", HistType::kTH1F, {{50, 0.0f, 50.0f, "ct(cm)"}}); - } - } - - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - - void processDoNotBuildLabels(aod::Decay3BodyDataLink const&) // is it possible to have none parameter? - { - // dummy process function - should not be required in the future - }; - PROCESS_SWITCH(decay3bodyLabelBuilder, processDoNotBuildLabels, "Do not produce MC label tables", true); - - void processBuildLabels(aod::Decay3BodysLinked const& decay3bodys, aod::Vtx3BodyDatas const& vtx3bodydatas, MCLabeledTracksIU const&, aod::McParticles const&) - { - std::vector lIndices; - lIndices.reserve(vtx3bodydatas.size()); - for (int ii = 0; ii < vtx3bodydatas.size(); ii++) { - lIndices[ii] = -1; - } - for (const auto& decay3body : decay3bodys) { - - int lLabel = -1; - int lPDG = -1; - float lPt = -1; - double MClifetime = -1; - bool is3bodyDecay = false; - int lGlobalIndex = -1; - - auto lTrack0 = decay3body.track0_as(); - auto lTrack1 = decay3body.track1_as(); - auto lTrack2 = decay3body.track2_as(); - registry.fill(HIST("hLabelCounter"), 0.5); - - // Association check - // There might be smarter ways of doing this in the future - if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { - vtxfulllabels(-1); - continue; - } - auto lMCTrack0 = lTrack0.mcParticle_as(); - auto lMCTrack1 = lTrack1.mcParticle_as(); - auto lMCTrack2 = lTrack2.mcParticle_as(); - if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { - vtxfulllabels(-1); - continue; - } - - for (const auto& lMother0 : lMCTrack0.mothers_as()) { - for (const auto& lMother1 : lMCTrack1.mothers_as()) { - for (const auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - lGlobalIndex = lMother1.globalIndex(); - lPt = lMother1.pt(); - lPDG = lMother1.pdgCode(); - MClifetime = RecoDecay::sqrtSumOfSquares(lMCTrack2.vx() - lMother2.vx(), lMCTrack2.vy() - lMother2.vy(), lMCTrack2.vz() - lMother2.vz()) * o2::constants::physics::MassHyperTriton / lMother2.p(); // only for hypertriton - is3bodyDecay = true; // vtxs with the same mother - } - } - } - } // end association check - if (!is3bodyDecay) { - vtxfulllabels(-1); - continue; - } - registry.fill(HIST("hLabelCounter"), 1.5); - - // Intended for hypertriton cross-checks only - if (lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) { - lLabel = lGlobalIndex; - double hypertritonMCMass = RecoDecay::m(std::array{std::array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, std::array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, std::array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hLabelCounter"), 2.5); - registry.fill(HIST("hHypertritonMCPt"), lPt); - registry.fill(HIST("hHypertritonMCLifetime"), MClifetime); - registry.fill(HIST("hHypertritonMCMass"), hypertritonMCMass); - } - if (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020) { - lLabel = lGlobalIndex; - double antiHypertritonMCMass = RecoDecay::m(std::array{std::array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, std::array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, std::array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hLabelCounter"), 2.5); - registry.fill(HIST("hAntiHypertritonMCPt"), lPt); - registry.fill(HIST("hAntiHypertritonMCLifetime"), MClifetime); - registry.fill(HIST("hAntiHypertritonMCMass"), antiHypertritonMCMass); - } - - // Construct label table, only vtx which corresponds to true mother and true daughters with a specified order is labeled - // for matter: track0->p, track1->pi, track2->bachelor - // for antimatter: track0->pi, track1->p, track2->bachelor - vtxfulllabels(lLabel); - if (decay3body.vtx3BodyDataId() != -1) { - lIndices[decay3body.vtx3BodyDataId()] = lLabel; - } - } - for (int ii = 0; ii < vtx3bodydatas.size(); ii++) { - vtxlabels(lIndices[ii]); - } + // do candidate analysis with MC processing + buildCandidates(bcs, // bc table + collisions, // collision table + decay3bodys, // decay3body table + mcParticles, // MC particle table + mcCollisions); // MC collision table } - PROCESS_SWITCH(decay3bodyLabelBuilder, processBuildLabels, "Produce MC label tables", false); -}; -struct decay3bodyInitializer { - Spawns vtx3bodydatas; - void init(InitContext const&) {} + PROCESS_SWITCH(decay3bodyBuilder, processRealData, "process real data", true); + PROCESS_SWITCH(decay3bodyBuilder, processRealDataReduced, "process real reduced data", false); + PROCESS_SWITCH(decay3bodyBuilder, processRealDataReduced3bodyMixing, "process real reduced data", false); + PROCESS_SWITCH(decay3bodyBuilder, processMonteCarlo, "process monte carlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx deleted file mode 100644 index bad62accce2..00000000000 --- a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx +++ /dev/null @@ -1,1197 +0,0 @@ -// 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. - -// This 3-body method is not recommended due to high cost of computing resources -// author: yuanzhe.wang@cern.ch - -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "DCAFitter/DCAFitterN.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/Vtx3BodyTables.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "EventFiltering/filterTables.h" - -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -using FullTracksExtIU = soa::Join; -using MCLabeledTracksIU = soa::Join; - -template -bool is3bodyDecayedH3L(TMCParticle const& particle) -{ - if (particle.pdgCode() != 1010010030 && particle.pdgCode() != -1010010030) { - return false; - } - bool haveProton = false, havePionPlus = false, haveDeuteron = false; - bool haveAntiProton = false, havePionMinus = false, haveAntiDeuteron = false; - for (auto& mcparticleDaughter : particle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == 2212) - haveProton = true; - if (mcparticleDaughter.pdgCode() == -2212) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == 211) - havePionPlus = true; - if (mcparticleDaughter.pdgCode() == -211) - havePionMinus = true; - if (mcparticleDaughter.pdgCode() == 1000010020) - haveDeuteron = true; - if (mcparticleDaughter.pdgCode() == -1000010020) - haveAntiDeuteron = true; - } - if (haveProton && havePionMinus && haveDeuteron && particle.pdgCode() == 1010010030) { - return true; - } else if (haveAntiProton && havePionPlus && haveAntiDeuteron && particle.pdgCode() == -1010010030) { - return true; - } - return false; -} - -namespace o2::aod -{ -namespace v0goodpostrack -{ -DECLARE_SOA_INDEX_COLUMN_FULL(GoodTrack, goodTrack, int, Tracks, "_GoodTrack"); -DECLARE_SOA_INDEX_COLUMN(Collision, collision); -} // namespace v0goodpostrack -DECLARE_SOA_TABLE(V0GoodPosTracks, "AOD", "V0GOODPOSTRACKS", o2::soa::Index<>, v0goodpostrack::GoodTrackId, v0goodpostrack::CollisionId); -namespace v0goodnegtrack -{ -DECLARE_SOA_INDEX_COLUMN_FULL(GoodTrack, goodTrack, int, Tracks, "_GoodTrack"); -DECLARE_SOA_INDEX_COLUMN(Collision, collision); -} // namespace v0goodnegtrack -DECLARE_SOA_TABLE(V0GoodNegTracks, "AOD", "V0GOODNEGTRACKS", o2::soa::Index<>, v0goodnegtrack::GoodTrackId, v0goodnegtrack::CollisionId); -namespace v0goodtrack -{ -DECLARE_SOA_INDEX_COLUMN_FULL(GoodTrack, goodTrack, int, Tracks, "_GoodTrack"); -DECLARE_SOA_INDEX_COLUMN(Collision, collision); -} // namespace v0goodtrack -DECLARE_SOA_TABLE(V0GoodTracks, "AOD", "V0GOODTRACKS", o2::soa::Index<>, v0goodtrack::GoodTrackId, v0goodtrack::CollisionId); -} // namespace o2::aod - -struct trackprefilter { - HistogramRegistry registry{ - "registry", - { - {"hCrossedRows", "hCrossedRows", {HistType::kTH1F, {{50, 0.0f, 200.0f}}}}, - {"hGoodTrackCount", "hGoodTrackCount", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, - {"hGoodPosTrackCount", "hGoodPosTrackCount", {HistType::kTH1F, {{1, 0.0f, 1.0f}}}}, - {"hGoodNegTrackCount", "hGoodNegTrackCount", {HistType::kTH1F, {{1, 0.0f, 1.0f}}}}, - {"h3bodyCounter", "h3bodyCounter", {HistType::kTH1F, {{6, 0.0f, 6.0f}}}}, - }, - }; - - // change the dca cut for helium3 - Configurable mintpcNCls{"mintpcNCls", 70, "min tpc Nclusters"}; - Configurable tpcrefit{"tpcrefit", 0, "demand TPC refit"}; - - Produces v0GoodPosTracks; - Produces v0GoodNegTracks; - Produces v0GoodTracks; - - // Fix: Add PID and pt cuts to tracks - void processDefault(aod::Collision const& /*collision*/, - FullTracksExtIU const& tracks) - { - for (auto& t0 : tracks) { - registry.fill(HIST("hGoodTrackCount"), 0.5); - registry.fill(HIST("hCrossedRows"), t0.tpcNClsCrossedRows()); - if (tpcrefit) { - if (!(t0.trackType() & o2::aod::track::TPCrefit)) { - continue; // TPC refit - } - } - registry.fill(HIST("hGoodTrackCount"), 1.5); - if (t0.tpcNClsFound() < mintpcNCls) { - continue; - } - registry.fill(HIST("hGoodTrackCount"), 2.5); - if (t0.signed1Pt() > 0.0f) { - v0GoodPosTracks(t0.globalIndex(), t0.collisionId()); - registry.fill(HIST("hGoodPosTrackCount"), 0.5); - registry.fill(HIST("hGoodTrackCount"), 3.5); - } - if (t0.signed1Pt() < 0.0f) { - v0GoodNegTracks(t0.globalIndex(), t0.collisionId()); - registry.fill(HIST("hGoodNegTrackCount"), 0.5); - registry.fill(HIST("hGoodTrackCount"), 3.5); - } - v0GoodTracks(t0.globalIndex(), t0.collisionId()); - } - } - PROCESS_SWITCH(trackprefilter, processDefault, "Default process function", true); - - // process function for MC d3body check - // void processCheck(aod::Collision const& collision, aod::Decay3Bodys const& decay3bodys, - void processCheck(aod::Decay3Bodys const& decay3bodys, - MCLabeledTracksIU const& /*tracks*/, aod::McParticles const& /*particlesMC*/) - { - for (auto& d3body : decay3bodys) { - registry.fill(HIST("h3bodyCounter"), 0.5); - auto lTrack0 = d3body.track0_as(); - auto lTrack1 = d3body.track1_as(); - auto lTrack2 = d3body.track2_as(); - if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { - continue; - } - registry.fill(HIST("h3bodyCounter"), 1.5); - auto lMCTrack0 = lTrack0.mcParticle_as(); - auto lMCTrack1 = lTrack1.mcParticle_as(); - auto lMCTrack2 = lTrack2.mcParticle_as(); - if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { - continue; - } - registry.fill(HIST("h3bodyCounter"), 2.5); - - int lPDG = -1; - bool is3bodyDecay = false; - for (auto& lMother0 : lMCTrack0.mothers_as()) { - for (auto& lMother1 : lMCTrack1.mothers_as()) { - for (auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - lPDG = lMother1.pdgCode(); - if (lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) { - is3bodyDecay = true; // vtxs with the same mother - } - if (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020) { - is3bodyDecay = true; // vtxs with the same mother - } - } - } - } - } // end association check - - if (!is3bodyDecay || std::abs(lPDG) != 1010010030) { - continue; - } - registry.fill(HIST("h3bodyCounter"), 3.5); - if (lTrack0.collisionId() != lTrack1.collisionId() || lTrack0.collisionId() != lTrack2.collisionId()) { - continue; - } - registry.fill(HIST("h3bodyCounter"), 4.5); - - if (lTrack0.collisionId() != d3body.collisionId()) { - continue; - } - registry.fill(HIST("h3bodyCounter"), 5.5); - - // LOG(info) << "; Track0ID: " << lTrack0.globalIndex() << "; Track1ID:" << lTrack1.globalIndex() << "; Track2ID:" << lTrack2.globalIndex(); - v0GoodPosTracks(lTrack0.globalIndex(), lTrack0.collisionId()); - v0GoodNegTracks(lTrack1.globalIndex(), lTrack1.collisionId()); - v0GoodTracks(lTrack2.globalIndex(), lTrack2.collisionId()); - } - } - PROCESS_SWITCH(trackprefilter, processCheck, "Check specific paired tracks", false); -}; - -struct hypertriton3bodyFinder { - - Produces vtx3bodydata; - Service ccdb; - - // Configurables - Configurable UseCFFilter{"UseCFFilter", true, "Reject event without CF LD trigger"}; - Configurable RejectBkgInMC{"RejectBkgInMC", false, "Reject fake 3-body pairs in MC check"}; - - Configurable d_UseAbsDCA{"d_UseAbsDCA", true, "Use Abs DCAs"}; - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - - // Selection criteria - Configurable minRToMeanVertex = {"minRToMeanVertex", 0.5, ""}; ///< min radial distance of V0 from beam line (mean vertex) - // Configurable causalityRTolerance = {"causalityRTolerance", 1., ""}; ///< V0 radius cannot exceed its contributors minR by more than this value - Configurable maxV0ToProngsRDiff = {"maxV0ToProngsRDiff", 50., ""}; ///< V0 radius cannot be lower than this ammount wrt minR of contributors - Configurable minPtV0 = {"minPtV0", 0.5, ""}; ///< v0 minimum pT - Configurable maxTglV0 = {"maxTglV0", 2., ""}; ///< maximum tgLambda of V0 - Configurable maxDCAXY2ToMeanVertex3bodyV0 = {"maxDCAXY2ToMeanVertex3bodyV0", 2 * 2, ""}; - Configurable minCosPAXYMeanVertex3bodyV0 = {"minCosPAXYMeanVertex3bodyV0", 0.9, ""}; ///< min cos of PA to beam line (mean vertex) in tr. plane for 3body V0 cand. - Configurable minCosPA3bodyV0 = {"minCosPA3bodyV0", 0.8, ""}; // min cos of PA to PV for 3body V0 - - // for 3 body reconstructed Vertex - Configurable minbachPt = {"minbachPt", 0.6, ""}; ///< Minimum bachelor Pt - Configurable maxRDiff3bodyV0 = {"maxRDiff3bodyV0", 3, ""}; ///< Maximum difference between V0 and 3body radii - Configurable minPt3Body = {"minPt3Body", 0.01, ""}; // minimum pT of 3body Vertex - Configurable maxTgl3Body = {"maxTgl3Body", 2, ""}; // maximum tgLambda of 3body Vertex - Configurable minCosPA3body = {"minCosPA3body", 0.8, ""}; // min cos of PA to PV for 3body Vertex - - // for DCA - Configurable dcavtxdau{"dcavtxdau", 2.0, "DCA Vtx Daughters"}; - Configurable d_UseH3LDCACut{"d_UseH3LDCACut", true, "Use Cuts for H3L DCA to PV"}; - Configurable maxDCAXY3Body{"maxDCAXY3Body", 0.5, "DCAXY H3L to PV"}; // max DCA of 3 body decay to PV in XY - Configurable maxDCAZ3Body{"maxDCAZ3Body", 1.0, "DCAZ H3L to PV"}; // max DCA of 3 body decay to PV in Z - - Configurable useMatCorrType{"useMatCorrType", 2, "0: none, 1: TGeo, 2: LUT"}; - // CCDB options - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - - Preslice perCollisionGoodPosTracks = o2::aod::v0goodpostrack::collisionId; - Preslice perCollisionGoodNegTracks = o2::aod::v0goodnegtrack::collisionId; - Preslice perCollisionGoodTracks = o2::aod::v0goodtrack::collisionId; - Preslice perCollisionV0s = o2::aod::v0::collisionId; - Preslice perCollisionV0Datas = o2::aod::v0data::collisionId; - - // Helper struct to pass V0 information - HistogramRegistry registry{ - "registry", - { - {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hDauTrackCounter", "hDauTrackCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"hV0Counter", "hV0Counter", {HistType::kTH1F, {{8, -0.5f, 7.5f}}}}, - {"hTrueV0Counter", "hTrueV0Counter", {HistType::kTH1F, {{8, -0.5f, 7.5f}}}}, - {"hVtx3BodyCounter", "hVtx3BodyCounter", {HistType::kTH1F, {{9, -0.5f, 8.5f}}}}, - {"hTrueVtx3BodyCounter", "hTrueVtx3BodyCounter", {HistType::kTH1F, {{9, -0.5f, 8.5f}}}}, - {"hVirtLambaCounter", "hVirtualLambaCounter", {HistType::kTH1F, {{6, -0.5f, 5.5f}}}}, - {"hCFFilteredVirtLambaCounter", "hCFFilteredVirtLambaCounter", {HistType::kTH1F, {{6, -0.5f, 5.5f}}}}, - }, - }; - - //------------------------------------------------------------------ - // Fill stats histograms - enum v0step { kV0All = 0, - kV0hasSV, - kV0Radius, - kV0Pt, - kV0TgLamda, - kV0InvMass, - kV0DcaXY, - kV0CosPA, - kNV0Steps }; - enum vtxstep { kVtxAll = 0, - kVtxbachPt, - kVtxhasSV, - kVtxRadius, - kVtxPt, - kVtxTgLamda, - kVtxCosPA, - kVtxDcaDau, - kVtxDcaH3L, - kNVtxSteps }; - - // Helper struct to do bookkeeping of building parameters - struct { - std::array v0stats; - std::array truev0stats; - std::array vtxstats; - std::array truevtxstats; - std::array virtLambdastats; - } statisticsRegistry; - - void resetHistos() - { - for (Int_t ii = 0; ii < kNV0Steps; ii++) { - statisticsRegistry.v0stats[ii] = 0; - statisticsRegistry.truev0stats[ii] = 0; - } - for (Int_t ii = 0; ii < kNVtxSteps; ii++) { - statisticsRegistry.vtxstats[ii] = 0; - statisticsRegistry.truevtxstats[ii] = 0; - } - for (Int_t ii = 0; ii < 12; ii++) { - statisticsRegistry.virtLambdastats[ii] = 0; - } - } - - void fillHistos() - { - for (Int_t ii = 0; ii < kNV0Steps; ii++) { - registry.fill(HIST("hV0Counter"), ii, statisticsRegistry.v0stats[ii]); - registry.fill(HIST("hTrueV0Counter"), ii, statisticsRegistry.truev0stats[ii]); - } - for (Int_t ii = 0; ii < kNVtxSteps; ii++) { - registry.fill(HIST("hVtx3BodyCounter"), ii, statisticsRegistry.vtxstats[ii]); - registry.fill(HIST("hTrueVtx3BodyCounter"), ii, statisticsRegistry.truevtxstats[ii]); - } - for (Int_t ii = 0; ii < 3; ii++) { - registry.fill(HIST("hVirtLambaCounter"), ii, statisticsRegistry.virtLambdastats[ii]); - registry.fill(HIST("hVirtLambaCounter"), ii + 3, statisticsRegistry.virtLambdastats[ii + 3]); - registry.fill(HIST("hCFFilteredVirtLambaCounter"), ii, statisticsRegistry.virtLambdastats[ii + 6]); - registry.fill(HIST("hCFFilteredVirtLambaCounter"), ii + 3, statisticsRegistry.virtLambdastats[ii + 9]); - } - } - - // v0, vtx, and virtual Lambda statiscs - void FillV0Counter(int kn, bool istrue = false) - { - statisticsRegistry.v0stats[kn]++; - if (istrue) { - statisticsRegistry.truev0stats[kn]++; - } - } - void FillVtxCounter(int kn, bool istrue = false) - { - statisticsRegistry.vtxstats[kn]++; - if (istrue) { - statisticsRegistry.truevtxstats[kn]++; - } - } - //------------------------------------------------------------------ - - int mRunNumber; - float d_bz; - float maxSnp; // max sine phi for propagation - float maxStep; // max step size (cm) for propagation - o2::base::MatLayerCylSet* lut = nullptr; - o2::vertexing::DCAFitterN<2> fitter; - o2::vertexing::DCAFitterN<3> fitter3body; - - void init(InitContext&) - { - resetHistos(); - mRunNumber = 0; - d_bz = 0; - maxSnp = 0.85f; // could be changed later - maxStep = 2.00f; // could be changed later - - TString DauCounterbinLabel[3] = {"Proton", "Pion", "Deuteron"}; - TString V0CounterbinLabel[8] = {"Total", "hasSV", "V0R", "V0Pt", "TgLambda", "V0Mass", "DcaXY", "CosPA"}; - TString VtxCounterbinLabel[9] = {"Total", "bachPt", "hasSV", "VtxR", "VtxPt", "TgLambda", "CosPA", "DcaDau", "DcaH3L"}; - for (int i{0}; i < 3; i++) { - registry.get(HIST("hDauTrackCounter"))->GetXaxis()->SetBinLabel(i + 1, DauCounterbinLabel[i]); - } - for (int i{0}; i < kNV0Steps; i++) { - registry.get(HIST("hV0Counter"))->GetXaxis()->SetBinLabel(i + 1, V0CounterbinLabel[i]); - registry.get(HIST("hTrueV0Counter"))->GetXaxis()->SetBinLabel(i + 1, V0CounterbinLabel[i]); - } - for (int i{0}; i < kNVtxSteps; i++) { - registry.get(HIST("hVtx3BodyCounter"))->GetXaxis()->SetBinLabel(i + 1, VtxCounterbinLabel[i]); - registry.get(HIST("hTrueVtx3BodyCounter"))->GetXaxis()->SetBinLabel(i + 1, VtxCounterbinLabel[i]); - } - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - // Set 2-body fitter and 3-body fitter3body - fitter.setPropagateToPCA(true); - fitter.setMaxR(200.); //->maxRIni3body - fitter.setMinParamChange(1e-3); - fitter.setMinRelChi2Change(0.9); - fitter.setMaxDZIni(1e9); - fitter.setMaxChi2(1e9); - fitter.setUseAbsDCA(d_UseAbsDCA); - fitter3body.setPropagateToPCA(true); - fitter3body.setMaxR(200.); //->maxRIni3body - fitter3body.setMinParamChange(1e-3); - fitter3body.setMinRelChi2Change(0.9); - fitter3body.setMaxDZIni(1e9); - fitter3body.setMaxChi2(1e9); - fitter3body.setUseAbsDCA(d_UseAbsDCA); - - // Material correction in the DCA fitter - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - if (useMatCorrType == 1) { - LOGF(info, "TGeo correction requested, loading geometry"); - if (!o2::base::GeometryManager::isGeometryLoaded()) { - ccdb->get(geoPath); - } - matCorr = o2::base::Propagator::MatCorrType::USEMatCorrTGeo; - } - if (useMatCorrType == 2) { - LOGF(info, "LUT correction requested, loading LUT"); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); - matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - } - fitter.setMatCorrType(matCorr); - fitter3body.setMatCorrType(matCorr); - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - fitter.setBz(d_bz); - fitter3body.setBz(d_bz); - o2::parameters::GRPMagField grpmag; - if (fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = bc.runNumber(); - return; - } - - auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - o2::parameters::GRPMagField* grpmag = 0x0; - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } - mRunNumber = bc.runNumber(); - // Set magnetic field value once known - fitter.setBz(d_bz); - fitter3body.setBz(d_bz); - - if (useMatCorrType == 2) { - // setMatLUT only after magfield has been initalized - // (setMatLUT has implicit and problematic init field call if not) - o2::base::Propagator::Instance()->setMatLUT(lut); - } - } - - //------------------------------------------------------------------ - // Check the info of good tracks - template - void CheckGoodTracks(TGoodTrackTable const& dGoodtracks, aod::McParticles const& /*particlesMC*/) - { - for (auto& goodtrackid : dGoodtracks) { - auto goodtrack = goodtrackid.template goodTrack_as(); - if (!goodtrack.has_mcParticle()) { - continue; - } - auto mcgoodtrack = goodtrack.template mcParticle_as(); - if (!mcgoodtrack.has_mothers()) { - continue; - } - bool flag_H3L = false; - for (auto& mothertrack : mcgoodtrack.template mothers_as()) { - if (is3bodyDecayedH3L(mothertrack)) { - flag_H3L = true; - } - } - if (flag_H3L && std::abs(mcgoodtrack.pdgCode()) == 2212) { - registry.fill(HIST("hDauTrackCounter"), 0.5); - } - if (flag_H3L && std::abs(mcgoodtrack.pdgCode()) == 211) { - registry.fill(HIST("hDauTrackCounter"), 1.5); - } - if (flag_H3L && std::abs(mcgoodtrack.pdgCode()) == 1000010020) { - registry.fill(HIST("hDauTrackCounter"), 2.5); - } - } - } - - o2::dataformats::VertexBase mMeanVertex{{0., 0., 0.}, {0.1 * 0.1, 0., 0.1 * 0.1, 0., 0., 6. * 6.}}; - //------------------------------------------------------------------ - // Virtual Lambda V0 finder - template - bool DecayV0Finder(TCollisionTable const& dCollision, TTrackTable const& dPtrack, TTrackTable const& dNtrack, float& rv0, bool isTrue3bodyV0 = false) - { - if (dPtrack.collisionId() != dNtrack.collisionId()) { - return false; - } - FillV0Counter(kV0All, isTrue3bodyV0); - if (!isTrue3bodyV0 && RejectBkgInMC) { - return false; - } - - auto Track0 = getTrackParCov(dPtrack); - auto Track1 = getTrackParCov(dNtrack); - int nCand = fitter.process(Track0, Track1); - if (nCand == 0) { - return false; - } - FillV0Counter(kV0hasSV, isTrue3bodyV0); - - // validate V0 radial position - // First check closeness to the beam-line as same as SVertexer - const auto& v0XYZ = fitter.getPCACandidate(); - float dxv0 = v0XYZ[0] - mMeanVertex.getX(), dyv0 = v0XYZ[1] - mMeanVertex.getY(), r2v0 = dxv0 * dxv0 + dyv0 * dyv0; - // float rv0 = std::sqrt(r2v0); - rv0 = std::sqrt(r2v0); - if (rv0 < minRToMeanVertex) { - return false; - } - FillV0Counter(kV0Radius, isTrue3bodyV0); - - // Not involved: Get minR with same way in SVertexer - // float drv0P = rv0 - Track0minR, drv0N = rv0 - Track1minR; - - // check: if the process function finish the propagation - if (!fitter.isPropagateTracksToVertexDone() && !fitter.propagateTracksToVertex()) { - return false; - } - - auto& trPProp = fitter.getTrack(0); - auto& trNProp = fitter.getTrack(1); - std::array pP, pN; - trPProp.getPxPyPzGlo(pP); - trNProp.getPxPyPzGlo(pN); - // estimate DCA of neutral V0 track to beamline: straight line with parametric equation - // x = X0 + pV0[0]*t, y = Y0 + pV0[1]*t reaches DCA to beamline (Xv, Yv) at - // t = -[ (x0-Xv)*pV0[0] + (y0-Yv)*pV0[1]) ] / ( pT(pV0)^2 ) - // Similar equation for 3D distance involving pV0[2] - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - float pt2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1], prodXYv0 = dxv0 * pV0[0] + dyv0 * pV0[1], tDCAXY = prodXYv0 / pt2V0; - float p2V0 = pt2V0 + pV0[2] * pV0[2], ptV0 = std::sqrt(pt2V0); - if (ptV0 < minPtV0) { // pt cut - return false; - } - FillV0Counter(kV0Pt, isTrue3bodyV0); - - if (pV0[2] / ptV0 > maxTglV0) { // tgLambda cut - return false; - } - FillV0Counter(kV0TgLamda, isTrue3bodyV0); - - // apply mass selections - float massV0LambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - float massV0AntiLambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - float massMargin = 20 * (0.001 * (1. + 0.5 * ptV0)) + 0.07; - if (massV0LambdaHyp - o2::constants::physics::MassLambda > massMargin && massV0AntiLambdaHyp - o2::constants::physics::MassLambda > massMargin) { - return false; - } - FillV0Counter(kV0InvMass, isTrue3bodyV0); - - float dcaX = dxv0 - pV0[0] * tDCAXY, dcaY = dyv0 - pV0[1] * tDCAXY, dca2 = dcaX * dcaX + dcaY * dcaY; - float cosPAXY = prodXYv0 / std::sqrt(r2v0 * pt2V0); - if (dca2 > maxDCAXY2ToMeanVertex3bodyV0) { - return false; - } - FillV0Counter(kV0DcaXY, isTrue3bodyV0); - - if (cosPAXY < minCosPAXYMeanVertex3bodyV0) { - return false; - } - float dx = v0XYZ[0] - dCollision.posX(), dy = v0XYZ[1] - dCollision.posY(), dz = v0XYZ[2] - dCollision.posZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; - float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); - if (cosPA < minCosPA3bodyV0) { - return false; - } - FillV0Counter(kV0CosPA, isTrue3bodyV0); - return true; - } - //------------------------------------------------------------------ - // 3body decay vertex finder - template - void Decay3bodyFinder(TCollisionTable const& dCollision, TTrackTable const& dPtrack, TTrackTable const& dNtrack, TTrackTable const& dBachtrack, float const& rv0, bool isTrue3bodyVtx = false) - { - if (dPtrack.collisionId() != dBachtrack.collisionId()) { - return; - } - if (dPtrack.globalIndex() == dBachtrack.globalIndex()) { - return; // skip the track used by V0 - } - FillVtxCounter(kVtxAll, isTrue3bodyVtx); - if (!isTrue3bodyVtx && RejectBkgInMC) { - return; - } - - auto track0 = getTrackParCov(dPtrack); - auto track1 = getTrackParCov(dNtrack); - auto bach = getTrackParCov(dBachtrack); - - if (bach.getPt() < minbachPt) { - return; - } - FillVtxCounter(kVtxbachPt, isTrue3bodyVtx); - - int n3bodyVtx = fitter3body.process(track0, track1, bach); - if (n3bodyVtx == 0) { // discard this pair - return; - } - FillVtxCounter(kVtxhasSV, isTrue3bodyVtx); - - const auto& vertexXYZ = fitter3body.getPCACandidatePos(); - // make sure the cascade radius is smaller than that of the vertex - float dxc = vertexXYZ[0] - dCollision.posX(), dyc = vertexXYZ[1] - dCollision.posY(), dzc = vertexXYZ[2] - dCollision.posZ(), r2vertex = dxc * dxc + dyc * dyc; - float rvertex = std::sqrt(r2vertex); - if (std::abs(rv0 - rvertex) > maxRDiff3bodyV0 || rvertex < minRToMeanVertex) { - return; - } - FillVtxCounter(kVtxRadius, isTrue3bodyVtx); - - // Not involved: bach.minR - rveretx check - - // check: if the process function finish the propagation - if (!fitter3body.isPropagateTracksToVertexDone() && !fitter3body.propagateTracksToVertex()) { - return; - } - - auto& tr0 = fitter3body.getTrack(0); - auto& tr1 = fitter3body.getTrack(1); - auto& tr2 = fitter3body.getTrack(2); - std::array p0, p1, p2; - tr0.getPxPyPzGlo(p0); - tr1.getPxPyPzGlo(p1); - tr2.getPxPyPzGlo(p2); - std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; - - float pt2 = p3B[0] * p3B[0] + p3B[1] * p3B[1], p2candidate = pt2 + p3B[2] * p3B[2]; - float pt = std::sqrt(pt2); - if (pt < minPt3Body) { // pt cut - return; - } - FillVtxCounter(kVtxPt, isTrue3bodyVtx); - - if (p3B[2] / pt > maxTgl3Body) { // tgLambda cut - return; - } - FillVtxCounter(kVtxTgLamda, isTrue3bodyVtx); - - float cosPA = (p3B[0] * dxc + p3B[1] * dyc + p3B[2] * dzc) / std::sqrt(p2candidate * (r2vertex + dzc * dzc)); - if (cosPA < minCosPA3body) { - return; - } - FillVtxCounter(kVtxCosPA, isTrue3bodyVtx); - - if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { - return; - } - FillVtxCounter(kVtxDcaDau, isTrue3bodyVtx); - - // Calculate DCA with respect to the collision associated to the V0, not individual tracks - std::array dcaInfo; - - auto Track0Par = getTrackPar(dPtrack); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track0dcaXY = dcaInfo[0]; - auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]); - - auto Track1Par = getTrackPar(dNtrack); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track1dcaXY = dcaInfo[0]; - auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]); - - auto Track2Par = getTrackPar(dBachtrack); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track2dcaXY = dcaInfo[0]; - auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]); - - // H3L DCA Check - // auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(), t2.sign()); - auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, dBachtrack.sign()); - o2::dataformats::DCA dca; - if (d_UseH3LDCACut && (!track3B.propagateToDCA({{dCollision.posX(), dCollision.posY(), dCollision.posZ()}, {dCollision.covXX(), dCollision.covXY(), dCollision.covYY(), dCollision.covXZ(), dCollision.covYZ(), dCollision.covZZ()}}, fitter3body.getBz(), &dca, 5.) || - std::abs(dca.getY()) > maxDCAXY3Body || std::abs(dca.getZ()) > maxDCAZ3Body)) { - return; - } - FillVtxCounter(kVtxDcaH3L, isTrue3bodyVtx); - - vtx3bodydata( - dPtrack.globalIndex(), dNtrack.globalIndex(), dBachtrack.globalIndex(), dCollision.globalIndex(), 0, - vertexXYZ[0], vertexXYZ[1], vertexXYZ[2], - p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], - fitter3body.getChi2AtPCACandidate(), - Track0dcaXY, Track1dcaXY, Track2dcaXY, - Track0dca, Track1dca, Track2dca, - 0); // To be fixed - } - //------------------------------------------------------------------ - // 3body decay finder for a collsion - template - void DecayFinder(TCollisionTable const& dCollision, TPosTrackTable const& dPtracks, TNegTrackTable const& dNtracks, TGoodTrackTable const& dGoodtracks) - { - for (auto& t0id : dPtracks) { // FIXME: turn into combination(...) - auto t0 = t0id.template goodTrack_as(); - - for (auto& t1id : dNtracks) { - auto t1 = t1id.template goodTrack_as(); - float rv0; - if (!DecayV0Finder(dCollision, t0, t1, rv0)) { - continue; - } - - for (auto& t2id : dGoodtracks) { - auto t2 = t2id.template goodTrack_as(); - Decay3bodyFinder(dCollision, t0, t1, t2, rv0); - } - } - } - fillHistos(); - resetHistos(); - } - //------------------------------------------------------------------ - // MC 3body decay vertex finder - template - void DecayFinderMC(TCollisionTable const& dCollision, TPosTrackTable const& dPtracks, TNegTrackTable const& dNtracks, TGoodTrackTable const& dGoodtracks) - { - for (auto& t0id : dPtracks) { // FIXME: turn into combination(...) - auto t0 = t0id.template goodTrack_as(); - for (auto& t1id : dNtracks) { - auto t1 = t1id.template goodTrack_as(); - if (t0.collisionId() != t1.collisionId()) { - continue; - } - - bool isTrue3bodyV0 = false; - if (t0.has_mcParticle() && t1.has_mcParticle()) { - auto t0mc = t0.template mcParticle_as(); - auto t1mc = t1.template mcParticle_as(); - if ((t0mc.pdgCode() == 2212 && t1mc.pdgCode() == -211) || (t0mc.pdgCode() == 211 && t1mc.pdgCode() == -2212)) { - if (t0mc.has_mothers() && t1mc.has_mothers()) { - for (auto& t0mother : t0mc.template mothers_as()) { - for (auto& t1mother : t1mc.template mothers_as()) { - if (t0mother.globalIndex() == t1mother.globalIndex() && std::abs(t0mother.pdgCode()) == 1010010030) { - isTrue3bodyV0 = true; - } - } - } - } - } - } - - float rv0; - if (!DecayV0Finder(dCollision, t0, t1, rv0, isTrue3bodyV0)) { - continue; - } - - for (auto& t2id : dGoodtracks) { - auto t2 = t2id.template goodTrack_as(); - - bool isTrue3bodyVtx = false; - if (t0.has_mcParticle() && t1.has_mcParticle() && t2.has_mcParticle()) { - auto t0mc = t0.template mcParticle_as(); - auto t1mc = t1.template mcParticle_as(); - auto t2mc = t2.template mcParticle_as(); - if ((t0mc.pdgCode() == 2212 && t1mc.pdgCode() == -211 && t2mc.pdgCode() == 1000010020) || (t0mc.pdgCode() == 211 && t1mc.pdgCode() == -2212 && t2mc.pdgCode() == -1000010020)) { - if (t0mc.has_mothers() && t1mc.has_mothers() && t2mc.has_mothers()) { - for (auto& t0mother : t0mc.template mothers_as()) { - for (auto& t1mother : t1mc.template mothers_as()) { - for (auto& t2mother : t2mc.template mothers_as()) { - if (t0mother.globalIndex() == t1mother.globalIndex() && t0mother.globalIndex() == t2mother.globalIndex() && std::abs(t0mother.pdgCode()) == 1010010030) { - isTrue3bodyVtx = true; - } - } - } - } - } - } - } - - Decay3bodyFinder(dCollision, t0, t1, t2, rv0, isTrue3bodyVtx); - } - } - } - fillHistos(); - resetHistos(); - } - //------------------------------------------------------------------ - // MC virtual lambda check - template - void VirtualLambdaCheck(TCollisionTable const& /*dCollision*/, TV0DataTable const& fullV0s, int bin) - { - for (auto& v0 : fullV0s) { - statisticsRegistry.virtLambdastats[bin]++; - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); - if (postrack.has_mcParticle() && negtrack.has_mcParticle()) { - auto postrackmc = postrack.template mcParticle_as(); - auto negtrackmc = negtrack.template mcParticle_as(); - - if ((postrackmc.pdgCode() == 2212 && negtrackmc.pdgCode() == -211) || (postrackmc.pdgCode() == 211 && negtrackmc.pdgCode() == -2212)) { - if (postrackmc.has_mothers() && negtrackmc.has_mothers()) { - for (auto& posmother : postrackmc.template mothers_as()) { - for (auto& negmother : negtrackmc.template mothers_as()) { - if (posmother.globalIndex() == negmother.globalIndex()) { - if (posmother.pdgCode() == 1010010030) - statisticsRegistry.virtLambdastats[bin + 1]++; - else if (posmother.pdgCode() == -1010010030) - statisticsRegistry.virtLambdastats[bin + 2]++; - } - } - } - } - } - } - } - fillHistos(); - resetHistos(); - } - - //------------------------------------------------------------------ - // Process Function - void processData(aod::Collision const& collision, aod::V0GoodPosTracks const& ptracks, aod::V0GoodNegTracks const& ntracks, aod::V0GoodTracks const& goodtracks, FullTracksExtIU const&, aod::BCsWithTimestamps const&) - { - auto bc = collision.bc_as(); - initCCDB(bc); - registry.fill(HIST("hEventCounter"), 0.5); - - DecayFinder(collision, ptracks, ntracks, goodtracks); - } - PROCESS_SWITCH(hypertriton3bodyFinder, processData, "Produce StoredVtx3BodyDatas with data", true); - - void processCFFilteredData(aod::Collisions const& collisions, aod::CFFilters const& cffilters, aod::V0GoodPosTracks const& Ptracks, aod::V0GoodNegTracks const& Ntracks, aod::V0GoodTracks const& Goodtracks, FullTracksExtIU const&, aod::BCsWithTimestamps const&) - { - for (int i{0}; i < collisions.size(); i++) { - auto collision = collisions.iteratorAt(i); - auto cffilter = cffilters.iteratorAt(i); - auto bc = collision.bc_as(); - initCCDB(bc); - registry.fill(HIST("hEventCounter"), 0.5); - - auto ptracks = Ptracks.sliceBy(perCollisionGoodPosTracks, collision.globalIndex()); - auto ntracks = Ntracks.sliceBy(perCollisionGoodNegTracks, collision.globalIndex()); - auto goodtracks = Goodtracks.sliceBy(perCollisionGoodTracks, collision.globalIndex()); - - if (!cffilter.hasLD_LooseKstar() && UseCFFilter) { - continue; - } - registry.fill(HIST("hEventCounter"), 1.5); - - DecayFinder(collision, ptracks, ntracks, goodtracks); - } - } - PROCESS_SWITCH(hypertriton3bodyFinder, processCFFilteredData, "Produce StoredVtx3BodyDatas with data using CFtriggers", false); - - void processMC(aod::Collision const& collision, aod::V0GoodPosTracks const& ptracks, aod::V0GoodNegTracks const& ntracks, aod::V0GoodTracks const& goodtracks, aod::McParticles const& particlesMC, MCLabeledTracksIU const&, aod::BCsWithTimestamps const&) - { - auto bc = collision.bc_as(); - initCCDB(bc); - registry.fill(HIST("hEventCounter"), 0.5); - - CheckGoodTracks(goodtracks, particlesMC); - DecayFinderMC(collision, ptracks, ntracks, goodtracks); - } - PROCESS_SWITCH(hypertriton3bodyFinder, processMC, "Produce StoredVtx3BodyDatas with MC", false); - - void processCFFilteredMC(aod::Collisions const& collisions, aod::CFFilters const& cffilters, aod::V0GoodPosTracks const& Ptracks, aod::V0GoodNegTracks const& Ntracks, aod::V0GoodTracks const& Goodtracks, aod::V0s const& V0s, aod::V0Datas const& fullV0s, aod::McParticles const& particlesMC, MCLabeledTracksIU const&, aod::BCsWithTimestamps const&) - { - for (int i{0}; i < collisions.size(); i++) { - auto collision = collisions.iteratorAt(i); - auto cffilter = cffilters.iteratorAt(i); - auto bc = collision.bc_as(); - initCCDB(bc); - registry.fill(HIST("hEventCounter"), 0.5); - - auto goodtracks = Goodtracks.sliceBy(perCollisionGoodTracks, collision.globalIndex()); - CheckGoodTracks(goodtracks, particlesMC); - auto v0s = V0s.sliceBy(perCollisionV0s, collision.globalIndex()); - auto fullv0s = fullV0s.sliceBy(perCollisionV0Datas, collision.globalIndex()); - VirtualLambdaCheck(collision, v0s, 0); - VirtualLambdaCheck(collision, fullv0s, 3); - - if (!cffilter.hasLD_LooseKstar() && UseCFFilter) { - continue; - } - registry.fill(HIST("hEventCounter"), 1.5); - - auto ptracks = Ptracks.sliceBy(perCollisionGoodPosTracks, collision.globalIndex()); - auto ntracks = Ntracks.sliceBy(perCollisionGoodNegTracks, collision.globalIndex()); - - VirtualLambdaCheck(collision, v0s, 6); - VirtualLambdaCheck(collision, fullv0s, 9); - DecayFinderMC(collision, ptracks, ntracks, goodtracks); - } - } - PROCESS_SWITCH(hypertriton3bodyFinder, processCFFilteredMC, "Produce StoredVtx3BodyDatas with MC using CFtriggers", false); -}; - -struct hypertriton3bodyLabelBuilder { - - Produces vtxlabels; - - // for bookkeeping purposes: how many V0s come from same mother etc - HistogramRegistry registry{ - "registry", - { - {"hLabelCounter", "hLabelCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"hHypertritonMCPt", "hHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hAntiHypertritonMCPt", "hAntiHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hHypertritonMCMass", "hHypertritonMCMass", {HistType::kTH1F, {{40, 2.95f, 3.05f, "Inv. Mass (GeV/c^{2})"}}}}, - {"hAntiHypertritonMCMass", "hAntiHypertritonMCMass", {HistType::kTH1F, {{40, 2.95f, 3.05f, "Inv. Mass (GeV/c^{2})"}}}}, - {"hHypertritonMCLifetime", "hHypertritonMCLifetime", {HistType::kTH1F, {{50, 0.0f, 50.0f, "ct(cm)"}}}}, - {"hAntiHypertritonMCLifetime", "hAntiHypertritonMCLifetime", {HistType::kTH1F, {{50, 0.0f, 50.0f, "ct(cm)"}}}}, - }, - }; - - void init(InitContext const&) - { - registry.get(HIST("hLabelCounter"))->GetXaxis()->SetBinLabel(1, "Total"); - registry.get(HIST("hLabelCounter"))->GetXaxis()->SetBinLabel(2, "Same MotherParticle"); - registry.get(HIST("hLabelCounter"))->GetXaxis()->SetBinLabel(3, "True H3L"); - } - - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - - void processDoNotBuildLabels(aod::Collisions::iterator const&) - { - // dummy process function - should not be required in the future - } - PROCESS_SWITCH(hypertriton3bodyLabelBuilder, processDoNotBuildLabels, "Do not produce MC label tables", true); - - void processBuildLabels(aod::Vtx3BodyDatas const& vtx3bodydatas, MCLabeledTracksIU const&, aod::McParticles const& /*particlesMC*/) - { - std::vector lIndices; - lIndices.reserve(vtx3bodydatas.size()); - for (int ii = 0; ii < vtx3bodydatas.size(); ii++) { - lIndices[ii] = -1; - } - - for (auto& vtx3body : vtx3bodydatas) { - - int lLabel = -1; - int lPDG = -1; - float lPt = -1; - double MClifetime = -1; - bool is3bodyDecay = false; - int lGlobalIndex = -1; - - auto lTrack0 = vtx3body.track0_as(); - auto lTrack1 = vtx3body.track1_as(); - auto lTrack2 = vtx3body.track2_as(); - registry.fill(HIST("hLabelCounter"), 0.5); - - // Association check - // There might be smarter ways of doing this in the future - if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { - vtxlabels(-1); - continue; - } - auto lMCTrack0 = lTrack0.mcParticle_as(); - auto lMCTrack1 = lTrack1.mcParticle_as(); - auto lMCTrack2 = lTrack2.mcParticle_as(); - if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { - vtxlabels(-1); - continue; - } - - for (auto& lMother0 : lMCTrack0.mothers_as()) { - for (auto& lMother1 : lMCTrack1.mothers_as()) { - for (auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - lGlobalIndex = lMother1.globalIndex(); - lPt = lMother1.pt(); - lPDG = lMother1.pdgCode(); - MClifetime = RecoDecay::sqrtSumOfSquares(lMCTrack2.vx() - lMother2.vx(), lMCTrack2.vy() - lMother2.vy(), lMCTrack2.vz() - lMother2.vz()) * o2::constants::physics::MassHyperTriton / lMother2.p(); - is3bodyDecay = true; // vtxs with the same mother - } - } - } - } // end association check - if (!is3bodyDecay) { - vtxlabels(-1); - continue; - } - registry.fill(HIST("hLabelCounter"), 1.5); - - // Intended for cross-checks only - // N.B. no rapidity cut! - if (lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) { - lLabel = lGlobalIndex; - double hypertritonMCMass = RecoDecay::m(array{array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hLabelCounter"), 2.5); - registry.fill(HIST("hHypertritonMCPt"), lPt); - registry.fill(HIST("hHypertritonMCLifetime"), MClifetime); - registry.fill(HIST("hHypertritonMCMass"), hypertritonMCMass); - } - if (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020) { - lLabel = lGlobalIndex; - double antiHypertritonMCMass = RecoDecay::m(array{array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hLabelCounter"), 2.5); - registry.fill(HIST("hAntiHypertritonMCPt"), lPt); - registry.fill(HIST("hAntiHypertritonMCLifetime"), MClifetime); - registry.fill(HIST("hAntiHypertritonMCMass"), antiHypertritonMCMass); - } - - // Construct label table, only true hypertriton and true daughters with a specified order is labeled - // for matter: track0->p, track1->pi, track2->d - // for antimatter: track0->pi, track1->p, track2->d - vtxlabels(lLabel); - } - } - PROCESS_SWITCH(hypertriton3bodyLabelBuilder, processBuildLabels, "Produce MC label tables", false); -}; - -struct hypertriton3bodyComparewithDecay3body { - - HistogramRegistry registry{ - "registry", - { - {"hMCInfoCounter", "hMCInfoCounter", {HistType::kTH1F, {{8, 0.0f, 8.0f}}}}, - {"hCheckCounter", "hCheckCounter", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, - {"hHypertritonMCPtTotal", "hHypertritonMCPtTotal", {HistType::kTH1F, {{20, 0.0f, 10.0f}}}}, - {"hHypertritonMCPt", "hHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hAntiHypertritonMCPt", "hAntiHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hHypertritonMCMass", "hHypertritonMCMass", {HistType::kTH1F, {{40, 2.95f, 3.05f}}}}, - {"hAntiHypertritonMCMass", "hAntiHypertritonMCMass", {HistType::kTH1F, {{40, 2.95f, 3.05f}}}}, - {"hPairedHypertritonMCPt", "hPairedHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hPairedAntiHypertritonMCPt", "hPairedAntiHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hSameMcIndexCounter", "hSameMcIndexCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - }, - }; - - void init(InitContext const&) - { - registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(1, "Total"); - registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(2, "Sig in Decay3body"); - registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(3, "Sig SameCol"); - registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(4, "Sig contained by finder"); - registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(5, "Sig SameIndex"); - } - struct Indexdaughters { // check duplicated paired daughters - int64_t index0; - int64_t index1; - int64_t index2; - bool operator==(const Indexdaughters& t) const - { - return (this->index0 == t.index0 && this->index1 == t.index1 && this->index2 == t.index2); - } - }; - - void processDoNotCompare(aod::Collisions::iterator const&) - { - // dummy process function - should not be required in the future - } - PROCESS_SWITCH(hypertriton3bodyComparewithDecay3body, processDoNotCompare, "Do not do comparison", true); - - void processDoComparison(aod::Decay3Bodys const& decay3bodytable, soa::Join const& vtx3bodydatas, MCLabeledTracksIU const&, aod::McParticles const& /*particlesMC*/) - { - std::vector set_pair; - for (auto d3body : decay3bodytable) { - registry.fill(HIST("hCheckCounter"), 0.5); - registry.fill(HIST("hMCInfoCounter"), 0.5); - auto lTrack0 = d3body.track0_as(); - auto lTrack1 = d3body.track1_as(); - auto lTrack2 = d3body.track2_as(); - if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { - continue; - } - registry.fill(HIST("hMCInfoCounter"), 1.5); - auto lMCTrack0 = lTrack0.mcParticle_as(); - auto lMCTrack1 = lTrack1.mcParticle_as(); - auto lMCTrack2 = lTrack2.mcParticle_as(); - if (lMCTrack0.isPhysicalPrimary() || lMCTrack1.isPhysicalPrimary() || lMCTrack2.isPhysicalPrimary()) { - continue; - } - if (lMCTrack0.producedByGenerator() || lMCTrack1.producedByGenerator() || lMCTrack2.producedByGenerator()) { - continue; - } - registry.fill(HIST("hMCInfoCounter"), 2.5); - - if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { - continue; - } - registry.fill(HIST("hMCInfoCounter"), 3.5); - - int lPDG = -1; - float lPt = -1; - bool is3bodyDecayedH3L = false; - int lGlobalIndex = -1; - - for (auto& lMother0 : lMCTrack0.mothers_as()) { - for (auto& lMother1 : lMCTrack1.mothers_as()) { - for (auto& lMother2 : lMCTrack2.mothers_as()) { - registry.fill(HIST("hMCInfoCounter"), 4.5); - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { // vtxs with the same mother - registry.fill(HIST("hMCInfoCounter"), 7.5); - lGlobalIndex = lMother1.globalIndex(); - lPDG = lMother1.pdgCode(); - lPt = lMother1.pt(); - if (lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) { - is3bodyDecayedH3L = true; - double hypertritonMCMass = RecoDecay::m(array{array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hHypertritonMCPt"), lPt); - registry.fill(HIST("hHypertritonMCMass"), hypertritonMCMass); - } - if (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020) { - is3bodyDecayedH3L = true; - double antiHypertritonMCMass = RecoDecay::m(array{array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hAntiHypertritonMCPt"), lPt); - registry.fill(HIST("hAntiHypertritonMCMass"), antiHypertritonMCMass); - } - } - } - } - } // end association check - - if (!is3bodyDecayedH3L) { - continue; - } - - registry.fill(HIST("hCheckCounter"), 1.5); - registry.fill(HIST("hMCInfoCounter"), 5.5); - // for check - registry.fill(HIST("hHypertritonMCPtTotal"), lPt); - - Indexdaughters temp = {lMCTrack0.globalIndex(), lMCTrack1.globalIndex(), lMCTrack2.globalIndex()}; - auto p = std::find(set_pair.begin(), set_pair.end(), temp); - if (p == set_pair.end()) { - set_pair.push_back(temp); - registry.fill(HIST("hMCInfoCounter"), 6.5); - } - - if (lTrack0.collisionId() != lTrack1.collisionId() || lTrack0.collisionId() != lTrack2.collisionId()) { - continue; - } - registry.fill(HIST("hCheckCounter"), 2.5); - - for (auto vtx : vtx3bodydatas) { - if (vtx.mcParticleId() == -1) { - continue; - } - auto mcparticle = vtx.mcParticle_as(); - if (mcparticle.globalIndex() == lGlobalIndex) { - registry.fill(HIST("hCheckCounter"), 4.5); // rare case check: if motherId matches but daughters not - if (lTrack0.globalIndex() == vtx.track0Id() && lTrack1.globalIndex() == vtx.track1Id() && lTrack2.globalIndex() == vtx.track2Id()) { - registry.fill(HIST("hCheckCounter"), 3.5); - if (lPDG > 0) { - registry.fill(HIST("hPairedHypertritonMCPt"), lPt); - } else { - registry.fill(HIST("hPairedAntiHypertritonMCPt"), lPt); - } - break; - } - } - } - } - } - PROCESS_SWITCH(hypertriton3bodyComparewithDecay3body, processDoComparison, "Compare decay3bodys and finder method with MC", false); -}; - -struct hypertriton3bodyInitializer { - Spawns vtx3bodydatas; - void init(InitContext const&) {} -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx index f8d3d04856a..4f52fdd8066 100644 --- a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx +++ b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx @@ -35,6 +35,7 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" #include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/RecoDecay.h" #include "TableHelper.h" #include "Tools/KFparticle/KFUtilities.h" @@ -78,7 +79,6 @@ struct reduced3bodyCreator { Produces reducedDecay3Bodys; Produces reduced3BodyInfo; Produces reducedFullTracksPIDIU; - Produces dcaFitterSVInfo; Service ccdb; Zorro zorro; @@ -88,7 +88,6 @@ struct reduced3bodyCreator { o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; - Configurable mc_event_selection{"mc_event_selection", true, "mc event selection count post kIsTriggerTVX and kNoTimeFrameBorder"}; Configurable event_posZ_selection{"event_posZ_selection", true, "event selection count post poZ cut"}; // CCDB options Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -114,6 +113,9 @@ struct reduced3bodyCreator { float d_bz; o2::pid::tof::TOFResoParamsV2 mRespParamsV2; + // tracked cluster size + std::vector fTrackedClSizeVector; + HistogramRegistry registry{"registry", {}}; void init(InitContext&) @@ -282,7 +284,7 @@ struct reduced3bodyCreator { //------------------------------------------------------------------ // function to fit KFParticle 3body vertex template - void fit3bodyVertex(TKFParticle& kfpProton, TKFParticle& kfpPion, TKFParticle& kfpDeuteron, TKFParticle& KFHt) + bool fit3bodyVertex(TKFParticle& kfpProton, TKFParticle& kfpPion, TKFParticle& kfpDeuteron, TKFParticle& KFHt) { // Construct 3body vertex int nDaughters3body = 3; @@ -292,12 +294,13 @@ struct reduced3bodyCreator { KFHt.Construct(Daughters3body, nDaughters3body); } catch (std::runtime_error& e) { LOG(debug) << "Failed to create Hyper triton 3-body vertex." << e.what(); - return; + return false; } LOG(debug) << "Hypertriton vertex constructed."; + return true; } - void process(ColwithEvTimesMultsCents const& collisions, TrackExtPIDIUwithEvTimes const&, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) + void process(ColwithEvTimesMultsCents const& collisions, TrackExtPIDIUwithEvTimes const&, aod::Decay3Bodys const& decay3bodys, aod::Tracked3Bodys const& tracked3bodys, aod::BCsWithTimestamps const&) { std::vector triggeredCollisions(collisions.size(), false); @@ -340,7 +343,14 @@ struct reduced3bodyCreator { int lastCollisionID = -1; // collisionId of last analysed decay3body. Table is sorted. - // Creat reduced table + // get tracked cluster size info + fTrackedClSizeVector.clear(); + fTrackedClSizeVector.resize(decay3bodys.size(), 0); + for (const auto& tvtx3body : tracked3bodys) { + fTrackedClSizeVector[tvtx3body.decay3BodyId()] = tvtx3body.itsClsSize(); + } + + // Create reduced table for (const auto& d3body : decay3bodys) { auto collision = d3body.template collision_as(); @@ -398,7 +408,7 @@ struct reduced3bodyCreator { const auto trackStartIndex = reducedFullTracksPIDIU.lastIndex(); reducedDecay3Bodys(collisionIndex, trackStartIndex - 2, trackStartIndex - 1, trackStartIndex); - // -------- save reduced decay3body info table -------- + // -------- get decay3body info with KF -------- // get trackParCov daughters auto trackParCovPos = getTrackParCov(daughter0); auto trackParCovNeg = getTrackParCov(daughter1); @@ -413,23 +423,29 @@ struct reduced3bodyCreator { kfpPion = createKFParticleFromTrackParCov(trackParCovPos, daughter0.sign(), constants::physics::MassPionCharged); } kfpDeuteron = createKFParticleFromTrackParCov(trackParCovBach, daughter2.sign(), constants::physics::MassDeuteron); - // fit 3body vertex + // fit 3body vertex and caclulate radius, phi, z position + float radius, phi, posZ; KFParticle KFHt; - fit3bodyVertex(kfpProton, kfpPion, kfpDeuteron, KFHt); - // calculate radius and phi - auto radius = std::sqrt(KFHt.GetX() * KFHt.GetX() + KFHt.GetY() * KFHt.GetY()); - float phi, sigma; - KFHt.GetPhi(phi, sigma); - // fill 3body info table - reduced3BodyInfo(radius, phi, KFHt.GetZ()); - - // -------- save dcaFitter secondary vertex info table -------- + if (fit3bodyVertex(kfpProton, kfpPion, kfpDeuteron, KFHt)) { + radius = std::hypot(KFHt.GetX(), KFHt.GetY()); + phi = std::atan2(KFHt.GetPx(), KFHt.GetPy()); + posZ = KFHt.GetZ(); + } else { + radius = -999.; + phi = -999.; + posZ = -999.; + } + + // -------- get decay3body info with DCA fitter -------- auto Track0 = getTrackParCov(daughter0); auto Track1 = getTrackParCov(daughter1); auto Track2 = getTrackParCov(daughter2); int n3bodyVtx = fitter3body.process(Track0, Track1, Track2); + float phiVtx, rVtx, zVtx; if (n3bodyVtx == 0) { // discard this pair - dcaFitterSVInfo(-999, -999, -999); + phiVtx = -999.; + rVtx = -999.; + zVtx = -999.; } else { const auto& vtxXYZ = fitter3body.getPCACandidate(); @@ -441,10 +457,13 @@ struct reduced3bodyCreator { propagatedTrack1.getPxPyPzGlo(p1); propagatedTrack2.getPxPyPzGlo(p2); std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; - float phiVtx = std::atan2(p3B[1], p3B[0]); - float rVtx = std::hypot(vtxXYZ[0], vtxXYZ[1]); - dcaFitterSVInfo(rVtx, phiVtx, vtxXYZ[2]); + phiVtx = std::atan2(p3B[1], p3B[0]); + rVtx = std::hypot(vtxXYZ[0], vtxXYZ[1]); + zVtx = vtxXYZ[2]; } + + // fill 3body info table (KF and DCA fitter info) + reduced3BodyInfo(radius, phi, posZ, rVtx, phiVtx, zVtx, fTrackedClSizeVector[d3body.globalIndex()]); } // end decay3body loop registry.fill(HIST("hEventCounter"), 3.5, reducedCollisions.lastIndex() + 1); diff --git a/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx deleted file mode 100644 index 1fed55805c2..00000000000 --- a/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx +++ /dev/null @@ -1,488 +0,0 @@ -// 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. -// -/// \brief Analysis task for KFVtx3BodyDatas (3body candidates reconstructed with KF) -/// \author Carolina Reetz --> partly copied from threebodyRecoTask.cxx -// ======================== - -#include -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/Vtx3BodyTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "CommonConstants/PhysicsConstants.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -using MCLabeledTracksIU = soa::Join; - -struct threebodyKFTask { - - Produces outputMCTable; - std::vector filledMothers; - std::vector isGoodCollision; - - // Configurables - Configurable bachelorPdgCode{"bachelorPdgCode", 1000010020, "pdgCode of bachelor daughter"}; - Configurable motherPdgCode{"motherPdgCode", 1010010030, "pdgCode of mother"}; - - ConfigurableAxis m2PrPiBins{"m2PrPiBins", {60, 1., 3.3}, "Binning for m2(p,pi) axis"}; - ConfigurableAxis m2PiDeBins{"m2PiDeBins", {120, 4.0, 8.0}, "Binning for m2(pi,d) axis"}; - - // collision filter and preslice - Filter collisionFilter = (aod::evsel::sel8 == true && nabs(aod::collision::posZ) < 10.f); - Preslice perCollisionVtx3BodyDatas = o2::aod::vtx3body::collisionId; - - HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - - void init(InitContext const&) - { - const AxisSpec axisM2PrPi{m2PrPiBins, "#it{m}^{2}(p,#pi^{-}) ((GeV/#it{c}^{2})^{2})"}; - const AxisSpec axisM2PiDe{m2PiDeBins, "#it{m}^{2}(#pi^{+},#bar{d}) ((GeV/#it{c}^{2})^{2})"}; - - registry.add("hCentFT0C", "hCentFT0C", HistType::kTH1F, {{100, 0.0f, 100.0f, "FT0C Centrality"}}); - - // mass spectrum of reco candidates - registry.add("hMassHypertriton", "Mass hypertriton", HistType::kTH1F, {{80, 2.96f, 3.04f, "#it{m}(p,#pi^{-},d) (GeV/#it{c}^{2})"}}); - registry.add("hMassAntiHypertriton", "Mass anti-hypertriton", HistType::kTH1F, {{80, 2.96f, 3.04f, "#it{m}(#bar{p},#pi^{+},#bar{d}) (GeV/#it{c}^{2})"}}); - // Dalitz diagrams of reco candidates - registry.add("hDalitzHypertriton", "Dalitz diagram", HistType::kTH2F, {axisM2PrPi, axisM2PiDe})->GetYaxis()->SetTitle("#it{m}^{2}(#pi^{-},d) ((GeV/#it{c}^{2})^{2})"); - registry.add("hDalitzAntiHypertriton", "Dalitz diagram", HistType::kTH2F, {axisM2PrPi, axisM2PiDe})->GetXaxis()->SetTitle("#it{m}^{2}(#bar{p},#pi^{+}) ((GeV/#it{c}^{2})^{2})"); - - // bachelor histgrams - registry.add("hAverageITSClusterSizeBachelor", "Average ITS cluster size bachelor track", HistType::kTH1F, {{15, 0.5, 15.5, "#langle ITS cluster size #rangle"}}); - registry.add("hdEdxBachelor", "TPC dE/dx bachelor track", HistType::kTH1F, {{200, 0.0f, 200.0f, "Average ITS cluster size"}}); - registry.add("hPIDTrackingBachelor", "Tracking PID bachelor track", HistType::kTH1F, {{20, 0.5, 20.5, "Tracking PID identifier"}}); - - // for gen information of reco candidates - auto LabelHist = registry.add("hLabelCounter", "Reco MC candidate counter", HistType::kTH1F, {{3, 0.0f, 3.0f}}); - LabelHist->GetXaxis()->SetBinLabel(1, "Total"); - LabelHist->GetXaxis()->SetBinLabel(2, "Have Same MotherTrack"); - LabelHist->GetXaxis()->SetBinLabel(3, "True H3L/Anti-H3L"); - registry.add("hTrueHypertritonMCPt", "pT gen. of reco. H3L", HistType::kTH1F, {{100, -10.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}}); - registry.add("hTrueHypertritonMCMass", "mass gen. of reco. H3L", HistType::kTH1F, {{40, 2.96f, 3.04f, "#it{m}(p,#pi^{-},d) (GeV/#it{c}^{2})"}}); - registry.add("hTrueHypMassWithMuReco", "mass gen. of reco. H3L", HistType::kTH1F, {{40, 2.96f, 3.04f, "#it{m}(p,#pi^{-},d) (GeV/#it{c}^{2})"}}); - registry.add("hTrueHypertritonMCCTau", "#it{c}#tau gen. of reco. H3L", HistType::kTH1F, {{50, 0.0f, 50.0f, "#it{c}#tau(cm)"}}); - registry.add("hTrueHypertritonMCMassPrPi", "inv. mass gen. of reco. V0 pair (H3L)", HistType::kTH1F, {{100, 0.0f, 6.0f, "#it{m}(p,#pi^{-}) (GeV/#it{c}^{2})"}}); - - // for gen information of non reco candidates - registry.add("hTrueHypertritonMCMassPrPi_nonReco", "inv. mass gen. of non-reco. V0 pair (H3L)", HistType::kTH1F, {{100, 0.0f, 6.0f, "#it{m}(p,#pi^{-}) (GeV/#it{c}^{2})"}}); - registry.add("hTrueHypertritonMCPtPion_nonReco", "Pion #it{p}_{T} gen. of non-reco. H3L", HistType::kTH1F, {{100, 0.0f, 6.0f, "#it{p}_{T}(#pi) (GeV/#it{c})"}}); - registry.add("hTrueHypertritonMCPtProton_nonReco", "Proton #it{p}_{T} gen. of non-reco. H3L", HistType::kTH1F, {{100, 0.0f, 6.0f, "#it{p}_{T}(p) (GeV/#it{c})"}}); - } - - // helper function to check if a mother track is a true H3L/Anti-H3L - template - int checkH3LTruth(MCTrack3B const& mcParticlePr, MCTrack3B const& mcParticlePi, MCTrack3B const& mcParticleDe, bool& isMuonReco) - { - if (abs(mcParticlePr.pdgCode()) != 2212 || abs(mcParticleDe.pdgCode()) != 1000010020) { - return -1; - } - // check proton and deuteron mother - int prDeMomID = -1; - for (const auto& motherPr : mcParticlePr.template mothers_as()) { - for (const auto& motherDe : mcParticleDe.template mothers_as()) { - if (motherPr.globalIndex() == motherDe.globalIndex() && std::abs(motherPr.pdgCode()) == 1010010030) { - prDeMomID = motherPr.globalIndex(); - break; - } - } - } - if (prDeMomID == -1) { - return -1; - } - if (std::abs(mcParticlePi.pdgCode()) != 211 && std::abs(mcParticlePi.pdgCode()) != 13) { - return -1; - } - // check if the pion track is a muon coming from a pi -> mu + vu decay, if yes, take the mother pi - auto mcParticlePiTmp = mcParticlePi; - if (std::abs(mcParticlePiTmp.pdgCode()) == 13) { - for (const auto& motherPi : mcParticlePiTmp.template mothers_as()) { - if (std::abs(motherPi.pdgCode()) == 211) { - mcParticlePiTmp = motherPi; - isMuonReco = true; - break; - } - } - } - // now loop over the pion mother - for (const auto& motherPi : mcParticlePiTmp.template mothers_as()) { - if (motherPi.globalIndex() == prDeMomID) { - return motherPi.globalIndex(); - } - } - return -1; - } - - template - void fillQAPlots(TCand const& vtx3body) - { - // Mass plot - if (vtx3body.track2sign() > 0) { // hypertriton - registry.fill(HIST("hMassHypertriton"), vtx3body.mass()); - } else if (vtx3body.track2sign() < 0) { // anti-hypertriton - registry.fill(HIST("hMassAntiHypertriton"), vtx3body.mass()); - } - - // Dalitz plot - auto m2prpi = RecoDecay::m2(array{array{vtx3body.pxtrack0(), vtx3body.pytrack0(), vtx3body.pztrack0()}, array{vtx3body.pxtrack1(), vtx3body.pytrack1(), vtx3body.pztrack1()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - auto m2pide = RecoDecay::m2(array{array{vtx3body.pxtrack1(), vtx3body.pytrack1(), vtx3body.pztrack1()}, array{vtx3body.pxtrack2(), vtx3body.pytrack2(), vtx3body.pztrack2()}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - if (std::abs(vtx3body.mass() - o2::constants::physics::MassHyperTriton) <= 0.005) { - if (vtx3body.track2sign() > 0) { // hypertriton - registry.fill(HIST("hDalitzHypertriton"), m2prpi, m2pide); - } else if (vtx3body.track2sign() < 0) { // anti-hypertriton - registry.fill(HIST("hDalitzAntiHypertriton"), m2prpi, m2pide); - } - } - - // ITS cluster sizes - registry.fill(HIST("hAverageITSClusterSizeBachelor"), vtx3body.itsclussizedeuteron()); - registry.fill(HIST("hdEdxBachelor"), vtx3body.tpcdedxdeuteron()); - registry.fill(HIST("hPIDTrackingBachelor"), vtx3body.pidtrackingdeuteron()); - } - - //------------------------------------------------------------------ - // process real data analysis - void processData(soa::Filtered>::iterator const& collision, - aod::KFVtx3BodyDatas const& vtx3bodydatas) - { - registry.fill(HIST("hCentFT0C"), collision.centFT0C()); - - for (auto& vtx3bodydata : vtx3bodydatas) { - // QA histograms - fillQAPlots(vtx3bodydata); - } - } - PROCESS_SWITCH(threebodyKFTask, processData, "Data analysis", true); - - //------------------------------------------------------------------ - // process mc analysis - void processMC(soa::Join const& collisions, - aod::KFVtx3BodyDatas const& vtx3bodydatas, - aod::McParticles const& particlesMC, - MCLabeledTracksIU const&, - aod::McCollisions const& mcCollisions) - { - filledMothers.clear(); - isGoodCollision.resize(mcCollisions.size(), false); - - // loop over collisions - for (const auto& collision : collisions) { - // event selection - if (!collision.sel8() || std::abs(collision.posZ()) > 10.f) { - continue; - } - // reco collision survived event selection filter --> fill value for MC collision if collision is "true" MC collision - if (collision.mcCollisionId() >= 0) { - isGoodCollision[collision.mcCollisionId()] = true; - } - - // fill MC table with reco MC candidate information and gen information if matched to MC particle - auto Decay3BodyTable_thisCollision = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); - for (auto& vtx3bodydata : Decay3BodyTable_thisCollision) { - registry.fill(HIST("hLabelCounter"), 0.5); - - // fill QA histograms for all reco candidates - fillQAPlots(vtx3bodydata); - - auto track0 = vtx3bodydata.track0_as(); - auto track1 = vtx3bodydata.track1_as(); - auto track2 = vtx3bodydata.track2_as(); - - if (!track0.has_mcParticle() || !track1.has_mcParticle() || !track2.has_mcParticle()) { - continue; - } - - auto mcTrack0 = track0.mcParticle_as(); - auto mcTrack1 = track1.mcParticle_as(); - auto mcTrack2 = track2.mcParticle_as(); - - float genPosPt = mcTrack0.pt(); - float genPosP = mcTrack0.p(); - int daughter0PDGcode = mcTrack0.pdgCode(); - float genNegPt = mcTrack1.pt(); - float genNegP = mcTrack1.p(); - int daughter1PDGcode = mcTrack1.pdgCode(); - float genBachPt = mcTrack2.pt(); - float genBachP = mcTrack2.p(); - int daughter2PDGcode = mcTrack2.pdgCode(); - bool isBachPrimary = mcTrack2.isPhysicalPrimary(); - - double MClifetime = -1.; - bool isTrueH3L = false; - bool isTrueAntiH3L = false; - float genPhi = -1.; - float genEta = -1.; - float genRap = -1.; - float genP = -1.; - float genPt = -1.; - std::array genDecVtx{-1.f}; - bool isMuonReco = false; - auto& mcTrackPr = vtx3bodydata.sign() > 0 ? mcTrack0 : mcTrack1; - auto& mcTrackPi = vtx3bodydata.sign() > 0 ? mcTrack1 : mcTrack0; - auto& mcTrackDe = mcTrack2; - int motherID = checkH3LTruth(mcTrackPr, mcTrackPi, mcTrackDe, isMuonReco); - if (motherID > 0) { - auto mcTrackHyp = particlesMC.rawIteratorAt(motherID); - genPhi = mcTrackHyp.phi(); - genEta = mcTrackHyp.eta(); - genPt = mcTrackHyp.pt(); - int chargeFactor = mcTrackHyp.pdgCode() > 0 ? 1 : -1; - isTrueH3L = chargeFactor > 0; - isTrueAntiH3L = chargeFactor < 0; - MClifetime = RecoDecay::sqrtSumOfSquares(mcTrackPr.vx() - mcTrackHyp.vx(), mcTrackPr.vy() - mcTrackHyp.vy(), mcTrackPr.vz() - mcTrackHyp.vz()) * o2::constants::physics::MassHyperTriton / mcTrackHyp.p(); - double MCMass = RecoDecay::m(array{array{mcTrackPr.px(), mcTrackPr.py(), mcTrackPr.pz()}, array{mcTrackPi.px(), mcTrackPi.py(), mcTrackPi.pz()}, array{mcTrackDe.px(), mcTrackDe.py(), mcTrackDe.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - float MCmassPrPi = RecoDecay::m(array{array{mcTrackPr.px(), mcTrackPr.py(), mcTrackPr.pz()}, array{mcTrackPi.px(), mcTrackPi.py(), mcTrackPi.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - registry.fill(HIST("hLabelCounter"), 2.5); - registry.fill(HIST("hTrueHypertritonMCPt"), mcTrackHyp.pt() * chargeFactor); - registry.fill(HIST("hTrueHypertritonMCCTau"), MClifetime); - registry.fill(HIST("hTrueHypertritonMCMass"), MCMass); - registry.fill(HIST("hTrueHypertritonMCMassPrPi"), MCmassPrPi); - if (isMuonReco) { - registry.fill(HIST("hTrueHypMassWithMuReco"), MCMass); - } - filledMothers.push_back(mcTrackHyp.globalIndex()); - } - outputMCTable( // filled for each reconstructed candidate (in KFVtx3BodyDatas) - vtx3bodydata.mass(), - vtx3bodydata.x(), vtx3bodydata.y(), vtx3bodydata.z(), - vtx3bodydata.xerr(), vtx3bodydata.yerr(), vtx3bodydata.zerr(), - vtx3bodydata.px(), vtx3bodydata.py(), vtx3bodydata.pz(), vtx3bodydata.pt(), - vtx3bodydata.pxerr(), vtx3bodydata.pyerr(), vtx3bodydata.pzerr(), vtx3bodydata.pterr(), - vtx3bodydata.sign(), - vtx3bodydata.dcavtxtopvkf(), vtx3bodydata.dcaxyvtxtopvkf(), - vtx3bodydata.vtxcospakf(), vtx3bodydata.vtxcosxypakf(), - vtx3bodydata.vtxcospakftopo(), vtx3bodydata.vtxcosxypakftopo(), - vtx3bodydata.decaylkf(), vtx3bodydata.decaylxykf(), vtx3bodydata.decayldeltal(), - vtx3bodydata.chi2geondf(), vtx3bodydata.chi2topondf(), - vtx3bodydata.ctaukftopo(), - vtx3bodydata.trackedclsize(), - vtx3bodydata.massv0(), vtx3bodydata.chi2massv0(), - vtx3bodydata.cospav0(), - vtx3bodydata.pxtrack0(), vtx3bodydata.pytrack0(), vtx3bodydata.pztrack0(), // proton - vtx3bodydata.pxtrack1(), vtx3bodydata.pytrack1(), vtx3bodydata.pztrack1(), // pion - vtx3bodydata.pxtrack2(), vtx3bodydata.pytrack2(), vtx3bodydata.pztrack2(), // deuteron - vtx3bodydata.tpcinnerparamtrack0(), vtx3bodydata.tpcinnerparamtrack1(), vtx3bodydata.tpcinnerparamtrack2(), // proton, pion, deuteron - vtx3bodydata.tpcncltrack0(), vtx3bodydata.tpcncltrack1(), vtx3bodydata.tpcncltrack1(), // proton, pion, deuteron - vtx3bodydata.tpcchi2ncldeuteron(), - vtx3bodydata.deltaphideuteron(), vtx3bodydata.deltaphiproton(), - vtx3bodydata.dcatrack0topvkf(), vtx3bodydata.dcatrack1topvkf(), vtx3bodydata.dcatrack2topvkf(), // proton, pion, deuteron - vtx3bodydata.dcaxytrack0topvkf(), vtx3bodydata.dcaxytrack1topvkf(), vtx3bodydata.dcaxytrack2topvkf(), // proton, pion, deuteron - vtx3bodydata.dcaxytrack0tosvkf(), vtx3bodydata.dcaxytrack1tosvkf(), vtx3bodydata.dcaxytrack2tosvkf(), // proton, pion, deuteron - vtx3bodydata.dcatrack0totrack1kf(), vtx3bodydata.dcatrack0totrack2kf(), vtx3bodydata.dcatrack1totrack2kf(), - vtx3bodydata.dcavtxdaughterskf(), - vtx3bodydata.dcaxytrackpostopv(), vtx3bodydata.dcaxytracknegtopv(), vtx3bodydata.dcaxytrackbachtopv(), - vtx3bodydata.dcatrackpostopv(), vtx3bodydata.dcatracknegtopv(), vtx3bodydata.dcatrackbachtopv(), - vtx3bodydata.track0sign(), vtx3bodydata.track1sign(), vtx3bodydata.track2sign(), // proton, pion, deuteron - vtx3bodydata.tpcnsigmaproton(), vtx3bodydata.tpcnsigmapion(), vtx3bodydata.tpcnsigmadeuteron(), vtx3bodydata.tpcnsigmapionbach(), - vtx3bodydata.tpcdedxproton(), vtx3bodydata.tpcdedxpion(), vtx3bodydata.tpcdedxdeuteron(), - vtx3bodydata.tofnsigmadeuteron(), - vtx3bodydata.itsclussizedeuteron(), - vtx3bodydata.pidtrackingdeuteron(), - // MC info (-1 if not matched to MC particle) - genP, - genPt, - genDecVtx[0], genDecVtx[1], genDecVtx[2], - MClifetime, - genPhi, - genEta, - genRap, - genPosP, genPosPt, genNegP, genNegPt, genBachP, genBachPt, - isTrueH3L, isTrueAntiH3L, - daughter0PDGcode, daughter1PDGcode, daughter2PDGcode, isBachPrimary, - true, // is reconstructed - true); // reco event passed event selection - } // end vtx3bodydatas loop - } // end collision loop - - // generated MC particle analysis - // fill MC table with gen information for all generated but not reconstructed particles - for (auto& mcparticle : particlesMC) { - - double genMCmassPrPi = -1.; - bool isTrueGenH3L = false; - bool isTrueGenAntiH3L = false; - float genPBach = -1.; - float genPtBach = -1.; - float genPPos = -1.; - float genPtPos = -1.; - float genPNeg = -1.; - float genPtNeg = -1.; - int posDauPdgCode = -1; - int negDauPdgCode = -1; - int bachDauPdgCode = -1; - - // check if mcparticle was reconstructed and already filled in the table - if (std::find(filledMothers.begin(), filledMothers.end(), mcparticle.globalIndex()) != std::end(filledMothers)) { - continue; - } - - // set flag if corresponding reco collision survived event selection - bool survEvSel = isGoodCollision[mcparticle.mcCollisionId()]; - - // check if MC particle is hypertriton with 3-body decay - if (std::abs(mcparticle.pdgCode()) != motherPdgCode) { - continue; - } - bool haveProton = false, havePion = false, haveBachelor = false; - bool haveAntiProton = false, haveAntiPion = false, haveAntiBachelor = false; - for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == 2212) - haveProton = true; - if (mcparticleDaughter.pdgCode() == -2212) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == 211) - havePion = true; - if (mcparticleDaughter.pdgCode() == -211) - haveAntiPion = true; - if (mcparticleDaughter.pdgCode() == bachelorPdgCode) - haveBachelor = true; - if (mcparticleDaughter.pdgCode() == -bachelorPdgCode) - haveAntiBachelor = true; - } - - // check if particle or anti-particle - if (haveProton && haveAntiPion && haveBachelor && mcparticle.pdgCode() > 0) { - isTrueGenH3L = true; - // get proton and pion daughter - std::array protonMom{0.f}; - std::array piMinusMom{0.f}; - for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == 2212) { - protonMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; - genPPos = mcparticleDaughter.p(); - genPtPos = mcparticleDaughter.pt(); - posDauPdgCode = mcparticleDaughter.pdgCode(); - } else if (mcparticleDaughter.pdgCode() == -211) { - piMinusMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; - genPNeg = mcparticleDaughter.p(); - genPtNeg = mcparticleDaughter.pt(); - negDauPdgCode = mcparticleDaughter.pdgCode(); - } - } - genMCmassPrPi = RecoDecay::m(array{protonMom, piMinusMom}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - registry.fill(HIST("hTrueHypertritonMCMassPrPi_nonReco"), genMCmassPrPi); - registry.fill(HIST("hTrueHypertritonMCPtProton_nonReco"), RecoDecay::sqrtSumOfSquares(protonMom[0], protonMom[1])); - registry.fill(HIST("hTrueHypertritonMCPtPion_nonReco"), RecoDecay::sqrtSumOfSquares(piMinusMom[0], piMinusMom[1])); - } else if (haveAntiProton && havePion && haveAntiBachelor && mcparticle.pdgCode() < 0) { - isTrueGenAntiH3L = true; - // get anti-proton and pion daughter - std::array antiProtonMom{0.f}; - std::array piPlusMom{0.f}; - for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == -2212) { - antiProtonMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; - genPNeg = mcparticleDaughter.p(); - genPtNeg = mcparticleDaughter.pt(); - negDauPdgCode = mcparticleDaughter.pdgCode(); - } else if (mcparticleDaughter.pdgCode() == 211) { - piPlusMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; - genPPos = mcparticleDaughter.p(); - genPtPos = mcparticleDaughter.pt(); - posDauPdgCode = mcparticleDaughter.pdgCode(); - } - } - genMCmassPrPi = RecoDecay::m(array{antiProtonMom, piPlusMom}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - registry.fill(HIST("hTrueHypertritonMCMassPrPi_nonReco"), genMCmassPrPi); - registry.fill(HIST("hTrueHypertritonMCPtProton_nonReco"), RecoDecay::sqrtSumOfSquares(antiProtonMom[0], antiProtonMom[1])); - registry.fill(HIST("hTrueHypertritonMCPtPion_nonReco"), RecoDecay::sqrtSumOfSquares(piPlusMom[0], piPlusMom[1])); - } else { - continue; // stop if particle is no true H3L or Anti-H3L - } - - // get gen decay vertex and calculate ctau - std::array genDecayVtx{0.f}; - for (auto& mcDaughter : mcparticle.daughters_as()) { - if (std::abs(mcDaughter.pdgCode()) == bachelorPdgCode) { - genDecayVtx = {mcDaughter.vx(), mcDaughter.vy(), mcDaughter.vz()}; - genPBach = mcDaughter.p(); - genPtBach = mcDaughter.pt(); - bachDauPdgCode = mcDaughter.pdgCode(); - } - } - double genMClifetime = RecoDecay::sqrtSumOfSquares(genDecayVtx[0] - mcparticle.vx(), genDecayVtx[1] - mcparticle.vy(), genDecayVtx[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - outputMCTable( // reco information (-1) - -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, - -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, - -1, -1, - -1, - -1, - -1, -1, - -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, - -1, - -1, - -1, - // gen information - mcparticle.p(), - mcparticle.pt(), - genDecayVtx[0], genDecayVtx[1], genDecayVtx[2], - genMClifetime, - mcparticle.phi(), - mcparticle.eta(), - mcparticle.y(), - genPPos, genPtPos, genPNeg, genPtNeg, genPBach, genPtBach, - isTrueGenH3L, isTrueGenAntiH3L, - posDauPdgCode, negDauPdgCode, bachDauPdgCode, - false, // isBachPrimary - false, // is reconstructed - survEvSel); - } // end mcparticles loop - } - PROCESS_SWITCH(threebodyKFTask, processMC, "MC analysis", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx deleted file mode 100644 index 36af287f95e..00000000000 --- a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx +++ /dev/null @@ -1,909 +0,0 @@ -// 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 threebodyRecoTask.cxx -/// \brief Analysis task for 3-body decay process (now mainly for hypertriton) -/// \author Yuanzhe Wang - -#include -#include -#include -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/Vtx3BodyTables.h" -#include "PWGLF/DataModel/Reduced3BodyTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "CommonConstants/PhysicsConstants.h" -#include "CCDB/BasicCCDBManager.h" - -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using ReducedCols = soa::Join; -using FullTracksExtIU = soa::Join; -using MCLabeledTracksIU = soa::Join; - -std::vector triggerLabels = { - "fTriggerEventF1Proton", "fTrackedOmega", "fTrackedXi", "fOmegaLargeRadius", - "fDoubleOmega", "fOmegaHighMult", "fSingleXiYN", "fQuadrupleXi", "fDoubleXi", - "fhadronOmega", "fOmegaXi", "fTripleXi", "fOmega", "fGammaVeryLowPtEMCAL", - "fGammaVeryLowPtDCAL", "fGammaHighPtEMCAL", "fGammaLowPtEMCAL", "fGammaVeryHighPtDCAL", - "fGammaVeryHighPtEMCAL", "fGammaLowPtDCAL", "fJetNeutralLowPt", "fJetNeutralHighPt", - "fGammaHighPtDCAL", "fJetFullLowPt", "fJetFullHighPt", "fEMCALReadout", "fPCMandEE", - "fPHOSnbar", "fPCMHighPtPhoton", "fPHOSPhoton", "fLD", "fPPPHI", "fPD", "fLLL", "fPLL", - "fPPL", "fPPP", "fLeadingPtTrack", "fHighFt0cFv0Flat", "fHighFt0cFv0Mult", "fHighFt0Flat", - "fHighFt0Mult", "fHighMultFv0", "fHighTrackMult", "fHfSingleNonPromptCharm3P", - "fHfSingleNonPromptCharm2P", "fHfSingleCharm3P", "fHfPhotonCharm3P", "fHfHighPt2P", - "fHfSigmaC0K0", "fHfDoubleCharm2P", "fHfBeauty3P", "fHfFemto3P", "fHfFemto2P", - "fHfHighPt3P", "fHfSigmaCPPK", "fHfDoubleCharm3P", "fHfDoubleCharmMix", - "fHfPhotonCharm2P", "fHfV0Charm2P", "fHfBeauty4P", "fHfV0Charm3P", "fHfSingleCharm2P", - "fHfCharmBarToXiBach", "fSingleMuHigh", "fSingleMuLow", "fLMeeHMR", "fDiMuon", - "fDiElectron", "fLMeeIMR", "fSingleE", "fTrackHighPt", "fTrackLowPt", "fJetChHighPt", - "fJetChLowPt", "fUDdiffLarge", "fUDdiffSmall", "fITSextremeIonisation", - "fITSmildIonisation", "fH3L3Body", "fHe", "fH2"}; - -struct Candidate3body { - // Index - int mcmotherId; - int track0Id; - int track1Id; - int track2Id; - // Collision - float colCentFT0C; - // sv and candidate - bool isMatter; - float invmass; - float ct; - float cosPA; - float dcadaughters; - float dcacandtopv; - float vtxradius; - // daughter tracks - TLorentzVector lcand; - TLorentzVector lproton; - TLorentzVector lpion; - TLorentzVector lbachelor; - uint8_t dautpcNclusters[3]; // 0 - proton, 1 - pion, 2 - bachelor - uint32_t dauitsclussize[3]; // 0 - proton, 1 - pion, 2 - bachelor - float daudcaxytopv[3]; // 0 - proton, 1 - pion, 2 - bachelor - float daudcatopv[3]; // 0 - proton, 1 - pion, 2 - bachelor - float dautpcNsigma[3]; // 0 - proton, 1 - pion, 2 - bachelor - float dauinnermostR[3]; // 0 - proton, 1 - pion, 2 - bachelor !!! TracksIU required !!! - float bachelortofNsigma; - bool isBachPrimary = false; - // MC infomartion - TLorentzVector lgencand = {0, 0, 0, 0}; - float genct = -1; - float genrapidity = -999; - bool isSignal = false; - bool isReco = false; - int pdgCode = -1; - bool survivedEventSelection = false; -}; - -struct ThreebodyRecoTask { - - Produces outputDataTable; - Produces outputMCTable; - std::vector candidates3body; - std::vector filledMothers; - std::vector isGoodCollision; - - Service ccdb; - Zorro zorro; - OutputObj zorroSummary{"zorroSummary"}; - - //------------------------------------------------------------------ - PresliceUnsorted perCollisionVtx3BodyDatas = o2::aod::vtx3body::collisionId; - - // Configurable for trigger selection - Configurable triggerList{"triggerList", "fTriggerEventF1Proton, fTrackedOmega, fTrackedXi, fOmegaLargeRadius, fDoubleOmega, fOmegaHighMult, fSingleXiYN, fQuadrupleXi, fDoubleXi, fhadronOmega, fOmegaXi, fTripleXi, fOmega, fGammaVeryLowPtEMCAL, fGammaVeryLowPtDCAL, fGammaHighPtEMCAL, fGammaLowPtEMCAL, fGammaVeryHighPtDCAL, fGammaVeryHighPtEMCAL, fGammaLowPtDCAL, fJetNeutralLowPt, fJetNeutralHighPt, fGammaHighPtDCAL, fJetFullLowPt, fJetFullHighPt, fEMCALReadout, fPCMandEE, fPHOSnbar, fPCMHighPtPhoton, fPHOSPhoton, fLD, fPPPHI, fPD, fLLL, fPLL, fPPL, fPPP, fLeadingPtTrack, fHighFt0cFv0Flat, fHighFt0cFv0Mult, fHighFt0Flat, fHighFt0Mult, fHighMultFv0, fHighTrackMult, fHfSingleNonPromptCharm3P, fHfSingleNonPromptCharm2P, fHfSingleCharm3P, fHfPhotonCharm3P, fHfHighPt2P, fHfSigmaC0K0, fHfDoubleCharm2P, fHfBeauty3P, fHfFemto3P, fHfFemto2P, fHfHighPt3P, fHfSigmaCPPK, fHfDoubleCharm3P, fHfDoubleCharmMix, fHfPhotonCharm2P, fHfV0Charm2P, fHfBeauty4P, fHfV0Charm3P, fHfSingleCharm2P, fHfCharmBarToXiBach, fSingleMuHigh, fSingleMuLow, fLMeeHMR, fDiMuon, fDiElectron, fLMeeIMR, fSingleE, fTrackHighPt, fTrackLowPt, fJetChHighPt, fJetChLowPt, fUDdiffLarge, fUDdiffSmall, fITSextremeIonisation, fITSmildIonisation, fH3L3Body, fHe, fH2", "List of triggers used to select events"}; - Configurable cfgOnlyKeepInterestedTrigger{"cfgOnlyKeepInterestedTrigger", false, "Flag to keep only interested trigger"}; - Configurable bcTolerance{"bcTolerance", 100, "Tolerance for BC in Zorro"}; - // Configuration to enable like-sign analysis - Configurable cfgLikeSignAnalysis{"cfgLikeSignAnalysis", false, "Enable like-sign analysis"}; - // Selection criteria - Configurable vtxcospa{"vtxcospa", 0.99, "Vtx CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcavtxdau{"dcavtxdau", 1.0, "DCA Vtx Daughters"}; // loose cut - Configurable dcapiontopv{"dcapiontopv", .05, "DCA Pion To PV"}; - Configurable etacut{"etacut", 0.9, "etacut"}; - Configurable rapiditycut{"rapiditycut", 1, "rapiditycut"}; - Configurable tofPIDNSigmaMin{"tofPIDNSigmaMin", -5, "tofPIDNSigmaMin"}; - Configurable tofPIDNSigmaMax{"tofPIDNSigmaMax", 5, "tofPIDNSigmaMax"}; - Configurable tpcPIDNSigmaCut{"tpcPIDNSigmaCut", 5, "tpcPIDNSigmaCut"}; - Configurable eventSel8Cut{"eventSel8Cut", true, "flag to enable event sel8 selection"}; - Configurable mcEventCut{"mcEventCut", true, "flag to enable mc event selection: kIsTriggerTVX and kNoTimeFrameBorder"}; - Configurable eventPosZCut{"eventPosZCut", true, "flag to enable event posZ selection"}; - Configurable lifetimecut{"lifetimecut", 40., "lifetimecut"}; // ct - Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; - Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; - Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; - Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; - Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; - Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; - Configurable minDeuteronPUseTOF{"minDeuteronPUseTOF", 1, "minDeuteronPt Enable TOF PID"}; - Configurable h3LMassLowerlimit{"h3LMassLowerlimit", 2.96, "Hypertriton mass lower limit"}; - Configurable h3LMassUpperlimit{"h3LMassUpperlimit", 3.04, "Hypertriton mass upper limit"}; - Configurable mintpcNClsproton{"mintpcNClsproton", 90, "min tpc Nclusters for proton"}; - Configurable mintpcNClspion{"mintpcNClspion", 70, "min tpc Nclusters for pion"}; - Configurable mintpcNClsdeuteron{"mintpcNClsdeuteron", 100, "min tpc Nclusters for deuteron"}; - - Configurable mcsigma{"mcsigma", 0.0015, "sigma of mc invariant mass fit"}; // obtained from MC - Configurable bachelorPdgCode{"bachelorPdgCode", 1000010020, "pdgCode of bachelor daughter"}; - Configurable motherPdgCode{"motherPdgCode", 1010010030, "pdgCode of mother track"}; - - // 3sigma region for Dalitz plot - float lowersignallimit = o2::constants::physics::MassHyperTriton - 3 * mcsigma; - float uppersignallimit = o2::constants::physics::MassHyperTriton + 3 * mcsigma; - - // CCDB options - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable pidPath{"pidPath", "", "Path to the PID response object"}; - - // Zorro counting - Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Skimmed dataset processing"}; - - HistogramRegistry registry{ - "registry", - { - {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, - {"hCentFT0C", "hCentFT0C", {HistType::kTH1F, {{100, 0.0f, 100.0f, "FT0C Centrality"}}}}, - {"hCandidatesCounter", "hCandidatesCounter", {HistType::kTH1F, {{12, 0.0f, 12.0f}}}}, - {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassHypertritonTotal", "hMassHypertritonTotal", {HistType::kTH1F, {{300, 2.9f, 3.2f}}}}, - {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hProtonTPCVsPt", "hProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hPionTPCVsPt", "hPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDeuteronTPCVsPt", "hDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDeuteronTOFVsPBeforeTOFCut", "hDeuteronTOFVsPBeforeTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"hDeuteronTOFVsPAtferTOFCut", "hDeuteronTOFVsPAtferTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - - {"hDalitz", "hDalitz", {HistType::kTH2F, {{120, 7.85, 8.45, "M^{2}(dp) (GeV^{2}/c^{4})"}, {60, 1.1, 1.4, "M^{2}(p#pi) (GeV^{2}/c^{4})"}}}}, - }, - }; - - //------------------------------------------------------------------ - // Fill stats histograms - enum Vtxstep { kCandAll = 0, - kCandDauEta, - kCandDauPt, - kCandTPCNcls, - kCandTPCPID, - kCandTOFPID, - kCandDcaToPV, - kCandRapidity, - kCandct, - kCandCosPA, - kCandDcaDau, - kCandInvMass, - kNCandSteps }; - - struct { - std::array candstats; - std::array truecandstats; - } statisticsRegistry; - - void resetHistos() - { - for (int ii = 0; ii < kNCandSteps; ii++) { - statisticsRegistry.candstats[ii] = 0; - statisticsRegistry.truecandstats[ii] = 0; - } - } - void fillCandCounter(int kn, bool istrue = false) - { - statisticsRegistry.candstats[kn]++; - if (istrue) { - statisticsRegistry.truecandstats[kn]++; - } - } - void fillHistos() - { - for (int ii = 0; ii < kNCandSteps; ii++) { - registry.fill(HIST("hCandidatesCounter"), ii, statisticsRegistry.candstats[ii]); - if (doprocessMC == true) { - registry.fill(HIST("hTrueHypertritonCounter"), ii, statisticsRegistry.truecandstats[ii]); - } - } - } - - int mRunNumber; - - void init(InitContext const&) - { - zorroSummary.setObject(zorro.getZorroSummary()); - - mRunNumber = 0; - - ccdb->setURL(ccdbUrl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(1, "total"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(2, "sel8"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(3, "vertexZ"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(4, "Zorro H3L 3body event"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(5, "has Candidate"); - - // Check for selection criteria !!! TracksIU required !!! - registry.add("hDiffRVtxProton", "hDiffRVtxProton", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of proton - registry.add("hDiffRVtxPion", "hDiffRVtxPion", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of pion - registry.add("hDiffRVtxDeuteron", "hDiffRVtxDeuteron", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of deuteron - registry.add("hDiffDaughterR", "hDiffDaughterR", HistType::kTH1F, {{10000, -100, 100}}); // difference between minR of pion&proton and R of deuteron(bachelor) - - // Check triggers - auto hEventTriggerCount = registry.add("hEventTriggerCount", "hEventTriggerCount", HistType::kTH1F, {{static_cast(triggerLabels.size() + 1), 0, static_cast(triggerLabels.size() + 1)}}); - for (size_t i = 0; i < triggerLabels.size(); i++) { - hEventTriggerCount->GetXaxis()->SetBinLabel(i + 1, triggerLabels[i].c_str()); - } - hEventTriggerCount->GetXaxis()->SetBinLabel(triggerLabels.size() + 1, "NoTrigger"); - - if (cfgLikeSignAnalysis) { - registry.add("hInvMassCorrectSign", "hInvMassCorrectSign", HistType::kTH1F, {{80, 2.96f, 3.04f}}); // check if there are contamination of possible signals which are caused by unexpected PID - } - - if (doprocessMC == true) { - registry.add("hTrueHypertritonCounter", "hTrueHypertritonCounter", HistType::kTH1F, {{12, 0.0f, 12.0f}}); - auto hGeneratedHypertritonCounter = registry.add("hGeneratedHypertritonCounter", "hGeneratedHypertritonCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); - hGeneratedHypertritonCounter->GetXaxis()->SetBinLabel(1, "Total"); - hGeneratedHypertritonCounter->GetXaxis()->SetBinLabel(2, "3-body decay"); - registry.add("hPtGeneratedHypertriton", "hPtGeneratedHypertriton", HistType::kTH1F, {{200, 0.0f, 10.0f}}); - registry.add("hctGeneratedHypertriton", "hctGeneratedHypertriton", HistType::kTH1F, {{50, 0, 50, "ct(cm)"}}); - registry.add("hEtaGeneratedHypertriton", "hEtaGeneratedHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - registry.add("hRapidityGeneratedHypertriton", "hRapidityGeneratedHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - registry.add("hPtGeneratedAntiHypertriton", "hPtGeneratedAntiHypertriton", HistType::kTH1F, {{200, 0.0f, 10.0f}}); - registry.add("hctGeneratedAntiHypertriton", "hctGeneratedAntiHypertriton", HistType::kTH1F, {{50, 0, 50, "ct(cm)"}}); - registry.add("hEtaGeneratedAntiHypertriton", "hEtaGeneratedAntiHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - registry.add("hRapidityGeneratedAntiHypertriton", "hRapidityGeneratedAntiHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - } - - TString candCounterbinLabel[kNCandSteps] = {"Total", "TrackEta", "DauPt", "TPCNcls", "TPCPID", "d TOFPID", "PionDcatoPV", "MomRapidity", "Lifetime", "VtxCosPA", "VtxDcaDau", "InvMass"}; - for (int i{0}; i < kNCandSteps; i++) { - registry.get(HIST("hCandidatesCounter"))->GetXaxis()->SetBinLabel(i + 1, candCounterbinLabel[i]); - if (doprocessMC == true) { - registry.get(HIST("hTrueHypertritonCounter"))->GetXaxis()->SetBinLabel(i + 1, candCounterbinLabel[i]); - } - } - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - if (cfgSkimmedProcessing) { - zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), triggerList); - zorro.populateHistRegistry(registry, bc.runNumber()); - } - - LOGF(info, "Initializing CCDB for run %d", bc.runNumber()); - mRunNumber = bc.runNumber(); - } - - //------------------------------------------------------------------ - // Check if the mcparticle is hypertriton which decays into 3 daughters - template - bool is3bodyDecayed(TMCParticle const& particle) - { - if (std::abs(particle.pdgCode()) != motherPdgCode) { - return false; - } - bool haveProton = false, havePion = false, haveBachelor = false; - bool haveAntiProton = false, haveAntiPion = false, haveAntiBachelor = false; - for (const auto& mcparticleDaughter : particle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == PDG_t::kProton) - haveProton = true; - if (mcparticleDaughter.pdgCode() == PDG_t::kProtonBar) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == PDG_t::kPiPlus) - havePion = true; - if (mcparticleDaughter.pdgCode() == PDG_t::kPiMinus) - haveAntiPion = true; - if (mcparticleDaughter.pdgCode() == bachelorPdgCode) - haveBachelor = true; - if (mcparticleDaughter.pdgCode() == -bachelorPdgCode) - haveAntiBachelor = true; - } - if (haveProton && haveAntiPion && haveBachelor && particle.pdgCode() > 0) { - return true; - } else if (haveAntiProton && havePion && haveAntiBachelor && particle.pdgCode() < 0) { - return true; - } - return false; - } - - //------------------------------------------------------------------ - // Event Selection - template - bool eventSelection(TCollision const& collision) - { - auto bc = collision.template bc_as(); - initCCDB(bc); - registry.fill(HIST("hEventCounter"), 0.5); - - if (eventSel8Cut && !collision.sel8()) { - return false; - } - registry.fill(HIST("hEventCounter"), 1.5); - if (eventPosZCut && std::abs(collision.posZ()) > 10.f) { // 10cm - return false; - } - registry.fill(HIST("hEventCounter"), 2.5); - registry.fill(HIST("hCentFT0C"), collision.centFT0C()); - - if (cfgSkimmedProcessing) { - bool zorroSelected = zorro.isSelected(bc.globalBC()); /// Just let Zorro do the accounting - if (zorroSelected) { - registry.fill(HIST("hEventCounter"), 3.5); - } else { - if (cfgOnlyKeepInterestedTrigger) { - return false; - } - } - } - - return true; - } - - //------------------------------------------------------------------ - // Fill candidate table - template - void fillCand(TCollisionTable const& collision, TCandTable const& candData, TTrackTable const& trackProton, TTrackTable const& trackPion, TTrackTable const& trackDeuteron, bool isMatter, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double mcLifetime = -1, bool isBachPrimary = false) - { - double cospa = candData.vtxcosPA(collision.posX(), collision.posY(), collision.posZ()); - double ct = candData.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassHyperTriton; - - Candidate3body cand3body; - cand3body.isMatter = isMatter; - if (isMatter == true) { - cand3body.lproton.SetXYZM(candData.pxtrack0(), candData.pytrack0(), candData.pztrack0(), o2::constants::physics::MassProton); - cand3body.lpion.SetXYZM(candData.pxtrack1(), candData.pytrack1(), candData.pztrack1(), o2::constants::physics::MassPionCharged); - } else { - cand3body.lproton.SetXYZM(candData.pxtrack1(), candData.pytrack1(), candData.pztrack1(), o2::constants::physics::MassPionCharged); - cand3body.lpion.SetXYZM(candData.pxtrack0(), candData.pytrack0(), candData.pztrack0(), o2::constants::physics::MassProton); - } - - cand3body.mcmotherId = lLabel; - cand3body.track0Id = candData.track0Id(); - cand3body.track1Id = candData.track1Id(); - cand3body.track2Id = candData.track2Id(); - cand3body.colCentFT0C = collision.centFT0C(); - cand3body.invmass = cand3body.isMatter ? candData.mHypertriton() : candData.mAntiHypertriton(); - cand3body.lcand.SetXYZM(candData.px(), candData.py(), candData.pz(), o2::constants::physics::MassHyperTriton); - cand3body.ct = ct; - cand3body.cosPA = cospa; - cand3body.dcadaughters = candData.dcaVtxdaughters(); - cand3body.dcacandtopv = candData.dcavtxtopv(collision.posX(), collision.posY(), collision.posZ()); - cand3body.vtxradius = candData.vtxradius(); - cand3body.lbachelor.SetXYZM(candData.pxtrack2(), candData.pytrack2(), candData.pztrack2(), o2::constants::physics::MassDeuteron); - cand3body.dautpcNclusters[0] = trackProton.tpcNClsFound(); - cand3body.dautpcNclusters[1] = trackPion.tpcNClsFound(); - cand3body.dautpcNclusters[2] = trackDeuteron.tpcNClsFound(); - cand3body.dauitsclussize[0] = trackProton.itsClusterSizes(); - cand3body.dauitsclussize[1] = trackPion.itsClusterSizes(); - cand3body.dauitsclussize[2] = trackDeuteron.itsClusterSizes(); - cand3body.dautpcNsigma[0] = trackProton.tpcNSigmaPr(); - cand3body.dautpcNsigma[1] = trackPion.tpcNSigmaPi(); - cand3body.dautpcNsigma[2] = trackDeuteron.tpcNSigmaDe(); - cand3body.daudcaxytopv[0] = cand3body.isMatter ? candData.dcaXYtrack0topv() : candData.dcaXYtrack1topv(); - cand3body.daudcaxytopv[1] = cand3body.isMatter ? candData.dcaXYtrack1topv() : candData.dcaXYtrack0topv(); - cand3body.daudcaxytopv[2] = candData.dcaXYtrack2topv(); - cand3body.daudcatopv[0] = cand3body.isMatter ? candData.dcatrack0topv() : candData.dcatrack1topv(); - cand3body.daudcatopv[1] = cand3body.isMatter ? candData.dcatrack1topv() : candData.dcatrack0topv(); - cand3body.daudcatopv[2] = candData.dcatrack2topv(); - cand3body.dauinnermostR[0] = trackProton.x(); - cand3body.dauinnermostR[1] = trackPion.x(); - cand3body.dauinnermostR[2] = trackDeuteron.x(); - - cand3body.bachelortofNsigma = candData.tofNSigmaBachDe(); - cand3body.isBachPrimary = isBachPrimary; - if (isTrueCand) { - cand3body.mcmotherId = lLabel; - cand3body.lgencand = lmother; - cand3body.genct = mcLifetime; - cand3body.genrapidity = lmother.Rapidity(); - cand3body.isSignal = true; - cand3body.isReco = true; - cand3body.pdgCode = cand3body.isMatter ? motherPdgCode : -motherPdgCode; - cand3body.survivedEventSelection = true; - filledMothers.push_back(lLabel); - } - - candidates3body.push_back(cand3body); - - registry.fill(HIST("hProtonTPCBB"), trackProton.sign() * trackProton.p(), trackProton.tpcSignal()); - registry.fill(HIST("hPionTPCBB"), trackPion.sign() * trackPion.p(), trackPion.tpcSignal()); - registry.fill(HIST("hDeuteronTPCBB"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tpcSignal()); - registry.fill(HIST("hProtonTPCVsPt"), trackProton.pt(), trackProton.tpcNSigmaPr()); - registry.fill(HIST("hPionTPCVsPt"), trackProton.pt(), trackPion.tpcNSigmaPi()); - registry.fill(HIST("hDeuteronTPCVsPt"), trackDeuteron.pt(), trackDeuteron.tpcNSigmaDe()); - registry.fill(HIST("hTOFPIDDeuteron"), candData.tofNSigmaBachDe()); - registry.fill(HIST("hDiffRVtxProton"), trackProton.x() - candData.vtxradius()); - registry.fill(HIST("hDiffRVtxPion"), trackPion.x() - candData.vtxradius()); - registry.fill(HIST("hDiffRVtxDeuteron"), trackDeuteron.x() - candData.vtxradius()); - float diffTrackR = trackDeuteron.x() - std::min(trackProton.x(), trackPion.x()); - registry.fill(HIST("hDiffDaughterR"), diffTrackR); - } - - //------------------------------------------------------------------ - // Selections for candidates - template - bool selectCand(TCollisionTable const& collision, TCandTable const& candData, TTrackTable const& trackProton, TTrackTable const& trackPion, TTrackTable const& trackDeuteron, bool isMatter, bool isTrueCand = false) - { - fillCandCounter(kCandAll, isTrueCand); - - // Selection on daughters - if (std::abs(trackProton.eta()) > etacut || std::abs(trackPion.eta()) > etacut || std::abs(trackDeuteron.eta()) > etacut) { - return false; - } - fillCandCounter(kCandDauEta, isTrueCand); - - if (trackProton.pt() < minProtonPt || trackProton.pt() > maxProtonPt || trackPion.pt() < minPionPt || trackPion.pt() > maxPionPt || trackDeuteron.pt() < minDeuteronPt || trackDeuteron.pt() > maxDeuteronPt) { - return false; - } - fillCandCounter(kCandDauPt, isTrueCand); - - if (trackProton.tpcNClsFound() < mintpcNClsproton || trackPion.tpcNClsFound() < mintpcNClspion || trackDeuteron.tpcNClsFound() < mintpcNClsdeuteron) { - return false; - } - fillCandCounter(kCandTPCNcls, isTrueCand); - - if (std::abs(trackProton.tpcNSigmaPr()) > tpcPIDNSigmaCut || std::abs(trackPion.tpcNSigmaPi()) > tpcPIDNSigmaCut || std::abs(trackDeuteron.tpcNSigmaDe()) > tpcPIDNSigmaCut) { - return false; - } - fillCandCounter(kCandTPCPID, isTrueCand); - - registry.fill(HIST("hDeuteronTOFVsPBeforeTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), candData.tofNSigmaBachDe()); - if ((candData.tofNSigmaBachDe() < tofPIDNSigmaMin || candData.tofNSigmaBachDe() > tofPIDNSigmaMax) && trackDeuteron.p() > minDeuteronPUseTOF) { - return false; - } - fillCandCounter(kCandTOFPID, isTrueCand); - registry.fill(HIST("hDeuteronTOFVsPAtferTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), candData.tofNSigmaBachDe()); - - double dcapion = isMatter ? candData.dcatrack1topv() : candData.dcatrack0topv(); - if (std::abs(dcapion) < dcapiontopv) { - return false; - } - fillCandCounter(kCandDcaToPV, isTrueCand); - - // Selection on candidate hypertriton - if (std::abs(candData.yHypertriton()) > rapiditycut) { - return false; - } - fillCandCounter(kCandRapidity, isTrueCand); - - double ct = candData.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassHyperTriton; - if (ct > lifetimecut) { - return false; - } - fillCandCounter(kCandct, isTrueCand); - - double cospa = candData.vtxcosPA(collision.posX(), collision.posY(), collision.posZ()); - if (cospa < vtxcospa) { - return false; - } - fillCandCounter(kCandCosPA, isTrueCand); - - if (candData.dcaVtxdaughters() > dcavtxdau) { - return false; - } - fillCandCounter(kCandDcaDau, isTrueCand); - - if ((isMatter && candData.mHypertriton() > h3LMassLowerlimit && candData.mHypertriton() < h3LMassUpperlimit)) { - // Hypertriton - registry.fill(HIST("hMassHypertriton"), candData.mHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), candData.mHypertriton()); - if (candData.mHypertriton() > lowersignallimit && candData.mHypertriton() < uppersignallimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(std::array{std::array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}, std::array{candData.pxtrack2(), candData.pytrack2(), candData.pztrack2()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), RecoDecay::m2(std::array{std::array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}, std::array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - } else if ((!isMatter && candData.mAntiHypertriton() > h3LMassLowerlimit && candData.mAntiHypertriton() < h3LMassUpperlimit)) { - // AntiHypertriton - registry.fill(HIST("hMassAntiHypertriton"), candData.mAntiHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), candData.mAntiHypertriton()); - if (candData.mAntiHypertriton() > lowersignallimit && candData.mAntiHypertriton() < uppersignallimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(std::array{std::array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}, std::array{candData.pxtrack2(), candData.pytrack2(), candData.pztrack2()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), RecoDecay::m2(std::array{std::array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}, std::array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - } else { - return false; - } - fillCandCounter(kCandInvMass, isTrueCand); - - return true; - } - - //------------------------------------------------------------------ - // Analysis process for a single candidate - template - void candidateAnalysis(TCollisionTable const& collision, TCandTable const& candData, bool& ifHasCandidate, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double mcLifetime = -1, double isBachPrimary = false) - { - auto track0 = candData.template track0_as(); - auto track1 = candData.template track1_as(); - auto track2 = candData.template track2_as(); - - bool isMatter = track2.sign() > 0; // true if the candidate is hypertriton (p pi- d) - - auto& trackProton = isMatter ? track0 : track1; - auto& trackPion = isMatter ? track1 : track0; - auto& trackDeuteron = track2; - - if (selectCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand)) { - ifHasCandidate = true; - fillCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand, lLabel, lmother, mcLifetime, isBachPrimary); - } - } - - //------------------------------------------------------------------ - // Analysis process for like-sign candidates : (p pi- anti-d) or (anti-p pi+ d) - template - void likeSignAnalysis(TCollisionTable const& collision, TCandTable const& candData, bool& ifHasCandidate, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double mcLifetime = -1, double isBachPrimary = false) - { - auto track0 = candData.template track0_as(); - auto track1 = candData.template track1_as(); - auto track2 = candData.template track2_as(); - - bool isMatter = track2.sign() < 0; // true if seach for background consists of (p pi- anti-d) - - // Assume proton has an oppisite charge with deuteron - auto& trackProton = isMatter ? track0 : track1; - auto& trackPion = isMatter ? track1 : track0; - auto& trackDeuteron = track2; - - if (selectCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand)) { - ifHasCandidate = true; - fillCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand, lLabel, lmother, mcLifetime, isBachPrimary); - // QA for if signals have the possibility to be reconginzed as a like-sign background - if (isMatter) { - registry.fill(HIST("hInvMassCorrectSign"), candData.mHypertriton()); - } else { - registry.fill(HIST("hInvMassCorrectSign"), candData.mAntiHypertriton()); - } - } - } - - //------------------------------------------------------------------ - // Analysis process for reduced data - template - void reducedAnalysis(TCollisionTable const& collision, TCandTable const& candData, TTracks tracks, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double mcLifetime = -1, double isBachPrimary = false) - { - auto track0 = tracks.rawIteratorAt(candData.track0Id()); - auto track1 = tracks.rawIteratorAt(candData.track1Id()); - auto track2 = tracks.rawIteratorAt(candData.track2Id()); - - bool isMatter = track2.sign() > 0; // true if the candidate is hypertriton (p pi- d) - - auto& trackProton = isMatter ? track0 : track1; - auto& trackPion = isMatter ? track1 : track0; - auto& trackDeuteron = track2; - - if (selectCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand)) { - fillCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand, lLabel, lmother, mcLifetime, isBachPrimary); - } - } - - //------------------------------------------------------------------ - // Analysis process for reduced data with like-sign candidates - template - void reducedLikeSignAnalysis(TCollisionTable const& collision, TCandTable const& candData, TTracks tracks, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double mcLifetime = -1, bool isBachPrimary = false) - { - auto track0 = tracks.rawIteratorAt(candData.track0Id()); - auto track1 = tracks.rawIteratorAt(candData.track1Id()); - auto track2 = tracks.rawIteratorAt(candData.track2Id()); - - bool isMatter = track2.sign() < 0; // true if seach for background consists of (p pi- anti-d) - - // Assume proton has an oppisite charge with deuteron - auto& trackProton = isMatter ? track0 : track1; - auto& trackPion = isMatter ? track1 : track0; - auto& trackDeuteron = track2; - - if (selectCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand)) { - fillCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand, lLabel, lmother, mcLifetime, isBachPrimary); - // QA for if signals have the possibility to be reconginzed as a like-sign background - if (isMatter) { - registry.fill(HIST("hInvMassCorrectSign"), candData.mHypertriton()); - } else { - registry.fill(HIST("hInvMassCorrectSign"), candData.mAntiHypertriton()); - } - } - } - - //------------------------------------------------------------------ - void fillOutputDataTable(Candidate3body const& cand3body) - { - outputDataTable(cand3body.colCentFT0C, - cand3body.isMatter, cand3body.invmass, cand3body.lcand.P(), cand3body.lcand.Pt(), cand3body.ct, - cand3body.cosPA, cand3body.dcadaughters, cand3body.dcacandtopv, cand3body.vtxradius, - cand3body.lproton.Pt(), cand3body.lproton.Eta(), cand3body.lproton.Phi(), cand3body.dauinnermostR[0], - cand3body.lpion.Pt(), cand3body.lpion.Eta(), cand3body.lpion.Phi(), cand3body.dauinnermostR[1], - cand3body.lbachelor.Pt(), cand3body.lbachelor.Eta(), cand3body.lbachelor.Phi(), cand3body.dauinnermostR[2], - cand3body.dautpcNclusters[0], cand3body.dautpcNclusters[1], cand3body.dautpcNclusters[2], - cand3body.dauitsclussize[0], cand3body.dauitsclussize[1], cand3body.dauitsclussize[2], - cand3body.dautpcNsigma[0], cand3body.dautpcNsigma[1], cand3body.dautpcNsigma[2], cand3body.bachelortofNsigma, - cand3body.daudcaxytopv[0], cand3body.daudcaxytopv[1], cand3body.daudcaxytopv[2], - cand3body.daudcatopv[0], cand3body.daudcatopv[1], cand3body.daudcatopv[2]); - } - - //------------------------------------------------------------------ - // collect information for generated hypertriton (should be called after event selection) - void getGeneratedH3LInfo(aod::McParticles const& particlesMC) - { - for (const auto& mcparticle : particlesMC) { - if (std::abs(mcparticle.pdgCode()) != motherPdgCode) { - continue; - } - registry.fill(HIST("hGeneratedHypertritonCounter"), 0.5); - - bool haveProton = false, havePionPlus = false, haveDeuteron = false; - bool haveAntiProton = false, havePionMinus = false, haveAntiDeuteron = false; - double mcLifetime = -1; - for (const auto& mcparticleDaughter : mcparticle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == PDG_t::kProton) - haveProton = true; - if (mcparticleDaughter.pdgCode() == PDG_t::kProtonBar) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == PDG_t::kPiPlus) - havePionPlus = true; - if (mcparticleDaughter.pdgCode() == -PDG_t::kPiPlus) - havePionMinus = true; - if (mcparticleDaughter.pdgCode() == bachelorPdgCode) { - haveDeuteron = true; - mcLifetime = RecoDecay::sqrtSumOfSquares(mcparticleDaughter.vx() - mcparticle.vx(), mcparticleDaughter.vy() - mcparticle.vy(), mcparticleDaughter.vz() - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - } - if (mcparticleDaughter.pdgCode() == -bachelorPdgCode) { - haveAntiDeuteron = true; - mcLifetime = RecoDecay::sqrtSumOfSquares(mcparticleDaughter.vx() - mcparticle.vx(), mcparticleDaughter.vy() - mcparticle.vy(), mcparticleDaughter.vz() - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - } - } - if (haveProton && havePionMinus && haveDeuteron && mcparticle.pdgCode() == motherPdgCode) { - registry.fill(HIST("hGeneratedHypertritonCounter"), 1.5); - registry.fill(HIST("hPtGeneratedHypertriton"), mcparticle.pt()); - registry.fill(HIST("hctGeneratedHypertriton"), mcLifetime); - registry.fill(HIST("hEtaGeneratedHypertriton"), mcparticle.eta()); - registry.fill(HIST("hRapidityGeneratedHypertriton"), mcparticle.y()); - } else if (haveAntiProton && havePionPlus && haveAntiDeuteron && mcparticle.pdgCode() == -motherPdgCode) { - registry.fill(HIST("hGeneratedHypertritonCounter"), 1.5); - registry.fill(HIST("hPtGeneratedAntiHypertriton"), mcparticle.pt()); - registry.fill(HIST("hctGeneratedAntiHypertriton"), mcLifetime); - registry.fill(HIST("hEtaGeneratedAntiHypertriton"), mcparticle.eta()); - registry.fill(HIST("hRapidityGeneratedAntiHypertriton"), mcparticle.y()); - } - } - } - - //------------------------------------------------------------------ - // process real data analysis - void processData(soa::Join const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, FullTracksExtIU const&, aod::BCsWithTimestamps const&) - { - for (const auto& collision : collisions) { - candidates3body.clear(); - - if (!eventSelection(collision)) { - continue; - } - - bool ifHasCandidate = false; - auto d3BodyCands = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); - for (const auto& vtx : d3BodyCands) { - if (cfgLikeSignAnalysis) { - likeSignAnalysis(collision, vtx, ifHasCandidate); - } else { - candidateAnalysis(collision, vtx, ifHasCandidate); - } - } - - if (ifHasCandidate) { - auto bc = collision.bc_as(); - auto triggerSelection = zorro.getTriggerOfInterestResults(bc.globalBC(), bcTolerance); - for (size_t i = 0; i < triggerSelection.size(); i++) { - if (triggerSelection[i]) { - registry.fill(HIST("hEventTriggerCount"), i + 0.5); - } - } - if (zorro.isNotSelectedByAny(bc.globalBC(), bcTolerance)) { - registry.fill(HIST("hEventTriggerCount"), triggerLabels.size() + 0.5); - } - registry.fill(HIST("hEventCounter"), 4.5); - } - fillHistos(); - resetHistos(); - - for (const auto& cand3body : candidates3body) { - fillOutputDataTable(cand3body); - } - } - } - PROCESS_SWITCH(ThreebodyRecoTask, processData, "Real data reconstruction", true); - - //------------------------------------------------------------------ - // process reduced data analysis - void processReducedData(ReducedCols const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, aod::RedIUTracks const& tracks) - { - candidates3body.clear(); - - registry.fill(HIST("hEventCounter"), 0.5, collisions.size()); - - for (const auto& vtx : vtx3bodydatas) { - const auto& collision = collisions.iteratorAt(vtx.collisionId()); - if (cfgLikeSignAnalysis) { - reducedLikeSignAnalysis(collision, vtx, tracks); - } else { - reducedAnalysis(collision, vtx, tracks); - } - for (const auto& cand3body : candidates3body) { - fillOutputDataTable(cand3body); - } - candidates3body.clear(); - } - fillHistos(); - resetHistos(); - } - PROCESS_SWITCH(ThreebodyRecoTask, processReducedData, "Reduced data reconstruction", false); - - //------------------------------------------------------------------ - // process mc analysis - void processMC(soa::Join const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, aod::McParticles const& particlesMC, MCLabeledTracksIU const& /*tracks*/, aod::McCollisions const& mcCollisions) - { - filledMothers.clear(); - getGeneratedH3LInfo(particlesMC); - isGoodCollision.resize(mcCollisions.size(), false); - - for (const auto& collision : collisions) { - candidates3body.clear(); - registry.fill(HIST("hEventCounter"), 0.5); - if (mcEventCut && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - registry.fill(HIST("hEventCounter"), 1.5); - if (eventPosZCut && std::abs(collision.posZ()) > 10.f) { // 10cm - continue; - } - registry.fill(HIST("hEventCounter"), 2.5); - registry.fill(HIST("hCentFT0C"), collision.centFT0C()); - - if (collision.mcCollisionId() >= 0) { - isGoodCollision[collision.mcCollisionId()] = true; - } - - bool ifHasCandidate = false; - auto vtxsThisCol = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); - - for (const auto& vtx : vtxsThisCol) { - bool isBachPrimary = false; - int lLabel = -1; - int lPDG = -1; - double mcLifetime = -1; - TLorentzVector lmother; - bool isTrueCand = false; - auto track0 = vtx.track0_as(); - auto track1 = vtx.track1_as(); - auto track2 = vtx.track2_as(); - if (track0.has_mcParticle() && track1.has_mcParticle() && track2.has_mcParticle()) { - auto lMCTrack0 = track0.mcParticle_as(); - auto lMCTrack1 = track1.mcParticle_as(); - auto lMCTrack2 = track2.mcParticle_as(); - - if (lMCTrack2.isPhysicalPrimary()) { - isBachPrimary = true; - } - - if (lMCTrack0.has_mothers() && lMCTrack1.has_mothers() && lMCTrack2.has_mothers()) { - for (const auto& lMother0 : lMCTrack0.mothers_as()) { - for (const auto& lMother1 : lMCTrack1.mothers_as()) { - for (const auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - lLabel = lMother0.globalIndex(); - lPDG = lMother0.pdgCode(); - if ((lPDG == motherPdgCode && lMCTrack0.pdgCode() == PDG_t::kProton && lMCTrack1.pdgCode() == PDG_t::kPiMinus && lMCTrack2.pdgCode() == bachelorPdgCode) || - (lPDG == -motherPdgCode && lMCTrack0.pdgCode() == PDG_t::kPiPlus && lMCTrack1.pdgCode() == PDG_t::kProtonBar && lMCTrack2.pdgCode() == -bachelorPdgCode)) { - isTrueCand = true; - mcLifetime = RecoDecay::sqrtSumOfSquares(lMCTrack2.vx() - lMother2.vx(), lMCTrack2.vy() - lMother2.vy(), lMCTrack2.vz() - lMother2.vz()) * o2::constants::physics::MassHyperTriton / lMother2.p(); - lmother.SetXYZM(lMother0.px(), lMother0.py(), lMother0.pz(), o2::constants::physics::MassHyperTriton); - } - } - } - } - } - } - } - - candidateAnalysis(collision, vtx, ifHasCandidate, isTrueCand, lLabel, lmother, mcLifetime, isBachPrimary); - } - - if (ifHasCandidate) - registry.fill(HIST("hEventCounter"), 4.5); - fillHistos(); - resetHistos(); - - for (const auto& cand3body : candidates3body) { - outputMCTable(cand3body.colCentFT0C, - cand3body.isMatter, cand3body.invmass, cand3body.lcand.P(), cand3body.lcand.Pt(), cand3body.ct, - cand3body.cosPA, cand3body.dcadaughters, cand3body.dcacandtopv, cand3body.vtxradius, - cand3body.lproton.Pt(), cand3body.lproton.Eta(), cand3body.lproton.Phi(), cand3body.dauinnermostR[0], - cand3body.lpion.Pt(), cand3body.lpion.Eta(), cand3body.lpion.Phi(), cand3body.dauinnermostR[1], - cand3body.lbachelor.Pt(), cand3body.lbachelor.Eta(), cand3body.lbachelor.Phi(), cand3body.dauinnermostR[2], - cand3body.dautpcNclusters[0], cand3body.dautpcNclusters[1], cand3body.dautpcNclusters[2], - cand3body.dauitsclussize[0], cand3body.dauitsclussize[1], cand3body.dauitsclussize[2], - cand3body.dautpcNsigma[0], cand3body.dautpcNsigma[1], cand3body.dautpcNsigma[2], cand3body.bachelortofNsigma, - cand3body.daudcaxytopv[0], cand3body.daudcaxytopv[1], cand3body.daudcaxytopv[2], - cand3body.daudcatopv[0], cand3body.daudcatopv[1], cand3body.daudcatopv[2], - cand3body.isBachPrimary, - cand3body.lgencand.P(), cand3body.lgencand.Pt(), cand3body.genct, cand3body.lgencand.Phi(), cand3body.lgencand.Eta(), cand3body.lgencand.Rapidity(), - cand3body.isSignal, cand3body.isReco, cand3body.pdgCode, cand3body.survivedEventSelection); - } - } - - // now we fill only the signal candidates that were not reconstructed - for (const auto& mcparticle : particlesMC) { - if (!is3bodyDecayed(mcparticle)) { - continue; - } - if (std::find(filledMothers.begin(), filledMothers.end(), mcparticle.globalIndex()) != std::end(filledMothers)) { - continue; - } - bool isSurEvSelection = isGoodCollision[mcparticle.mcCollisionId()]; - std::array posSV{0.f}; - for (const auto& mcDaughter : mcparticle.daughters_as()) { - if (std::abs(mcDaughter.pdgCode()) == bachelorPdgCode) { - posSV = {mcDaughter.vx(), mcDaughter.vy(), mcDaughter.vz()}; - } - } - double mcLifetime = RecoDecay::sqrtSumOfSquares(posSV[0] - mcparticle.vx(), posSV[1] - mcparticle.vy(), posSV[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - outputMCTable(-1, - -1, -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - false, - mcparticle.p(), mcparticle.pt(), mcLifetime, mcparticle.phi(), mcparticle.eta(), mcparticle.y(), - true, false, mcparticle.pdgCode(), isSurEvSelection); - } - } - PROCESS_SWITCH(ThreebodyRecoTask, processMC, "MC reconstruction", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index b2af549c871..895e15935fc 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -24,16 +24,6 @@ o2physics_add_dpl_workflow(nuclei-hist PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(hypertriton3bodyanalysis - SOURCES hypertriton3bodyanalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hypertriton3bodymcqa - SOURCES hypertriton3bodyMcqa.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore O2::TOFBase - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(helium-flow SOURCES helium_flow.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyMcqa.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyMcqa.cxx deleted file mode 100644 index ef8dfb4b958..00000000000 --- a/PWGLF/Tasks/Nuspex/hypertriton3bodyMcqa.cxx +++ /dev/null @@ -1,908 +0,0 @@ -// 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 hypertriton3bodyMcqa.cxx -/// \brief QA for MC productions which contain hypertriton 3body decay process, including special checks for TOF PID -/// \author Yuanzhe Wang - -#include -#include -#include -#include -#include -#include -#include - -#include "CommonDataFormat/InteractionRecord.h" -#include "CommonDataFormat/IRFrame.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/TableProducer/PID/pidTOFBase.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "CommonConstants/PhysicsConstants.h" -#include "CCDB/BasicCCDBManager.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; -using ColwithEvTimes = o2::soa::Join; -using FullTracksExtIU = soa::Join; -using MCLabeledTracksIU = soa::Join; - -template -bool is3bodyDecayedH3L(TMCParticle const& particle) -{ - if (std::abs(particle.pdgCode()) != 1010010030) { - return false; - } - bool haveProton = false, havePion = false, haveDeuteron = false; - bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; - for (const auto& mcDaughter : particle.template daughters_as()) { - if (mcDaughter.pdgCode() == 2212) - haveProton = true; - if (mcDaughter.pdgCode() == -2212) - haveAntiProton = true; - if (mcDaughter.pdgCode() == 211) - havePion = true; - if (mcDaughter.pdgCode() == -211) - haveAntiPion = true; - if (mcDaughter.pdgCode() == 1000010020) - haveDeuteron = true; - if (mcDaughter.pdgCode() == -1000010020) - haveAntiDeuteron = true; - } - if (haveProton && haveAntiPion && haveDeuteron && particle.pdgCode() > 0) { - return true; - } else if (haveAntiProton && havePion && haveAntiDeuteron && particle.pdgCode() < 0) { - return true; - } - return false; -} - -template -bool isPairedH3LDaughters(TMCParticle const& mctrack0, TMCParticle const& mctrack1, TMCParticle const& mctrack2) -{ - for (const auto& particleMother : mctrack0.template mothers_as()) { - if (!(particleMother.pdgCode() == 1010010030 && mctrack0.pdgCode() == 2212 && mctrack1.pdgCode() == -211 && mctrack2.pdgCode() == 1000010020) && - !(particleMother.pdgCode() == -1010010030 && mctrack0.pdgCode() == -2212 && mctrack1.pdgCode() == 211 && mctrack2.pdgCode() == -1000010020)) { - continue; - } - bool flag1 = false, flag2 = false; - for (const auto& mcDaughter : particleMother.template daughters_as()) { - if (mcDaughter.globalIndex() == mctrack1.globalIndex()) - flag1 = true; - if (mcDaughter.globalIndex() == mctrack2.globalIndex()) - flag2 = true; - } - if (!flag1 || !flag2) - continue; - // move the requirement in mass region into the loop to draw a histogram - // double hypertritonMCMass = RecoDecay::m(array{array{mctrack0.px(), mctrack0.py(), mctrack0.pz()}, array{mctrack1.px(), mctrack1.py(), mctrack1.pz()}, array{mctrack2.px(), mctrack2.py(), mctrack2.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - // if (hypertritonMCMass > 2.990 && hypertritonMCMass < 2.993) - return true; - } - return false; -} - -// check the properties of daughters candidates and true daughters -struct Hypertriton3bodyMcqa { - - Service ccdb; - Preslice perCollisionTracks = aod::track::collisionId; - - int mRunNumber; - - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"hParticleCounter", "hParticleCounter", {HistType::kTH1F, {{7, 0.0f, 7.0f}}}}, - - {"hTPCNCls", "hTPCNCls", {HistType::kTH1F, {{160, 0.0f, 160.0f}}}}, - {"hTPCNClsCrossedRows", "hTPCNClsCrossedRows", {HistType::kTH1F, {{160, 0.0f, 160.0f}}}}, - {"hTrackEta", "hTrackEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hTrackITSNcls", "hTrackITSNcls", {HistType::kTH1F, {{10, 0.0f, 10.0f}}}}, - {"hTrackMcRapidity", "hTrackMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hTrackNsigmaProton", "hTrackNsigmaProton", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hTrackNsigmaPion", "hTrackNsigmaPion", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hTrackNsigmaDeuteron", "hTrackNsigmaDeuteron", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - - {"hHypertritonEta", "hHypertritomEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hHypertritonMcRapidity", "hHypertritonMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hHypertritonMcPt", "hHypertritonMcPt", {HistType::kTH1F, {{300, 0.0f, 15.0f}}}}, - - {"hProtonCounter", "hProtonCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hProtonPt", "hProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonP", "hProtonP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonMcPt", "hProtonMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonMcP", "hProtonMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonEta", "hProtonEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hProtonMcRapidity", "hProtonMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hProtonNsigmaProton", "hProtonNsigmaProton", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hProtonTPCNCls", "hProtonTPCNCls", {HistType::kTH1F, {{120, 0.0f, 120.0f}}}}, - {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hProtonTPCBBAfterTPCNclsCut", "hProtonTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDauProtonPt", "hDauProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauProtonMcPt", "hDauProtonMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauProtonNsigmaProton", "hDauProtonNsigmaProton", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hDauProtonTPCVsPt", "hDauProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {120, -6.0f, 6.0f, "TPC n#sigma"}}}}, - - {"hPionCounter", "hPionCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hPionPt", "hPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionP", "hPionP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionMcPt", "hPionMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionMcP", "hPionMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionEta", "hPionEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hPionMcRapidity", "hPionMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hPionNsigmaPion", "hPionNsigmaPion", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hPionTPCNCls", "hPionTPCNCls", {HistType::kTH1F, {{160, 0.0f, 160.0f}}}}, - {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hPionTPCBBAfterTPCNclsCut", "hPionTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDauPionPt", "hDauPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauPionMcPt", "hDauPionMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauPionNsigmaPion", "hDauPionNsigmaPion", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hDauPionTPCVsPt", "hDauPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {120, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDauPionDcaXY", "hDauPionDcaXY", {HistType::kTH1F, {{100, -10.0f, 10.0f}}}}, - - {"hDeuteronCounter", "hDeuteronCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hDeuteronPt", "hDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronP", "hDeuteronP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronMcPt", "hDeuteronMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronMcP", "hDeuteronMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronEta", "hDeuteronEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hDeuteronMcRapidity", "hDeuteronMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hDeuteronNsigmaDeuteron", "hDeuteronNsigmaDeuteron", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hDeuteronTPCNCls", "hDeuteronTPCNCls", {HistType::kTH1F, {{120, 0.0f, 120.0f}}}}, - {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDeuteronTPCBBAfterTPCNclsCut", "hDeuteronTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDauDeuteronPt", "hDauDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauDeuteronMcPt", "hDauDeuteronMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauDeuteronTPCVsPt", "hDauDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {120, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDauDeuteronTOFNSigmaVsP", "hDauDeuteronTOFNSigmaVsP", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronTOFNSigmaVsPHasTOF", "hDauDeuteronTOFNSigmaVsPHasTOF", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronMatchCounter", "hDauDeuteronMatchCounter", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, - - {"hTPCBB", "hTPCBB", {HistType::kTH2F, {{120, -8.0f, 8.0f, "p/z(GeV/c)"}, {100, 0.0f, 1000.0f, "TPCSignal"}}}}, - - {"hPairedH3LDaughers", "hPairedH3LDaughers", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"hPairedH3LDaughersInvMass", "hPairedH3LDaughersInvMass", {HistType::kTH1F, {{300, 2.9f, 3.2f}}}}, - {"hDuplicatedH3LDaughers", "hDuplicatedH3LDaughers", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - - // Diff checks always requir hasTOF - {"hDiffTrackTOFSignal", "hDiffTrackTOFSignal", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, - {"hDiffEvTimeForTrack", "hDiffEvTimeForTrack", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, - {"hDiffTrackTOFNSigmaDe", "hDiffTrackTOFNSigmaDe", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, - {"hDauDeuteronNewTOFNSigmaVsP", "hDauDeuteronNewTOFNSigmaVsP", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hWrongDeuteronTOFNSigmaVsP", "hWrongDeuteronTOFNSigmaVsP", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hWrongDeuteronNewTOFNSigmaVsP", "hWrongDeuteronNewTOFNSigmaVsP", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDiffColTime", "hDiffColTime", {HistType::kTH1F, {{200, -100.0f, 100.0f}}}}, - {"hDauDeuteronDiffTOFNsigmaDeHasTOF", "hDauDeuteronDiffTOFNsigmaDeHasTOF", {HistType::kTH1F, {{200, -100.0f, 100.0f}}}}, - - // _v2 for using relinked collision - {"hDauDeuteronTOFNSigmaVsP_CorrectCol", "hDauDeuteronTOFNSigmaVsP_CorrectCol", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronNewTOFNSigmaVsP_CorrectCol", "hDauDeuteronNewTOFNSigmaVsP_CorrectCol", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronTOFNSigmaVsP_v2", "hDauDeuteronTOFNSigmaVsP_v2", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronNewTOFNSigmaVsP_v2_AO2D", "hDauDeuteronNewTOFNSigmaVsP_v2 AO2D", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronNewTOFNSigmaVsP_v2_EvSel", "hDauDeuteronNewTOFNSigmaVsP_v2 EvSel", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronTOFNSigmaVsColTimeRes_v2", "hDauDeuteronTOFNSigmaVsColTimeRes_v2", {HistType::kTH2F, {{100, 0.0f, 400.0f, "CollisionTimeRes(ns)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronTOFNSigmaVsColTimeRes_v2_AO2D", "hDauDeuteronTOFNSigmaVsColTimeRes_v2 AO2D", {HistType::kTH2F, {{100, 0.0f, 400.0f, "CollisionTimeRes(ns)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronTOFNSigmaVsColTimeRes_v2_EvSel", "hDauDeuteronTOFNSigmaVsColTimeRes_v2 EvSel", {HistType::kTH2F, {{100, 0.0f, 400.0f, "CollisionTimeRes(ns)"}, {600, -300.0f, 300.0f, "TOF n#sigma"}}}}, - {"hDauDeuteronTOFPIDCounter", "hDauDeuteronTOFPIDCounter", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, - {"hDauDeuteronTOFPIDCounter_CloseBC", "hDauDeuteronTOFPIDCounter CloseBC", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, - }, - }; - - void init(InitContext&) - { - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(1, "Readin"); - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(2, "Has_mcparticle"); - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(3, "Rapidity Cut"); - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(4, "McisHypertriton"); - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(5, "McisProton"); - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(6, "McisPion"); - registry.get(HIST("hParticleCounter"))->GetXaxis()->SetBinLabel(7, "McisDeuteron"); - - TString trackCounterbinLabel[2] = {"hasMom", "FromHypertriton"}; - for (int i{0}; i < 2; i++) { - registry.get(HIST("hProtonCounter"))->GetXaxis()->SetBinLabel(i + 1, trackCounterbinLabel[i]); - registry.get(HIST("hPionCounter"))->GetXaxis()->SetBinLabel(i + 1, trackCounterbinLabel[i]); - registry.get(HIST("hDeuteronCounter"))->GetXaxis()->SetBinLabel(i + 1, trackCounterbinLabel[i]); - } - registry.get(HIST("hDuplicatedH3LDaughers"))->GetXaxis()->SetBinLabel(1, "proton"); - registry.get(HIST("hDuplicatedH3LDaughers"))->GetXaxis()->SetBinLabel(2, "pion"); - registry.get(HIST("hDuplicatedH3LDaughers"))->GetXaxis()->SetBinLabel(3, "deuteron"); - - registry.get(HIST("hDauDeuteronMatchCounter"))->GetXaxis()->SetBinLabel(1, "Total"); - registry.get(HIST("hDauDeuteronMatchCounter"))->GetXaxis()->SetBinLabel(2, "correct collision"); - registry.get(HIST("hDauDeuteronMatchCounter"))->GetXaxis()->SetBinLabel(3, "hasTOF"); - registry.get(HIST("hDauDeuteronMatchCounter"))->GetXaxis()->SetBinLabel(4, "hasTOF & correct collsion"); - - registry.get(HIST("hDauDeuteronTOFPIDCounter"))->GetXaxis()->SetBinLabel(1, "Origin |n#sigma| >= 5"); - registry.get(HIST("hDauDeuteronTOFPIDCounter"))->GetXaxis()->SetBinLabel(2, "BothBC work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter"))->GetXaxis()->SetBinLabel(3, "Only BCAO2D work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter"))->GetXaxis()->SetBinLabel(4, "Only BCEvSel work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter"))->GetXaxis()->SetBinLabel(5, "BothBC not work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter_CloseBC"))->GetXaxis()->SetBinLabel(1, "Origin |n#sigma| < 6"); - registry.get(HIST("hDauDeuteronTOFPIDCounter_CloseBC"))->GetXaxis()->SetBinLabel(2, "BothBC work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter_CloseBC"))->GetXaxis()->SetBinLabel(3, "Only BCAO2D work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter_CloseBC"))->GetXaxis()->SetBinLabel(4, "Only BCEvSel work"); - registry.get(HIST("hDauDeuteronTOFPIDCounter_CloseBC"))->GetXaxis()->SetBinLabel(5, "BothBC not work"); - } - - Configurable dcapiontopv{"dcapiontopv", .05, "DCA Pion To PV"}; - Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; - Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; - Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; - Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; - Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; - Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; - Configurable mc_event_selection{"mc_event_selection", true, "mc event selection count post kIsTriggerTVX and kNoTimeFrameBorder"}; - Configurable event_posZ_selection{"event_posZ_selection", true, "event selection count post poZ cut"}; - - // CCDB TOF PID paras - Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; - Configurable paramFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; - Configurable parametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; - Configurable passName{"passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; - Configurable timeShiftCCDBPath{"timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; - Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; - Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; - - o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - mRunNumber = bc.runNumber(); - - // Initial TOF PID Paras, copied from PIDTOF.h - timestamp.value = bc.timestamp(); - ccdb->setTimestamp(timestamp.value); - // Not later than now objects - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - // TODO: implement the automatic pass name detection from metadata - if (passName.value == "") { - passName.value = "unanchored"; // temporary default - LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << passName.value << "'"; - } - LOG(info) << "Using parameter collection, starting from pass '" << passName.value << "'"; - - const std::string fname = paramFileName.value; - if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << parametrizationPath.value; - if (1) { - o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, parametrizationPath.value); - LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV2, passName.value)) { - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } - } else { - mRespParamsV2.setShiftParameters(paramCollection.getPars(passName.value)); - mRespParamsV2.printShiftParameters(); - } - } else { - mRespParamsV2.loadParamFromFile(fname.data(), parametrizationPath.value); - } - } else if (loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << parametrizationPath.value << " for timestamp " << timestamp.value; - o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(parametrizationPath.value, timestamp.value); - paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV2, passName.value)) { // Attempt at loading the parameters with the pass defined - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } - } else { // Pass is available, load non standard parameters - mRespParamsV2.setShiftParameters(paramCollection->getPars(passName.value)); - mRespParamsV2.printShiftParameters(); - } - } - mRespParamsV2.print(); - if (timeShiftCCDBPath.value != "") { - if (timeShiftCCDBPath.value.find(".root") != std::string::npos) { - mRespParamsV2.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Pos", true); - mRespParamsV2.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Neg", false); - } else { - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/pos", timeShiftCCDBPath.value.c_str()), timestamp.value), true); - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/neg", timeShiftCCDBPath.value.c_str()), timestamp.value), false); - } - } - - bachelorTOFPID.SetParams(mRespParamsV2); - } - - struct Indexdaughters { // check duplicated paired daughters - int64_t index0; - int64_t index1; - int64_t index2; - bool operator==(const Indexdaughters& t) const - { - return (this->index0 == t.index0 && this->index1 == t.index1 && this->index2 == t.index2); - } - }; - - void process(ColwithEvTimes const& collisions, MCLabeledTracksIU const& tracks, aod::McParticles const& /*particlesMC*/, aod::McCollisions const& /*mcCollisions*/, aod::BCsWithTimestamps const&) - { - for (const auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - registry.fill(HIST("hEventCounter"), 0.5); - if (mc_event_selection && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - registry.fill(HIST("hEventCounter"), 1.5); - if (event_posZ_selection && std::abs(collision.posZ()) > 10.f) { // 10cm - continue; - } - registry.fill(HIST("hEventCounter"), 2.5); - - std::vector protons, pions, deuterons; // index for daughter tracks - std::unordered_set set_proton, set_pion, set_deuteron; // check duplicated daughters - int itrack = -1; - - auto coltracks = tracks.sliceBy(perCollisionTracks, collision.globalIndex()); - - for (const auto& track : coltracks) { - - ++itrack; - registry.fill(HIST("hParticleCounter"), 0.5); - registry.fill(HIST("hTrackITSNcls"), track.itsNCls()); - registry.fill(HIST("hTPCNCls"), track.tpcNClsFound()); - registry.fill(HIST("hTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("hTrackNsigmaDeuteron"), track.tpcNSigmaDe()); - registry.fill(HIST("hTrackNsigmaProton"), track.tpcNSigmaPr()); - registry.fill(HIST("hTrackNsigmaPion"), track.tpcNSigmaPi()); - - if (!track.has_mcParticle()) { - continue; - } - auto mcparticle = track.mcParticle_as(); - registry.fill(HIST("hTPCBB"), track.p() * track.sign(), track.tpcSignal()); - - registry.fill(HIST("hParticleCounter"), 1.5); - - // if (TMath::Abs(mcparticle.y()) > 0.9) {continue;} - registry.fill(HIST("hParticleCounter"), 2.5); - registry.fill(HIST("hTrackEta"), track.eta()); - registry.fill(HIST("hTrackMcRapidity"), mcparticle.y()); - - // Hypertriton detected directly - if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hParticleCounter"), 3.5); - registry.fill(HIST("hHypertritonMcPt"), mcparticle.pt()); - registry.fill(HIST("hHypertritonEta"), track.eta()); - registry.fill(HIST("hHypertritonMcRapidity"), mcparticle.y()); - } - - // Proton - if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { - registry.fill(HIST("hParticleCounter"), 4.5); - if (track.tpcNClsFound() > 70) { - registry.fill(HIST("hProtonTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); - } - - if (mcparticle.has_mothers()) { - registry.fill(HIST("hProtonCounter"), 0.5); - for (const auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - protons.push_back(itrack); - auto p = set_proton.insert(mcparticle.globalIndex()); - if (p.second == false) - registry.fill(HIST("hDuplicatedH3LDaughers"), 0); - registry.fill(HIST("hProtonCounter"), 1.5); - registry.fill(HIST("hDauProtonPt"), track.pt()); - registry.fill(HIST("hDauProtonMcPt"), mcparticle.pt()); - registry.fill(HIST("hDauProtonNsigmaProton"), track.tpcNSigmaPr()); - registry.fill(HIST("hDauProtonTPCVsPt"), track.pt(), track.tpcNSigmaPr()); - } - } - - registry.fill(HIST("hProtonMcPt"), mcparticle.pt()); - registry.fill(HIST("hProtonMcP"), mcparticle.p()); - registry.fill(HIST("hProtonPt"), track.pt()); - registry.fill(HIST("hProtonP"), track.p()); - - registry.fill(HIST("hProtonNsigmaProton"), track.tpcNSigmaPr()); - registry.fill(HIST("hProtonTPCNCls"), track.tpcNClsFound()); - registry.fill(HIST("hProtonEta"), track.eta()); - registry.fill(HIST("hProtonMcRapidity"), mcparticle.y()); - registry.fill(HIST("hProtonTPCBB"), track.p() * track.sign(), track.tpcSignal()); - } - - // Pion - if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { - registry.fill(HIST("hParticleCounter"), 5.5); - if (track.tpcNClsFound() > 70) { - registry.fill(HIST("hPionTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); - } - - if (mcparticle.has_mothers()) { - registry.fill(HIST("hPionCounter"), 0.5); - for (const auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - pions.push_back(itrack); - auto p = set_pion.insert(mcparticle.globalIndex()); - if (p.second == false) { - registry.fill(HIST("hDuplicatedH3LDaughers"), 1); - } - registry.fill(HIST("hPionCounter"), 1.5); - registry.fill(HIST("hDauPionPt"), track.pt()); - registry.fill(HIST("hDauPionMcPt"), mcparticle.pt()); - registry.fill(HIST("hDauPionTPCVsPt"), track.pt(), track.tpcNSigmaPi()); - registry.fill(HIST("hDauPionDcaXY"), track.dcaXY()); - } - } - - registry.fill(HIST("hPionMcPt"), mcparticle.pt()); - registry.fill(HIST("hPionMcP"), mcparticle.p()); - registry.fill(HIST("hPionPt"), track.pt()); - registry.fill(HIST("hPionP"), track.p()); - - registry.fill(HIST("hPionNsigmaPion"), track.tpcNSigmaPi()); - registry.fill(HIST("hPionTPCNCls"), track.tpcNClsFound()); - registry.fill(HIST("hPionEta"), track.eta()); - registry.fill(HIST("hPionMcRapidity"), mcparticle.y()); - registry.fill(HIST("hPionTPCBB"), track.p() * track.sign(), track.tpcSignal()); - } - - float tofNsigmaDe = -999; - static constexpr float kCSPEED = TMath::C() * 1.0e2f * 1.0e-12f; // c in cm/ps - - if (track.hasTOF() && track.has_collision()) { - auto responseDe = o2::pid::tof::ExpTimes(); - // float bachExpTime = track.length() * sqrt((o2::constants::physics::MassDeuteron * o2::constants::physics::MassDeuteron) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v - - float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; - float bachExpTime = track.length() * std::sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v - float tofsignal = track.trackTime() * 1000 + bachExpTime; // in ps - - float expSigma = responseDe.GetExpectedSigma(mRespParamsV2, track, tofsignal, track.tofEvTimeErr()); - // tofNsigmaDe = (track.tofSignal() - track.tofEvTime() - responseDe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - tofNsigmaDe = (tofsignal - track.tofEvTime() - responseDe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - // tofNsigmaDe = (tofsignal - track.evTimeForTrack() - responseDe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - - if (collision.bcId() == collision.foundBCId()) { - registry.fill(HIST("hDiffColTime"), track.tofEvTime() - collision.collisionTime()); - } - - // Assume deuterons linked to the correct collision, result of new TOF PID should be same as the default one - registry.fill(HIST("hDiffTrackTOFSignal"), track.tofSignal() - tofsignal); - registry.fill(HIST("hDiffEvTimeForTrack"), track.tofEvTime() - track.evTimeForTrack()); - registry.fill(HIST("hDiffTrackTOFNSigmaDe"), track.tofNSigmaDe() - bachelorTOFPID.GetTOFNSigma(o2::track::PID::Deuteron, track, collision, collision)); - // registry.fill(HIST("hDiffTrackTOFNSigmaDe"), track.tofExpSigmaDe() - bachelorTOFPID.GetTOFNSigma(o2::track::PID::Deuteron, track, collision, collision)); - } - - // Deuteron - if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { - registry.fill(HIST("hParticleCounter"), 6.5); - if (track.tpcNClsFound() > 70) { - registry.fill(HIST("hDeuteronTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); - } - - if (mcparticle.has_mothers()) { - registry.fill(HIST("hDeuteronCounter"), 0.5); - for (const auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - deuterons.push_back(itrack); - auto p = set_deuteron.insert(mcparticle.globalIndex()); - if (p.second == false) - registry.fill(HIST("hDuplicatedH3LDaughers"), 2); - registry.fill(HIST("hDeuteronCounter"), 1.5); - registry.fill(HIST("hDauDeuteronPt"), track.pt()); - registry.fill(HIST("hDauDeuteronMcPt"), mcparticle.pt()); - registry.fill(HIST("hDauDeuteronTPCVsPt"), track.pt(), track.tpcNSigmaDe()); - registry.fill(HIST("hDauDeuteronTOFNSigmaVsP"), track.sign() * track.p(), track.tofNSigmaDe()); - - registry.fill(HIST("hDauDeuteronNewTOFNSigmaVsP"), track.sign() * track.p(), tofNsigmaDe); - if (track.hasTOF()) { - registry.fill(HIST("hDauDeuteronTOFNSigmaVsPHasTOF"), track.sign() * track.p(), track.tofNSigmaDe()); - registry.fill(HIST("hDauDeuteronDiffTOFNsigmaDeHasTOF"), track.tofNSigmaDe() - tofNsigmaDe); - } - registry.fill(HIST("hDauDeuteronMatchCounter"), 0.5); - if (mcparticle.mcCollisionId() == collision.mcCollisionId()) { - registry.fill(HIST("hDauDeuteronMatchCounter"), 1.5); - } - if (track.hasTOF()) { - registry.fill(HIST("hDauDeuteronMatchCounter"), 2.5); - if (mcparticle.mcCollisionId() == collision.mcCollisionId()) { - registry.fill(HIST("hDauDeuteronMatchCounter"), 3.5); - } - } - } - } - - registry.fill(HIST("hDeuteronMcPt"), mcparticle.pt()); - registry.fill(HIST("hDeuteronMcP"), mcparticle.p()); - registry.fill(HIST("hDeuteronPt"), track.pt()); - registry.fill(HIST("hDeuteronP"), track.p()); - - registry.fill(HIST("hDeuteronNsigmaDeuteron"), track.tpcNSigmaDe()); - registry.fill(HIST("hDeuteronTPCNCls"), track.tpcNClsFound()); - registry.fill(HIST("hDeuteronEta"), track.eta()); - registry.fill(HIST("hDeuteronMcRapidity"), mcparticle.y()); - registry.fill(HIST("hDeuteronTPCBB"), track.p() * track.sign(), track.tpcSignal()); - } else { - if (track.hasTOF()) { - registry.fill(HIST("hWrongDeuteronTOFNSigmaVsP"), track.sign() * track.p(), track.tofNSigmaDe()); - registry.fill(HIST("hWrongDeuteronNewTOFNSigmaVsP"), track.sign() * track.p(), tofNsigmaDe); - } - } - } - - std::vector set_pair; - for (size_t iproton = 0; iproton < protons.size(); iproton++) { - auto track0 = tracks.iteratorAt(protons[iproton]); - auto mctrack0 = track0.mcParticle_as(); - for (size_t ipion = 0; ipion < pions.size(); ipion++) { - auto track1 = tracks.iteratorAt(pions[ipion]); - auto mctrack1 = track1.mcParticle_as(); - for (size_t ideuteron = 0; ideuteron < deuterons.size(); ideuteron++) { - auto track2 = tracks.iteratorAt(deuterons[ideuteron]); - auto mctrack2 = track2.mcParticle_as(); - if (isPairedH3LDaughters(mctrack0, mctrack1, mctrack2)) { - registry.fill(HIST("hPairedH3LDaughers"), 0); - // MC mass cut, to check if the daughters are from materials - double hypertritonMCMass = RecoDecay::m(std::array{std::array{mctrack0.px(), mctrack0.py(), mctrack0.pz()}, std::array{mctrack1.px(), mctrack1.py(), mctrack1.pz()}, std::array{mctrack2.px(), mctrack2.py(), mctrack2.pz()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hPairedH3LDaughersInvMass"), hypertritonMCMass); - if (hypertritonMCMass < 2.990 || hypertritonMCMass > 2.993) - continue; - registry.fill(HIST("hPairedH3LDaughers"), 1); - // duplicated daughters check - Indexdaughters temp = {mctrack0.globalIndex(), mctrack1.globalIndex(), mctrack2.globalIndex()}; - auto p = std::find(set_pair.begin(), set_pair.end(), temp); - if (p == set_pair.end()) { - set_pair.push_back(temp); - registry.fill(HIST("hPairedH3LDaughers"), 2); - } - } - } - } - } - } - - // Check for recalculated TOF PID for secondary deuterons - - std::vector SelectedEvents(collisions.size()); - int nevts = 0; - for (const auto& collision : collisions) { - SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); - } - - for (const auto& track : tracks) { - if (!track.has_mcParticle()) { - continue; - } - auto mcparticle = track.mcParticle_as(); - if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { - if (!mcparticle.has_mothers()) { - continue; - } - const auto evtReconstructed = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcparticle.mcCollision_as().globalIndex()); - if (evtReconstructed == SelectedEvents.end() || !track.has_collision()) { - continue; - } - if (!track.has_collision()) { - continue; - } - auto collision = collisions.iteratorAt(evtReconstructed - SelectedEvents.begin()); - auto originalcollision = track.collision_as(); - - for (const auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - - auto bc = collision.bc_as(); - initCCDB(bc); - float tofNsigmaDeAO2D = -999; - float tofNsigmaDeEvSel = -999; - - if (track.hasTOF()) { - /*auto responseDe = o2::pid::tof::ExpTimes(); - //float bachExpTime = track.length() * sqrt((o2::constants::physics::MassDeuteron * o2::constants::physics::MassDeuteron) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v - float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; - float bachExpTime = track.length() * std::sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v - */ - - tofNsigmaDeAO2D = bachelorTOFPID.GetTOFNSigma(o2::track::PID::Deuteron, track, originalcollision, collision); - tofNsigmaDeEvSel = bachelorTOFPID.GetTOFNSigma(o2::track::PID::Deuteron, track, originalcollision, collision, false); - - if (collision.globalIndex() == originalcollision.globalIndex()) { - registry.fill(HIST("hDauDeuteronTOFNSigmaVsP_CorrectCol"), track.sign() * track.p(), track.tofNSigmaDe()); - registry.fill(HIST("hDauDeuteronNewTOFNSigmaVsP_CorrectCol"), track.sign() * track.p(), tofNsigmaDeAO2D); - continue; - } - - /*if (originalcollision.collisionTimeRes() > 40){ - continue; - }*/ - registry.fill(HIST("hDauDeuteronTOFNSigmaVsP_v2"), track.sign() * track.p(), track.tofNSigmaDe()); - registry.fill(HIST("hDauDeuteronNewTOFNSigmaVsP_v2_AO2D"), track.sign() * track.p(), tofNsigmaDeAO2D); - registry.fill(HIST("hDauDeuteronNewTOFNSigmaVsP_v2_EvSel"), track.sign() * track.p(), tofNsigmaDeEvSel); - registry.fill(HIST("hDauDeuteronTOFNSigmaVsColTimeRes_v2"), collision.collisionTimeRes(), track.tofNSigmaDe()); - registry.fill(HIST("hDauDeuteronTOFNSigmaVsColTimeRes_v2_AO2D"), originalcollision.collisionTimeRes(), tofNsigmaDeAO2D); - registry.fill(HIST("hDauDeuteronTOFNSigmaVsColTimeRes_v2_EvSel"), originalcollision.collisionTimeRes(), tofNsigmaDeEvSel); - - if (std::abs(track.tofNSigmaDe()) >= 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter"), 0.5); - if (std::abs(tofNsigmaDeAO2D) < 5 && std::abs(tofNsigmaDeEvSel) < 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter"), 1.5); - } else if (std::abs(tofNsigmaDeAO2D) < 5 && std::abs(tofNsigmaDeEvSel) >= 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter"), 2.5); - } else if (std::abs(tofNsigmaDeAO2D) >= 5 && std::abs(tofNsigmaDeEvSel) < 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter"), 3.5); - } else if (std::abs(tofNsigmaDeAO2D) >= 5 && std::abs(tofNsigmaDeEvSel) >= 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter"), 4.5); - } - } else if (std::abs(track.tofNSigmaDe()) < 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter_CloseBC"), 0.5); - if (std::abs(tofNsigmaDeAO2D) < 5 && std::abs(tofNsigmaDeEvSel) < 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter_CloseBC"), 1.5); - } else if (std::abs(tofNsigmaDeAO2D) < 5 && std::abs(tofNsigmaDeEvSel) >= 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter_CloseBC"), 2.5); - } else if (std::abs(tofNsigmaDeAO2D) >= 5 && std::abs(tofNsigmaDeEvSel) < 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter_CloseBC"), 3.5); - } else if (std::abs(tofNsigmaDeAO2D) >= 5 && std::abs(tofNsigmaDeEvSel) >= 5) { - registry.fill(HIST("hDauDeuteronTOFPIDCounter_CloseBC"), 4.5); - } - } - } - } - } - } - } -}; - -// check the performance of mcparticle -struct Hypertriton3bodyMcParticleCheck { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hMcCollCounter", "hMcCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - - {"h3dMCDecayedHypertriton", "h3dMCDecayedHypertriton", {HistType::kTH3F, {{20, -1.0f, 1.0f, "Rapidity"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {50, 0.0f, 50.0f, "ct(cm)"}}}}, - - {"hMcHypertritonCounter", "hMcHypertritonCounter", {HistType::kTH1F, {{9, 0.0f, 9.0f}}}}, - {"hMcHypertritonPt", "hMcHypertritonPt", {HistType::kTH1F, {{300, 0.0f, 15.0f}}}}, - {"hMcProtonPt", "hMcProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hMcPionPt", "hMcPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hMcDeuteronPt", "hMcDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - - {"hMcRecoInvMass", "hMcRecoInvMass", {HistType::kTH1F, {{100, 2.95, 3.05f}}}}, - - {"hDiffDaughterR", "hDiffDaughterR", {HistType::kTH1F, {{10000, -100, 100}}}}, // difference between minR of pion&proton and R of deuteron(bachelor) - {"hTrackX", "hTrackX", {HistType::kTH1F, {{10000, -100, 100}}}}, - {"hTrackY", "hTrackY", {HistType::kTH1F, {{10000, -100, 100}}}}, - {"hTrackZ", "hTrackZ", {HistType::kTH1F, {{10000, -100, 100}}}}, - }, - }; - - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; - - void init(InitContext&) - { - registry.get(HIST("hMcCollCounter"))->GetXaxis()->SetBinLabel(1, "Total Counter"); - registry.get(HIST("hMcCollCounter"))->GetXaxis()->SetBinLabel(2, "Reconstructed"); - - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(1, "Hypertriton All"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(2, "Matter All"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(3, "AntiMatter All"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(4, "confirm to 3-body decay"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(5, "Matter"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(6, "AntiMatter"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(7, "Rapidity"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(8, "Lifetime"); - registry.get(HIST("hMcHypertritonCounter"))->GetXaxis()->SetBinLabel(9, "PtCut"); - } - - Configurable mc_event_selection{"mc_event_selection", true, "mc event selection count post kIsTriggerTVX and kNoTimeFrameBorder"}; - Configurable event_posZ_selection{"event_posZ_selection", true, "event selection count post poZ cut"}; - - Preslice permcCollision = o2::aod::mcparticle::mcCollisionId; - - std::vector mcPartIndices; - template - void SetTrackIDForMC(aod::McParticles const& particlesMC, TTrackTable const& tracks) - { - mcPartIndices.clear(); - mcPartIndices.resize(particlesMC.size()); - std::fill(mcPartIndices.begin(), mcPartIndices.end(), -1); - for (const auto& track : tracks) { - if (track.has_mcParticle()) { - auto mcparticle = track.template mcParticle_as(); - if (mcPartIndices[mcparticle.globalIndex()] == -1) { - mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); - } else { - auto candTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); - // Use the track which has innest information (also best quality? - if (track.x() < candTrack.x()) { - mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); - } - } - - // Checks for TrackR - registry.fill(HIST("hTrackX"), track.x()); - registry.fill(HIST("hTrackY"), track.y()); - registry.fill(HIST("hTrackZ"), track.z()); - } - } - } - - void process(aod::McCollisions const& mcCollisions, aod::McParticles const& particlesMC, const o2::soa::Join& collisions, MCLabeledTracksIU const& tracks) - { - SetTrackIDForMC(particlesMC, tracks); - std::vector SelectedEvents(collisions.size()); - int nevts = 0; - for (const auto& collision : collisions) { - if (mc_event_selection && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - if (event_posZ_selection && std::abs(collision.posZ()) > 10.f) { // 10cm - continue; - } - SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); - } - SelectedEvents.resize(nevts); - - for (const auto& mcCollision : mcCollisions) { - registry.fill(HIST("hMcCollCounter"), 0.5); - const auto evtReconstructedAndSelected = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcCollision.globalIndex()) != SelectedEvents.end(); - if (!evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection - continue; - } - registry.fill(HIST("hMcCollCounter"), 1.5); - - const auto& dparticlesMC = particlesMC.sliceBy(permcCollision, mcCollision.globalIndex()); - - for (const auto& mcparticle : dparticlesMC) { - - if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { - registry.fill(HIST("hMcProtonPt"), mcparticle.pt()); - } - if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { - registry.fill(HIST("hMcPionPt"), mcparticle.pt()); - } - if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { - registry.fill(HIST("hMcDeuteronPt"), mcparticle.pt()); - } - if (mcparticle.pdgCode() == 1010010030) { - registry.fill(HIST("hMcHypertritonCounter"), 1.5); - } else if (mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcHypertritonCounter"), 2.5); - } - if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcHypertritonCounter"), 0.5); - registry.fill(HIST("hMcHypertritonPt"), mcparticle.pt()); - - double dauDeuteronPos[3] = {-999, -999, -999}; - double dauProtonMom[3] = {-999, -999, -999}; - double dauPionMom[3] = {-999, -999, -999}; - double dauDeuteronMom[3] = {-999, -999, -999}; - double MClifetime = 999; - double dauProtonTrackR = 9999, dauPionTrackR = 99999, dauDeuteronTrackR = 999999; - bool flag_H3L = is3bodyDecayedH3L(mcparticle); - if (!flag_H3L) { - continue; - } - for (const auto& mcparticleDaughter : mcparticle.daughters_as()) { - if (std::abs(mcparticleDaughter.pdgCode()) == 2212) { - dauProtonMom[0] = mcparticleDaughter.px(); - dauProtonMom[1] = mcparticleDaughter.py(); - dauProtonMom[2] = mcparticleDaughter.pz(); - if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { - auto trackProton = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); - dauProtonTrackR = trackProton.x(); - } - } - if (std::abs(mcparticleDaughter.pdgCode()) == 211) { - dauPionMom[0] = mcparticleDaughter.px(); - dauPionMom[1] = mcparticleDaughter.py(); - dauPionMom[2] = mcparticleDaughter.pz(); - if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { - auto trackPion = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); - dauPionTrackR = trackPion.x(); - } - } - if (std::abs(mcparticleDaughter.pdgCode()) == 1000010020) { - dauDeuteronPos[0] = mcparticleDaughter.vx(); - dauDeuteronPos[1] = mcparticleDaughter.vy(); - dauDeuteronPos[2] = mcparticleDaughter.vz(); - dauDeuteronMom[0] = mcparticleDaughter.px(); - dauDeuteronMom[1] = mcparticleDaughter.py(); - dauDeuteronMom[2] = mcparticleDaughter.pz(); - if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { - auto trackDeuteron = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); - dauDeuteronTrackR = trackDeuteron.x(); - } - } - } - if (mcparticle.pdgCode() == 1010010030) { - registry.fill(HIST("hMcHypertritonCounter"), 3.5); - registry.fill(HIST("hMcHypertritonCounter"), 4.5); - } - if (mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcHypertritonCounter"), 3.5); - registry.fill(HIST("hMcHypertritonCounter"), 5.5); - } - double hypertritonMCMass = RecoDecay::m(std::array{std::array{dauProtonMom[0], dauProtonMom[1], dauProtonMom[2]}, std::array{dauPionMom[0], dauPionMom[1], dauPionMom[2]}, std::array{dauDeuteronMom[0], dauDeuteronMom[1], dauDeuteronMom[2]}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); - registry.fill(HIST("hMcRecoInvMass"), hypertritonMCMass); - - if (hypertritonMCMass > 2.990 && hypertritonMCMass < 2.993) { - MClifetime = RecoDecay::sqrtSumOfSquares(dauDeuteronPos[0] - mcparticle.vx(), dauDeuteronPos[1] - mcparticle.vy(), dauDeuteronPos[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - registry.fill(HIST("h3dMCDecayedHypertriton"), mcparticle.y(), mcparticle.pt(), MClifetime); - - double diffTrackR = dauDeuteronTrackR - std::min(dauPionTrackR, dauProtonTrackR); - registry.fill(HIST("hDiffDaughterR"), diffTrackR); - - // int daughterPionCount = 0; - // for (auto& mcparticleDaughter : mcparticle.daughters_as()) { - // if (std::abs(mcparticleDaughter.pdgCode()) == 211) { - // daughterPionCount++; - // } - // } - - // Counter for hypertriton N_gen - if (std::abs(mcparticle.y()) < 1) { - registry.fill(HIST("hMcHypertritonCounter"), 6.5); - if (MClifetime < 40) { - registry.fill(HIST("hMcHypertritonCounter"), 7.5); - if (mcparticle.pt() > 1 && mcparticle.pt() < 10) { - registry.fill(HIST("hMcHypertritonCounter"), 8.5); - } - } - } - } - } - } - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx deleted file mode 100644 index b8aeb1d34c3..00000000000 --- a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx +++ /dev/null @@ -1,797 +0,0 @@ -// 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 hypertriton3bodyanalysis.cxx -/// \brief Standard analysis workflow for hypertriton 3-body decay -/// \author Yuanzhe Wang - -#include -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -// #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/Vtx3BodyTables.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "CommonConstants/PhysicsConstants.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using FullTracksExtIU = soa::Join; -// using FullTracksExtIU = soa::Join; // For TOF PID check -using MCLabeledTracksIU = soa::Join; - -struct hypertriton3bodyQa { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hVtxRadius", "hVtxRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, - {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtPionMinus", "hPtPionMinus", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, - {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, - {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, - {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hVtxPt", "hVtxPt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hDeuTOFNsigma", "Deuteron TOF Nsigma distribution", {HistType::kTH2F, {{1200, -6, 6, "#it{p} (GeV/#it{c})"}, {2000, -100, 100, "TOF n#sigma"}}}}, - {"hDeuTOFNsigmaWithTPC", "Deuteron TOF Nsigma distribution", {HistType::kTH2F, {{1200, -6, 6, "#it{p} (GeV/#it{c})"}, {1000, -100, 100, "TOF n#sigma"}}}}, - }, - }; - - void init(InitContext const&) - { - AxisSpec massAxis = {120, 2.9f, 3.2f, "Inv. Mass (GeV/c^{2})"}; - registry.add("hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {massAxis}}); - registry.add("hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {massAxis}}); - // Check for selection criteria - registry.add("hDiffRVtxProton", "hDiffRVtxProton", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of proton - registry.add("hDiffRVtxPion", "hDiffRVtxPion", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of pion - registry.add("hDiffRVtxDeuteron", "hDiffRVtxDeuteron", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of deuteron - registry.add("hDiffDaughterR", "hDiffDaughterR", HistType::kTH1F, {{10000, -100, 100}}); // difference between minR of pion&proton and R of deuteron(bachelor) - } - - void process(aod::Collision const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, FullTracksExtIU const& /*tracks*/) - { - for (const auto& vtx : vtx3bodydatas) { - auto track0 = vtx.track0_as(); - auto track1 = vtx.track1_as(); - auto track2 = vtx.track2_as(); - - registry.fill(HIST("hVtxRadius"), vtx.vtxradius()); - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hVtxPt"), vtx.pt()); - registry.fill(HIST("hMassHypertriton"), vtx.mHypertriton()); - registry.fill(HIST("hMassAntiHypertriton"), vtx.mAntiHypertriton()); - if (std::abs(track2.tpcNSigmaDe()) < 5) { - registry.fill(HIST("hDeuTOFNsigmaWithTPC"), track2.tpcInnerParam() * track2.sign(), vtx.tofNSigmaBachDe()); - } - if (track2.sign() > 0) { - registry.fill(HIST("hPtProton"), track0.pt()); - registry.fill(HIST("hPtPionMinus"), track1.pt()); - registry.fill(HIST("hPtDeuteron"), track2.pt()); - registry.fill(HIST("hDCAXYProtonToPV"), vtx.dcaXYtrack0topv()); - registry.fill(HIST("hDCAXYPionToPV"), vtx.dcaXYtrack1topv()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hDiffRVtxProton"), track0.x() - vtx.vtxradius()); - registry.fill(HIST("hDiffRVtxPion"), track1.x() - vtx.vtxradius()); - } else { - registry.fill(HIST("hPtPionPlus"), track0.pt()); - registry.fill(HIST("hPtAntiProton"), track1.pt()); - registry.fill(HIST("hPtAntiDeuteron"), track2.pt()); - registry.fill(HIST("hDCAXYProtonToPV"), vtx.dcaXYtrack1topv()); - registry.fill(HIST("hDCAXYPionToPV"), vtx.dcaXYtrack0topv()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hDiffRVtxProton"), track1.x() - vtx.vtxradius()); - registry.fill(HIST("hDiffRVtxPion"), track0.x() - vtx.vtxradius()); - } - registry.fill(HIST("hDCAXYDeuteronToPV"), vtx.dcaXYtrack2topv()); - registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); - registry.fill(HIST("hTOFPIDDeuteron"), vtx.tofNSigmaBachDe()); - registry.fill(HIST("hDeuTOFNsigma"), track2.tpcInnerParam() * track2.sign(), vtx.tofNSigmaBachDe()); - registry.fill(HIST("hDiffRVtxDeuteron"), track2.x() - vtx.vtxradius()); - float diffTrackR = track2.x() - std::min(track0.x(), track1.x()); - registry.fill(HIST("hDiffDaughterR"), diffTrackR); - } - } -}; - -struct hypertriton3bodyAnalysis { - - Preslice perCollisionVtx3BodyDatas = o2::aod::vtx3body::collisionId; - - // Selection criteria - Configurable vtxcospa{"vtxcospa", 0.99, "Vtx CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcavtxdau{"dcavtxdau", 1.0, "DCA Vtx Daughters"}; // loose cut - Configurable dcapiontopv{"dcapiontopv", .05, "DCA Pion To PV"}; - Configurable etacut{"etacut", 0.9, "etacut"}; - Configurable rapiditycut{"rapiditycut", 1, "rapiditycut"}; - Configurable tofPIDNSigmaMin{"tofPIDNSigmaMin", -5, "tofPIDNSigmaMin"}; - Configurable tofPIDNSigmaMax{"tofPIDNSigmaMax", 5, "tofPIDNSigmaMax"}; - Configurable tpcPIDNSigmaCut{"tpcPIDNSigmaCut", 5, "tpcPIDNSigmaCut"}; - Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; - Configurable mc_event_selection{"mc_event_selection", true, "mc event selection count post kIsTriggerTVX and kNoTimeFrameBorder"}; - Configurable event_posZ_selection{"event_posZ_selection", true, "event selection count post poZ cut"}; - Configurable lifetimecut{"lifetimecut", 40., "lifetimecut"}; // ct - Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; - Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; - Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; - Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; - Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; - Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; - Configurable minDeuteronPUseTOF{"minDeuteronPUseTOF", 1, "minDeuteronPt Enable TOF PID"}; - Configurable h3LMassLowerlimit{"h3LMassLowerlimit", 2.96, "Hypertriton mass lower limit"}; - Configurable h3LMassUpperlimit{"h3LMassUpperlimit", 3.04, "Hypertriton mass upper limit"}; - Configurable mintpcNClsproton{"mintpcNClsproton", 90, "min tpc Nclusters for proton"}; - Configurable mintpcNClspion{"mintpcNClspion", 70, "min tpc Nclusters for pion"}; - Configurable mintpcNClsdeuteron{"mintpcNClsdeuteron", 100, "min tpc Nclusters for deuteron"}; - - Configurable mcsigma{"mcsigma", 0.0015, "sigma of mc invariant mass fit"}; // obtained from MC - Configurable bachelorPdgCode{"bachelorPdgCode", 1000010020, "pdgCode of bachelor daughter"}; - Configurable motherPdgCode{"motherPdgCode", 1010010030, "pdgCode of mother track"}; - - // 3sigma region for Dalitz plot - float lowersignallimit = o2::constants::physics::MassHyperTriton - 3 * mcsigma; - float uppersignallimit = o2::constants::physics::MassHyperTriton + 3 * mcsigma; - - HistogramRegistry registry{ - "registry", - { - {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, - {"hCandidatesCounter", "hCandidatesCounter", {HistType::kTH1F, {{12, 0.0f, 12.0f}}}}, - {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"hMassHypertritonTotal", "hMassHypertritonTotal", {HistType::kTH1F, {{300, 2.9f, 3.2f, "Inv. Mass (GeV/c^{2})"}}}}, - {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, - {"hPtPionMinus", "hPtPionMinus", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, - {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, - {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, - {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, - {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}}, - {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, - {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hTPCPIDProton", "hTPCPIDProton", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hTPCPIDPion", "hTPCPIDPion", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hTPCPIDDeuteron", "hTPCPIDDeuteron", {HistType::kTH1F, {{120, -6.0f, 6.0f}}}}, - {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hProtonTPCVsPt", "hProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {120, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hPionTPCVsPt", "hPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {120, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDeuteronTPCVsPt", "hDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {120, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDeuteronTOFVsPBeforeTOFCut", "hDeuteronTOFVsPBeforeTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"hDeuteronTOFVsPAfterTOFCut", "hDeuteronTOFVsPAfterTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - - {"hDalitz", "hDalitz", {HistType::kTH2F, {{120, 7.85, 8.45, "M^{2}(dp) (GeV^{2}/c^{4})"}, {60, 1.1, 1.4, "M^{2}(p#pi) (GeV^{2}/c^{4})"}}}}, - {"h3dMassHypertriton", "h3dMassHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dMassAntiHypertriton", "h3dMassAntiHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dTotalHypertriton", "h3dTotalHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - - {"hDeuteronTOFVsPBeforeTOFCutSig", "hDeuteronTOFVsPBeforeTOFCutSig", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"hDeuteronTOFVsPAfterTOFCutSig", "hDeuteronTOFVsPAfterTOFCutSig", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"h3dTotalTrueHypertriton", "h3dTotalTrueHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - // For TOF PID check - /*{"hDeuteronDefaultTOFVsPBeforeTOFCut", "hDeuteronDefaultTOFVsPBeforeTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"hDeuteronDefaultTOFVsPAtferTOFCut", "hDeuteronDefaultTOFVsPAtferTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"hDeuteronDefaultTOFVsPBeforeTOFCutSig", "hDeuteronDefaultTOFVsPBeforeTOFCutSig", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, - {"hDeuteronDefaultTOFVsPAfterTOFCutSig", "hDeuteronDefaultTOFVsPAfterTOFCutSig", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}},*/ - }, - }; - - //------------------------------------------------------------------ - // Fill stats histograms - enum vtxstep { kCandAll = 0, - kCandDauEta, - kCandDauPt, - kCandTPCNcls, - kCandTPCPID, - kCandTOFPID, - kCandDcaToPV, - kCandRapidity, - kCandct, - kCandCosPA, - kCandDcaDau, - kCandInvMass, - kNCandSteps }; - - struct { - std::array candstats; - std::array truecandstats; - } statisticsRegistry; - - void resetHistos() - { - for (int ii = 0; ii < kNCandSteps; ii++) { - statisticsRegistry.candstats[ii] = 0; - statisticsRegistry.truecandstats[ii] = 0; - } - } - void FillCandCounter(int kn, bool istrue = false) - { - statisticsRegistry.candstats[kn]++; - if (istrue) { - statisticsRegistry.truecandstats[kn]++; - } - } - void fillHistos() - { - for (int ii = 0; ii < kNCandSteps; ii++) { - registry.fill(HIST("hCandidatesCounter"), ii, statisticsRegistry.candstats[ii]); - if (doprocessMC == true) { - registry.fill(HIST("hTrueHypertritonCounter"), ii, statisticsRegistry.truecandstats[ii]); - } - } - } - - ConfigurableAxis dcaBinning{"dca-binning", {200, 0.0f, 1.0f}, ""}; - ConfigurableAxis ptBinning{"pt-binning", {200, 0.0f, 10.0f}, ""}; - - void init(InitContext const&) - { - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(1, "total"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(2, "sel8"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(3, "vertexZ"); - registry.get(HIST("hEventCounter"))->GetXaxis()->SetBinLabel(4, "has Candidate"); - - if (doprocessMC == true) { - registry.add("hTrueHypertritonCounter", "hTrueHypertritonCounter", HistType::kTH1F, {{12, 0.0f, 12.0f}}); - auto hGeneratedHypertritonCounter = registry.add("hGeneratedHypertritonCounter", "hGeneratedHypertritonCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); - hGeneratedHypertritonCounter->GetXaxis()->SetBinLabel(1, "Total"); - hGeneratedHypertritonCounter->GetXaxis()->SetBinLabel(2, "3-body decay"); - registry.add("hPtGeneratedHypertriton", "hPtGeneratedHypertriton", HistType::kTH1F, {{200, 0.0f, 10.0f}}); - registry.add("hctGeneratedHypertriton", "hctGeneratedHypertriton", HistType::kTH1F, {{50, 0, 50, "ct(cm)"}}); - registry.add("hEtaGeneratedHypertriton", "hEtaGeneratedHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - registry.add("hRapidityGeneratedHypertriton", "hRapidityGeneratedHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - registry.add("hPtGeneratedAntiHypertriton", "hPtGeneratedAntiHypertriton", HistType::kTH1F, {{200, 0.0f, 10.0f}}); - registry.add("hctGeneratedAntiHypertriton", "hctGeneratedAntiHypertriton", HistType::kTH1F, {{50, 0, 50, "ct(cm)"}}); - registry.add("hEtaGeneratedAntiHypertriton", "hEtaGeneratedAntiHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - registry.add("hRapidityGeneratedAntiHypertriton", "hRapidityGeneratedAntiHypertriton", HistType::kTH1F, {{40, -2.0f, 2.0f}}); - } - - TString CandCounterbinLabel[kNCandSteps] = {"Total", "TrackEta", "DauPt", "TPCNcls", "TPCPID", "d TOFPID", "PionDcatoPV", "MomRapidity", "Lifetime", "VtxCosPA", "VtxDcaDau", "InvMass"}; - for (int i{0}; i < kNCandSteps; i++) { - registry.get(HIST("hCandidatesCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); - if (doprocessMC == true) { - registry.get(HIST("hTrueHypertritonCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); - } - } - } - - //------------------------------------------------------------------ - // Selections for candidates - template - bool SelectCand(TCollisionTable const& collision, TCandTable const& candData, TTrackTable const& trackProton, TTrackTable const& trackPion, TTrackTable const& trackDeuteron, bool isMatter, bool isTrueCand = false, double MClifetime = -1, double lPt = -1) - { - FillCandCounter(kCandAll, isTrueCand); - - // Selection on daughters - if (std::abs(trackProton.eta()) > etacut || std::abs(trackPion.eta()) > etacut || std::abs(trackDeuteron.eta()) > etacut) { - return false; - } - FillCandCounter(kCandDauEta, isTrueCand); - - if (trackProton.pt() < minProtonPt || trackProton.pt() > maxProtonPt || trackPion.pt() < minPionPt || trackPion.pt() > maxPionPt || trackDeuteron.pt() < minDeuteronPt || trackDeuteron.pt() > maxDeuteronPt) { - return false; - } - FillCandCounter(kCandDauPt, isTrueCand); - - if (trackProton.tpcNClsFound() < mintpcNClsproton || trackPion.tpcNClsFound() < mintpcNClspion || trackDeuteron.tpcNClsFound() < mintpcNClsdeuteron) { - return false; - } - FillCandCounter(kCandTPCNcls, isTrueCand); - - if (std::abs(trackProton.tpcNSigmaPr()) > tpcPIDNSigmaCut || std::abs(trackPion.tpcNSigmaPi()) > tpcPIDNSigmaCut || std::abs(trackDeuteron.tpcNSigmaDe()) > tpcPIDNSigmaCut) { - return false; - } - FillCandCounter(kCandTPCPID, isTrueCand); - - // registry.fill(HIST("hDeuteronDefaultTOFVsPBeforeTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); - registry.fill(HIST("hDeuteronTOFVsPBeforeTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), candData.tofNSigmaBachDe()); - if (isTrueCand) { - // registry.fill(HIST("hDeuteronDefaultTOFVsPBeforeTOFCutSig"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); - registry.fill(HIST("hDeuteronTOFVsPBeforeTOFCutSig"), trackDeuteron.sign() * trackDeuteron.p(), candData.tofNSigmaBachDe()); - } - if ((candData.tofNSigmaBachDe() < tofPIDNSigmaMin || candData.tofNSigmaBachDe() > tofPIDNSigmaMax) && trackDeuteron.p() > minDeuteronPUseTOF) { - return false; - } - FillCandCounter(kCandTOFPID, isTrueCand); - // registry.fill(HIST("hDeuteronDefaultTOFVsPAtferTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); - registry.fill(HIST("hDeuteronTOFVsPAfterTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), candData.tofNSigmaBachDe()); - if (isTrueCand) { - // registry.fill(HIST("hDeuteronDefaultTOFVsPAfterTOFCutSig"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); - registry.fill(HIST("hDeuteronTOFVsPAfterTOFCutSig"), trackDeuteron.sign() * trackDeuteron.p(), candData.tofNSigmaBachDe()); - } - - double dcapion = isMatter ? candData.dcatrack1topv() : candData.dcatrack0topv(); - if (std::abs(dcapion) < dcapiontopv) { - return false; - } - FillCandCounter(kCandDcaToPV, isTrueCand); - - // Selection on candidate hypertriton - if (std::abs(candData.yHypertriton()) > rapiditycut) { - return false; - } - FillCandCounter(kCandRapidity, isTrueCand); - - double ct = candData.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassHyperTriton; - if (ct > lifetimecut) { - return false; - } - FillCandCounter(kCandct, isTrueCand); - - double cospa = candData.vtxcosPA(collision.posX(), collision.posY(), collision.posZ()); - if (cospa < vtxcospa) { - return false; - } - FillCandCounter(kCandCosPA, isTrueCand); - - if (candData.dcaVtxdaughters() > dcavtxdau) { - return false; - } - FillCandCounter(kCandDcaDau, isTrueCand); - - if ((isMatter && candData.mHypertriton() > h3LMassLowerlimit && candData.mHypertriton() < h3LMassUpperlimit)) { - // Hypertriton - registry.fill(HIST("hPtProton"), trackProton.pt()); - registry.fill(HIST("hPtPionMinus"), trackPion.pt()); - registry.fill(HIST("hPtDeuteron"), trackDeuteron.pt()); - registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack0topv()); - registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack1topv()); - registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack0topv()); - registry.fill(HIST("hDCAPionToPV"), candData.dcatrack1topv()); - - registry.fill(HIST("hMassHypertriton"), candData.mHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), candData.mHypertriton()); - registry.fill(HIST("h3dMassHypertriton"), 0., candData.pt(), candData.mHypertriton()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("h3dTotalHypertriton"), ct, candData.pt(), candData.mHypertriton()); - if (candData.mHypertriton() > lowersignallimit && candData.mHypertriton() < uppersignallimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(std::array{std::array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}, std::array{candData.pxtrack2(), candData.pytrack2(), candData.pztrack2()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), RecoDecay::m2(std::array{std::array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}, std::array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - if (isTrueCand) { - registry.fill(HIST("h3dTotalTrueHypertriton"), MClifetime, lPt, candData.mHypertriton()); - } - } else if ((!isMatter && candData.mAntiHypertriton() > h3LMassLowerlimit && candData.mAntiHypertriton() < h3LMassUpperlimit)) { - // AntiHypertriton - registry.fill(HIST("hPtAntiProton"), trackProton.pt()); - registry.fill(HIST("hPtPionPlus"), trackPion.pt()); - registry.fill(HIST("hPtAntiDeuteron"), trackDeuteron.pt()); - registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack1topv()); - registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack0topv()); - registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack1topv()); - registry.fill(HIST("hDCAPionToPV"), candData.dcatrack0topv()); - - registry.fill(HIST("hMassAntiHypertriton"), candData.mAntiHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), candData.mAntiHypertriton()); - registry.fill(HIST("h3dMassAntiHypertriton"), 0., candData.pt(), candData.mAntiHypertriton()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("h3dTotalHypertriton"), ct, candData.pt(), candData.mAntiHypertriton()); - if (candData.mAntiHypertriton() > lowersignallimit && candData.mAntiHypertriton() < uppersignallimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(std::array{std::array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}, std::array{candData.pxtrack2(), candData.pytrack2(), candData.pztrack2()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), RecoDecay::m2(std::array{std::array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}, std::array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - if (isTrueCand) { - registry.fill(HIST("h3dTotalTrueHypertriton"), MClifetime, lPt, candData.mHypertriton()); - } - } else { - return false; - } - - FillCandCounter(kCandInvMass, isTrueCand); - - registry.fill(HIST("hDCAXYDeuteronToPV"), candData.dcaXYtrack2topv()); - registry.fill(HIST("hDCADeuteronToPV"), candData.dcatrack2topv()); - registry.fill(HIST("hVtxCosPA"), candData.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), candData.dcaVtxdaughters()); - registry.fill(HIST("hProtonTPCNcls"), trackProton.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), trackPion.tpcNClsCrossedRows()); - registry.fill(HIST("hDeuteronTPCNcls"), trackDeuteron.tpcNClsCrossedRows()); - registry.fill(HIST("hTPCPIDProton"), trackProton.tpcNSigmaPr()); - registry.fill(HIST("hTPCPIDPion"), trackPion.tpcNSigmaPi()); - registry.fill(HIST("hTPCPIDDeuteron"), trackDeuteron.tpcNSigmaDe()); - registry.fill(HIST("hProtonTPCBB"), trackProton.sign() * trackProton.p(), trackProton.tpcSignal()); - registry.fill(HIST("hPionTPCBB"), trackPion.sign() * trackPion.p(), trackPion.tpcSignal()); - registry.fill(HIST("hDeuteronTPCBB"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tpcSignal()); - registry.fill(HIST("hProtonTPCVsPt"), trackProton.pt(), trackProton.tpcNSigmaPr()); - registry.fill(HIST("hPionTPCVsPt"), trackProton.pt(), trackPion.tpcNSigmaPi()); - registry.fill(HIST("hDeuteronTPCVsPt"), trackDeuteron.pt(), trackDeuteron.tpcNSigmaDe()); - registry.fill(HIST("hTOFPIDDeuteron"), candData.tofNSigmaBachDe()); - - return true; - } - - //------------------------------------------------------------------ - // Analysis process for a single candidate - template - void CandidateAnalysis(TCollisionTable const& collision, TCandTable const& candData, bool& if_hasvtx, bool isTrueCand = false, double MClifetime = -1, double lPt = -1) - { - - auto track0 = candData.template track0_as(); - auto track1 = candData.template track1_as(); - auto track2 = candData.template track2_as(); - - bool isMatter = track2.sign() > 0; - - auto& trackProton = isMatter ? track0 : track1; - auto& trackPion = isMatter ? track1 : track0; - auto& trackDeuteron = track2; - - if (SelectCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand, MClifetime, lPt)) { - if_hasvtx = true; - } - } - - //------------------------------------------------------------------ - // collect information for generated hypertriton (should be called after event selection) - void GetGeneratedH3LInfo(aod::McParticles const& particlesMC) - { - for (const auto& mcparticle : particlesMC) { - if (std::abs(mcparticle.pdgCode()) != motherPdgCode) { - continue; - } - registry.fill(HIST("hGeneratedHypertritonCounter"), 0.5); - - bool haveProton = false, havePionPlus = false, haveDeuteron = false; - bool haveAntiProton = false, havePionMinus = false, haveAntiDeuteron = false; - double MClifetime = -1; - for (const auto& mcparticleDaughter : mcparticle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == 2212) - haveProton = true; - if (mcparticleDaughter.pdgCode() == -2212) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == 211) - havePionPlus = true; - if (mcparticleDaughter.pdgCode() == -211) - havePionMinus = true; - if (mcparticleDaughter.pdgCode() == bachelorPdgCode) { - haveDeuteron = true; - MClifetime = RecoDecay::sqrtSumOfSquares(mcparticleDaughter.vx() - mcparticle.vx(), mcparticleDaughter.vy() - mcparticle.vy(), mcparticleDaughter.vz() - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - } - if (mcparticleDaughter.pdgCode() == -bachelorPdgCode) { - haveAntiDeuteron = true; - MClifetime = RecoDecay::sqrtSumOfSquares(mcparticleDaughter.vx() - mcparticle.vx(), mcparticleDaughter.vy() - mcparticle.vy(), mcparticleDaughter.vz() - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - } - } - if (haveProton && havePionMinus && haveDeuteron && mcparticle.pdgCode() == motherPdgCode) { - registry.fill(HIST("hGeneratedHypertritonCounter"), 1.5); - registry.fill(HIST("hPtGeneratedHypertriton"), mcparticle.pt()); - registry.fill(HIST("hctGeneratedHypertriton"), MClifetime); - registry.fill(HIST("hEtaGeneratedHypertriton"), mcparticle.eta()); - registry.fill(HIST("hRapidityGeneratedHypertriton"), mcparticle.y()); - } else if (haveAntiProton && havePionPlus && haveAntiDeuteron && mcparticle.pdgCode() == -motherPdgCode) { - registry.fill(HIST("hGeneratedHypertritonCounter"), 1.5); - registry.fill(HIST("hPtGeneratedAntiHypertriton"), mcparticle.pt()); - registry.fill(HIST("hctGeneratedAntiHypertriton"), MClifetime); - registry.fill(HIST("hEtaGeneratedAntiHypertriton"), mcparticle.eta()); - registry.fill(HIST("hRapidityGeneratedAntiHypertriton"), mcparticle.y()); - } - } - } - - //------------------------------------------------------------------ - // process real data analysis - void processData(soa::Join::iterator const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, FullTracksExtIU const& /*tracks*/) - { - registry.fill(HIST("hEventCounter"), 0.5); - if (event_sel8_selection && !collision.sel8()) { - return; - } - registry.fill(HIST("hEventCounter"), 1.5); - if (event_posZ_selection && std::abs(collision.posZ()) > 10.f) { // 10cm - return; - } - registry.fill(HIST("hEventCounter"), 2.5); - - bool if_hasvtx = false; - - for (const auto& vtx : vtx3bodydatas) { - CandidateAnalysis(collision, vtx, if_hasvtx); - } - - if (if_hasvtx) - registry.fill(HIST("hEventCounter"), 3.5); - fillHistos(); - resetHistos(); - } - PROCESS_SWITCH(hypertriton3bodyAnalysis, processData, "Real data analysis", true); - - //------------------------------------------------------------------ - // process mc analysis - void processMC(soa::Join const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, aod::McParticles const& particlesMC, MCLabeledTracksIU const& /*tracks*/) - { - GetGeneratedH3LInfo(particlesMC); - - for (const auto& collision : collisions) { - registry.fill(HIST("hEventCounter"), 0.5); - if (mc_event_selection && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - registry.fill(HIST("hEventCounter"), 1.5); - if (event_posZ_selection && std::abs(collision.posZ()) > 10.f) { // 10cm - continue; - } - registry.fill(HIST("hEventCounter"), 2.5); - - bool if_hasvtx = false; - auto vtxsthiscol = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); - - for (const auto& vtx : vtxsthiscol) { - // int lLabel = -1; - int lPDG = -1; - float lPt = -1; - double MClifetime = -1; - bool isTrueCand = false; - auto track0 = vtx.track0_as(); - auto track1 = vtx.track1_as(); - auto track2 = vtx.track2_as(); - if (track0.has_mcParticle() && track1.has_mcParticle() && track2.has_mcParticle()) { - auto lMCTrack0 = track0.mcParticle_as(); - auto lMCTrack1 = track1.mcParticle_as(); - auto lMCTrack2 = track2.mcParticle_as(); - if (lMCTrack0.has_mothers() && lMCTrack1.has_mothers() && lMCTrack2.has_mothers()) { - for (const auto& lMother0 : lMCTrack0.mothers_as()) { - for (const auto& lMother1 : lMCTrack1.mothers_as()) { - for (const auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - // lLabel = lMother1.globalIndex(); - lPt = lMother1.pt(); - lPDG = lMother1.pdgCode(); - if ((lPDG == motherPdgCode && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == bachelorPdgCode) || - (lPDG == -motherPdgCode && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -bachelorPdgCode)) { - isTrueCand = true; - MClifetime = RecoDecay::sqrtSumOfSquares(lMCTrack2.vx() - lMother2.vx(), lMCTrack2.vy() - lMother2.vy(), lMCTrack2.vz() - lMother2.vz()) * o2::constants::physics::MassHyperTriton / lMother2.p(); - } - } - } - } - } - } - } - - CandidateAnalysis(collision, vtx, if_hasvtx, isTrueCand, MClifetime, lPt); - } - - if (if_hasvtx) - registry.fill(HIST("hEventCounter"), 3.5); - fillHistos(); - resetHistos(); - } - } - PROCESS_SWITCH(hypertriton3bodyAnalysis, processMC, "MC analysis", false); -}; - -// check vtx3body with mclabels -struct hypertriton3bodyLabelCheck { - - Configurable mc_event_selection{"mc_event_selection", true, "mc event selection count post kIsTriggerTVX and kNoTimeFrameBorder"}; - Configurable event_posZ_selection{"event_posZ_selection", false, "event selection count post poZ cut"}; - Configurable tpcPIDNSigmaCut{"tpcPIDNSigmaCut", 5, "tpcPIDNSigmaCut"}; - Configurable motherPdgCode{"motherPdgCode", 1010010030, "pdgCode of mother track"}; - - HistogramRegistry registry{"registry", {}}; - - void init(InitContext const&) - { - if (doprocessData == false) { - auto hLabeledVtxCounter = registry.add("hLabeledVtxCounter", "hLabeledVtxCounter", HistType::kTH1F, {{3, 0.0f, 3.0f}}); - hLabeledVtxCounter->GetXaxis()->SetBinLabel(1, "Readin"); - hLabeledVtxCounter->GetXaxis()->SetBinLabel(2, "TrueMCH3L"); - hLabeledVtxCounter->GetXaxis()->SetBinLabel(3, "Nonrepetitive"); - registry.add("hMassTrueH3L", "hMassTrueH3L", HistType::kTH1F, {{80, 2.96f, 3.04f}}); - registry.add("hMassTrueH3LMatter", "hMassTrueH3LMatter", HistType::kTH1F, {{80, 2.96f, 3.04f}}); - registry.add("hMassTrueH3LAntiMatter", "hMassTrueH3LAntiMatter", HistType::kTH1F, {{80, 2.96f, 3.04f}}); - auto hPIDCounter = registry.add("hPIDCounter", "hPIDCounter", HistType::kTH1F, {{6, 0.0f, 6.0f}}); - hPIDCounter->GetXaxis()->SetBinLabel(1, "H3L Proton PID > 5"); - hPIDCounter->GetXaxis()->SetBinLabel(2, "H3L Pion PID > 5"); - hPIDCounter->GetXaxis()->SetBinLabel(3, "H3L Deuteron PID > 5"); - hPIDCounter->GetXaxis()->SetBinLabel(4, "#bar{H3L} Proton PID > 5"); - hPIDCounter->GetXaxis()->SetBinLabel(5, "#bar{H3L} Pion PID > 5"); - hPIDCounter->GetXaxis()->SetBinLabel(6, "#bar{H3L} Deuteron PID > 5"); - auto hHypertritonCounter = registry.add("hHypertritonCounter", "hHypertritonCounter", HistType::kTH1F, {{4, 0.0f, 4.0f}}); - hHypertritonCounter->GetXaxis()->SetBinLabel(1, "H3L"); - hHypertritonCounter->GetXaxis()->SetBinLabel(2, "H3L daughters pass PID"); - hHypertritonCounter->GetXaxis()->SetBinLabel(3, "#bar{H3L}"); - hHypertritonCounter->GetXaxis()->SetBinLabel(4, "#bar{H3L} daughters pass PID"); - auto hDecay3BodyCounter = registry.add("hDecay3BodyCounter", "hDecay3BodyCounter", HistType::kTH1F, {{5, 0.0f, 5.0f}}); - hDecay3BodyCounter->GetXaxis()->SetBinLabel(1, "Total"); - hDecay3BodyCounter->GetXaxis()->SetBinLabel(2, "True H3L"); - hDecay3BodyCounter->GetXaxis()->SetBinLabel(3, "Unduplicated H3L"); - hDecay3BodyCounter->GetXaxis()->SetBinLabel(4, "Correct collision"); - hDecay3BodyCounter->GetXaxis()->SetBinLabel(5, "Same ColID for daughters"); - registry.add("hDiffRVtxProton", "hDiffRVtxProton", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of proton - registry.add("hDiffRVtxPion", "hDiffRVtxPion", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of pion - registry.add("hDiffRVtxDeuteron", "hDiffRVtxDeuteron", HistType::kTH1F, {{100, -10, 10}}); // difference between the radius of decay vertex and minR of deuteron - } - } - - struct Indexdaughters { // check duplicated paired daughters - int64_t index0; - int64_t index1; - int64_t index2; - bool operator==(const Indexdaughters& t) const - { - return (this->index0 == t.index0 && this->index1 == t.index1 && this->index2 == t.index2); - } - }; - - void processData(soa::Join::iterator const&) - { - // dummy function - } - PROCESS_SWITCH(hypertriton3bodyLabelCheck, processData, "Donot check MC label tables", true); - - void processCheckLabel(soa::Join::iterator const& collision, aod::Decay3Bodys const& decay3bodys, soa::Join const& vtx3bodydatas, MCLabeledTracksIU const& /*tracks*/, aod::McParticles const& /*particlesMC*/, aod::McCollisions const& /*mcCollisions*/) - { - // check the decay3body table - std::vector set_pair; - for (const auto& d3body : decay3bodys) { - registry.fill(HIST("hDecay3BodyCounter"), 0.5); - auto lTrack0 = d3body.track0_as(); - auto lTrack1 = d3body.track1_as(); - auto lTrack2 = d3body.track2_as(); - if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { - continue; - } - auto lMCTrack0 = lTrack0.mcParticle_as(); - auto lMCTrack1 = lTrack1.mcParticle_as(); - auto lMCTrack2 = lTrack2.mcParticle_as(); - if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { - continue; - } - - for (const auto& lMother0 : lMCTrack0.mothers_as()) { - for (const auto& lMother1 : lMCTrack1.mothers_as()) { - for (const auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - registry.fill(HIST("hDecay3BodyCounter"), 1.5); - // duplicated daughters check - Indexdaughters temp = {lMCTrack0.globalIndex(), lMCTrack1.globalIndex(), lMCTrack2.globalIndex()}; - auto p = std::find(set_pair.begin(), set_pair.end(), temp); - if (p == set_pair.end()) { - set_pair.push_back(temp); - registry.fill(HIST("hDecay3BodyCounter"), 2.5); - if (lMother0.mcCollisionId() == collision.mcCollisionId()) { - registry.fill(HIST("hDecay3BodyCounter"), 3.5); - if (lTrack0.collisionId() == lTrack1.collisionId() && lTrack0.collisionId() == lTrack2.collisionId()) { - registry.fill(HIST("hDecay3BodyCounter"), 4.5); - } - } - } - } - } - } - } - } - - if (mc_event_selection && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - return; - } - - if (event_posZ_selection && std::abs(collision.posZ()) > 10.f) { // 10cm - return; - } - - std::vector set_mothertrack; - for (const auto& vtx : vtx3bodydatas) { - registry.fill(HIST("hLabeledVtxCounter"), 0.5); - if (vtx.mcParticleId() != -1) { - auto mcparticle = vtx.mcParticle_as(); - auto lTrack0 = vtx.track0_as(); - auto lTrack1 = vtx.track1_as(); - auto lTrack2 = vtx.track2_as(); - if (std::abs(mcparticle.pdgCode()) != motherPdgCode) { - continue; - } - registry.fill(HIST("hLabeledVtxCounter"), 1.5); - registry.fill(HIST("hDiffRVtxDeuteron"), lTrack2.x() - vtx.vtxradius()); - if (mcparticle.pdgCode() > 0) { - registry.fill(HIST("hHypertritonCounter"), 0.5); - registry.fill(HIST("hMassTrueH3L"), vtx.mHypertriton()); - registry.fill(HIST("hMassTrueH3LMatter"), vtx.mHypertriton()); - registry.fill(HIST("hDiffRVtxProton"), lTrack0.x() - vtx.vtxradius()); - registry.fill(HIST("hDiffRVtxPion"), lTrack1.x() - vtx.vtxradius()); - auto p = std::find(set_mothertrack.begin(), set_mothertrack.end(), mcparticle.globalIndex()); - if (p == set_mothertrack.end()) { - set_mothertrack.push_back(mcparticle.globalIndex()); - registry.fill(HIST("hLabeledVtxCounter"), 2.5); - } - if (std::abs(lTrack0.tpcNSigmaPr()) > tpcPIDNSigmaCut) { - registry.fill(HIST("hPIDCounter"), 0.5); - } - if (std::abs(lTrack1.tpcNSigmaPi()) > tpcPIDNSigmaCut) { - registry.fill(HIST("hPIDCounter"), 1.5); - } - if (std::abs(lTrack2.tpcNSigmaDe()) > tpcPIDNSigmaCut) { - registry.fill(HIST("hPIDCounter"), 2.5); - } - if (std::abs(lTrack0.tpcNSigmaPr()) < tpcPIDNSigmaCut && std::abs(lTrack1.tpcNSigmaPi()) < tpcPIDNSigmaCut && std::abs(lTrack2.tpcNSigmaDe()) < tpcPIDNSigmaCut) { - registry.fill(HIST("hHypertritonCounter"), 1.5); - } - } else { - registry.fill(HIST("hHypertritonCounter"), 2.5); - registry.fill(HIST("hMassTrueH3L"), vtx.mAntiHypertriton()); - registry.fill(HIST("hMassTrueH3LAntiMatter"), vtx.mAntiHypertriton()); - registry.fill(HIST("hDiffRVtxProton"), lTrack1.x() - vtx.vtxradius()); - registry.fill(HIST("hDiffRVtxPion"), lTrack0.x() - vtx.vtxradius()); - auto p = std::find(set_mothertrack.begin(), set_mothertrack.end(), mcparticle.globalIndex()); - if (p == set_mothertrack.end()) { - set_mothertrack.push_back(mcparticle.globalIndex()); - registry.fill(HIST("hLabeledVtxCounter"), 2.5); - } - if (std::abs(lTrack0.tpcNSigmaPi()) > tpcPIDNSigmaCut) { - registry.fill(HIST("hPIDCounter"), 4.5); - } - if (std::abs(lTrack1.tpcNSigmaPr()) > tpcPIDNSigmaCut) { - registry.fill(HIST("hPIDCounter"), 3.5); - } - if (std::abs(lTrack2.tpcNSigmaDe()) > tpcPIDNSigmaCut) { - registry.fill(HIST("hPIDCounter"), 5.5); - } - if (std::abs(lTrack0.tpcNSigmaPi()) < tpcPIDNSigmaCut && std::abs(lTrack1.tpcNSigmaPr()) < tpcPIDNSigmaCut && std::abs(lTrack2.tpcNSigmaDe()) < tpcPIDNSigmaCut) { - registry.fill(HIST("hHypertritonCounter"), 3.5); - } - } - } - } - } - PROCESS_SWITCH(hypertriton3bodyLabelCheck, processCheckLabel, "Check MC label tables", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/Utils/decay3bodyBuilderHelper.h b/PWGLF/Utils/decay3bodyBuilderHelper.h new file mode 100644 index 00000000000..550625f2fc6 --- /dev/null +++ b/PWGLF/Utils/decay3bodyBuilderHelper.h @@ -0,0 +1,838 @@ +// 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. + +#ifndef PWGLF_UTILS_DECAY3BODYBUILDERHELPER_H_ +#define PWGLF_UTILS_DECAY3BODYBUILDERHELPER_H_ + +#include +#include +#include +#include "DCAFitter/DCAFitterN.h" +#include "Framework/AnalysisDataModel.h" +#include "ReconstructionDataFormats/Track.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsVertexing/SVertexHypothesis.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Common/Core/trackUtilities.h" +#include "Common/Core/RecoDecay.h" +#include "Tools/KFparticle/KFUtilities.h" + +#ifndef HomogeneousField +#define HomogeneousField +#endif + +/// includes KFParticle +#include "KFParticle.h" +#include "KFPTrack.h" +#include "KFPVertex.h" +#include "KFParticleBase.h" +#include "KFVertex.h" + +namespace o2 +{ +namespace pwglf +{ + +//_______________________________________________________________________ +// Deca3body information storage +struct decay3bodyCandidate { + // indexing + int collisionID = -1; + int decay3bodyID = -1; + int protonID = -1; + int pionID = -1; + int deuteronID = -1; + + // daughter properties + std::array momProton = {0.0f, 0.0f, 0.0f}; + std::array momPion = {0.0f, 0.0f, 0.0f}; + std::array momDeuteron = {0.0f, 0.0f, 0.0f}; + std::array posProton = {0.0f, 0.0f, 0.0f}; + std::array posPion = {0.0f, 0.0f, 0.0f}; + std::array posDeuteron = {0.0f, 0.0f, 0.0f}; + std::array trackDCAxyToPV = {0.0f, 0.0f, 0.0f}; // 0 - proton, 1 - pion, 2 - deuteron + std::array trackDCAzToPV = {0.0f, 0.0f, 0.0f}; // 0 - proton, 1 - pion, 2 - deuteron + std::array tpcNsigma = {0.0f, 0.0f, 0.0f, 0.0f}; // 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp + double tofNsigmaDeuteron = 0.0f; + std::array averageITSClSize = {0.0f, 0.0f, 0.0f}; // 0 - proton, 1 - pion, 2 - deuteron + std::array tpcNCl = {0.0f, 0.0f, 0.0f}; // 0 - proton, 1 - pion, 2 - deuteron + int pidForTrackingDeuteron = 0; + + // vertex properties + float mass; + float massV0; + int sign; + float momentum[3]; + float position[3]; + // std::array momentum = {0.0f, 0.0f, 0.0f}; + // std::array position = {0.0f, 0.0f, 0.0f}; + // float dcaToPV = 0.0f; + // float dcaxyToPV = 0.0f; + float chi2 = 0.0f; + float trackedClSize = 0.0f; + float daughterDCAatSV = 0.0f; // quadratic sum of DCA between daughters at SV + std::array daughterDCAtoSV = {0.0f, 0.0f, 0.0f}; // 0 - pos, 1 - neg, 2 - bach + + // covariance matrix + float covProton[21] = {0.0f}; + float covPion[21] = {0.0f}; + float covDeuteron[21] = {0.0f}; + float covariance[21] = {0.0f}; +}; + +//_______________________________________________________________________ +// builder helper class +class decay3bodyBuilderHelper +{ + public: + decay3bodyBuilderHelper() + { + fitter3body.setPropagateToPCA(true); + fitter3body.setMaxR(200.); //->maxRIni3body + fitter3body.setMinParamChange(1e-3); + fitter3body.setMinRelChi2Change(0.9); + fitter3body.setMaxDZIni(1e9); + fitter3body.setMaxDXYIni(4.0f); + fitter3body.setMaxChi2(1e9); + fitter3body.setUseAbsDCA(true); + + fitterV0.setPropagateToPCA(true); + fitterV0.setMaxR(200.); + fitterV0.setMinParamChange(1e-3); + fitterV0.setMinRelChi2Change(0.9); + fitterV0.setMaxDZIni(1e9); + fitterV0.setMaxChi2(1e9); + fitterV0.setUseAbsDCA(true); + + // mag field has to be set later + fitter3body.setBz(-999.9f); // will NOT make sense if not changed + }; + + o2::vertexing::DCAFitterN<2> fitterV0; // 2-prong o2 dca fitter + o2::vertexing::DCAFitterN<3> fitter3body; // 3-prong o2 dca fitter + + decay3bodyCandidate decay3body; // storage for Decay3body candidate properties + + o2::dataformats::VertexBase mMeanVertex{{0., 0., 0.}, {0.1 * 0.1, 0., 0.1 * 0.1, 0., 0., 6. * 6.}}; + o2::vertexing::SVertexHypothesis mV0Hyps; // 0 - Lambda, 1 - AntiLambda + + // decay3body candidate criteria + struct { + // daughter tracks + float maxEtaDaughters; + int minTPCNClProton; + int minTPCNClPion; + int minTPCNClDeuteron; + float minDCAProtonToPV; + float minDCAPionToPV; + float minDCADeuteronToPV; + float minPtProton; + float minPtPion; + float minPtDeuteron; + float maxPtProton; + float maxPtPion; + float maxPtDeuteron; + float maxTPCnSigma; + double minTOFnSigmaDeuteron; + double maxTOFnSigmaDeuteron; + float minPDeuteronUseTOF; + float maxDCADauAtSV; + // candidate + float maxRapidity; + float minPt; + float maxPt; + float minMass; + float maxMass; + float minCtau; + float maxCtau; + float minCosPA; + float maxChi2; + } decay3bodyselections; + + // SVertexer selection criteria + struct { + float minPt2V0; + float maxTgl2V0; + float maxDCAXY2ToMeanVertex3bodyV0; + float minCosPAXYMeanVertex3bodyV0; + float minCosPA3bodyV0; + float maxRDiffV03body; + float minPt3Body; + float maxTgl3Body; + float maxDCAXY3Body; + float maxDCAZ3Body; + } svertexerselections; + + //_______________________________________________________________________ + // build Decay3body from three tracks, including V0 building. + template + bool buildDecay3BodyCandidate(TCollision const& collision, + TTrack const& trackProton, + TTrack const& trackPion, + TTrack const& trackDeuteron, + int decay3bodyIndex, + double tofNsigmaDeuteron, + float trackedClSize, + bool useKFParticle = false, + bool kfSetTopologicalConstraint = false, + bool useSelections = true, + bool useTPCforPion = false, + bool acceptTPCOnly = false, + bool calculateCovariance = true, + bool isEventMixing = false) + { + int collisionIndex = collision.globalIndex(); + float pvX = collision.posX(); + float pvY = collision.posY(); + float pvZ = collision.posZ(); + + auto trackParCovProton = getTrackParCov(trackProton); + auto trackParCovPion = getTrackParCov(trackPion); + auto trackParCovDeuteron = getTrackParCov(trackDeuteron); + + decay3body.collisionID = collisionIndex; + decay3body.decay3bodyID = decay3bodyIndex; + decay3body.protonID = trackProton.globalIndex(); + decay3body.pionID = trackPion.globalIndex(); + decay3body.deuteronID = trackDeuteron.globalIndex(); + + //_______________________________________________________________________ + // track selections + if (useSelections) { + // proton track quality + if (trackProton.tpcNClsFound() < decay3bodyselections.minTPCNClProton) { + decay3body = {}; + return false; + } + // pion track quality + if (useTPCforPion) { + if (trackPion.tpcNClsFound() < decay3bodyselections.minTPCNClPion) { + decay3body = {}; + return false; + } + } + // deuteron track quality + if (trackDeuteron.tpcNClsFound() < decay3bodyselections.minTPCNClDeuteron) { + decay3body = {}; + return false; + } + + // track eta + if (std::fabs(trackProton.eta()) > decay3bodyselections.maxEtaDaughters) { + decay3body = {}; + return false; + } + if (std::fabs(trackPion.eta()) > decay3bodyselections.maxEtaDaughters) { + decay3body = {}; + return false; + } + if (std::fabs(trackDeuteron.eta()) > decay3bodyselections.maxEtaDaughters) { + decay3body = {}; + return false; + } + + // TPC only + if (!acceptTPCOnly && (!trackProton.hasITS() || !trackPion.hasITS() || !trackDeuteron.hasITS())) { + decay3body = {}; + return false; + } + + // daughter TPC PID + if (std::fabs(trackProton.tpcNSigmaPr()) > decay3bodyselections.maxTPCnSigma) { + decay3body = {}; + return false; + } + if (useTPCforPion && std::fabs(trackPion.tpcNSigmaPi()) > decay3bodyselections.maxTPCnSigma) { + decay3body = {}; + return false; + } + if (std::fabs(trackDeuteron.tpcNSigmaDe()) > decay3bodyselections.maxTPCnSigma) { + decay3body = {}; + return false; + } + + // deuteron TOF PID + if ((tofNsigmaDeuteron < decay3bodyselections.minTOFnSigmaDeuteron || tofNsigmaDeuteron > decay3bodyselections.maxTOFnSigmaDeuteron) && trackDeuteron.p() > decay3bodyselections.minPDeuteronUseTOF) { + decay3body = {}; + return false; + } + } // end of selections + + //_______________________________________________________________________ + // daughter track DCA to PV associated with decay3body + o2::dataformats::VertexBase mPV; + o2::dataformats::DCA mDcaInfoCov; + auto trackParCovProtonCopy = trackParCovProton; + auto trackParCovPionCopy = trackParCovPion; + auto trackParCovDeuteronCopy = trackParCovDeuteron; + mPV.setPos({pvX, pvY, pvZ}); + mPV.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + // proton track + o2::base::Propagator::Instance()->propagateToDCABxByBz(mPV, trackParCovProtonCopy, 2.f, fitter3body.getMatCorrType(), &mDcaInfoCov); + decay3body.trackDCAxyToPV[0] = mDcaInfoCov.getY(); + decay3body.trackDCAzToPV[0] = mDcaInfoCov.getZ(); + auto trackProtonDCAToPV = std::sqrt(decay3body.trackDCAxyToPV[0] * decay3body.trackDCAxyToPV[0] + decay3body.trackDCAzToPV[0] * decay3body.trackDCAzToPV[0]); + if (useSelections) { + if (trackProtonDCAToPV < decay3bodyselections.minDCAProtonToPV) { + decay3body = {}; + return false; + } + } + // pion track + o2::base::Propagator::Instance()->propagateToDCABxByBz(mPV, trackParCovPionCopy, 2.f, fitter3body.getMatCorrType(), &mDcaInfoCov); + decay3body.trackDCAxyToPV[1] = mDcaInfoCov.getY(); + decay3body.trackDCAzToPV[1] = mDcaInfoCov.getZ(); + auto trackPionDCAToPV = std::sqrt(decay3body.trackDCAxyToPV[1] * decay3body.trackDCAxyToPV[1] + decay3body.trackDCAzToPV[1] * decay3body.trackDCAzToPV[1]); + if (useSelections) { + if (trackPionDCAToPV < decay3bodyselections.minDCAPionToPV) { + decay3body = {}; + return false; + } + } + // deuteron track + o2::base::Propagator::Instance()->propagateToDCABxByBz(mPV, trackParCovDeuteronCopy, 2.f, fitter3body.getMatCorrType(), &mDcaInfoCov); + decay3body.trackDCAxyToPV[2] = mDcaInfoCov.getY(); + decay3body.trackDCAzToPV[2] = mDcaInfoCov.getZ(); + auto trackDeuteronDCAToPV = std::sqrt(decay3body.trackDCAxyToPV[2] * decay3body.trackDCAxyToPV[2] + decay3body.trackDCAzToPV[2] * decay3body.trackDCAzToPV[2]); + if (useSelections) { + if (trackDeuteronDCAToPV < decay3bodyselections.minDCADeuteronToPV) { + decay3body = {}; + return false; + } + } + + //_______________________________________________________________________ + // fit 3body vertex + if (!useKFParticle) { + fitVertexWithDCAFitter(trackProton, trackPion, trackDeuteron, calculateCovariance); + } else { + fitVertexWithKF(collision, trackProton, trackPion, trackDeuteron, kfSetTopologicalConstraint, calculateCovariance); + } + + //_______________________________________________________________________ + // get vertex information + // daughter pT + auto trackProtonPt = std::sqrt(decay3body.momProton[0] * decay3body.momProton[0] + decay3body.momProton[1] * decay3body.momProton[1]); + auto trackPionPt = std::sqrt(decay3body.momPion[0] * decay3body.momPion[0] + decay3body.momPion[1] * decay3body.momPion[1]); + auto trackDeuteronPt = std::sqrt(decay3body.momDeuteron[0] * decay3body.momDeuteron[0] + decay3body.momDeuteron[1] * decay3body.momDeuteron[1]); + + // DCA between daughters at SV + decay3body.daughterDCAatSV = std::hypot( + std::hypot(decay3body.posProton[0] - decay3body.posPion[0], + decay3body.posProton[1] - decay3body.posPion[1], + decay3body.posProton[2] - decay3body.posPion[2]), + std::hypot(decay3body.posProton[0] - decay3body.posDeuteron[0], + decay3body.posProton[1] - decay3body.posDeuteron[1], + decay3body.posProton[2] - decay3body.posDeuteron[2]), + std::hypot(decay3body.posPion[0] - decay3body.posProton[0], + decay3body.posPion[1] - decay3body.posProton[1], + decay3body.posPion[2] - decay3body.posProton[2])); + + // daughter DCA to SV + // proton daughter + decay3body.daughterDCAtoSV[0] = std::hypot( + decay3body.posProton[0] - decay3body.position[0], + decay3body.posProton[1] - decay3body.position[1], + decay3body.posProton[2] - decay3body.position[2]); + // pion daughter + decay3body.daughterDCAtoSV[1] = std::hypot( + decay3body.posPion[0] - decay3body.position[0], + decay3body.posPion[1] - decay3body.position[1], + decay3body.posPion[2] - decay3body.position[2]); + // deuteron daughter + decay3body.daughterDCAtoSV[2] = std::hypot( + decay3body.posDeuteron[0] - decay3body.position[0], + decay3body.posDeuteron[1] - decay3body.position[1], + decay3body.posDeuteron[2] - decay3body.position[2]); + + //_____________________________________________________ + // selections after vertex fit + if (useSelections) { + // daughter pT + // proton + if (trackProtonPt < decay3bodyselections.minPtProton || trackProtonPt > decay3bodyselections.maxPtProton) { + decay3body = {}; + return false; + } + // pion + if (trackPionPt < decay3bodyselections.minPtPion || trackPionPt > decay3bodyselections.maxPtPion) { + decay3body = {}; + return false; + } + // deuteron + if (trackDeuteronPt < decay3bodyselections.minPtDeuteron || trackDeuteronPt > decay3bodyselections.maxPtDeuteron) { + decay3body = {}; + return false; + } + + // daughter DCAs at SV + if (decay3body.daughterDCAatSV > decay3bodyselections.maxDCADauAtSV) { + decay3body = {}; + return false; + } + + // rapidity + float rapidity = RecoDecay::y(std::array{decay3body.momentum[0], decay3body.momentum[1], decay3body.momentum[2]}, o2::constants::physics::MassHyperTriton); + if (std::fabs(rapidity) > decay3bodyselections.maxRapidity) { + decay3body = {}; + return false; + } + + // pT + float pT = RecoDecay::pt(std::array{decay3body.momentum[0], decay3body.momentum[1], decay3body.momentum[2]}); + if (pT < decay3bodyselections.minPt || pT > decay3bodyselections.maxPt) { + decay3body = {}; + return false; + } + + // mass window + if (decay3body.mass < decay3bodyselections.minMass || decay3body.mass > decay3bodyselections.maxMass) { + decay3body = {}; + return false; + } + + // pointing angle + float cpa = RecoDecay::cpa(std::array{pvX, pvY, pvZ}, std::array{decay3body.position[0], decay3body.position[1], decay3body.position[2]}, std::array{decay3body.momentum[0], decay3body.momentum[1], decay3body.momentum[2]}); + if (cpa < decay3bodyselections.minCosPA) { + decay3body = {}; + return false; + } + + // vertex chi2 + if (decay3body.chi2 > decay3bodyselections.maxChi2) { + decay3body = {}; + return false; + } + + // ctau + float P = RecoDecay::sqrtSumOfSquares(decay3body.momentum[0], decay3body.momentum[1], decay3body.momentum[2]); + float ctau = std::sqrt(std::pow(decay3body.position[0] - pvX, 2) + std::pow(decay3body.position[1] - pvY, 2) + std::pow(decay3body.position[2] - pvZ, 2)) / (P + 1E-10) * o2::constants::physics::MassHyperTriton; + if (ctau < decay3bodyselections.minCtau || ctau > decay3bodyselections.maxCtau) { + decay3body = {}; + return false; + } + } + + //_______________________________________________________________________ + // SVertexer selections in case of event mixing + if (isEventMixing) { + applySVertexerCuts(collision, trackProton, trackPion, trackDeuteron, /*applyV0Cut = */ true); + } + + //_______________________________________________________________________ + // fill remaining candidate information + // daughter PID + decay3body.tpcNsigma[0] = trackProton.tpcNSigmaPr(); + decay3body.tpcNsigma[1] = trackPion.tpcNSigmaPi(); + decay3body.tpcNsigma[2] = trackDeuteron.tpcNSigmaDe(); + decay3body.tpcNsigma[3] = trackDeuteron.tpcNSigmaPi(); + // recalculated bachelor TOF PID + decay3body.tofNsigmaDeuteron = tofNsigmaDeuteron; + + // average ITS cluster size of daughter tracks + double averageClusterSizeProton(0), averageClusterSizePion(0), averageClusterSizeDeuteron(0); + int nClsProton(0), nClsPion(0), nClsDeuteron(0); + for (int i = 0; i < 7; i++) { + int clusterSizePr = trackProton.itsClsSizeInLayer(i); + int clusterSizePi = trackPion.itsClsSizeInLayer(i); + int clusterSizeDe = trackDeuteron.itsClsSizeInLayer(i); + averageClusterSizeProton += static_cast(clusterSizePr); + averageClusterSizePion += static_cast(clusterSizePi); + averageClusterSizeDeuteron += static_cast(clusterSizeDe); + if (clusterSizePr > 0) + nClsProton++; + if (clusterSizePi > 0) + nClsPion++; + if (clusterSizeDe > 0) + nClsDeuteron++; + } + averageClusterSizeProton = averageClusterSizeProton / static_cast(nClsProton); + averageClusterSizePion = averageClusterSizePion / static_cast(nClsPion); + averageClusterSizeDeuteron = averageClusterSizeDeuteron / static_cast(nClsDeuteron); + decay3body.averageITSClSize[0] = averageClusterSizeProton; + decay3body.averageITSClSize[1] = averageClusterSizePion; + decay3body.averageITSClSize[2] = averageClusterSizeDeuteron; + + // number of TPC clusters + decay3body.tpcNCl[0] = trackProton.tpcNClsFound(); + decay3body.tpcNCl[1] = trackPion.tpcNClsFound(); + decay3body.tpcNCl[2] = trackDeuteron.tpcNClsFound(); + + // PID for tracking of deuteron track + decay3body.pidForTrackingDeuteron = trackDeuteron.pidForTracking(); + + // tracked cluster size + decay3body.trackedClSize = trackedClSize; + + return true; + } + + //___________________________________________________________________________________ + // functionality to fit 3body vertex with KFParticle and fill vertex information + template + void fitVertexWithKF(TCollision const& collision, + TTrack const& trackProton, + TTrack const& trackPion, + TTrack const& trackDeuteron, + bool kfSetTopologicalConstraint = true, + bool calculateCovariance = true) + { + // get TrackParCov daughters + auto trackParCovProton = getTrackParCov(trackProton); + auto trackParCovPion = getTrackParCov(trackPion); + auto trackParCovDeuteron = getTrackParCov(trackDeuteron); + + // initialise KF primary vertex + KFVertex kfpVertex = createKFPVertexFromCollision(collision); + KFParticle kfpv(kfpVertex); + + // create KFParticle objects + KFParticle kfpProton, kfpPion, kfpDeuteron; + kfpProton = createKFParticleFromTrackParCov(trackParCovProton, trackProton.sign(), constants::physics::MassProton); + kfpPion = createKFParticleFromTrackParCov(trackParCovPion, trackPion.sign(), constants::physics::MassPionCharged); + kfpDeuteron = createKFParticleFromTrackParCov(trackParCovDeuteron, trackDeuteron.sign(), constants::physics::MassDeuteron); + + // construct V0 vertex + KFParticle KFV0; + int nDaughtersV0 = 2; + const KFParticle* DaughtersV0[2] = {&kfpProton, &kfpPion}; + KFV0.SetConstructMethod(2); + try { + KFV0.Construct(DaughtersV0, nDaughtersV0); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to create V0 vertex." << e.what(); + return; + } + + // construct vertex + KFParticle KFH3L; + int nDaughters3body = 3; + const KFParticle* Daughters3body[3] = {&kfpProton, &kfpPion, &kfpDeuteron}; + KFH3L.SetConstructMethod(2); + try { + KFH3L.Construct(Daughters3body, nDaughters3body); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to create Hyper triton 3-body vertex." << e.what(); + return; + } + + // topological constraint + if (kfSetTopologicalConstraint) { + KFH3L.SetProductionVertex(kfpv); + KFH3L.TransportToDecayVertex(); + } + + // get vertex position and momentum + decay3body.position[0] = KFH3L.GetX(); + decay3body.position[1] = KFH3L.GetY(); + decay3body.position[2] = KFH3L.GetZ(); + decay3body.momentum[0] = KFH3L.GetPx(); + decay3body.momentum[1] = KFH3L.GetPy(); + decay3body.momentum[2] = KFH3L.GetPz(); + + // get sign + decay3body.sign = KFH3L.GetQ() / std::abs(KFH3L.GetQ()); + + // transport all daughter tracks to hypertriton vertex + kfpProton.TransportToPoint(decay3body.position); + kfpPion.TransportToPoint(decay3body.position); + kfpDeuteron.TransportToPoint(decay3body.position); + + // daughter positions + decay3body.posProton[0] = kfpProton.GetX(); + decay3body.posProton[1] = kfpProton.GetY(); + decay3body.posProton[2] = kfpProton.GetZ(); + decay3body.posPion[0] = kfpPion.GetX(); + decay3body.posPion[1] = kfpPion.GetY(); + decay3body.posPion[2] = kfpPion.GetZ(); + decay3body.posDeuteron[0] = kfpDeuteron.GetX(); + decay3body.posDeuteron[1] = kfpDeuteron.GetY(); + decay3body.posDeuteron[2] = kfpDeuteron.GetZ(); + + // daughter momenta + decay3body.momProton[0] = kfpProton.GetPx(); + decay3body.momProton[1] = kfpProton.GetPy(); + decay3body.momProton[2] = kfpProton.GetPz(); + decay3body.momPion[0] = kfpPion.GetPx(); + decay3body.momPion[1] = kfpPion.GetPy(); + decay3body.momPion[2] = kfpPion.GetPz(); + decay3body.momDeuteron[0] = kfpDeuteron.GetPx(); + decay3body.momDeuteron[1] = kfpDeuteron.GetPy(); + decay3body.momDeuteron[2] = kfpDeuteron.GetPz(); + + // candidate mass + float mass, massErr; + KFH3L.GetMass(mass, massErr); + decay3body.mass = mass; + + // V0 mass + float massV0, massV0Err; + KFV0.GetMass(massV0, massV0Err); + decay3body.massV0 = massV0; + + // vertex chi2 + decay3body.chi2 = KFH3L.GetChi2() / KFH3L.GetNDF(); + + // caluclate covariance matrices + if (calculateCovariance) { + // candidate covariance matrix + std::array covKF; + for (int i = 0; i < 21; i++) { // get covariance matrix elements (lower triangle) + covKF[i] = KFH3L.GetCovariance(i); + decay3body.covariance[i] = covKF[i]; + } + // daughter track covariance matrices + for (int i = 0; i < 21; i++) { // get covariance matrix elements (lower triangle) + decay3body.covProton[i] = kfpProton.GetCovariance(i); + decay3body.covPion[i] = kfpPion.GetCovariance(i); + decay3body.covDeuteron[i] = kfpDeuteron.GetCovariance(i); + } + } + + return; + } + + //_______________________________________________________________________ + // functionality to fit 3body vertex with DCAFitter + template + void fitVertexWithDCAFitter(TTrack const& trackProton, + TTrack const& trackPion, + TTrack const& trackDeuteron, + bool calculateCovariance = true) + { + // get TrackParCov daughters + auto trackParCovProton = getTrackParCov(trackProton); + auto trackParCovPion = getTrackParCov(trackPion); + auto trackParCovDeuteron = getTrackParCov(trackDeuteron); + + // fit the vertex + int n3bodyVtx = fitter3body.process(trackParCovProton, trackParCovPion, trackParCovDeuteron); + if (n3bodyVtx == 0) { // discard this pair + return; + } + + // get vertex position + const auto& vtxXYZ = fitter3body.getPCACandidate(); + for (int i = 0; i < 3; i++) { + decay3body.position[i] = vtxXYZ[i]; + } + + // get daughter momenta + const auto& propagatedTrackProton = fitter3body.getTrack(0); + const auto& propagatedTrackPion = fitter3body.getTrack(1); + const auto& propagatedTrackDeuteron = fitter3body.getTrack(2); + propagatedTrackProton.getPxPyPzGlo(decay3body.momProton); + propagatedTrackPion.getPxPyPzGlo(decay3body.momPion); + propagatedTrackDeuteron.getPxPyPzGlo(decay3body.momDeuteron); + propagatedTrackProton.getXYZGlo(decay3body.posProton); + propagatedTrackPion.getXYZGlo(decay3body.posPion); + propagatedTrackDeuteron.getXYZGlo(decay3body.posDeuteron); + + // get daughter positions at vertex + + // calculate candidate momentum + decay3body.momentum[0] = decay3body.momProton[0] + decay3body.momPion[0] + decay3body.momDeuteron[0]; + decay3body.momentum[1] = decay3body.momProton[1] + decay3body.momPion[1] + decay3body.momDeuteron[1]; + decay3body.momentum[2] = decay3body.momProton[2] + decay3body.momPion[2] + decay3body.momDeuteron[2]; + + // candidate and V0 mass + decay3body.mass = RecoDecay::m( + std::array{std::array{decay3body.momProton[0], decay3body.momProton[1], decay3body.momProton[2]}, + std::array{decay3body.momPion[0], decay3body.momPion[1], decay3body.momPion[2]}, + std::array{decay3body.momDeuteron[0], decay3body.momDeuteron[1], decay3body.momDeuteron[2]}}, + std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); + decay3body.massV0 = RecoDecay::m( + std::array{std::array{decay3body.momProton[0], decay3body.momProton[1], decay3body.momProton[2]}, + std::array{decay3body.momPion[0], decay3body.momPion[1], decay3body.momPion[2]}}, + std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + + // vertex chi2 at PCA + decay3body.chi2 = fitter3body.getChi2AtPCACandidate(); + + // candidate sign + decay3body.sign = trackDeuteron.sign(); + + // caluclate covariance matrices + if (calculateCovariance) { + // candidate position covariance matrix + auto covVtxV = fitter3body.calcPCACovMatrix(0); + decay3body.covariance[0] = covVtxV(0, 0); + decay3body.covariance[1] = covVtxV(1, 0); + decay3body.covariance[2] = covVtxV(1, 1); + decay3body.covariance[3] = covVtxV(2, 0); + decay3body.covariance[4] = covVtxV(2, 1); + decay3body.covariance[5] = covVtxV(2, 2); + // daughter covariance matrices + std::array covTproton = {0.}; + std::array covTpion = {0.}; + std::array covTdeuteron = {0.}; + propagatedTrackProton.getCovXYZPxPyPzGlo(covTproton); + propagatedTrackPion.getCovXYZPxPyPzGlo(covTpion); + propagatedTrackDeuteron.getCovXYZPxPyPzGlo(covTdeuteron); + for (int i = 0; i < 21; i++) { + decay3body.covProton[i] = covTproton[i]; + decay3body.covPion[i] = covTpion[i]; + decay3body.covDeuteron[i] = covTdeuteron[i]; + } + // candidate momentum covairance matrix + constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + for (int i = 0; i < 6; i++) { + decay3body.covariance[MomInd[i]] = covTproton[MomInd[i]] + covTpion[MomInd[i]] + covTdeuteron[MomInd[i]]; + } + /// WARNING: position-momentum covariances are not calculated in the DCAFitter - remain zero + } + + return; + } + + //_______________________________________________________________________ + // functionality to apply SVertexer cuts in case of event mixing + template + void applySVertexerCuts(TCollision const& collision, + TTrack const& trackProton, + TTrack const& trackPion, + TTrack const& trackDeuteron, + bool applyV0Cut = true) + { + // get TrackParCov daughters + auto trackParCovProton = getTrackParCov(trackProton); + auto trackParCovPion = getTrackParCov(trackPion); + auto trackParCovDeuteron = getTrackParCov(trackDeuteron); + + const float pidCutsLambda[o2::vertexing::SVertexHypothesis::NPIDParams] = {0., 20, 0., 5.0, 0.0, 1.09004e-03, 2.62291e-04, 8.93179e-03, 2.83121}; // Lambda + mV0Hyps.set(o2::track::PID::Lambda, o2::track::PID::Proton, o2::track::PID::Pion, pidCutsLambda, fitter3body.getBz()); + + int nV0 = fitterV0.process(trackParCovProton, trackParCovPion); + if (nV0 == 0) { + return; + } + + std::array v0pos = {0.}; + const auto& v0vtxXYZ = fitterV0.getPCACandidate(); + for (int i = 0; i < 3; i++) { + v0pos[i] = v0vtxXYZ[i]; + } + const int cand = 0; + if (!fitterV0.isPropagateTracksToVertexDone(cand) && !fitterV0.propagateTracksToVertex(cand)) { + return; + } + + const auto& trProtonProp = fitterV0.getTrack(0, cand); + const auto& trPionProp = fitterV0.getTrack(1, cand); + std::array pProtonV0{}, pPionV0{}; + trProtonProp.getPxPyPzGlo(pProtonV0); + trPionProp.getPxPyPzGlo(pPionV0); + std::array pV0 = {pProtonV0[0] + pPionV0[0], pProtonV0[1] + pPionV0[1], pProtonV0[2] + pPionV0[2]}; + // Cut for Virtual V0 + float dxv0 = v0pos[0] - mMeanVertex.getX(), dyv0 = v0pos[1] - mMeanVertex.getY(), r2v0 = dxv0 * dxv0 + dyv0 * dyv0; + float rv0 = std::sqrt(r2v0); + float pt2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1], prodXYv0 = dxv0 * pV0[0] + dyv0 * pV0[1], tDCAXY = prodXYv0 / pt2V0; + if (applyV0Cut && pt2V0 <= svertexerselections.minPt2V0) { + return; + } + if (applyV0Cut && pV0[2] * pV0[2] / pt2V0 > svertexerselections.maxTgl2V0) { // tgLambda cut + return; + } + + float p2V0 = pt2V0 + pV0[2] * pV0[2], ptV0 = std::sqrt(pt2V0); + // apply mass selections + float p2Proton = pProtonV0[0] * pProtonV0[0] + pProtonV0[1] * pProtonV0[1] + pProtonV0[2] * pProtonV0[2], p2Pion = pPionV0[0] * pPionV0[0] + pPionV0[1] * pPionV0[1] + pPionV0[2] * pPionV0[2]; + bool good3bodyV0Hyp = false; + float massForLambdaHyp = mV0Hyps.calcMass(p2Proton, p2Pion, p2V0); + if (massForLambdaHyp - mV0Hyps.getMassV0Hyp() < mV0Hyps.getMargin(ptV0)) { + good3bodyV0Hyp = true; + } + if (applyV0Cut && !good3bodyV0Hyp) { + return; + } + + float dcaX = dxv0 - pV0[0] * tDCAXY, dcaY = dyv0 - pV0[1] * tDCAXY, dca2 = dcaX * dcaX + dcaY * dcaY; + float cosPAXY = prodXYv0 / rv0 * ptV0; + if (applyV0Cut && dca2 > svertexerselections.maxDCAXY2ToMeanVertex3bodyV0) { + return; + } + // FIXME: V0 cosPA cut to be investigated + if (applyV0Cut && cosPAXY < svertexerselections.minCosPAXYMeanVertex3bodyV0) { + return; + } + // Check: CosPA Cut of Virtual V0 may not be used since the V0 may be based on another PV + float dx = v0pos[0] - collision.posX(); + float dy = v0pos[1] - collision.posY(); + float dz = v0pos[2] - collision.posZ(); + float prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; + float v0CosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); + if (applyV0Cut && v0CosPA < svertexerselections.minCosPA3bodyV0) { + return; + } + + // 3body vertex + int n3bodyVtx = fitter3body.process(trackParCovProton, trackParCovPion, trackParCovDeuteron); + if (n3bodyVtx == 0) { // discard this pair + return; + } + const auto& vertexXYZ = fitter3body.getPCACandidatePos(); + std::array pos = {0.}; + for (int i = 0; i < 3; i++) { + pos[i] = vertexXYZ[i]; + } + + std::array pProton = {0.}, pPion = {0.}, pDeuteron{0.}; + const auto& propagatedTrackProton = fitter3body.getTrack(0); + const auto& propagatedTrackPion = fitter3body.getTrack(1); + const auto& propagatedTrackDeuteron = fitter3body.getTrack(2); + propagatedTrackProton.getPxPyPzGlo(pProton); + propagatedTrackPion.getPxPyPzGlo(pPion); + propagatedTrackDeuteron.getPxPyPzGlo(pDeuteron); + std::array p3B = {pProton[0] + pPion[0] + pDeuteron[0], pProton[1] + pPion[1] + pDeuteron[1], pProton[2] + pPion[2] + pDeuteron[2]}; + + float r3body = std::hypot(pos[0], pos[1]); + if (r3body < 0.5) { + return; + } + + // Cut for the compatibility of V0 and 3body vertex + float deltaR = std::abs(rv0 - r3body); + if (deltaR > svertexerselections.maxRDiffV03body) { + return; + } + + float pt3B = std::hypot(p3B[0], p3B[1]); + if (pt3B < svertexerselections.minPt3Body) { // pt cut + return; + } + if (p3B[2] / pt3B > svertexerselections.maxTgl3Body) { // tgLambda cut + return; + } + + // H3L DCA Check + auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, trackDeuteron.sign()); + o2::dataformats::DCA dca; + if (!track3B.propagateToDCA({{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}, fitter3body.getBz(), &dca, 5.) || + std::abs(dca.getY()) > svertexerselections.maxDCAXY3Body || std::abs(dca.getZ()) > svertexerselections.maxDCAZ3Body) { + return; + } + + return; + } + + private: + // internal helper to calculate DCA (3D) of a straight line to a given PV analytically + float CalculateDCAStraightToPV(float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) + { + return std::sqrt((std::pow((pvY - Y) * Pz - (pvZ - Z) * Py, 2) + std::pow((pvX - X) * Pz - (pvZ - Z) * Px, 2) + std::pow((pvX - X) * Py - (pvY - Y) * Px, 2)) / (Px * Px + Py * Py + Pz * Pz)); + } +}; + +} // namespace pwglf +} // namespace o2 + +#endif // PWGLF_UTILS_DECAY3BODYBUILDERHELPER_H_ From 62adf8b29c6ffb08186e70cfbddf59ab75854d43 Mon Sep 17 00:00:00 2001 From: chengtt0406 <39661669+chengtt0406@users.noreply.github.com> Date: Thu, 12 Jun 2025 15:49:47 +0800 Subject: [PATCH 38/62] [PWGHF] Remove indexRexCharmBaryon=-1 case for MC rec matching (#11556) --- PWGHF/TableProducer/treeCreatorOmegacSt.cxx | 81 +++++++++++---------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index 8d2780cd435..4d3c59cfcd1 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -15,39 +15,41 @@ /// \author Jochen Klein /// \author Tiantian Cheng -#include -#include -#include -#include +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" #include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "DCAFitter/DCAFitterN.h" #include "DetectorsBase/Propagator.h" -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" +#include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoA.h" #include "Framework/HistogramRegistry.h" #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -369,8 +371,7 @@ struct HfTreeCreatorOmegacSt { } else if (idxKaonDaughter >= 0 && idxCascDaughter >= 0) { decayChannel = o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK; // OmegaC -> Omega + K } else { - decayChannel = -1; - LOG(warning) << "Decay channel not recognized!"; + decayChannel = -1; // LOG(warning) << "Decay channel not recognized!"; } if (decayChannel != -1) { int idxDaughter = (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) ? idxPionDaughter : idxKaonDaughter; @@ -662,32 +663,36 @@ struct HfTreeCreatorOmegacSt { // Match Omegac0 → Omega- + Pi+ indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughters, o2::constants::physics::kOmegaC0, std::array{+kPiPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3, &nPiToMuOmegac0, &nKaToPiOmegac0); + indexRecCharmBaryon = indexRec; + if (indexRec > -1) { + // Omega- → K pi p (Cascade match) + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2, &nPiToMuCasc, &nKaToPiCasc); + if (indexRec > -1) { + // Lambda → p pi (Lambda match) + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1, &nPiToMuV0); + if (indexRec > -1) { + isMatched = true; + } + } + } } else if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { // Match Omegac0 → Omega- + K+ indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughters, o2::constants::physics::kOmegaC0, std::array{+kKPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3, &nPiToMuOmegac0, &nKaToPiOmegac0); - } - indexRecCharmBaryon = indexRec; - if (indexRec > -1) { - // Omega- → K pi p (Cascade match) - indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2, &nPiToMuCasc, &nKaToPiCasc); + indexRecCharmBaryon = indexRec; if (indexRec > -1) { - // Lambda → p pi (Lambda match) - indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1, &nPiToMuV0); - if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { - if (nPiToMuOmegac0 >= 1 && nKaToPiOmegac0 == 0) { - isMatched = true; - } else if (nPiToMuOmegac0 == 0 && nKaToPiOmegac0 == 0) { - isMatched = true; - } - } else if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { - if (nPiToMuOmegac0 == 0 && nKaToPiOmegac0 == 0) { + // Omega- → K pi p (Cascade match) + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2, &nPiToMuCasc, &nKaToPiCasc); + if (indexRec > -1) { + // Lambda → p pi (Lambda match) + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1, &nPiToMuV0); + if (indexRec > -1) { isMatched = true; } } } } - if (isMatched) { + if (isMatched && indexRecCharmBaryon > -1) { auto particle = mcParticles->get().rawIteratorAt(indexRecCharmBaryon); origin = RecoDecay::getCharmHadronOrigin(mcParticles->get(), particle, false, &idxBhadMothers); } From 43d850725593af6ad0097e168aabb875749679f9 Mon Sep 17 00:00:00 2001 From: sashingo Date: Thu, 12 Jun 2025 16:50:27 +0900 Subject: [PATCH 39/62] [PWGHF] added some histograms for EMCal (#11554) --- PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index be71ab35a01..72ff0ccdf8d 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -160,6 +160,8 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisM02{100, 0, 1, "M02"}; const AxisSpec axisdPhi{100, -0.5, 0.5, "dPhi"}; const AxisSpec axisdEta{100, -0.5, 0.5, "dEta"}; + const AxisSpec axisdR{20, 0.0, 0.2, "dR"}; + const AxisSpec axisNcell{50, 0.0, 50.0, "Ncell"}; const AxisSpec axisPhi{350, 0, 7, "Phi"}; const AxisSpec axisEop{200, 0, 2, "Eop"}; const AxisSpec axisChi2{250, 0.0, 25.0, "#chi^{2}"}; @@ -184,7 +186,8 @@ struct HfTaskElectronWeakBoson { registry.add("hPt", "track pt", kTH1F, {axisPt}); registry.add("hTPCNsigma", "TPC electron Nsigma", kTH2F, {{axisPt}, {axisNsigma}}); registry.add("hEnergy", "EMC cluster energy", kTH1F, {axisE}); - registry.add("hTrMatch", "Track EMC Match", kTH2F, {{axisdPhi}, {axisdEta}}); + registry.add("hEnergyNcell", "EMC cluster energy and cell", kTH2F, {{axisE}, {axisNcell}}); + registry.add("hTrMatchR", "Track EMC Match in radius", kTH2F, {{axisPt}, {axisdR}}); registry.add("hTrMatch_mim", "Track EMC Match minimu minimumm", kTH2F, {{axisdPhi}, {axisdEta}}); registry.add("hMatchPhi", "Match in Phi", kTH2F, {{axisPhi}, {axisPhi}}); registry.add("hMatchEta", "Match in Eta", kTH2F, {{axisEta}, {axisEta}}); @@ -198,6 +201,7 @@ struct HfTaskElectronWeakBoson { registry.add("hInvMassZeeLs", "invariant mass for Z LS pair", kTH2F, {{axisPt}, {axisInvMassZ}}); registry.add("hInvMassZeeUls", "invariant mass for Z ULS pair", kTH2F, {{axisPt}, {axisInvMassZ}}); registry.add("hTHnElectrons", "electron info", HistType::kTHnSparseF, {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack}); + registry.add("hTHnTrMatch", "Track EMC Match", HistType::kTHnSparseF, {axisPt, axisdPhi, axisdEta}); // hisotgram for EMCal trigger registry.add("hEMCalTrigger", "EMCal trigger", kTH1F, {axisTrigger}); @@ -298,7 +302,7 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hEMCalTrigger"), isTriggered ? 1 : 0); // Skip event if not triggered and we're processing skimmed data - if (!isTriggered && cfgSkimmedProcessing) { + if (!isTriggered) { return; } } @@ -397,13 +401,16 @@ struct HfTaskElectronWeakBoson { dPhiMin = dPhi; dEtaMin = dEta; } - registry.fill(HIST("hTrMatch"), dPhi, dEta); + registry.fill(HIST("hTHnTrMatch"), match.track_as().pt(), dPhi, dEta); registry.fill(HIST("hEMCtime"), timeEmc); registry.fill(HIST("hEnergy"), energyEmc); - if (r > rMatchMax) + if (std::abs(dPhi) > rMatchMax || std::abs(dEta) > rMatchMax) continue; + registry.fill(HIST("hTrMatchR"), match.track_as().pt(), r); + registry.fill(HIST("hEnergyNcell"), energyEmc, match.emcalcluster_as().nCells()); + const auto& cluster = match.emcalcluster_as(); double eop = energyEmc / match.track_as().p(); From 0edd40fdbead25e68543e02e2543225891415696 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Thu, 12 Jun 2025 10:31:21 +0200 Subject: [PATCH 40/62] Add number of PV contributors (#11558) Co-authored-by: Francesco Mazzaschi --- PWGLF/DataModel/LFSlimNucleiTables.h | 8 ++- PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx | 6 +-- PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx | 54 +++++++++---------- PWGLF/TableProducer/Nuspex/nucleiUtils.h | 1 + 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h index e562c35ddc6..e1c0e0eb364 100644 --- a/PWGLF/DataModel/LFSlimNucleiTables.h +++ b/PWGLF/DataModel/LFSlimNucleiTables.h @@ -14,10 +14,11 @@ /// \brief Slim nuclei tables /// -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" #include "Common/DataModel/Centrality.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" + #ifndef PWGLF_DATAMODEL_LFSLIMNUCLEITABLES_H_ #define PWGLF_DATAMODEL_LFSLIMNUCLEITABLES_H_ @@ -31,6 +32,7 @@ DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(TPCInnerParam, tpcInnerParam, float); DECLARE_SOA_COLUMN(Beta, beta, float); DECLARE_SOA_COLUMN(Zvertex, zVertex, float); +DECLARE_SOA_COLUMN(NContrib, nContrib, int); DECLARE_SOA_COLUMN(DCAxy, dcaxy, float); DECLARE_SOA_COLUMN(DCAz, dcaz, float); DECLARE_SOA_COLUMN(TPCsignal, tpcSignal, float); @@ -102,6 +104,7 @@ DECLARE_SOA_TABLE(NucleiTable, "AOD", "NUCLEITABLE", NucleiTableNS::TPCInnerParam, NucleiTableNS::Beta, NucleiTableNS::Zvertex, + NucleiTableNS::NContrib, NucleiTableNS::DCAxy, NucleiTableNS::DCAz, NucleiTableNS::TPCsignal, @@ -139,6 +142,7 @@ DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC", NucleiTableNS::TPCInnerParam, NucleiTableNS::Beta, NucleiTableNS::Zvertex, + NucleiTableNS::NContrib, NucleiTableNS::DCAxy, NucleiTableNS::DCAz, NucleiTableNS::TPCsignal, diff --git a/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx b/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx index 68c9b7ac91d..6c15c2a626c 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx @@ -440,7 +440,7 @@ struct nucleiFlowTree { } nuclei::candidates.emplace_back(NucleusCandidate{ static_cast(track.globalIndex()), static_cast(track.collisionId()), (1 - 2 * iC) * mTrackParCov.getPt(), mTrackParCov.getEta(), mTrackParCov.getPhi(), - correctedTpcInnerParam, beta, collision.posZ(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), track.tpcChi2NCl(), track.tofChi2(), + correctedTpcInnerParam, beta, collision.posZ(), collision.numContrib(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), track.tpcChi2NCl(), track.tofChi2(), nSigmaTPC, tofMasses, fillTree, fillDCAHist, correctPV, isSecondary, fromWeakDecay, flag, track.tpcNClsFindable(), static_cast(track.tpcNClsCrossedRows()), track.itsClusterMap(), static_cast(track.tpcNClsFound()), static_cast(track.tpcNClsShared()), static_cast(track.itsNCls()), static_cast(track.itsClusterSizes())}); } @@ -456,7 +456,7 @@ struct nucleiFlowTree { } fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, 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); + nucleiTable(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); } for (auto& c : nuclei::candidates_flow) { nucleiTableFlow(c.centFV0A, c.centFT0M, c.centFT0A, c.centFT0C, c.psiFT0A, c.psiFT0C, c.psiTPC, c.psiTPCl, c.psiTPCr, c.qFT0A, c.qFT0C, c.qTPC, c.qTPCl, c.qTPCr); @@ -473,7 +473,7 @@ struct nucleiFlowTree { } fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, 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); + nucleiTable(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); } for (auto& c : nuclei::candidates_flow) { nucleiTableFlow(c.centFV0A, c.centFT0M, c.centFT0A, c.centFT0C, c.psiFT0A, c.psiFT0C, c.psiTPC, c.psiTPCl, c.psiTPCr, c.qFT0A, c.qFT0C, c.qTPC, c.qTPCl, c.qTPCr); diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 205c0eda0a4..22945965595 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -19,52 +19,47 @@ // o2-analysis-pid-tof-base, o2-analysis-multiplicity-table, o2-analysis-event-selection // (to add flow: o2-analysis-qvector-table, o2-analysis-centrality-table) -#include -#include -#include -#include -#include - -#include "Math/Vector4D.h" - -#include "CCDB/BasicCCDBManager.h" +#include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGLF/DataModel/LFSlimNucleiTables.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Core/PID/PIDTOF.h" #include "Common/TableProducer/PID/pidTOFBase.h" -#include "Common/Core/EventPlaneHelper.h" -#include "Common/DataModel/Qvectors.h" -#include "Common/Core/RecoDecay.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsTPC/BetheBlochAleph.h" #include "DetectorsBase/GeometryManager.h" #include "DetectorsBase/Propagator.h" - -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" - +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" - #include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" -#include "PWGLF/DataModel/LFSlimNucleiTables.h" - +#include "Math/Vector4D.h" #include "TRandom3.h" +#include +#include +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -79,6 +74,7 @@ struct NucleusCandidate { float tpcInnerParam; float beta; float zVertex; + int nContrib; float DCAxy; float DCAz; float TPCsignal; @@ -793,7 +789,7 @@ struct nucleiSpectra { } nuclei::candidates.emplace_back(NucleusCandidate{ static_cast(track.globalIndex()), static_cast(track.collisionId()), (1 - 2 * iC) * mTrackParCov.getPt(), mTrackParCov.getEta(), mTrackParCov.getPhi(), - correctedTpcInnerParam, beta, collision.posZ(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), track.tpcChi2NCl(), track.tofChi2(), + correctedTpcInnerParam, beta, collision.posZ(), collision.numContrib(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), track.tpcChi2NCl(), track.tofChi2(), nSigmaTPC, tofMasses, fillTree, fillDCAHist, correctPV, isSecondary, fromWeakDecay, flag, track.tpcNClsFindable(), static_cast(track.tpcNClsCrossedRows()), track.itsClusterMap(), static_cast(track.tpcNClsFound()), static_cast(track.tpcNClsShared()), static_cast(track.itsNCls()), static_cast(track.itsClusterSizes())}); } @@ -814,7 +810,7 @@ struct nucleiSpectra { for (size_t i1{0}; i1 < nuclei::candidates.size(); ++i1) { auto& c1 = nuclei::candidates[i1]; if (c1.fillTree) { - nucleiTable(c1.pt, c1.eta, c1.phi, c1.tpcInnerParam, c1.beta, c1.zVertex, c1.DCAxy, c1.DCAz, c1.TPCsignal, c1.ITSchi2, c1.TPCchi2, c1.TOFchi2, c1.flags, c1.TPCfindableCls, c1.TPCcrossedRows, c1.ITSclsMap, c1.TPCnCls, c1.TPCnClsShared, c1.clusterSizesITS); + nucleiTable(c1.pt, c1.eta, c1.phi, c1.tpcInnerParam, c1.beta, c1.zVertex, c1.nContrib, c1.DCAxy, c1.DCAz, c1.TPCsignal, c1.ITSchi2, c1.TPCchi2, c1.TOFchi2, c1.flags, c1.TPCfindableCls, c1.TPCcrossedRows, c1.ITSclsMap, c1.TPCnCls, c1.TPCnClsShared, c1.clusterSizesITS); if (cfgFillPairTree) { for (size_t i2{i1 + 1}; i2 < nuclei::candidates.size(); ++i2) { auto& c2 = nuclei::candidates[i2]; @@ -849,7 +845,7 @@ struct nucleiSpectra { fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { if (c.fillTree) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, 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); + nucleiTable(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); } if (c.fillDCAHist) { for (int iS{0}; iS < nuclei::species; ++iS) { @@ -878,7 +874,7 @@ struct nucleiSpectra { fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { if (c.fillTree) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, 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); + nucleiTable(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); } if (c.fillDCAHist) { for (int iS{0}; iS < nuclei::species; ++iS) { @@ -971,7 +967,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.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); + 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); } int index{0}; @@ -1014,7 +1010,7 @@ struct nucleiSpectra { if (!isReconstructed[index] && (cfgTreeConfig->get(iS, 0u) || cfgTreeConfig->get(iS, 1u))) { float absDecL = computeAbsoDecL(particle); - nucleiTableMC(999., 999., 999., 0., 0., 999., 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); + 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); } break; } diff --git a/PWGLF/TableProducer/Nuspex/nucleiUtils.h b/PWGLF/TableProducer/Nuspex/nucleiUtils.h index 2a9a64bc4b2..29cd489768d 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiUtils.h +++ b/PWGLF/TableProducer/Nuspex/nucleiUtils.h @@ -29,6 +29,7 @@ struct NucleusCandidate { float tpcInnerParam; float beta; float zVertex; + int nContrib; float DCAxy; float DCAz; float TPCsignal; From a2279d5a790843388d961933791d30d8f08ac1fb Mon Sep 17 00:00:00 2001 From: aimeric-landou <46970521+aimeric-landou@users.noreply.github.com> Date: Thu, 12 Jun 2025 11:23:57 +0200 Subject: [PATCH 41/62] [PWGJE] trackEfficiency: use true track weight for numerator for fake tracks (#11493) --- PWGJE/Tasks/trackEfficiency.cxx | 86 ++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/PWGJE/Tasks/trackEfficiency.cxx b/PWGJE/Tasks/trackEfficiency.cxx index a591c32f958..87e37014ae7 100644 --- a/PWGJE/Tasks/trackEfficiency.cxx +++ b/PWGJE/Tasks/trackEfficiency.cxx @@ -82,6 +82,9 @@ struct TrackEfficiency { Configurable ptHatMin{"ptHatMin", 5, "min pT hat of collisions"}; Configurable ptHatMax{"ptHatMax", 300, "max pT hat of collisions"}; Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatMaxFractionMCD{"pTHatMaxFractionMCD", 999.0, "maximum fraction of hard scattering for reconstructed track acceptance in MC"}; + + Configurable useTrueTrackWeight{"useTrueTrackWeight", 1, "test configurable, to be removed"}; std::vector eventSelectionBits; int trackSelection = -1; @@ -110,6 +113,13 @@ struct TrackEfficiency { if (!(jetderiveddatautilities::selectTrack(track, trackSelection) && jetderiveddatautilities::selectTrackDcaZ(track, trackDcaZmax))) { continue; } + + float simPtRef = 10.; + float pTHat = simPtRef / (std::pow(weight, 1.0 / pTHatExponent)); + if (track.pt() > pTHatMaxFractionMCD * pTHat) { + continue; + } + registry.fill(HIST("h2_centrality_track_pt"), collision.centrality(), track.pt(), weight); registry.fill(HIST("h2_centrality_track_eta"), collision.centrality(), track.eta(), weight); registry.fill(HIST("h2_centrality_track_phi"), collision.centrality(), track.phi(), weight); @@ -164,8 +174,16 @@ struct TrackEfficiency { registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(1, "allTracksInSelColl"); registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(2, "trackSel"); registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(3, "hasMcParticle"); - registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(4, "mcPartIsPrimary"); - registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(5, "etaAcc"); // not actually applied here but it will give an idea of what will be done in the post processing + + if (doprocessEFficiencyPurity) { + registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(4, "mcPartIsPrimary"); + registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(5, "etaAcc"); // not actually applied here but it will give an idea of what will be done in the post processing + } + if (doprocessEFficiencyPurityWeighted) { + registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(4, "ptHatMaxFraction"); + registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(5, "mcPartIsPrimary"); + registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(6, "etaAcc"); // not actually applied here but it will give an idea of what will be done in the post processing + } AxisSpec ptAxisEff = {nBinsLowPt, 0., 10., "#it{p}_{T} (GeV/#it{c})"}; AxisSpec ptAxisHighEff = {18, 10., 100., "#it{p}_{T} (GeV/#it{c})"}; @@ -478,8 +496,9 @@ struct TrackEfficiency { } registry.fill(HIST("hMcCollCutsCounts"), 5.5); // at least one of the reconstructed collisions associated with this mcCollision is selected with regard to centrality - float eventWeight = mcCollision.weight(); - float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + float simPtRef = 10.; + float mcCollEventWeight = mcCollision.weight(); + float pTHat = simPtRef / (std::pow(mcCollEventWeight, 1.0 / pTHatExponent)); if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max return; } @@ -493,16 +512,16 @@ struct TrackEfficiency { } registry.fill(HIST("hMcPartCutsCounts"), 1.5); // isCharged - registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_mcpart_nonprimary"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_mcpart_nonprimary"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), mcCollEventWeight); if (checkPrimaryPart && !jMcParticle.isPhysicalPrimary()) { // global tracks should be mostly primaries continue; } registry.fill(HIST("hMcPartCutsCounts"), 2.5); // isPrimary - registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), mcCollEventWeight); - registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), mcCollEventWeight); if ((std::abs(jMcParticle.eta()) < trackEtaAcceptanceCountQA)) { // removed from actual cuts for now because all the histograms have an eta axis registry.fill(HIST("hMcPartCutsCounts"), 3.5); // etaAccept // not actually applied here but it will give an idea of what will be done in the post processing @@ -532,27 +551,36 @@ struct TrackEfficiency { registry.fill(HIST("hTrackCutsCounts"), 1.5); if (!track.has_mcParticle()) { - registry.fill(HIST("h3_track_pt_track_eta_track_phi_nonassociatedtrack"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_track_eta_track_phi_nonassociatedtrack"), track.pt(), track.eta(), track.phi(), mcCollEventWeight); // weight attribution here not trivial; I use the one of the current mcCollision, but track belongs to no collision; what should be its weight? could be a moot point but algo has complained about invalid index for mcParticle if I put th etrueTrackCollEventWeight before this cut - registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_nonassociatedtrack"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_nonassociatedtrack"), track.pt(), track.eta(), track.phi(), mcCollEventWeight); continue; } registry.fill(HIST("hTrackCutsCounts"), 2.5); + if (track.pt() > pTHatMaxFractionMCD * pTHat) { + continue; + } + registry.fill(HIST("hTrackCutsCounts"), 3.5); + + auto mcParticle = track.mcParticle_as(); + auto trueTrackMcCollision = mcParticle.mcCollision_as(); + float trueTrackCollEventWeight = useTrueTrackWeight ? trueTrackMcCollision.weight() : mcCollEventWeight; // test1 + auto jMcParticleFromTrack = track.mcParticle_as(); if (!jMcParticleFromTrack.isPhysicalPrimary()) { - registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_nonprimary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); - registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_nonprimary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); if (std::find(seenMcParticlesVector.begin(), seenMcParticlesVector.end(), jMcParticleFromTrack.globalIndex()) != seenMcParticlesVector.end()) { - registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_split_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_split_nonprimary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); - registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_nonprimary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); } else { seenMcParticlesVector.push_back(jMcParticleFromTrack.globalIndex()); } @@ -560,28 +588,28 @@ struct TrackEfficiency { continue; } - registry.fill(HIST("hTrackCutsCounts"), 3.5); + registry.fill(HIST("hTrackCutsCounts"), 4.5); - registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_primary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); - registry.fill(HIST("h2_particle_pt_track_pt_residual_associatedtrack_primary"), jMcParticleFromTrack.pt(), (jMcParticleFromTrack.pt() - track.pt()) / jMcParticleFromTrack.pt(), eventWeight); + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_primary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h2_particle_pt_track_pt_residual_associatedtrack_primary"), jMcParticleFromTrack.pt(), (jMcParticleFromTrack.pt() - track.pt()) / jMcParticleFromTrack.pt(), trueTrackCollEventWeight); - registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_primary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); - registry.fill(HIST("h2_particle_pt_high_track_pt_high_residual_associatedtrack_primary"), jMcParticleFromTrack.pt(), (jMcParticleFromTrack.pt() - track.pt()) / jMcParticleFromTrack.pt(), eventWeight); + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_primary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h2_particle_pt_high_track_pt_high_residual_associatedtrack_primary"), jMcParticleFromTrack.pt(), (jMcParticleFromTrack.pt() - track.pt()) / jMcParticleFromTrack.pt(), trueTrackCollEventWeight); if (std::find(seenMcParticlesVector.begin(), seenMcParticlesVector.end(), jMcParticleFromTrack.globalIndex()) != seenMcParticlesVector.end()) { - registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_split_primary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_split_primary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); - registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_primary"), track.pt(), track.eta(), track.phi(), eventWeight); - registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_primary"), track.pt(), track.eta(), track.phi(), trueTrackCollEventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), trueTrackCollEventWeight); } else { seenMcParticlesVector.push_back(jMcParticleFromTrack.globalIndex()); } if (std::abs(jMcParticleFromTrack.eta()) < trackEtaAcceptanceCountQA) { // not actually applied here but it will give an idea of what will be done in the post processing - registry.fill(HIST("hTrackCutsCounts"), 4.5); + registry.fill(HIST("hTrackCutsCounts"), 5.5); } } } From 708e160b5051e39b7773537ad59d48e4b87e954f Mon Sep 17 00:00:00 2001 From: Archita-Dash <91664849+Archita-Dash@users.noreply.github.com> Date: Thu, 12 Jun 2025 11:26:11 +0200 Subject: [PATCH 42/62] [PWGJE] removal of the redundant outlier cut from Data (#11534) --- PWGJE/Tasks/fullJetSpectra.cxx | 35 ++++++---------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/PWGJE/Tasks/fullJetSpectra.cxx b/PWGJE/Tasks/fullJetSpectra.cxx index 40e233f9a90..5ddcde82ffb 100644 --- a/PWGJE/Tasks/fullJetSpectra.cxx +++ b/PWGJE/Tasks/fullJetSpectra.cxx @@ -674,8 +674,6 @@ struct FullJetSpectra { void processJetsData(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { bool eventAccepted = false; - double weight = 1.0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); registry.fill(HIST("hDetcollisionCounter"), 0.5); // allDetColl if (std::fabs(collision.posZ()) > vertexZCut) { @@ -683,37 +681,24 @@ struct FullJetSpectra { } registry.fill(HIST("hDetcollisionCounter"), 1.5); // DetCollWithVertexZ - // outlier check: for every outlier jet, reject the whole event - for (auto const& jet : jets) { - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // for MCD jets only to remove outliers; setting pTHatMaxMCD = 1 improves purity - registry.fill(HIST("hDetcollisionCounter"), 2.5); // RejectedDetCollWithOutliers - return; - } - // this cut only to be used for calculating Jet Purity and not for Response Matrix - // this is mainly applied to remove all high weight jets causing big fluctuations - if (jet.pt() > 1 * pTHat) { - registry.fill(HIST("h_full_jet_pt_pTHatcut"), jet.pt(), weight); - } - } - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { - registry.fill(HIST("hDetcollisionCounter"), 3.5); // MBRejectedDetEvents + registry.fill(HIST("hDetcollisionCounter"), 2.5); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - registry.fill(HIST("hDetcollisionCounter"), 4.5); // EventsNotSatisfyingEventSelection + registry.fill(HIST("hDetcollisionCounter"), 3.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hDetcollisionCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hDetcollisionCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC eventAccepted = true; } } @@ -724,10 +709,10 @@ struct FullJetSpectra { fillRejectedJetHistograms(jet, 1.0); } } - registry.fill(HIST("hDetcollisionCounter"), 6.5); // AllRejectedDetEventsAfterEMCEventSelection + registry.fill(HIST("hDetcollisionCounter"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("hDetcollisionCounter"), 7.5); // EMCAcceptedDetColl + registry.fill(HIST("hDetcollisionCounter"), 6.5); // EMCAcceptedDetColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -1410,8 +1395,6 @@ struct FullJetSpectra { void processDataTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) { bool eventAccepted = false; - double weight = 1.0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); registry.fill(HIST("hCollisionsUnweighted"), 0.5); // allDetColl if (std::fabs(collision.posZ()) > vertexZCut) { @@ -1419,12 +1402,6 @@ struct FullJetSpectra { } registry.fill(HIST("hCollisionsUnweighted"), 1.5); // DetCollWithVertexZ - // for (auto const& track : tracks) { - if (pTHat < pTHatAbsoluteMin) { // Track outlier rejection: should this be for every track iteration or for every collision? - return; - } - // } - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { registry.fill(HIST("hCollisionsUnweighted"), 2.5); // MBRejectedDetEvents return; From a24963def74ec46c0a6dce0a5aa99c36dc1a44d8 Mon Sep 17 00:00:00 2001 From: ynishida-style Date: Thu, 12 Jun 2025 18:26:44 +0900 Subject: [PATCH 43/62] [PWGJE] improvement of the track selection in jetShape.cxx (#11546) --- PWGJE/Tasks/jetShape.cxx | 89 +++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/PWGJE/Tasks/jetShape.cxx b/PWGJE/Tasks/jetShape.cxx index d7e1f2f0557..3c2bfb4c03c 100644 --- a/PWGJE/Tasks/jetShape.cxx +++ b/PWGJE/Tasks/jetShape.cxx @@ -13,14 +13,10 @@ /// \author Yuto Nishida /// \brief Task for measuring the dependence of the jet shape function rho(r) on the distance r from the jet axis. -#include -#include -#include - -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/DataModel/Jet.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" @@ -28,13 +24,16 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGJE/Core/FastJetUtilities.h" -#include "PWGJE/Core/JetUtilities.h" -#include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "PWGJE/DataModel/Jet.h" - +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -61,6 +60,7 @@ struct JetShapeTask { {"ptSum", "ptSum", {HistType::kTH2F, {{14, 0, 0.7}, {300, 0, 300}}}}, {"ptSumBg1", "ptSumBg1", {HistType::kTH2F, {{14, 0, 0.7}, {300, 0, 300}}}}, {"ptSumBg2", "ptSumBg2", {HistType::kTH2F, {{14, 0, 0.7}, {300, 0, 300}}}}, + {"event/vertexz", ";Vtx_{z} (cm);Entries", {HistType::kTH1F, {{100, -20, 20}}}}, {"ptVsCentrality", "ptvscentrality", {HistType::kTH2F, {{100, 0, 100}, {300, 0, 300}}}}}}; Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; @@ -79,9 +79,13 @@ struct JetShapeTask { Configurable> distanceCategory{"distanceCategory", {0.00f, 0.05f, 0.10f, 0.15f, 0.20f, 0.25f, 0.30f, 0.35f, 0.40f, 0.45f, 0.50f, 0.55f, 0.60f, 0.65f, 0.70f}, "distance of category"}; // for ppi production - Configurable maxTpcNClsCrossedRows{"maxTpcNClsCrossedRows", 70, ""}; - Configurable maxDcaXY{"maxDcaXY", 0.2, ""}; - Configurable maxItsNCls{"maxItsNCls", 2, ""}; + Configurable etaTrUp{"etaTrUp", 0.7f, "maximum track eta"}; + Configurable dcaxyMax{"dcaxyMax", 2.0f, "mximum DCA xy"}; + Configurable chi2ItsMax{"chi2ItsMax", 15.0f, "its chi2 cut"}; + Configurable chi2TpcMax{"chi2TpcMax", 4.0f, "tpc chi2 cut"}; + Configurable nclItsMin{"nclItsMin", 2.0f, "its # of cluster cut"}; + Configurable nclTpcMin{"nclTpcMin", 100.0f, "tpc # if cluster cut"}; + Configurable nclcrossTpcMin{"nclcrossTpcMin", 70.0f, "tpc # of crossedRows cut"}; Configurable triggerMasks{"triggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; @@ -145,18 +149,10 @@ struct JetShapeTask { void processJetShape(soa::Filtered>::iterator const& collision, aod::JetTracks const& tracks, soa::Join const& jets) { - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - return; - } - std::vector ptDensity; - std::vector ptDensityBg1; - std::vector ptDensityBg2; - - ptDensity.reserve(distanceCategory->size() - 1); - ptDensityBg1.reserve(distanceCategory->size() - 1); - ptDensityBg2.reserve(distanceCategory->size() - 1); - // std::cout << collision.centrality() << std::endl; + std::vector ptDensity(distanceCategory->size() - 1, 0.f); + std::vector ptDensityBg1(distanceCategory->size() - 1, 0.f); + std::vector ptDensityBg2(distanceCategory->size() - 1, 0.f); for (auto const& jet : jets) { if (!isAcceptedJet(jet)) { @@ -178,12 +174,10 @@ struct JetShapeTask { registry.fill(HIST("ptVsCentrality"), collision.centrality(), track.pt()); // calculate compornents of jetshapefunction rho(r) - std::vector trackPtSum; - std::vector trackPtSumBg1; - std::vector trackPtSumBg2; - trackPtSum.reserve(distanceCategory->size() - 1); - trackPtSumBg1.reserve(distanceCategory->size() - 1); - trackPtSumBg2.reserve(distanceCategory->size() - 1); + std::vector trackPtSum(distanceCategory->size() - 1, 0.f); + std::vector trackPtSumBg1(distanceCategory->size() - 1, 0.f); + std::vector trackPtSumBg2(distanceCategory->size() - 1, 0.f); + float phiBg1 = jet.phi() + (o2::constants::math::PIHalf); float phiBg2 = jet.phi() - (o2::constants::math::PIHalf); @@ -197,11 +191,11 @@ struct JetShapeTask { float distanceBg2 = std::sqrt(deltaEta * deltaEta + deltaPhiBg2 * deltaPhiBg2); for (size_t i = 0; i < distanceCategory->size() - 1; i++) { - if (distance < distanceCategory->at(i + 1)) + if (distanceCategory->at(i) <= distance && distance < distanceCategory->at(i + 1)) trackPtSum[i] += track.pt(); - if (distanceBg1 < distanceCategory->at(i + 1)) + if (distanceCategory->at(i) <= distanceBg1 && distanceBg1 < distanceCategory->at(i + 1)) trackPtSumBg1[i] += track.pt(); - if (distanceBg2 < distanceCategory->at(i + 1)) + if (distanceCategory->at(i) <= distanceBg2 && distanceBg2 < distanceCategory->at(i + 1)) trackPtSumBg2[i] += track.pt(); } @@ -221,9 +215,9 @@ struct JetShapeTask { for (size_t i = 0; i < distanceCategory->size() - 1; i++) { double jetX = (distanceCategory->at(i + 1) - distanceCategory->at(i)) * i + (distanceCategory->at(i + 1) - distanceCategory->at(i)) / 2; - double jetShapeFunction = ptDensity[i + 1]; - double jetShapeFunctionBg1 = ptDensityBg1[i + 1]; - double jetShapeFunctionBg2 = ptDensityBg2[i + 1]; + double jetShapeFunction = ptDensity[i]; + double jetShapeFunctionBg1 = ptDensityBg1[i]; + double jetShapeFunctionBg2 = ptDensityBg2[i]; registry.fill(HIST("ptSum"), jetX, jetShapeFunction); registry.fill(HIST("ptSumBg1"), jetX, jetShapeFunctionBg1); registry.fill(HIST("ptSumBg2"), jetX, jetShapeFunctionBg2); @@ -238,6 +232,8 @@ struct JetShapeTask { return; } + registry.fill(HIST("event/vertexz"), collision.posZ()); + for (auto const& jet : jets) { if (!isAcceptedJet(jet)) { continue; @@ -245,13 +241,20 @@ struct JetShapeTask { // tracks conditions for (const auto& track : tracks) { - if (track.tpcNClsCrossedRows() < maxTpcNClsCrossedRows) + if (std::abs(track.eta()) > etaTrUp) continue; - if (std::fabs(track.dcaXY()) > maxDcaXY) + if (track.tpcNClsCrossedRows() < nclcrossTpcMin) continue; - if (track.itsNCls() < maxItsNCls) { + if (std::abs(track.dcaXY()) > dcaxyMax) + continue; + if (track.itsChi2NCl() > chi2ItsMax) + continue; + if (track.tpcChi2NCl() > chi2TpcMax) + continue; + if (track.tpcNClsFound() < nclTpcMin) + continue; + if (track.itsNCls() < nclItsMin) continue; - } // PID check registry.fill(HIST("tpcDedx"), track.pt(), track.tpcSignal()); From 33ca9017489a3b72ad05161f449aa362533b6816 Mon Sep 17 00:00:00 2001 From: spucillo <93769017+spucillo@users.noreply.github.com> Date: Thu, 12 Jun 2025 12:01:30 +0200 Subject: [PATCH 44/62] [PWGLF] Fix the reweighting for cascades in MC + temporarily disabling histograms for secondary lambdas (#11559) Co-authored-by: ALICE Action Bot --- PWGLF/Tasks/Strangeness/strangenessInJets.cxx | 408 ++++++++++++------ 1 file changed, 267 insertions(+), 141 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangenessInJets.cxx b/PWGLF/Tasks/Strangeness/strangenessInJets.cxx index b7e65345661..3cb2ac41f2b 100644 --- a/PWGLF/Tasks/Strangeness/strangenessInJets.cxx +++ b/PWGLF/Tasks/Strangeness/strangenessInJets.cxx @@ -12,7 +12,7 @@ /// \file strangenessInJets.cxx /// /// \brief task for analysis of strangeness in jets -/// \author Alberto Caliva (alberto.caliva@cern.ch), Francesca Ercolessi (francesca.ercolessi@cern.ch), Nicolò Jacazio (nicolo.jacazio@cern.ch) +/// \author Alberto Caliva (alberto.caliva@cern.ch), Francesca Ercolessi (francesca.ercolessi@cern.ch), Nicolò Jacazio (nicolo.jacazio@cern.ch), Sara Pucillo (sara.pucillo@cern.ch) /// \since May 22, 2024 #include @@ -156,9 +156,13 @@ struct StrangenessInJets { Configurable histoNameWeightAntilambdaJet{"histoNameWeightAntilambdaJet", "", "reweighting histogram: antilambda in jet"}; Configurable histoNameWeightAntilambdaUe{"histoNameWeightAntilambdaUe", "", "reweighting histogram: antilambda in ue"}; Configurable histoNameWeightsXiInJet{"histoNameWeightsXiInJet", "", "reweighting histogram: xi in jet"}; - Configurable histoNameWeightsXiInUe{"histoNameWeightsXiInUe", "", "reweighting histogram: xi in ue"}; + Configurable histoNameWeightsXiUe{"histoNameWeightsXiUe", "", "reweighting histogram: xi in ue"}; Configurable histoNameWeightsAntiXiInJet{"histoNameWeightsAntiXiInJet", "", "reweighting histogram: antixi in jet"}; - Configurable histoNameWeightsAntiXiInUe{"histoNameWeightsAntiXiInUe", "", "reweighting histogram: antixi in ue"}; + Configurable histoNameWeightsAntiXiUe{"histoNameWeightsAntiXiUe", "", "reweighting histogram: antixi in ue"}; + Configurable histoNameWeightsOmegaInJet{"histoNameWeightsOmegaInJet", "", "reweighting histogram: omega in jet"}; + Configurable histoNameWeightsOmegaUe{"histoNameWeightsOmegaUe", "", "reweighting histogram: omega in ue"}; + Configurable histoNameWeightsAntiOmegaInJet{"histoNameWeightsAntiOmegaInJet", "", "reweighting histogram: antiomega in jet"}; + Configurable histoNameWeightsAntiOmegaUe{"histoNameWeightsAntiOmegaUe", "", "reweighting histogram: antiomega in ue"}; // Two-dimensional weights TH2F* twodWeightsPiplusJet = nullptr; @@ -171,10 +175,14 @@ struct StrangenessInJets { TH2F* twodWeightsLambdaUe; TH2F* twodWeightsAntilambdaJet; TH2F* twodWeightsAntilambdaUe; - TH1F* weightsXiInJet; - TH1F* weightsXiInUe; - TH1F* weightsAntiXiInJet; - TH1F* weightsAntiXiInUe; + TH2F* twodWeightsXiInJet; + TH2F* twodWeightsXiUe; + TH2F* twodWeightsAntiXiInJet; + TH2F* twodWeightsAntiXiUe; + TH2F* twodWeightsOmegaInJet; + TH2F* twodWeightsOmegaUe; + TH2F* twodWeightsAntiOmegaInJet; + TH2F* twodWeightsAntiOmegaUe; // List of Particles enum Option { KZeroLambda, @@ -214,10 +222,14 @@ struct StrangenessInJets { twodWeightsLambdaUe = nullptr; twodWeightsAntilambdaJet = nullptr; twodWeightsAntilambdaUe = nullptr; - weightsXiInJet = nullptr; - weightsXiInUe = nullptr; - weightsAntiXiInJet = nullptr; - weightsAntiXiInUe = nullptr; + twodWeightsXiInJet = nullptr; + twodWeightsXiUe = nullptr; + twodWeightsAntiXiInJet = nullptr; + twodWeightsAntiXiUe = nullptr; + twodWeightsOmegaInJet = nullptr; + twodWeightsOmegaUe = nullptr; + twodWeightsAntiOmegaInJet = nullptr; + twodWeightsAntiOmegaUe = nullptr; } // Event Counters @@ -241,8 +253,8 @@ struct StrangenessInJets { registryQC.add("sumPtUE", "sumPtUE", HistType::kTH1F, {{500, 0, 50, "#it{p}_{T} (GeV/#it{c})"}}); registryQC.add("nJets_found", "nJets_found", HistType::kTH1F, {{10, 0, 10, "#it{n}_{Jet}"}}); registryQC.add("nJets_selected", "nJets_selected", HistType::kTH1F, {{10, 0, 10, "#it{n}_{Jet}"}}); - registryQC.add("dcaxy_vs_pt", "dcaxy_vs_pt", HistType::kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{xy} (cm)"}}); - registryQC.add("dcaz_vs_pt", "dcaz_vs_pt", HistType::kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{z} (cm)"}}); + // registryQC.add("dcaxy_vs_pt", "dcaxy_vs_pt", HistType::kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{xy} (cm)"}}); + // registryQC.add("dcaz_vs_pt", "dcaz_vs_pt", HistType::kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{z} (cm)"}}); registryQC.add("jet_jet_overlaps", "jet_jet_overlaps", HistType::kTH2F, {{20, 0.0, 20.0, "#it{n}_{jet}"}, {200, 0.0, 200.0, "#it{n}_{overlaps}"}}); registryQC.add("jet_ue_overlaps", "jet_ue_overlaps", HistType::kTH2F, {{20, 0.0, 20.0, "#it{n}_{jet}"}, {200, 0.0, 200.0, "#it{n}_{overlaps}"}}); registryQC.add("ue_ue_overlaps", "ue_ue_overlaps", HistType::kTH2F, {{20, 0.0, 20.0, "#it{n}_{jet}"}, {200, 0.0, 200.0, "#it{n}_{overlaps}"}}); @@ -344,10 +356,14 @@ struct StrangenessInJets { registryMC.add("Lambda_generated_ue", "Lambda_generated_ue", HistType::kTH2F, {multBinning, ptAxis}); registryMC.add("AntiLambda_generated_jet", "AntiLambda_generated_jet", HistType::kTH2F, {multBinning, ptAxis}); registryMC.add("AntiLambda_generated_ue", "AntiLambda_generated_ue", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("XiPos_generated", "XiPos_generated", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("XiNeg_generated", "XiNeg_generated", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("OmegaPos_generated", "OmegaPos_generated", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("OmegaNeg_generated", "OmegaNeg_generated", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiPos_generated_jet", "XiPos_generated_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiPos_generated_ue", "XiPos_generated_ue", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiNeg_generated_jet", "XiNeg_generated_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiNeg_generated_ue", "XiNeg_generated_ue", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaPos_generated_jet", "OmegaPos_generated_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaPos_generated_ue", "OmegaPos_generated_ue", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaNeg_generated_jet", "OmegaNeg_generated_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaNeg_generated_ue", "OmegaNeg_generated_ue", HistType::kTH2F, {multBinning, ptAxis}); // Histograms for efficiency (reconstructed) registryMC.add("K0s_reconstructed_jet", "K0s_reconstructed_jet", HistType::kTH2F, {multBinning, ptAxis}); @@ -356,21 +372,30 @@ struct StrangenessInJets { registryMC.add("Lambda_reconstructed_ue", "Lambda_reconstructed_ue", HistType::kTH2F, {multBinning, ptAxis}); registryMC.add("AntiLambda_reconstructed_jet", "AntiLambda_reconstructed_jet", HistType::kTH2F, {multBinning, ptAxis}); registryMC.add("AntiLambda_reconstructed_ue", "AntiLambda_reconstructed_ue", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("XiPos_reconstructed", "XiPos_reconstructed", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("XiNeg_reconstructed", "XiNeg_reconstructed", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("OmegaPos_reconstructed", "OmegaPos_reconstructed", HistType::kTH2F, {multBinning, ptAxis}); - registryMC.add("OmegaNeg_reconstructed", "OmegaNeg_reconstructed", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiPos_reconstructed_jet", "XiPos_reconstructed_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiPos_reconstructed_ue", "XiPos_reconstructed_ue", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiNeg_reconstructed_jet", "XiNeg_reconstructed_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiNeg_reconstructed_ue", "XiNeg_reconstructed_ue", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaPos_reconstructed_jet", "OmegaPos_reconstructed_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaPos_reconstructed_ue", "OmegaPos_reconstructed_ue", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaNeg_reconstructed_jet", "OmegaNeg_reconstructed_jet", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaNeg_reconstructed_ue", "OmegaNeg_reconstructed_ue", HistType::kTH2F, {multBinning, ptAxis}); // Histograms for secondary hadrons registryMC.add("K0s_reconstructed_incl", "K0s_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); registryMC.add("Lambda_reconstructed_incl", "Lambda_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); registryMC.add("AntiLambda_reconstructed_incl", "AntiLambda_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiPos_reconstructed_incl", "XiPos_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("XiNeg_reconstructed_incl", "XiNeg_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaPos_reconstructed_incl", "OmegaPos_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); + registryMC.add("OmegaNeg_reconstructed_incl", "OmegaNeg_reconstructed_incl", HistType::kTH2F, {multBinning, ptAxis}); + // Histograms for secondary lambda in jet and UE - registryMC.add("Secondary_Lambda_InJet", "Secondary_Lambda_InJet", HistType::kTH1F, {ptAxis}); - registryMC.add("Secondary_Lambda_InUe", "Secondary_Lambda_InUe", HistType::kTH1F, {ptAxis}); - registryMC.add("Secondary_AntiLambda_InJet", "Secondary_AntiLambda_InJet", HistType::kTH1F, {ptAxis}); - registryMC.add("Secondary_AntiLambda_InUe", "Secondary_AntiLambda_InUe", HistType::kTH1F, {ptAxis}); + // registryMC.add("Secondary_Lambda_InJet", "Secondary_Lambda_InJet", HistType::kTH1F, {ptAxis}); + // registryMC.add("Secondary_Lambda_Ue", "Secondary_Lambda_Ue", HistType::kTH1F, {ptAxis}); + // registryMC.add("Secondary_AntiLambda_InJet", "Secondary_AntiLambda_InJet", HistType::kTH1F, {ptAxis}); + // registryMC.add("Secondary_AntiLambda_Ue", "Secondary_AntiLambda_Ue", HistType::kTH1F, {ptAxis}); // Histograms for 2d reweighting (pion) registryMC.add("mc_pi_plus_eta_pt/jet", "", HistType::kTH2F, {ptAxisPi, etaAxis}); @@ -399,20 +424,20 @@ struct StrangenessInJets { registryMC.add("AntiLambda_eta_pt_pythia", "AntiLambda_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); // Histograms for 2d reweighting (Xi) - registryMC.add("Xi_eta_pt_jet", "Xi_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("Xi_eta_pt_ue", "Xi_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("Xi_eta_pt_pythia", "Xi_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("AntiXi_eta_pt_jet", "AntiXi_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("AntiXi_eta_pt_ue", "AntiXi_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("AntiXi_eta_pt_pythia", "AntiXi_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("XiNeg_eta_pt_jet", "Xi_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("XiNeg_eta_pt_ue", "Xi_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("XiNeg_eta_pt_pythia", "Xi_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("XiPos_eta_pt_jet", "AntiXi_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("XiPos_eta_pt_ue", "AntiXi_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("XiPos_eta_pt_pythia", "AntiXi_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); // Histograms for 2d reweighting (Omega) - registryMC.add("Omega_eta_pt_jet", "Omega_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("Omega_eta_pt_ue", "Omega_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("Omega_eta_pt_pythia", "Omega_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("AntiOmega_eta_pt_jet", "AntiOmega_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("AntiOmega_eta_pt_ue", "AntiOmega_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); - registryMC.add("AntiOmega_eta_pt_pythia", "AntiOmega_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("OmegaNeg_eta_pt_jet", "Omega_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("OmegaNeg_eta_pt_ue", "Omega_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("OmegaNeg_eta_pt_pythia", "Omega_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("OmegaPos_eta_pt_jet", "AntiOmega_eta_pt_jet", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("OmegaPos_eta_pt_ue", "AntiOmega_eta_pt_ue", HistType::kTH2F, {ptAxis, etaAxis}); + registryMC.add("OmegaPos_eta_pt_pythia", "AntiOmega_eta_pt_pythia", HistType::kTH2F, {ptAxis, etaAxis}); // Histograms for efficiency (pions) registryMC.add("mc_pi_plus/in_jet/gen", "", HistType::kTH2F, {multBinning, ptAxisPi}); @@ -1017,25 +1042,17 @@ struct StrangenessInJets { get2DWeightHisto(histoNameWeightAntilambdaJet, twodWeightsAntilambdaJet); get2DWeightHisto(histoNameWeightAntilambdaUe, twodWeightsAntilambdaUe); - auto get1DWeightHisto = [&](Configurable name, TH1F*& histo) { - LOG(info) << "Looking for 1D weight histogram '" << name.value << "' for " << name.name; - if (name.value == "") { - LOG(info) << " -> Skipping"; - return; - } - histo = static_cast(l->FindObject(name.value.c_str())); - if (!histo) { - LOG(error) << "Could not open histogram '" << name.value << "'"; - return; - } - LOG(info) << "Opened histogram " << histo->ClassName() << " " << histo->GetName(); - }; - - // Secondary Lambda - get1DWeightHisto(histoNameWeightsXiInJet, weightsXiInJet); - get1DWeightHisto(histoNameWeightsXiInUe, weightsXiInUe); - get1DWeightHisto(histoNameWeightsAntiXiInJet, weightsAntiXiInJet); - get1DWeightHisto(histoNameWeightsAntiXiInUe, weightsAntiXiInUe); + // Xi + get2DWeightHisto(histoNameWeightsXiInJet, twodWeightsXiInJet); + get2DWeightHisto(histoNameWeightsXiUe, twodWeightsXiUe); + get2DWeightHisto(histoNameWeightsAntiXiInJet, twodWeightsAntiXiInJet); + get2DWeightHisto(histoNameWeightsAntiXiUe, twodWeightsAntiXiUe); + + // Omega + get2DWeightHisto(histoNameWeightsOmegaInJet, twodWeightsOmegaInJet); + get2DWeightHisto(histoNameWeightsOmegaUe, twodWeightsOmegaUe); + get2DWeightHisto(histoNameWeightsAntiOmegaInJet, twodWeightsAntiOmegaInJet); + get2DWeightHisto(histoNameWeightsAntiOmegaUe, twodWeightsAntiOmegaUe); } void processData(SelCollisions::iterator const& collision, @@ -1271,22 +1288,22 @@ struct StrangenessInJets { } bool isInJet = false; - bool isInUe = false; + bool isUe = false; if (deltaRjet < rJet) isInJet = true; if (deltaRue1 < rJet || deltaRue2 < rJet) - isInUe = true; + isUe = true; if (isHighPurityPion(track, nsigmaTPC, nsigmaTOF)) { if (track.sign() > 0) { if (isInJet) registryData.fill(HIST("piplus_dcaxy_in_jet"), multiplicity, track.pt(), track.dcaXY()); - if (isInUe) + if (isUe) registryData.fill(HIST("piplus_dcaxy_in_ue"), multiplicity, track.pt(), track.dcaXY()); } else { if (isInJet) registryData.fill(HIST("piminus_dcaxy_in_jet"), multiplicity, track.pt(), track.dcaXY()); - if (isInUe) + if (isUe) registryData.fill(HIST("piminus_dcaxy_in_ue"), multiplicity, track.pt(), track.dcaXY()); } } @@ -1301,7 +1318,7 @@ struct StrangenessInJets { if (isInJet) { registryData.fill(HIST("piplus_tpc_in_jet"), multiplicity, track.pt(), nsigmaTPC); } - if (isInUe) { + if (isUe) { registryData.fill(HIST("piplus_tpc_in_ue"), multiplicity, track.pt(), nsigmaTPC); } break; @@ -1309,7 +1326,7 @@ struct StrangenessInJets { if (isInJet) { registryData.fill(HIST("piminus_tpc_in_jet"), multiplicity, track.pt(), nsigmaTPC); } - if (isInUe) { + if (isUe) { registryData.fill(HIST("piminus_tpc_in_ue"), multiplicity, track.pt(), nsigmaTPC); } break; @@ -1327,7 +1344,7 @@ struct StrangenessInJets { if (isInJet) { registryData.fill(HIST("piplus_tof_in_jet"), multiplicity, track.pt(), nsigmaTOF); } - if (isInUe) { + if (isUe) { registryData.fill(HIST("piplus_tof_in_ue"), multiplicity, track.pt(), nsigmaTOF); } break; @@ -1335,7 +1352,7 @@ struct StrangenessInJets { if (isInJet) { registryData.fill(HIST("piminus_tof_in_jet"), multiplicity, track.pt(), nsigmaTOF); } - if (isInUe) { + if (isUe) { registryData.fill(HIST("piminus_tof_in_ue"), multiplicity, track.pt(), nsigmaTOF); } break; @@ -1504,66 +1521,66 @@ struct StrangenessInJets { TVector3 momentumV0 = momentumPos + momentumNeg; // Feed-down for lambda - if (passedLambdaSelection(v0, pos, neg) && pdgParent == kLambda0) { - if (!isPhysPrim) { - double wSecLambdaInJet(1.0); - double wSecLambdaInUe(1.0); - int idMother = posParticle.mothersIds()[0]; - const auto& mother = mcParticles.iteratorAt(idMother); - int idGrandMother = mother.mothersIds()[0]; - const auto& grandMother = mcParticles.iteratorAt(idGrandMother); - switch (grandMother.pdgCode()) { - case kXiMinus: - case kXiPlusBar: - // case 3322: - // case -3322: - if (weightsXiInJet) { - int ibinXiInJet = weightsXiInJet->GetXaxis()->FindBin(grandMother.pt()); - wSecLambdaInJet = weightsXiInJet->GetBinContent(ibinXiInJet); - } - if (weightsXiInUe) { - int ibinXiInUe = weightsXiInUe->GetXaxis()->FindBin(grandMother.pt()); - wSecLambdaInUe = weightsXiInUe->GetBinContent(ibinXiInUe); - } - break; - default: - break; - } - registryMC.fill(HIST("Secondary_Lambda_InJet"), v0.pt(), wSecLambdaInJet); - registryMC.fill(HIST("Secondary_Lambda_InUe"), v0.pt(), wSecLambdaInUe); - } - } + // if (passedLambdaSelection(v0, pos, neg) && pdgParent == kLambda0) { + // if (!isPhysPrim) { + // double wSecLambdaInJet(1.0); + // double wSecLambdaUe(1.0); + // int idMother = posParticle.mothersIds()[0]; + // const auto& mother = mcParticles.iteratorAt(idMother); + // int idGrandMother = mother.mothersIds()[0]; + // const auto& grandMother = mcParticles.iteratorAt(idGrandMother); + // switch (grandMother.pdgCode()) { + // case kXiMinus: + // case kXiPlusBar: + // // case 3322: + // // case -3322: + // if (weightsXiInJet) { + // int ibinXiInJet = weightsXiInJet->GetXaxis()->FindBin(grandMother.pt()); + // wSecLambdaInJet = weightsXiInJet->GetBinContent(ibinXiInJet); + // } + // if (weightsXiUe) { + // int ibinXiUe = weightsXiUe->GetXaxis()->FindBin(grandMother.pt()); + // wSecLambdaUe = weightsXiUe->GetBinContent(ibinXiUe); + // } + // break; + // default: + // break; + // } + // registryMC.fill(HIST("Secondary_Lambda_InJet"), v0.pt(), wSecLambdaInJet); + // registryMC.fill(HIST("Secondary_Lambda_Ue"), v0.pt(), wSecLambdaUe); + // } + //} // Feed-down for antilambda - if (passedAntiLambdaSelection(v0, pos, neg) && pdgParent == kLambda0Bar) { - if (!isPhysPrim) { - double wSecAntiLambdaInJet(1.0); - double wSecAntiLambdaInUe(1.0); - int idMother = posParticle.mothersIds()[0]; - const auto& mother = mcParticles.iteratorAt(idMother); - int idGrandMother = mother.mothersIds()[0]; - const auto& grandMother = mcParticles.iteratorAt(idGrandMother); - switch (grandMother.pdgCode()) { - case kXiMinus: - case kXiPlusBar: - // case 3322: - // case -3322: - if (weightsAntiXiInJet) { - int ibinAntiXiInJet = weightsAntiXiInJet->GetXaxis()->FindBin(grandMother.pt()); - wSecAntiLambdaInJet = weightsAntiXiInJet->GetBinContent(ibinAntiXiInJet); - } - if (weightsAntiXiInUe) { - int ibinAntiXiInUe = weightsAntiXiInUe->GetXaxis()->FindBin(grandMother.pt()); - wSecAntiLambdaInUe = weightsAntiXiInUe->GetBinContent(ibinAntiXiInUe); - } - break; - default: - break; - } - registryMC.fill(HIST("Secondary_AntiLambda_InJet"), v0.pt(), wSecAntiLambdaInJet); - registryMC.fill(HIST("Secondary_AntiLambda_InUe"), v0.pt(), wSecAntiLambdaInUe); - } - } + // if (passedAntiLambdaSelection(v0, pos, neg) && pdgParent == kLambda0Bar) { + // if (!isPhysPrim) { + // double wSecAntiLambdaInJet(1.0); + // double wSecAntiLambdaUe(1.0); + // int idMother = posParticle.mothersIds()[0]; + // const auto& mother = mcParticles.iteratorAt(idMother); + // int idGrandMother = mother.mothersIds()[0]; + // const auto& grandMother = mcParticles.iteratorAt(idGrandMother); + // switch (grandMother.pdgCode()) { + // case kXiMinus: + // case kXiPlusBar: + // // case 3322: + // // case -3322: + // if (weightsAntiXiInJet) { + // int ibinAntiXiInJet = weightsAntiXiInJet->GetXaxis()->FindBin(grandMother.pt()); + // wSecAntiLambdaInJet = weightsAntiXiInJet->GetBinContent(ibinAntiXiInJet); + // } + // if (weightsAntiXiUe) { + // int ibinAntiXiUe = weightsAntiXiUe->GetXaxis()->FindBin(grandMother.pt()); + // wSecAntiLambdaUe = weightsAntiXiUe->GetBinContent(ibinAntiXiUe); + // } + // break; + // default: + // break; + // } + // registryMC.fill(HIST("Secondary_AntiLambda_InJet"), v0.pt(), wSecAntiLambdaInJet); + // registryMC.fill(HIST("Secondary_AntiLambda_Ue"), v0.pt(), wSecAntiLambdaUe); + // } + //} if (passedK0ShortSelection(v0, pos, neg) && pdgParent == kK0Short) { registryMC.fill(HIST("K0s_reconstructed_incl"), multiplicity, v0.pt()); @@ -1645,6 +1662,7 @@ struct StrangenessInJets { continue; int pdgParent(0); + bool isPhysPrim = false; for (const auto& particleMotherOfNeg : negParticle.mothers_as()) { for (const auto& particleMotherOfPos : posParticle.mothers_as()) { for (const auto& particleMotherOfBach : bachParticle.mothers_as()) { @@ -1656,27 +1674,95 @@ struct StrangenessInJets { continue; pdgParent = particleMotherOfBach.pdgCode(); + isPhysPrim = particleMotherOfBach.isPhysicalPrimary(); } } } if (pdgParent == 0) continue; + // Generated Momentum of casc + TVector3 momentumPos(posParticle.px(), posParticle.py(), posParticle.pz()); + TVector3 momentumNeg(negParticle.px(), negParticle.py(), negParticle.pz()); + TVector3 momentumBach(bachParticle.px(), bachParticle.py(), bachParticle.pz()); + TVector3 momentumV0 = momentumPos + momentumNeg; + TVector3 momentumCasc = momentumV0 + momentumBach; + + // Xi+ + if (passedXiSelection(casc, pos, neg, bach, collision) && pdgParent == kXiPlusBar) { + registryMC.fill(HIST("XiPos_reconstructed_incl"), multiplicity, casc.pt()); + } + // Xi- + if (passedXiSelection(casc, pos, neg, bach, collision) && pdgParent == kXiMinus) { + registryMC.fill(HIST("XiNeg_reconstructed_incl"), multiplicity, casc.pt()); + } + // Omega+ + if (passedOmegaSelection(casc, pos, neg, bach, collision) && pdgParent == kOmegaPlusBar) { + registryMC.fill(HIST("OmegaPos_reconstructed_incl"), multiplicity, casc.pt()); + } + // Omega- + if (passedOmegaSelection(casc, pos, neg, bach, collision) && pdgParent == kOmegaMinus) { + registryMC.fill(HIST("OmegaNeg_reconstructed_incl"), multiplicity, casc.pt()); + } + + if (!isPhysPrim) + continue; + + double wXiPosJet(1.0), wXiPosUe(1.0), wXiNegJet(1.0), wXiNegUe(1.0), wOmegaPosJet(1.0), wOmegaPosUe(1.0), wOmegaNegJet(1.0), wOmegaNegUe(1.0); + if (applyReweighting) { + int ix = twodWeightsXiInJet->GetXaxis()->FindBin(momentumCasc.Pt()); + int iy = twodWeightsXiInJet->GetYaxis()->FindBin(momentumCasc.Eta()); + wXiPosJet = twodWeightsAntiXiInJet->GetBinContent(ix, iy); + wXiPosUe = twodWeightsAntiXiUe->GetBinContent(ix, iy); + wXiNegJet = twodWeightsXiInJet->GetBinContent(ix, iy); + wXiNegUe = twodWeightsXiUe->GetBinContent(ix, iy); + wOmegaPosJet = twodWeightsAntiOmegaInJet->GetBinContent(ix, iy); + wOmegaPosUe = twodWeightsAntiOmegaUe->GetBinContent(ix, iy); + wOmegaNegJet = twodWeightsOmegaInJet->GetBinContent(ix, iy); + wOmegaNegUe = twodWeightsOmegaUe->GetBinContent(ix, iy); + + // protections + if (ix == 0 || ix > twodWeightsXiInJet->GetNbinsX()) { + wXiPosJet = 1.0; + wXiPosUe = 1.0; + wXiNegJet = 1.0; + wXiNegUe = 1.0; + wOmegaPosJet = 1.0; + wOmegaPosUe = 1.0; + wOmegaNegJet = 1.0; + wOmegaNegUe = 1.0; + } + if (iy == 0 || iy > twodWeightsXiInJet->GetNbinsY()) { + wXiPosJet = 1.0; + wXiPosUe = 1.0; + wXiNegJet = 1.0; + wXiNegUe = 1.0; + wOmegaPosJet = 1.0; + wOmegaPosUe = 1.0; + wOmegaNegJet = 1.0; + wOmegaNegUe = 1.0; + } + } + // Xi+ if (passedXiSelection(casc, pos, neg, bach, collision) && pdgParent == kXiPlusBar) { - registryMC.fill(HIST("XiPos_reconstructed"), multiplicity, casc.pt()); + registryMC.fill(HIST("XiPos_reconstructed_jet"), multiplicity, casc.pt(), wXiPosJet); + registryMC.fill(HIST("XiPos_reconstructed_ue"), multiplicity, casc.pt(), wXiPosUe); } // Xi- if (passedXiSelection(casc, pos, neg, bach, collision) && pdgParent == kXiMinus) { - registryMC.fill(HIST("XiNeg_reconstructed"), multiplicity, casc.pt()); + registryMC.fill(HIST("XiNeg_reconstructed_jet"), multiplicity, casc.pt(), wXiNegJet); + registryMC.fill(HIST("XiNeg_reconstructed_ue"), multiplicity, casc.pt(), wXiNegUe); } // Omega+ if (passedOmegaSelection(casc, pos, neg, bach, collision) && pdgParent == kOmegaPlusBar) { - registryMC.fill(HIST("OmegaPos_reconstructed"), multiplicity, casc.pt()); + registryMC.fill(HIST("OmegaPos_reconstructed_jet"), multiplicity, casc.pt(), wOmegaPosJet); + registryMC.fill(HIST("OmegaPos_reconstructed_ue"), multiplicity, casc.pt(), wOmegaPosUe); } // Omega- if (passedOmegaSelection(casc, pos, neg, bach, collision) && pdgParent == kOmegaMinus) { - registryMC.fill(HIST("OmegaNeg_reconstructed"), multiplicity, casc.pt()); + registryMC.fill(HIST("OmegaNeg_reconstructed_jet"), multiplicity, casc.pt(), wOmegaNegJet); + registryMC.fill(HIST("OmegaNeg_reconstructed_ue"), multiplicity, casc.pt(), wOmegaNegUe); } } @@ -1854,6 +1940,42 @@ struct StrangenessInJets { } } + double wXiPosJet(1.0), wXiPosUe(1.0), wXiNegJet(1.0), wXiNegUe(1.0), wOmegaPosJet(1.0), wOmegaPosUe(1.0), wOmegaNegJet(1.0), wOmegaNegUe(1.0); + if (applyReweighting) { + int ix = twodWeightsXiInJet->GetXaxis()->FindBin(mcParticle.pt()); + int iy = twodWeightsXiInJet->GetYaxis()->FindBin(mcParticle.eta()); + wXiPosJet = twodWeightsAntiXiInJet->GetBinContent(ix, iy); + wXiPosUe = twodWeightsAntiXiUe->GetBinContent(ix, iy); + wXiNegJet = twodWeightsXiInJet->GetBinContent(ix, iy); + wXiNegUe = twodWeightsXiUe->GetBinContent(ix, iy); + wOmegaPosJet = twodWeightsAntiOmegaInJet->GetBinContent(ix, iy); + wOmegaPosUe = twodWeightsAntiOmegaUe->GetBinContent(ix, iy); + wOmegaNegJet = twodWeightsOmegaInJet->GetBinContent(ix, iy); + wOmegaNegUe = twodWeightsOmegaUe->GetBinContent(ix, iy); + + // protections + if (ix == 0 || ix > twodWeightsXiInJet->GetNbinsX()) { + wXiPosJet = 1.0; + wXiPosUe = 1.0; + wXiNegJet = 1.0; + wXiNegUe = 1.0; + wOmegaPosJet = 1.0; + wOmegaPosUe = 1.0; + wOmegaNegJet = 1.0; + wOmegaNegUe = 1.0; + } + if (iy == 0 || iy > twodWeightsXiInJet->GetNbinsY()) { + wXiPosJet = 1.0; + wXiPosUe = 1.0; + wXiNegJet = 1.0; + wXiNegUe = 1.0; + wOmegaPosJet = 1.0; + wOmegaPosUe = 1.0; + wOmegaNegJet = 1.0; + wOmegaNegUe = 1.0; + } + } + switch (mcParticle.pdgCode()) { /* case kPiPlus: // Pi+ @@ -1903,20 +2025,24 @@ struct StrangenessInJets { registryMC.fill(HIST("AntiLambda_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); break; case kXiPlusBar: // Xi Pos - registryMC.fill(HIST("XiPos_generated"), multiplicity, mcParticle.pt()); + registryMC.fill(HIST("XiPos_generated_jet"), multiplicity, mcParticle.pt(), wXiPosJet); + registryMC.fill(HIST("XiPos_generated_ue"), multiplicity, mcParticle.pt(), wXiPosUe); registryMC.fill(HIST("Xi_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); break; case kXiMinus: // Xi Neg - registryMC.fill(HIST("XiNeg_generated"), multiplicity, mcParticle.pt()); - registryMC.fill(HIST("AntiXi_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); + registryMC.fill(HIST("XiNeg_generated_jet"), multiplicity, mcParticle.pt(), wXiNegJet); + registryMC.fill(HIST("XiNeg_generated_ue"), multiplicity, mcParticle.pt(), wXiNegUe); + registryMC.fill(HIST("XiNeg_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); break; case kOmegaPlusBar: // Omega Pos - registryMC.fill(HIST("OmegaPos_generated"), multiplicity, mcParticle.pt()); - registryMC.fill(HIST("Omega_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); + registryMC.fill(HIST("OmegaPos_generated_jet"), multiplicity, mcParticle.pt(), wOmegaPosJet); + registryMC.fill(HIST("OmegaPos_generated_ue"), multiplicity, mcParticle.pt(), wOmegaPosUe); + registryMC.fill(HIST("OmegaPos_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); break; case kOmegaMinus: // Omega Neg - registryMC.fill(HIST("OmegaNeg_generated"), multiplicity, mcParticle.pt()); - registryMC.fill(HIST("AntiOmega_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); + registryMC.fill(HIST("OmegaNeg_generated_jet"), multiplicity, mcParticle.pt(), wOmegaNegJet); + registryMC.fill(HIST("OmegaNeg_generated_ue"), multiplicity, mcParticle.pt(), wOmegaNegUe); + registryMC.fill(HIST("OmegaNeg_eta_pt_pythia"), mcParticle.pt(), mcParticle.eta()); break; } } @@ -2038,16 +2164,16 @@ struct StrangenessInJets { registryMC.fill(HIST("AntiLambda_eta_pt_jet"), particle.pt(), particle.eta()); break; case kXiMinus: - registryMC.fill(HIST("Xi_eta_pt_jet"), particle.pt(), particle.eta()); + registryMC.fill(HIST("XiNeg_eta_pt_jet"), particle.pt(), particle.eta()); break; case kXiPlusBar: - registryMC.fill(HIST("AntiXi_eta_pt_jet"), particle.pt(), particle.eta()); + registryMC.fill(HIST("XiPos_eta_pt_jet"), particle.pt(), particle.eta()); break; case kOmegaMinus: - registryMC.fill(HIST("Omega_eta_pt_jet"), particle.pt(), particle.eta()); + registryMC.fill(HIST("OmegaNeg_eta_pt_jet"), particle.pt(), particle.eta()); break; case kOmegaPlusBar: - registryMC.fill(HIST("AntiOmega_eta_pt_jet"), particle.pt(), particle.eta()); + registryMC.fill(HIST("OmegaPos_eta_pt_jet"), particle.pt(), particle.eta()); break; default: continue; @@ -2074,16 +2200,16 @@ struct StrangenessInJets { registryMC.fill(HIST("AntiLambda_eta_pt_ue"), particle.pt(), particle.eta()); break; case kXiMinus: - registryMC.fill(HIST("Xi_eta_pt_ue"), particle.pt(), particle.eta()); + registryMC.fill(HIST("XiNeg_eta_pt_ue"), particle.pt(), particle.eta()); break; case kXiPlusBar: - registryMC.fill(HIST("AntiXi_eta_pt_ue"), particle.pt(), particle.eta()); + registryMC.fill(HIST("XiPos_eta_pt_ue"), particle.pt(), particle.eta()); break; case kOmegaMinus: - registryMC.fill(HIST("Omega_eta_pt_ue"), particle.pt(), particle.eta()); + registryMC.fill(HIST("OmegaNeg_eta_pt_ue"), particle.pt(), particle.eta()); break; case kOmegaPlusBar: - registryMC.fill(HIST("AntiOmega_eta_pt_ue"), particle.pt(), particle.eta()); + registryMC.fill(HIST("OmegaPos_eta_pt_ue"), particle.pt(), particle.eta()); break; default: continue; From 0cf40a5b9baa0d95ca1d46b4c452f9d7cefae2ca Mon Sep 17 00:00:00 2001 From: Javier Castillo Castellanos Date: Thu, 12 Jun 2025 13:31:32 +0200 Subject: [PATCH 45/62] [Common] Use MCH track counterpart of global muon (#11542) --- Common/Tasks/qaMuon.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/Tasks/qaMuon.cxx b/Common/Tasks/qaMuon.cxx index 1f210249089..7c854935930 100644 --- a/Common/Tasks/qaMuon.cxx +++ b/Common/Tasks/qaMuon.cxx @@ -2399,7 +2399,7 @@ struct muonQa { mch::Track mchrealigned1, mchrealigned2; VarClusters fgValuesCls1, fgValuesCls2; - if (!FillClusters(muonTrack1, clusters, fgValuesCls1, mchrealigned1) || !FillClusters(muonTrack2, clusters, fgValuesCls2, mchrealigned2)) { + if (!FillClusters(mchTrack1, clusters, fgValuesCls1, mchrealigned1) || !FillClusters(mchTrack2, clusters, fgValuesCls2, mchrealigned2)) { continue; // Refit is not valid } From 00a3b2bc23fcac41a5aaf4454ef84b6a83140c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 12 Jun 2025 13:47:59 +0200 Subject: [PATCH 46/62] [ALICE3] Update FastTracker (#11570) Co-authored-by: ALICE Action Bot --- ALICE3/Core/FastTracker.cxx | 198 ++++++++++++++++-------------------- ALICE3/Core/FastTracker.h | 87 +++++++++------- 2 files changed, 139 insertions(+), 146 deletions(-) diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index 1d06958504b..fe89fcd80fd 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -9,13 +9,17 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include +#include "FastTracker.h" + +#include "ReconstructionDataFormats/TrackParametrization.h" + #include "TMath.h" #include "TMatrixD.h" -#include "TRandom.h" #include "TMatrixDSymEigen.h" -#include "FastTracker.h" +#include "TRandom.h" + +#include +#include namespace o2 { @@ -24,36 +28,6 @@ namespace fastsim // +-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+ -FastTracker::FastTracker() -{ - // base constructor - magneticField = 20; // in kiloGauss - applyZacceptance = false; - applyMSCorrection = true; - applyElossCorrection = true; - applyEffCorrection = true; - covMatFactor = 0.99f; - verboseLevel = 0; - - // last fast-tracked track properties - covMatOK = 0; - covMatNotOK = 0; - nIntercepts = 0; - nSiliconPoints = 0; - nGasPoints = 0; - - maxRadiusSlowDet = 10; - integrationTime = 0.02; // ms - crossSectionMinB = 8; - dNdEtaCent = 2200; - dNdEtaMinB = 1; - avgRapidity = 0.45; - sigmaD = 6.0; - luminosity = 1.e27; - otherBackground = 0.0; // [0, 1] - upcBackgroundMultiplier = 1.0; -} - void FastTracker::AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi, float resZ, float eff, int type) { DetLayer newLayer(name, r, z, x0, xrho, resRPhi, resZ, eff, type); @@ -61,6 +35,17 @@ void FastTracker::AddLayer(TString name, float r, float z, float x0, float xrho, if (newLayer.getEfficiency() > 0.0f && newLayer.isInert()) { LOG(error) << "Layer " << name << " with efficiency > 0.0 should not be inert"; } + // Layers should be ordered by increasing radius, check this + if (!layers.empty() && newLayer.getRadius() < layers.back().getRadius()) { + LOG(fatal) << "Layer " << newLayer << " is not ordered correctly, it should be after layer " << layers.back(); + } + // Layers should all have different names + for (const auto& layer : layers) { + if (layer.getName() == newLayer.getName()) { + LOG(fatal) << "Layer with name " << newLayer.getName() << " already exists in FastTracker layers"; + } + } + // Add the new layer to the layers vector layers.push_back(newLayer); } @@ -78,7 +63,7 @@ DetLayer FastTracker::GetLayer(int layer, bool ignoreBarrelLayers) const return layers[layerIdx]; } -int FastTracker::GetLayerIndex(std::string name) const +int FastTracker::GetLayerIndex(const std::string& name) const { int i = 0; for (const auto& layer : layers) { @@ -211,9 +196,9 @@ float FastTracker::Dist(float z, float r) // https://github.com/AliceO2Group/DelphesO2/blob/master/src/DetectorK/DetectorK.cxx#L743 int index = 1; int nSteps = 301; - double dist = 0.0; - double dz0 = (4 * sigmaD - (-4) * sigmaD / (nSteps = 1)); - double z0 = 0.0; + float dist = 0.0; + float dz0 = (4 * sigmaD - (-4) * sigmaD / (nSteps = 1)); + float z0 = 0.0; for (int i = 0; i < nSteps; i++) { if (i == nSteps - 1) index = 1; @@ -243,7 +228,7 @@ float FastTracker::IntegratedHitDensity(float multiplicity, float radius) // porting of DetektorK::IntegratedHitDensity // see here: // https://github.com/AliceO2Group/DelphesO2/blob/master/src/DetectorK/DetectorK.cxx#L712 - float zdcHz = luminosity * 1.e24 * crossSectionMinB; + float zdcHz = luminosity * 1.e24 * mCrossSectionMinB; float den = zdcHz * integrationTime / 1000. * multiplicity * Dist(0., radius) / (o2::constants::math::TwoPI * radius); if (den < OneEventHitDensity(multiplicity, radius)) den = OneEventHitDensity(multiplicity, radius); @@ -301,6 +286,7 @@ float FastTracker::ProbGoodChiSqHit(float radius, float searchRadiusRPhi, float // returns number of intercepts (generic for now) int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackParCov& outputTrack, const float nch) { + dNdEtaCent = nch; // set the number of charged particles per unit rapidity hits.clear(); nIntercepts = 0; nSiliconPoints = 0; @@ -310,38 +296,54 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa 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 + } + int firstActiveLayer = -1; // first layer that is not inert + for (size_t i = 0; i < layers.size(); ++i) { + if (!layers[i].isInert()) { + firstActiveLayer = i; + break; + } + } + if (firstActiveLayer <= 0) { + LOG(fatal) << "No active layers found in FastTracker, check layer setup"; + return -2; // no active layers + } const int xrhosteps = 100; const bool applyAngularCorrection = true; goodHitProbability.clear(); - for (int i = 0; i < kMaxNumberOfDetectors; ++i) + for (int i = 0; i < kMaxNumberOfDetectors; ++i) { goodHitProbability.push_back(-1.); - goodHitProbability[0] = 1.; + } + goodHitProbability[0] = 1.; // we use layer zero to accumulate // +-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+ // Outward pass to find intercepts int firstLayerReached = -1; int lastLayerReached = -1; new (&outputTrack)(o2::track::TrackParCov)(inputTrack); - for (uint32_t il = 0; il < layers.size(); il++) { + for (size_t il = 0; il < layers.size(); il++) { // check if layer is doable - if (layers[il].getRadius() < initialRadius) + if (layers[il].getRadius() < initialRadius) { continue; // this layer should not be attempted, but go ahead + } // check if layer is reached float targetX = 1e+3; - bool ok = true; inputTrack.getXatLabR(layers[il].getRadius(), targetX, magneticField); if (targetX > 999.f) { LOGF(debug, "Failed to find intercept for layer %d at radius %.2f cm", il, layers[il].getRadius()); break; // failed to find intercept } - ok = inputTrack.propagateTo(targetX, magneticField); - if (ok && applyMSCorrection && layers[il].getRadiationLength() > 0) { + bool ok = inputTrack.propagateTo(targetX, magneticField); + if (ok && mApplyMSCorrection && layers[il].getRadiationLength() > 0) { ok = inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection); } - if (ok && applyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps + if (ok && mApplyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps for (int ise = xrhosteps; ise--;) { ok = inputTrack.correctForMaterial(0, -layers[il].getDensity() / xrhosteps, applyAngularCorrection); if (!ok) @@ -361,7 +363,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa break; } } - if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) { + if (std::abs(inputTrack.getZ()) > layers[il].getZ() && mApplyZacceptance) { break; // out of acceptance bounds } @@ -384,39 +386,19 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa o2::track::TrackParCov inwardTrack(inputTrack); // Enlarge covariance matrix - std::array trPars = {0.}; - for (int ip = 0; ip < 5; ip++) { + std::array trPars = {0.}; + for (int ip = 0; ip < o2::track::kNParams; ip++) { trPars[ip] = outputTrack.getParam(ip); } - std::array largeCov = {0.}; - enum { kY, - kZ, - kSnp, - kTgl, - kPtI }; // track parameter aliases - enum { kY2, - kYZ, - kZ2, - kYSnp, - kZSnp, - kSnp2, - kYTgl, - kZTgl, - kSnpTgl, - kTgl2, - kYPtI, - kZPtI, - kSnpPtI, - kTglPtI, - kPtI2 }; // cov.matrix aliases - const double kLargeErr2Coord = 5 * 5; - const double kLargeErr2Dir = 0.7 * 0.7; - const double kLargeErr2PtI = 30.5 * 30.5; - for (int ic = 15; ic--;) + static constexpr float kLargeErr2Coord = 5 * 5; + static constexpr float kLargeErr2Dir = 0.7 * 0.7; + static constexpr float kLargeErr2PtI = 30.5 * 30.5; + std::array largeCov = {0.}; + for (int ic = o2::track::kCovMatSize; ic--;) largeCov[ic] = 0.; - largeCov[kY2] = largeCov[kZ2] = kLargeErr2Coord; - largeCov[kSnp2] = largeCov[kTgl2] = kLargeErr2Dir; - largeCov[kPtI2] = kLargeErr2PtI * trPars[kPtI] * trPars[kPtI]; + largeCov[o2::track::CovLabels::kSigY2] = largeCov[o2::track::CovLabels::kSigZ2] = kLargeErr2Coord; + largeCov[o2::track::CovLabels::kSigSnp2] = largeCov[o2::track::CovLabels::kSigTgl2] = kLargeErr2Dir; + largeCov[o2::track::CovLabels::kSigQ2Pt2] = kLargeErr2PtI * trPars[o2::track::ParLabels::kQ2Pt] * trPars[o2::track::ParLabels::kQ2Pt]; inwardTrack.setCov(largeCov); inwardTrack.checkCovariance(); @@ -434,7 +416,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa continue; // failed to propagate } - if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) { + if (std::abs(inputTrack.getZ()) > layers[il].getZ() && mApplyZacceptance) { continue; // out of acceptance bounds but continue inwards } @@ -444,10 +426,10 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa std::vector thisHit = {spacePoint[0], spacePoint[1], spacePoint[2]}; // towards adding cluster: move to track alpha - double alpha = inwardTrack.getAlpha(); - double xyz1[3]{ - TMath::Cos(alpha) * spacePoint[0] + TMath::Sin(alpha) * spacePoint[1], - -TMath::Sin(alpha) * spacePoint[0] + TMath::Cos(alpha) * spacePoint[1], + float alpha = inwardTrack.getAlpha(); + float xyz1[3]{ + std::cos(alpha) * spacePoint[0] + std::sin(alpha) * spacePoint[1], + -std::sin(alpha) * spacePoint[0] + std::cos(alpha) * spacePoint[1], spacePoint[2]}; if (!inwardTrack.propagateTo(xyz1[0], magneticField)) continue; @@ -462,7 +444,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa inwardTrack.checkCovariance(); } - if (applyMSCorrection && layers[il].getRadiationLength() > 0) { + if (mApplyMSCorrection && layers[il].getRadiationLength() > 0) { if (!inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) { return -6; } @@ -470,7 +452,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa return -6; } } - if (applyElossCorrection && layers[il].getDensity() > 0) { + if (mApplyElossCorrection && layers[il].getDensity() > 0) { for (int ise = xrhosteps; ise--;) { // correct in small steps if (!inputTrack.correctForMaterial(0, layers[il].getDensity() / xrhosteps, applyAngularCorrection)) { return -7; @@ -488,9 +470,9 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa hits.push_back(thisHit); - if (applyEffCorrection && !layers[il].isInert()) { // good hit probability calculation - double sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi()); - double sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].getResolutionZ() * layers[il].getResolutionZ()); + if (!layers[il].isInert()) { // good hit probability calculation + float sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi()); + float sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].getResolutionZ() * layers[il].getResolutionZ()); goodHitProbability[il] = ProbGoodChiSqHit(layers[il].getRadius() * 100, sigYCmb * 100, sigZCmb * 100); goodHitProbability[0] *= goodHitProbability[il]; } @@ -498,9 +480,11 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa // backpropagate to original radius float finalX = 1e+3; - inwardTrack.getXatLabR(initialRadius, finalX, magneticField); - if (finalX > 999) + bool inPropStatus = inwardTrack.getXatLabR(initialRadius, finalX, magneticField); + if (finalX > 999) { + LOG(debug) << "Failed to find intercept for initial radius " << initialRadius << " cm, x = " << finalX << " and status " << inPropStatus << " and sn = " << inwardTrack.getSnp() << " r = " << inwardTrack.getY() * inwardTrack.getY(); return -3; // failed to find intercept + } if (!inwardTrack.propagateTo(finalX, magneticField)) { return -4; // failed to propagate @@ -511,17 +495,15 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa return nIntercepts; // generate efficiency - if (applyEffCorrection) { - dNdEtaCent = nch; - float eff = 1.; - for (int i = 0; i < kMaxNumberOfDetectors; i++) { - float iGoodHit = goodHitProbability[i]; - if (iGoodHit <= 0) - continue; - - eff *= iGoodHit; - } + float eff = 1.; + for (int i = 0; i < kMaxNumberOfDetectors; i++) { + float iGoodHit = goodHitProbability[i]; + if (iGoodHit <= 0) + continue; + eff *= iGoodHit; + } + if (mApplyEffCorrection) { if (gRandom->Uniform() > eff) return -8; } @@ -530,11 +512,11 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa outputTrack.checkCovariance(); // Use covariance matrix based smearing - std::array covMat = {0.}; - for (int ii = 0; ii < 15; ii++) + std::array covMat = {0.}; + for (int ii = 0; ii < o2::track::kCovMatSize; ii++) covMat[ii] = outputTrack.getCov()[ii]; TMatrixDSym m(5); - double fcovm[5][5]; + float fcovm[5][5]; for (int ii = 0, k = 0; ii < 5; ++ii) { for (int j = 0; j < ii + 1; ++j, ++k) { @@ -544,7 +526,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa } // evaluate ruben's conditional, regularise - bool makePositiveDefinite = (covMatFactor > -1e-5); // apply fix + const bool makePositiveDefinite = (covMatFactor > -1e-5); // apply fix bool rubenConditional = false; for (int ii = 0; ii < 5; ii++) { for (int jj = 0; jj < 5; jj++) { @@ -571,7 +553,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa } if (negEigVal && rubenConditional && makePositiveDefinite) { - if (verboseLevel > 0) { + if (mVerboseLevel > 0) { LOG(info) << "WARNING: this diagonalization (at pt = " << inputTrack.getPt() << ") has negative eigenvalues despite Ruben's fix! Please be careful!"; LOG(info) << "Printing info:"; LOG(info) << "Kalman updates: " << nIntercepts; @@ -585,9 +567,9 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa covMatOK++; // transform parameter vector and smear - double params_[5]; + float params_[5]; for (int ii = 0; ii < 5; ++ii) { - double val = 0.; + float val = 0.; for (int j = 0; j < 5; ++j) val += eigVec[j][ii] * outputTrack.getParam(j); // smear parameters according to eigenvalues @@ -598,7 +580,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa eigVec.Invert(); // transform back params vector for (int ii = 0; ii < 5; ++ii) { - double val = 0.; + float val = 0.; for (int j = 0; j < 5; ++j) val += eigVec[j][ii] * params_[j]; outputTrack.setParam(val, ii); diff --git a/ALICE3/Core/FastTracker.h b/ALICE3/Core/FastTracker.h index 702caa9e84b..a0dba5d7ec5 100644 --- a/ALICE3/Core/FastTracker.h +++ b/ALICE3/Core/FastTracker.h @@ -12,12 +12,15 @@ #ifndef ALICE3_CORE_FASTTRACKER_H_ #define ALICE3_CORE_FASTTRACKER_H_ -#include // not a system header but megalinter thinks so -#include -#include #include "DetLayer.h" + #include "ReconstructionDataFormats/Track.h" +#include // not a system header but megalinter thinks so + +#include +#include + namespace o2 { namespace fastsim @@ -32,13 +35,16 @@ class FastTracker { public: // Constructor/destructor - FastTracker(); + FastTracker() = default; + // Destructor virtual ~FastTracker() {} // Layer and layer configuration void AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi = 0.0f, float resZ = 0.0f, float eff = 0.0f, int type = 0); DetLayer GetLayer(const int layer, bool ignoreBarrelLayers = true) const; - int GetLayerIndex(const std::string name) const; + int GetLayerIndex(const std::string& name) const; + size_t GetNLayers() const { return layers.size(); } + bool IsLayerInert(const int layer) const { return layers[layer].isInert(); } void SetRadiationLength(const std::string layerName, float x0) { layers[GetLayerIndex(layerName)].setRadiationLength(x0); } void SetRadius(const std::string layerName, float r) { layers[GetLayerIndex(layerName)].setRadius(r); } void SetResolutionRPhi(const std::string layerName, float resRPhi) { layers[GetLayerIndex(layerName)].setResolutionRPhi(resRPhi); } @@ -80,20 +86,24 @@ class FastTracker void SetIntegrationTime(float t) { integrationTime = t; } void SetMaxRadiusOfSlowDetectors(float r) { maxRadiusSlowDet = r; } void SetAvgRapidity(float y) { avgRapidity = y; } - void SetdNdEtaCent(float d) { dNdEtaCent = d; } + void SetdNdEtaCent(int d) { dNdEtaCent = d; } void SetLhcUPCscale(float s) { lhcUPCScale = s; } void SetBField(float b) { magneticField = b; } void SetMinRadTrack(float r) { fMinRadTrack = r; } void SetMagneticField(float b) { magneticField = b; } - void SetApplyZacceptance(bool b) { applyZacceptance = b; } - void SetApplyMSCorrection(bool b) { applyMSCorrection = b; } - void SetApplyElossCorrection(bool b) { applyElossCorrection = b; } + void SetApplyZacceptance(bool b) { mApplyZacceptance = b; } + void SetApplyMSCorrection(bool b) { mApplyMSCorrection = b; } + void SetApplyElossCorrection(bool b) { mApplyElossCorrection = b; } + void SetApplyEffCorrection(bool b) { mApplyEffCorrection = b; } // Getters for the last track int GetNIntercepts() const { return nIntercepts; } int GetNSiliconPoints() const { return nSiliconPoints; } int GetNGasPoints() const { return nGasPoints; } - float GetGoodHitProb(int layer) const { return goodHitProbability[layer]; } + float GetGoodHitProb(int layer) const + { + return (layer >= 0 && static_cast(layer) < goodHitProbability.size()) ? goodHitProbability[layer] : 0.0f; + } std::size_t GetNHits() const { return hits.size(); } float GetHitX(const int i) const { return hits[i][0]; } float GetHitY(const int i) const { return hits[i][1]; } @@ -106,34 +116,35 @@ class FastTracker std::vector layers; std::vector> hits; // bookkeep last added hits - // operational - bool applyZacceptance; // check z acceptance or not - bool applyMSCorrection; // Apply correction for multiple scattering - bool applyElossCorrection; // Apply correction for eloss (requires MS correction) - bool applyEffCorrection; // Apply correction for hit efficiency - int verboseLevel; // 0: not verbose, >0 more verbose - int crossSectionMinB; - int dNdEtaCent; - int dNdEtaMinB; - float integrationTime; - float magneticField; // in kiloGauss (5 = 0.5T, etc) - float covMatFactor; // covmat off-diagonal factor to use for covmat fix (negative: no factor) - float sigmaD; - float luminosity; - float otherBackground; - float maxRadiusSlowDet; - float avgRapidity; - float lhcUPCScale; - float upcBackgroundMultiplier; - float fMinRadTrack = 132.; - - uint64_t covMatOK; // cov mat has negative eigenvals - uint64_t covMatNotOK; // cov mat has negative eigenvals - - // last track information - int nIntercepts; // found in first outward propagation - int nSiliconPoints; // silicon-based space points added to track - int nGasPoints; // tpc-based space points added to track + /// configuration parameters + bool mApplyZacceptance = false; /// check z acceptance or not + bool mApplyMSCorrection = true; /// Apply correction for multiple scattering + bool mApplyElossCorrection = true; /// Apply correction for eloss (requires MS correction) + bool mApplyEffCorrection = true; /// Apply correction for hit efficiency + int mVerboseLevel = 0; /// 0: not verbose, >0 more verbose + const float mCrossSectionMinB = 8; /// Minimum bias Cross section for event under study (PbPb MinBias ~ 8 Barns) + int dNdEtaCent = 2200; /// dN/deta e.g. at centrality 0-5% (for 5 TeV PbPb) + int dNdEtaMinB = 1; /// dN/deta for minimum bias events + float integrationTime = 0.02f; /// Integration time in ms + float magneticField = 20.f; /// Magnetic field in kiloGauss (5 = 0.5T, 20 = 2T, etc) + float covMatFactor = 0.99f; /// covmat off-diagonal factor to use for covmat fix (negative: no factor) + float sigmaD = 6.0f; /// sigma for the detector resolution in cm + float luminosity = 1.e27f; /// luminosity in cm^-2 s^-1 (e.g. 1.e27 for PbPb at 5 TeV) + float otherBackground = 0.0f; /// background from other sources, e.g. pileup, in [0, 1] + float maxRadiusSlowDet = 10.f; /// maximum radius of slow detectors in cm + float avgRapidity = 0.45f; /// average rapidity for hit density calculation + float lhcUPCScale = 1.0f; /// scale factor for LHC UPC events + float upcBackgroundMultiplier = 1.0f; /// multiplier for UPC background + float fMinRadTrack = 132.f; /// minimum radius for track propagation in cm + + /// counters for covariance matrix statuses + uint64_t covMatOK = 0; /// cov mat has positive eigenvals + uint64_t covMatNotOK = 0; /// cov mat has negative eigenvals + + /// last track information + int nIntercepts = 0; /// found in first outward propagation + int nSiliconPoints = 0; /// silicon-based space points added to track + int nGasPoints = 0; /// tpc-based space points added to track std::vector goodHitProbability; ClassDef(FastTracker, 1); From fdb3a2c848bc76fa1c569f0cc80f2f55fcd48a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 12 Jun 2025 14:32:16 +0200 Subject: [PATCH 47/62] [Common] Include What You Use (#11547) --- Common/Core/fwdtrackUtilities.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Common/Core/fwdtrackUtilities.h b/Common/Core/fwdtrackUtilities.h index 13fb27c5862..74fe125c2f0 100644 --- a/Common/Core/fwdtrackUtilities.h +++ b/Common/Core/fwdtrackUtilities.h @@ -18,10 +18,18 @@ #ifndef COMMON_CORE_FWDTRACKUTILITIES_H_ #define COMMON_CORE_FWDTRACKUTILITIES_H_ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + #include -#include -#include "Math/SMatrix.h" -#include "TGeoGlobalMagField.h" namespace o2::aod { From b0c3474f1882926e03ab59c503cdf758e25f6458 Mon Sep 17 00:00:00 2001 From: marcobianchi463 <121625445+marcobianchi463@users.noreply.github.com> Date: Thu, 12 Jun 2025 16:13:33 +0200 Subject: [PATCH 48/62] [PWGLF] Harmonics configurable and amplitude definition (#11555) --- PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx | 10 ++--- PWGLF/TableProducer/QC/flowQC.cxx | 42 ++++++++++--------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx b/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx index 6c15c2a626c..14192166fae 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx @@ -428,11 +428,11 @@ struct nucleiFlowTree { computeEventPlane(collision.qvecTPCallImVec()[cfgHarmonics - 2], collision.qvecTPCallReVec()[cfgHarmonics - 2]), computeEventPlane(collision.qvecTPCnegImVec()[cfgHarmonics - 2], collision.qvecTPCnegReVec()[cfgHarmonics - 2]), computeEventPlane(collision.qvecTPCposImVec()[cfgHarmonics - 2], collision.qvecTPCposReVec()[cfgHarmonics - 2]), - collision.sumAmplFT0A(), - collision.sumAmplFT0C(), - static_cast(collision.nTrkTPCall()), - static_cast(collision.nTrkTPCneg()), - static_cast(collision.nTrkTPCpos())}); + std::hypot(collision.qvecFT0AImVec()[cfgHarmonics - 2], collision.qvecFT0AReVec()[cfgHarmonics - 2]), + std::hypot(collision.qvecFT0CImVec()[cfgHarmonics - 2], collision.qvecFT0CReVec()[cfgHarmonics - 2]), + std::hypot(collision.qvecTPCallImVec()[cfgHarmonics - 2], collision.qvecTPCallReVec()[cfgHarmonics - 2]), + std::hypot(collision.qvecTPCnegImVec()[cfgHarmonics - 2], collision.qvecTPCnegReVec()[cfgHarmonics - 2]), + std::hypot(collision.qvecTPCposImVec()[cfgHarmonics - 2], collision.qvecTPCposReVec()[cfgHarmonics - 2])}); } if (flag & kTriton) { if (track.pt() < cfgCutPtMinTree || track.pt() > cfgCutPtMaxTree || track.sign() > 0) diff --git a/PWGLF/TableProducer/QC/flowQC.cxx b/PWGLF/TableProducer/QC/flowQC.cxx index f5dfa06f9d7..1e32b954120 100644 --- a/PWGLF/TableProducer/QC/flowQC.cxx +++ b/PWGLF/TableProducer/QC/flowQC.cxx @@ -111,9 +111,11 @@ struct flowQC { int mRunNumber = 0; float mBz = 0.f; + Configurable cfgHarmonics{"cfgHarmonics", 2, "Harmonics for flow analysis"}; + // Flow analysis using CollWithEPandQvec = soa::Join::iterator; + aod::EvSels, aod::CentFT0As, aod::CentFT0Cs, aod::CentFT0Ms, aod::CentFV0As, aod::FT0Mults, aod::FV0Mults, aod::TPCMults, aod::EPCalibrationTables, aod::QvectorFT0CVecs, aod::QvectorFT0AVecs, aod::QvectorFT0MVecs, aod::QvectorFV0AVecs, aod::QvectorTPCallVecs, aod::QvectorTPCposVecs, aod::QvectorTPCnegVecs>::iterator; HistogramRegistry general{"general", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry flow_ep{"flow_ep", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -171,15 +173,15 @@ struct flowQC { const AxisSpec centAxis{cfgCentralityBins, fmt::format("{} percentile", (std::string)centDetectorNames[cfgCentralityEstimator])}; - const AxisSpec QxAxis{cfgQvecBins, "Q_{2,x}"}; - const AxisSpec QyAxis{cfgQvecBins, "Q_{2,y}"}; + const AxisSpec QxAxis{cfgQvecBins, Form("Q_{%d,x}", cfgHarmonics.value)}; + const AxisSpec QyAxis{cfgQvecBins, Form("Q_{%d,y}", cfgHarmonics.value)}; - const AxisSpec NormQxAxis{cfgQvecBins, "#frac{Q_{2,x}}{||#vec{Q_{2}}||}"}; - const AxisSpec NormQyAxis{cfgQvecBins, "#frac{Q_{2,y}}{||#vec{Q_{2}}||}"}; + const AxisSpec NormQxAxis{cfgQvecBins, Form("#frac{Q_{%d,x}}{||#vec{Q_{%d}}||}", cfgHarmonics.value, cfgHarmonics.value)}; + const AxisSpec NormQyAxis{cfgQvecBins, Form("#frac{Q_{%d,y}}{||#vec{Q_{%d}}||}", cfgHarmonics.value, cfgHarmonics.value)}; - const AxisSpec psiAxis{cfgPhiBins, "#psi_{2}"}; - const AxisSpec psiCompAxis{cfgPhiBins, "#psi_{2}^{EP} - #psi_{2}^{Qvec}"}; - const AxisSpec cosPsiCompAxis{cfgCosPhiBins, "cos[2(#psi_{2}^{EP} - #psi_{2}^{Qvec})]"}; + const AxisSpec psiAxis{cfgPhiBins, Form("#psi_{%d}", cfgHarmonics.value)}; + const AxisSpec psiCompAxis{cfgPhiBins, Form("#psi_{%d}^{EP} - #psi_{%d}^{Qvec}", cfgHarmonics.value, cfgHarmonics.value)}; + const AxisSpec cosPsiCompAxis{cfgCosPhiBins, Form("cos[2(#psi_{%d}^{EP} - #psi_{%d}^{Qvec})]", cfgHarmonics.value, cfgHarmonics.value)}; // z vertex histogram general.add("hRecVtxZData", "collision z position", HistType::kTH1F, {{200, -20., +20., "z position (cm)"}}); @@ -203,12 +205,12 @@ struct flowQC { hDeltaPsi[iMethod][iQvecDet][jQvecDet] = registry->add(Form("hDeltaPsi_%s_%s_%s", qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str(), suffixes[iMethod].c_str()), "", HistType::kTH2F, {centAxis, {cfgDeltaPhiBins, Form("#psi_{%s} - #psi_{%s}", qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str())}}); // Scalar-product histograms - auto spLabel = Form("#vec{Q}_{2}^{%s} #upoint #vec{Q}_{2}^{%s}", qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str()); + auto spLabel = Form("#vec{Q}_{%d}^{%s} #upoint #vec{Q}_{%d}^{%s}", cfgHarmonics.value, qVecDetectorNames[iQvecDet].c_str(), cfgHarmonics.value, qVecDetectorNames[jQvecDet].c_str()); hScalarProduct[iMethod][iQvecDet][jQvecDet] = registry->add(Form("hScalarProduct_%s_%s_%s", qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str(), suffixes[iMethod].c_str()), "", HistType::kTH2F, {centAxis, {cfgQvecBins, spLabel}}); // Normalised scalar-product histograms - auto normSpLabel = Form("#frac{#vec{Q}_{2}^{%s} #upoint #vec{Q}_{2}^{%s}}{||#vec{Q}_{2}^{%s}|| ||#vec{Q}_{2}^{%s}||}", qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str(), qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str()); + auto normSpLabel = Form("#frac{#vec{Q}_{%d}^{%s} #upoint #vec{Q}_{%d}^{%s}}{||#vec{Q}_{%d}^{%s}|| ||#vec{Q}_{%d}^{%s}||}", cfgHarmonics.value, qVecDetectorNames[iQvecDet].c_str(), cfgHarmonics.value, qVecDetectorNames[jQvecDet].c_str(), cfgHarmonics.value, qVecDetectorNames[iQvecDet].c_str(), cfgHarmonics.value, qVecDetectorNames[jQvecDet].c_str()); hNormalisedScalarProduct[iMethod][iQvecDet][jQvecDet] = registry->add(Form("hNormalisedScalarProduct_%s_%s_%s", qVecDetectorNames[iQvecDet].c_str(), qVecDetectorNames[jQvecDet].c_str(), suffixes[iMethod].c_str()), "", HistType::kTH2F, {centAxis, {cfgQvecBins, normSpLabel}}); } @@ -285,28 +287,28 @@ struct flowQC { float QyTPC_EP = QmodTPC_EP * std::sin(2 * psiTPC_EP); // Qvec method - float QxFT0A_Qvec = collision.qvecFT0ARe(); - float QyFT0A_Qvec = collision.qvecFT0AIm(); + float QxFT0A_Qvec = collision.qvecFT0AReVec()[cfgHarmonics - 2]; + float QyFT0A_Qvec = collision.qvecFT0AImVec()[cfgHarmonics - 2]; float QmodFT0A_Qvec = std::hypot(QxFT0A_Qvec, QyFT0A_Qvec); float psiFT0A_Qvec = computeEventPlane(QyFT0A_Qvec, QxFT0A_Qvec); - float QxFT0C_Qvec = collision.qvecFT0CRe(); - float QyFT0C_Qvec = collision.qvecFT0CIm(); + float QxFT0C_Qvec = collision.qvecFT0CReVec()[cfgHarmonics - 2]; + float QyFT0C_Qvec = collision.qvecFT0CImVec()[cfgHarmonics - 2]; float QmodFT0C_Qvec = std::hypot(QxFT0C_Qvec, QyFT0C_Qvec); float psiFT0C_Qvec = computeEventPlane(QyFT0C_Qvec, QxFT0C_Qvec); - float QxTPCl_Qvec = collision.qvecBNegRe(); - float QyTPCl_Qvec = collision.qvecBNegIm(); + float QxTPCl_Qvec = collision.qvecTPCnegReVec()[cfgHarmonics - 2]; + float QyTPCl_Qvec = collision.qvecTPCnegImVec()[cfgHarmonics - 2]; float QmodTPCl_Qvec = std::hypot(QxTPCl_Qvec, QyTPCl_Qvec); float psiTPCl_Qvec = computeEventPlane(QyTPCl_Qvec, QxTPCl_Qvec); - float QxTPCr_Qvec = collision.qvecBPosRe(); - float QyTPCr_Qvec = collision.qvecBPosIm(); + float QxTPCr_Qvec = collision.qvecTPCposReVec()[cfgHarmonics - 2]; + float QyTPCr_Qvec = collision.qvecTPCposImVec()[cfgHarmonics - 2]; float QmodTPCr_Qvec = std::hypot(QxTPCr_Qvec, QyTPCr_Qvec); float psiTPCr_Qvec = computeEventPlane(QyTPCr_Qvec, QxTPCr_Qvec); - float QxTPC_Qvec = collision.qvecBTotRe(); - float QyTPC_Qvec = collision.qvecBTotIm(); + float QxTPC_Qvec = collision.qvecTPCallReVec()[cfgHarmonics - 2]; + float QyTPC_Qvec = collision.qvecTPCallImVec()[cfgHarmonics - 2]; float QmodTPC_Qvec = std::hypot(QxTPC_Qvec, QyTPC_Qvec); float psiTPC_Qvec = computeEventPlane(QyTPC_Qvec, QxTPC_Qvec); From 0b5eb032bf30fc9192498f5747f5ebd895722f01 Mon Sep 17 00:00:00 2001 From: hernasab Date: Thu, 12 Jun 2025 09:31:25 -0500 Subject: [PATCH 49/62] [PWGCF] added ccdb objects (#11568) Co-authored-by: Sabrina Hernandez --- PWGCF/Flow/Tasks/flowZdcTask.cxx | 131 +++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 34 deletions(-) diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index 3bad6691449..18b92bbfff8 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -14,30 +14,34 @@ /// \since 10/01/2024 /// \brief task to evaluate flow and neutron skin with information from ZDC -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include #include "TList.h" -#include -#include +#include #include +#include +#include #include #include -#include -#include + +#include +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -98,7 +102,10 @@ struct FlowZdcTask { Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "T0C Occu cut?"}; Configurable isTDCcut{"isTDCcut", false, "Use TDC cut?"}; Configurable isZEMcut{"isZEMcut", true, "Use ZEM cut?"}; + Configurable useMidRapNchSel{"useMidRapNchSel", true, "Use mid-rapidit Nch selection"}; + Configurable applyEff{"applyEff", true, "Apply track-by-track efficiency correction"}; + Configurable nSigmaNchCut{"nSigmaNchCut", 1., "nSigma Nch selection"}; Configurable minNchSel{"minNchSel", 5., "min Nch Selection"}; Configurable znBasedCut{"znBasedCut", 100, "ZN-based cut"}; Configurable zemCut{"zemCut", 1000., "ZEM cut"}; @@ -106,6 +113,11 @@ struct FlowZdcTask { Configurable minOccCut{"minOccCut", 0, "min Occu cut"}; Configurable maxOccCut{"maxOccCut", 500, "max Occu cut"}; Configurable minITSnCls{"minITSnCls", 5, "min ITSnCls"}; + Configurable minPt{"minPt", 0.1, "minimum pt of the tracks"}; + Configurable maxPt{"maxPt", 3., "maximum pt of the tracks"}; + Configurable maxPtSpectra{"maxPtSpectra", 50., "maximum pt of the tracks"}; + Configurable minEta{"minEta", -0.8, "minimum eta"}; + Configurable maxEta{"maxEta", +0.8, "maximum eta"}; // axis configs ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; @@ -138,9 +150,12 @@ struct FlowZdcTask { using CollisionDataTable = soa::Join; using TrackDataTable = soa::Join; using FilTrackDataTable = soa::Filtered; - std::complex qTPC; // init q TPC - std::complex qZNA{0, 0}; // init qZNA - std::complex qZNC{0, 0}; // init qZNC + + // CCDB paths + Configurable paTH{"paTH", "Users/s/sahernan/test", "base path to the ccdb object"}; + Configurable paTHmeanNch{"paTHmeanNch", "Users/s/shernan/test", "base path to the ccdb object"}; + Configurable paTHsigmaNch{"paTHsigmaNch", "Users/s/shernan/testSigma", "base path to the ccdb object"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; enum EvCutLabel { All = 1, @@ -164,8 +179,7 @@ struct FlowZdcTask { // Begin Histogram Registry HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - OutputObj pCosPsiDifferences{TProfile("pCosPsiDifferences", "Differences in cos(psi) vs Centrality;Centrality;Mean cos(psi) Difference", 200, 0, 100, -1, 1)}; - OutputObj pSinPsiDifferences{TProfile("pSinPsiDifferences", "Differences in sin(psi) vs Centrality;Centrality;Mean sin(psi) Difference", 200, 0, 100, -1, 1)}; + Service ccdb; OutputObj pZNvsFT0Ccent{TProfile("pZNvsFT0Ccent", "ZN Energy vs FT0C Centrality", 100, 0, 100, 0, 500)}; OutputObj pZPvsFT0Ccent{TProfile("pZPvsFT0Ccent", "ZP Energy vs FT0C Centrality", 100, 0, 100, 0, 500)}; OutputObj pZNratiovscent{TProfile("pZNratiovscent", "Ratio ZNC/ZNA vs FT0C Centrality", 100, 0, 100, 0, 5)}; @@ -337,6 +351,24 @@ struct FlowZdcTask { histos.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZn}}}); histos.add("ZNDifVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA-ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {100, -50., 50.}}}); } + LOG(info) << "\tccdbNoLaterThan=" << ccdbNoLaterThan.value; + LOG(info) << "\tapplyEff=" << applyEff.value; + LOG(info) << "\tpaTH=" << paTH.value; + LOG(info) << "\tuseMidRapNchSel=" << useMidRapNchSel.value; + LOG(info) << "\tpaTHmeanNch=" << paTHmeanNch.value; + LOG(info) << "\tpaTHsigmaNch=" << paTHsigmaNch.value; + LOG(info) << "\tminPt=" << minPt.value; + LOG(info) << "\tmaxPt=" << maxPt.value; + LOG(info) << "\tmaxPtSpectra=" << maxPtSpectra.value; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + // Enabling object caching, otherwise each call goes to the CCDB server + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + // Not later than now, will be replaced by the value of the train creation + // This avoids that users can replace objects **while** a train is running + ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); } template bool isEventSelected(EventCuts const& col) @@ -480,6 +512,7 @@ struct FlowZdcTask { histos.fill(HIST("hEventCounter"), EvCutLabel::Zem); } + const double normT0M{(aT0A + aT0C) / 100.}; float znA = zdc.amplitudeZNA() / cfgCollisionEnergy; float znC = zdc.amplitudeZNC() / cfgCollisionEnergy; float zpA = zdc.amplitudeZPA() / cfgCollisionEnergy; @@ -506,7 +539,50 @@ struct FlowZdcTask { } glbTracks++; } + bool skipEvent{false}; + if (useMidRapNchSel) { + auto hMeanNch = ccdb->getForTimeStamp(paTHmeanNch.value, foundBC.timestamp()); + auto hSigmaNch = ccdb->getForTimeStamp(paTHsigmaNch.value, foundBC.timestamp()); + if (!hMeanNch) { + LOGF(info, "hMeanNch NOT LOADED!"); + return; + } + if (!hSigmaNch) { + LOGF(info, "hSigmaNch NOT LOADED!"); + return; + } + const int binT0M{hMeanNch->FindBin(normT0M)}; + const double meanNch{hMeanNch->GetBinContent(binT0M)}; + const double sigmaNch{hSigmaNch->GetBinContent(binT0M)}; + const double nSigmaSelection{nSigmaNchCut * sigmaNch}; + const double diffMeanNch{meanNch - glbTracks}; + + if (!(std::abs(diffMeanNch) < nSigmaSelection)) { + histos.fill(HIST("ExcludedEvtVsNch"), glbTracks); + } else { + skipEvent = true; + } + } + if (!skipEvent) { + return; + } + + for (const auto& track : tracks) { + // Track Selection + if (!track.isGlobalTrack()) { + continue; + } + if ((track.pt() < minPt) || (track.pt() > maxPtSpectra)) { + continue; + } + + histos.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); + histos.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + histos.fill(HIST("dcaXYvspT"), track.dcaXY(), track.pt()); + et += std::sqrt(std::pow(track.pt(), 2.) + std::pow(o2::constants::physics::MassPionCharged, 2.)); + meanpt += track.pt(); + } histos.fill(HIST("zPos"), collision.posZ()); histos.fill(HIST("T0Ccent"), collision.centFT0C()); @@ -574,18 +650,12 @@ struct FlowZdcTask { int globalTracks = tracks.size(); if (globalTracks < 1) return; - // this is the q vector for the TPC data. it is a complex function - double qTpcReal = 0.0; // Initialize qTPC_real - double qTpcIm = 0.0; // init qTPC_imaginary - std::complex qTPC(0, 0); // Starting with a q-vector of zero int nTot{0}; // Tracks are already filtered with GlobalTrack || GlobalTrackSDD for (const auto& track : tracks) { - double phi = track.phi(); nTot++; histos.fill(HIST("etaHistogram"), track.eta()); histos.fill(HIST("phiHistogram"), track.phi()); histos.fill(HIST("ptHistogram"), track.pt()); - qTPC += std::complex(std::cos(2.0 * phi), std::sin(2.0 * phi)); } // end track loop 1 double pT{0}; for (const auto& track : tracks) { @@ -599,16 +669,9 @@ struct FlowZdcTask { histos.fill(HIST("multvsCent"), cent, nTot); histos.fill(HIST("hYield"), nTot, pT); histos.fill(HIST("multHistogram"), nTot); - qTpcReal = qTPC.real() / nTot; // normalize these vectors by the total number of particles - qTpcIm = qTPC.imag() / nTot; - - histos.fill(HIST("REqHistogram"), qTpcReal); - histos.fill(HIST("IMqHistogram"), qTpcIm); histos.fill(HIST("TPCmultiplicity"), multTPC); histos.fill(HIST("hGlobalTracks"), globalTracks); - - histos.fill(HIST("revsimag"), qTpcReal, qTpcIm); } void processZdcCollAssoc( AodCollisions::iterator const& collision, From b94e4fbb18514a70c75bd27077a6e4a7514f1319 Mon Sep 17 00:00:00 2001 From: Noor Koster <82090643+cnkoster@users.noreply.github.com> Date: Thu, 12 Jun 2025 16:55:59 +0200 Subject: [PATCH 50/62] [Common] Add timestamp, centrality and evSelection to inter-calib table (#11457) Co-authored-by: ALICE Action Bot --- Common/DataModel/ZDCInterCalib.h | 35 +++--- Common/TableProducer/CMakeLists.txt | 4 +- ...k-intercalib.cxx => zdcTaskInterCalib.cxx} | 116 ++++++++++++++++-- 3 files changed, 129 insertions(+), 26 deletions(-) rename Common/TableProducer/{zdc-task-intercalib.cxx => zdcTaskInterCalib.cxx} (53%) diff --git a/Common/DataModel/ZDCInterCalib.h b/Common/DataModel/ZDCInterCalib.h index 290a3ac61fe..d7b66575340 100644 --- a/Common/DataModel/ZDCInterCalib.h +++ b/Common/DataModel/ZDCInterCalib.h @@ -20,21 +20,23 @@ namespace o2::aod { -namespace znoutput +namespace znoutput // o2-linter: disable=name/workflow-file { -DECLARE_SOA_COLUMN(ZNApmc, commonPMZNA, float); //! PMC ZNA // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNApm1, ZNAPM1, float); //! PM1 ZNA // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNApm2, ZNAPM2, float); //! PM2 ZNA // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNApm3, ZNAPM3, float); //! PM3 ZNA // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNApm4, ZNAPM4, float); //! PM4 ZNA // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNAtdc, ZNATDC, float); //! TDC ZNA // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNCpmc, commonPMZNC, float); //! PMC ZNC // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNCpm1, ZNCPM1, float); //! PM1 ZNC // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNCpm2, ZNCPM2, float); //! PM2 ZNC // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNCpm3, ZNCPM3, float); //! PM3 ZNC // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNCpm4, ZNCPM4, float); //! PM4 ZNC // o2-linter: disable=name/o2-column -DECLARE_SOA_COLUMN(ZNCtdc, ZNCTDC, float); //! TDC ZNC // o2-linter: disable=name/o2-column - +DECLARE_SOA_COLUMN(ZNApmc, commonPMZNA, float); //! PMC ZNA // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNApm1, ZNAPM1, float); //! PM1 ZNA // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNApm2, ZNAPM2, float); //! PM2 ZNA // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNApm3, ZNAPM3, float); //! PM3 ZNA // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNApm4, ZNAPM4, float); //! PM4 ZNA // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNAtdc, ZNATDC, float); //! TDC ZNA // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNCpmc, commonPMZNC, float); //! PMC ZNC // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNCpm1, ZNCPM1, float); //! PM1 ZNC // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNCpm2, ZNCPM2, float); //! PM2 ZNC // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNCpm3, ZNCPM3, float); //! PM3 ZNC // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNCpm4, ZNCPM4, float); //! PM4 ZNC // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(ZNCtdc, ZNCTDC, float); //! TDC ZNC // o2-linter: disable=name/o2-column +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Centrality +DECLARE_SOA_COLUMN(Timestamp, timestamp, uint64_t); //! Timestamp +DECLARE_SOA_COLUMN(SelectionBits, selectionBits, uint8_t); //! Selection Flags } // namespace znoutput DECLARE_SOA_TABLE(ZDCInterCalib, "AOD", "ZDCIC", o2::soa::Index<>, @@ -49,7 +51,10 @@ DECLARE_SOA_TABLE(ZDCInterCalib, "AOD", "ZDCIC", o2::soa::Index<>, znoutput::ZNCpm2, znoutput::ZNCpm3, znoutput::ZNCpm4, - znoutput::ZNCtdc); + znoutput::ZNCtdc, + znoutput::Centrality, + znoutput::Timestamp, + znoutput::SelectionBits); } // namespace o2::aod #endif // COMMON_DATAMODEL_ZDCINTERCALIB_H_ diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 1d6918d6121..d2d59ea2506 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -125,8 +125,8 @@ o2physics_add_dpl_workflow(match-mft-ft0 O2::DetectorsBase O2::DetectorsCommonDataFormats COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(zdc-task-intercalib - SOURCES zdc-task-intercalib.cxx +o2physics_add_dpl_workflow(zdc-task-inter-calib + SOURCES zdcTaskInterCalib.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/Common/TableProducer/zdc-task-intercalib.cxx b/Common/TableProducer/zdcTaskInterCalib.cxx similarity index 53% rename from Common/TableProducer/zdc-task-intercalib.cxx rename to Common/TableProducer/zdcTaskInterCalib.cxx index 77b590bde57..78054580b81 100644 --- a/Common/TableProducer/zdc-task-intercalib.cxx +++ b/Common/TableProducer/zdcTaskInterCalib.cxx @@ -9,12 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file zdc-task-intercalib.cxx +/// \file zdcTaskInterCalib.cxx /// \brief Task for ZDC tower inter-calibration /// \author chiara.oppedisano@cern.ch -// o2-linter: disable=name/workflow-file -// o2-linter: disable=name/file-cpp #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/HistogramRegistry.h" @@ -35,9 +33,9 @@ using namespace o2::framework::expressions; using namespace o2::aod::evsel; using BCsRun3 = soa::Join; -using ColEvSels = soa::Join; +using ColEvSels = soa::Join; -struct ZDCCalibTower { +struct ZdcTaskInterCalib { Produces zTab; @@ -48,9 +46,32 @@ struct ZDCCalibTower { Configurable tdcCut{"tdcCut", false, "Flag for TDC cut"}; Configurable tdcZNmincut{"tdcZNmincut", -2.5, "Min ZN TDC cut"}; Configurable tdcZNmaxcut{"tdcZNmaxcut", -2.5, "Max ZN TDC cut"}; + // Event selections + Configurable cfgEvSelSel8{"cfgEvSelSel8", true, "Event selection: sel8"}; + Configurable cfgEvSelVtxZ{"cfgEvSelVtxZ", 10, "Event selection: zVtx"}; + Configurable cfgEvSelsDoOccupancySel{"cfgEvSelsDoOccupancySel", true, "Event selection: do occupancy selection"}; + Configurable cfgEvSelsMaxOccupancy{"cfgEvSelsMaxOccupancy", 10000, "Event selection: set max occupancy"}; + Configurable cfgEvSelsNoSameBunchPileupCut{"cfgEvSelsNoSameBunchPileupCut", true, "Event selection: no same bunch pileup cut"}; + Configurable cfgEvSelsIsGoodZvtxFT0vsPV{"cfgEvSelsIsGoodZvtxFT0vsPV", true, "Event selection: is good ZVTX FT0 vs PV"}; + Configurable cfgEvSelsNoCollInTimeRangeStandard{"cfgEvSelsNoCollInTimeRangeStandard", true, "Event selection: no collision in time range standard"}; + Configurable cfgEvSelsIsVertexITSTPC{"cfgEvSelsIsVertexITSTPC", true, "Event selection: is vertex ITSTPC"}; + Configurable cfgEvSelsIsGoodITSLayersAll{"cfgEvSelsIsGoodITSLayersAll", true, "Event selection: is good ITS layers all"}; // HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + enum SelectionCriteria { + evSel_zvtx, + evSel_sel8, + evSel_occupancy, + evSel_kNoSameBunchPileup, + evSel_kIsGoodZvtxFT0vsPV, + evSel_kNoCollInTimeRangeStandard, + evSel_kIsVertexITSTPC, + evSel_kIsGoodITSLayersAll, + evSel_allEvents, + nEventSelections + }; + void init(InitContext const&) { registry.add("ZNApmc", "ZNApmc; ZNA PMC; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}}); @@ -65,16 +86,93 @@ struct ZDCCalibTower { registry.add("ZNCpm4", "ZNCpm4; ZNC PM4; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}}); registry.add("ZNAsumq", "ZNAsumq; ZNA uncalib. sum PMQ; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}}); registry.add("ZNCsumq", "ZNCsumq; ZNC uncalib. sum PMQ; Entries", {HistType::kTH1F, {{nBins, -0.5, maxZN}}}); + + registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_allEvents + 1, "All events"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_zvtx + 1, "vtxZ"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kkIsGoodITSLayersAll"); + } + + template + uint8_t eventSelected(TCollision collision) + { + uint8_t selectionBits = 0; + bool selected; + + registry.fill(HIST("hEventCount"), evSel_allEvents); + + selected = std::fabs(collision.posZ()) < cfgEvSelVtxZ; + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_zvtx); + registry.fill(HIST("hEventCount"), evSel_zvtx); + } + + selected = collision.sel8(); + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_sel8); + registry.fill(HIST("hEventCount"), evSel_sel8); + } + + auto occupancy = collision.trackOccupancyInTimeRange(); + selected = occupancy <= cfgEvSelsMaxOccupancy; + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_occupancy); + registry.fill(HIST("hEventCount"), evSel_occupancy); + } + + selected = collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup); + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_kNoSameBunchPileup); + registry.fill(HIST("hEventCount"), evSel_kNoSameBunchPileup); + } + + selected = collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV); + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_kIsGoodZvtxFT0vsPV); + registry.fill(HIST("hEventCount"), evSel_kIsGoodZvtxFT0vsPV); + } + + selected = collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard); + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_kNoCollInTimeRangeStandard); + registry.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeStandard); + } + + selected = collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC); + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_kIsVertexITSTPC); + registry.fill(HIST("hEventCount"), evSel_kIsVertexITSTPC); + } + + selected = collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll); + if (selected) { + selectionBits |= (uint8_t)(0x1u << evSel_kIsGoodITSLayersAll); + registry.fill(HIST("hEventCount"), evSel_kIsGoodITSLayersAll); + } + + return selectionBits; } void process(ColEvSels const& cols, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcs*/) { // collision-based event selection + int nTowers = 4; // number of ZDC towers + for (auto const& collision : cols) { const auto& foundBC = collision.foundBC_as(); if (foundBC.has_zdc()) { const auto& zdc = foundBC.zdc(); + uint8_t evSelection = eventSelected(collision); + + float centrality = collision.centFT0C(); + // To assure that ZN have a genuine signal (tagged by the relative TDC) // we can check that the amplitude is >0 or that ADC is NOT very negative (-inf) @@ -117,7 +215,7 @@ struct ZDCCalibTower { }; // if (isZNChit) { - for (int it = 0; it < 4; it++) { + for (int it = 0; it < nTowers; it++) { pmqZNC[it] = (zdc.energySectorZNC())[it]; sumZNC += pmqZNC[it]; } @@ -129,7 +227,7 @@ struct ZDCCalibTower { registry.get(HIST("ZNCsumq"))->Fill(sumZNC); } if (isZNAhit) { - for (int it = 0; it < 4; it++) { + for (int it = 0; it < nTowers; it++) { pmqZNA[it] = (zdc.energySectorZNA())[it]; sumZNA += pmqZNA[it]; } @@ -142,7 +240,7 @@ struct ZDCCalibTower { registry.get(HIST("ZNAsumq"))->Fill(sumZNA); } if (isZNAhit || isZNChit) - zTab(pmcZNA, pmqZNA[0], pmqZNA[1], pmqZNA[2], pmqZNA[3], tdcZNC, pmcZNC, pmqZNC[0], pmqZNC[1], pmqZNC[2], pmqZNC[3], tdcZNA); + zTab(pmcZNA, pmqZNA[0], pmqZNA[1], pmqZNA[2], pmqZNA[3], tdcZNC, pmcZNC, pmqZNC[0], pmqZNC[1], pmqZNC[2], pmqZNC[3], tdcZNA, centrality, foundBC.timestamp(), evSelection); } } } @@ -151,5 +249,5 @@ struct ZDCCalibTower { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) // o2-linter: disable=name/file-cpp { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } From ae6cdfd02bb32f00ac69a788820a3d8d7e73aeeb Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:02:14 +0200 Subject: [PATCH 51/62] Add flag to disable its rof cut (#11572) Co-authored-by: Francesco Mazzaschi --- PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx | 51 ++++++++++---------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx index 09ed3ec07b8..5a8624e50e1 100644 --- a/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx @@ -11,39 +11,39 @@ // // Build hypertriton candidates from V0s and tracks -#include -#include -#include -#include -#include +#include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGLF/DataModel/LFHypernucleiTables.h" +#include "PWGLF/Utils/svPoolCreator.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" - +#include "Common/TableProducer/PID/pidTOFBase.h" #include "EventFiltering/Zorro.h" #include "EventFiltering/ZorroSummary.h" -#include "Common/Core/PID/TPCPIDResponse.h" -#include "Common/Core/PID/PIDTOF.h" -#include "Common/TableProducer/PID/pidTOFBase.h" -#include "DataFormatsTPC/BetheBlochAleph.h" +#include "CCDB/BasicCCDBManager.h" #include "DCAFitter/DCAFitterN.h" -#include "PWGLF/Utils/svPoolCreator.h" -#include "PWGLF/DataModel/LFHypernucleiTables.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -168,6 +168,7 @@ struct hyperRecoTask { Configurable useCustomVertexer{"useCustomVertexer", false, "Use custom vertexer"}; Configurable skipAmbiTracks{"skipAmbiTracks", false, "Skip ambiguous tracks"}; + Configurable disableITSROFCut{"disableITSROFCut", false, "Disable ITS ROC cut for event selection"}; Configurable customVertexerTimeMargin{"customVertexerTimeMargin", 800, "Time margin for custom vertexer (ns)"}; Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 1, 6, particleName, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for He3"}; Configurable cfgCompensatePIDinTracking{"cfgCompensatePIDinTracking", true, "If true, divide tpcInnerParam by the electric charge"}; @@ -341,7 +342,7 @@ struct hyperRecoTask { initCCDB(bc); hEvents->Fill(0.); - if (!collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + if (!collision.selection_bit(aod::evsel::kNoITSROFrameBorder) && !disableITSROFCut) { continue; } From d7dfc739dd392a055f953eec8a5fae549f12503d Mon Sep 17 00:00:00 2001 From: Artem Kotliarov <71133985+KotliarovAr@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:44:43 +0200 Subject: [PATCH 52/62] [PWGJE] PWGJE Change scheme for outlier removal (#11577) --- PWGJE/Tasks/recoilJets.cxx | 117 +++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/PWGJE/Tasks/recoilJets.cxx b/PWGJE/Tasks/recoilJets.cxx index f39d1c9fe25..26abd49517a 100644 --- a/PWGJE/Tasks/recoilJets.cxx +++ b/PWGJE/Tasks/recoilJets.cxx @@ -13,35 +13,33 @@ /// \file recoilJets.cxx /// \brief hadron-jet correlation analysis -#include -#include -#include +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/DataModel/Jet.h" -#include "TRandom3.h" -#include "TVector2.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/filterTables.h" +#include "CommonConstants/MathConstants.h" #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" -#include "CommonConstants/MathConstants.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "PWGJE/Core/FastJetUtilities.h" -#include "PWGJE/Core/JetFinder.h" -#include "PWGJE/Core/JetFindingUtilities.h" -#include "PWGJE/DataModel/Jet.h" - -#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "TRandom3.h" +#include "TVector2.h" -#include "EventFiltering/filterTables.h" +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -82,7 +80,6 @@ struct RecoilJets { // List of configurable parameters for MC Configurable pTHatExponent{"pTHatExponent", 4.0, "Exponent of the event weight for the calculation of pTHat"}; Configurable pTHatMax{"pTHatMax", 999.0, "Maximum fraction of hard scattering for jet acceptance in MC"}; - Configurable pTHatMaxTrack{"pTHatMaxTrack", 999.0, "Maximum fraction of hard scattering for track acceptance in MC"}; // Parameters for recoil jet selection Configurable ptTTrefMin{"ptTTrefMin", 5., "Minimum pT of reference TT"}; @@ -130,17 +127,29 @@ struct RecoilJets { void init(InitContext const&) { - eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(evSel)); - trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trkSel)); + std::string evSelToString = static_cast(evSel); + std::string trkSelToString = static_cast(trkSel); + + eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(evSelToString); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(trkSelToString); triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); // List of raw and MC det. distributions if (doprocessData || doprocessMCDetLevel || doprocessMCDetLevelWeighted) { + spectra.add("hEventSelectionCount", "Count # of events in the analysis", kTH1F, {{3, 0.0, 3.}}); + spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(1, "Total # of events"); + spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(2, Form("# of events after sel. %s", evSelToString.data())); + spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(3, "# of events w. outlier"); + spectra.add("vertexZ", "Z vertex of collisions", kTH1F, {{60, -12., 12.}}); spectra.add("hHasAssocMcCollision", "Has det. level coll. associat. MC coll.", kTH1F, {{2, 0.0, 2.}}); spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(1, "Yes"); spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(2, "No"); + spectra.add("hTrackSelectionCount", "Count # of tracks in the analysis", kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hTrackSelectionCount"))->GetXaxis()->SetBinLabel(1, "Total # of tracks"); + spectra.get(HIST("hTrackSelectionCount"))->GetXaxis()->SetBinLabel(2, Form("# of tracks after sel. %s", trkSelToString.data())); + spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, {pT, pseudorap, phiAngle}); spectra.add("hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, {{40, 10., 50.}}); // needed to distinguish merged data from diff. wagons @@ -228,28 +237,33 @@ struct RecoilJets { // Fill histograms with raw or MC det. level data template - void fillHistograms(Collision const& collision, Jets const& jets, Tracks const& tracks, bool bIsMC = false, float weight = 1.) + void fillHistograms(Collision const& collision, Jets const& jets, Tracks const& tracks, float weight = 1.) { - bool bSigEv = false; std::vector vPhiOfTT; double phiTT = 0.; int nTT = 0; - float pTHat = 0.; - if (bIsMC) - pTHat = getPtHat(weight); + float pTHat = getPtHat(weight); auto dice = rand->Rndm(); if (dice < fracSig) bSigEv = true; + // Remove whole event if jet passes the outlier removal condition + for (const auto& jet : jets) { + if (jet.pt() > pTHatMax * pTHat) { + spectra.fill(HIST("hEventSelectionCount"), 2.5); + return; + } + } + for (const auto& track : tracks) { - if (skipTrack(track)) - continue; + spectra.fill(HIST("hTrackSelectionCount"), 0.5); - if (bIsMC && (track.pt() > pTHatMaxTrack * pTHat)) + if (skipTrack(track)) continue; + spectra.fill(HIST("hTrackSelectionCount"), 1.5); spectra.fill(HIST("hTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), weight); // Search for TT candidate @@ -279,10 +293,6 @@ struct RecoilJets { } for (const auto& jet : jets) { - - if (bIsMC && (jet.pt() > pTHatMax * pTHat)) - continue; - spectra.fill(HIST("hJetPtEtaPhiRhoArea"), jet.pt(), jet.eta(), jet.phi(), collision.rho(), jet.area(), weight); if (nTT > 0) { @@ -327,6 +337,11 @@ struct RecoilJets { if (dice < fracSig) bSigEv = true; + for (const auto& jet : jets) { + if (jet.pt() > pTHatMax * pTHat) + return; + } + for (const auto& particle : particles) { auto pdgParticle = pdg->GetParticle(particle.pdgCode()); if (!pdgParticle) @@ -337,9 +352,6 @@ struct RecoilJets { if (bParticleNeutral || !particle.isPhysicalPrimary()) continue; - if (particle.pt() > pTHatMaxTrack * pTHat) - continue; - spectra.fill(HIST("hPartPtEtaPhi"), particle.pt(), particle.eta(), particle.phi(), weight); if (bSigEv && (particle.pt() > ptTTsigMin && particle.pt() < ptTTsigMax)) { @@ -367,10 +379,6 @@ struct RecoilJets { } for (const auto& jet : jets) { - - if (jet.pt() > pTHatMax * pTHat) - continue; - spectra.fill(HIST("hJetPtEtaPhiRhoArea_Part"), jet.pt(), jet.eta(), jet.phi(), collision.rho(), jet.area(), weight); if (nTT > 0) { @@ -410,13 +418,15 @@ struct RecoilJets { double phiTTSig = 0.; float pTHat = getPtHat(weight); + for (const auto& jetBase : jetsBase) { + if (jetBase.pt() > pTHatMax * pTHat) + return; + } + for (const auto& track : tracks) { if (skipTrack(track)) continue; - if (track.pt() > pTHatMaxTrack * pTHat) - continue; - if (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax) { vPhiOfTT.push_back(track.phi()); } @@ -428,9 +438,6 @@ struct RecoilJets { phiTTSig = getPhiTT(vPhiOfTT); for (const auto& jetBase : jetsBase) { - if (jetBase.pt() > pTHatMax * pTHat) - continue; - bool bIsBaseJetRecoil = get<1>(isRecoilJet(jetBase, phiTTSig)) && bIsThereTTSig; dataForUnfolding(jetBase, jetsTag, bIsBaseJetRecoil, weight); } @@ -440,9 +447,13 @@ struct RecoilJets { FilteredTracks const& tracks, FilteredJets const& jets) { + spectra.fill(HIST("hEventSelectionCount"), 0.5); + if (skipEvent(collision)) return; + spectra.fill(HIST("hEventSelectionCount"), 1.5); + spectra.fill(HIST("vertexZ"), collision.posZ()); fillHistograms(collision, jets, tracks); } @@ -452,11 +463,14 @@ struct RecoilJets { FilteredTracks const& tracks, FilteredJetsDetLevel const& jets) { + spectra.fill(HIST("hEventSelectionCount"), 0.5); if (skipEvent(collision) || skipMBGapEvent(collision)) return; + spectra.fill(HIST("hEventSelectionCount"), 1.5); + spectra.fill(HIST("vertexZ"), collision.posZ()); - fillHistograms(collision, jets, tracks, true); + fillHistograms(collision, jets, tracks); } PROCESS_SWITCH(RecoilJets, processMCDetLevel, "process MC detector level", false); @@ -465,9 +479,12 @@ struct RecoilJets { FilteredTracks const& tracks, FilteredJetsDetLevel const& jets) { + spectra.fill(HIST("hEventSelectionCount"), 0.5); if (skipEvent(collision) || skipMBGapEvent(collision)) return; + spectra.fill(HIST("hEventSelectionCount"), 1.5); + auto weight = collision.mcCollision().weight(); spectra.fill(HIST("vertexZ"), collision.posZ(), weight); @@ -477,7 +494,7 @@ struct RecoilJets { spectra.fill(HIST("hHasAssocMcCollision"), 1.5, weight); } - fillHistograms(collision, jets, tracks, true, weight); + fillHistograms(collision, jets, tracks, weight); } PROCESS_SWITCH(RecoilJets, processMCDetLevelWeighted, "process MC detector level with event weight", false); From e17f0f35ba9334edef775c795c87f0cbc3e8af11 Mon Sep 17 00:00:00 2001 From: prottayCMT <61418725+prottayCMT@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:17:27 +0200 Subject: [PATCH 53/62] [PWGLF] adjusted size of 2D array for mixing in derived data (#11583) Co-authored-by: Prottay Das --- PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx index 33157c327bf..be85c214406 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -985,8 +985,8 @@ struct LfTaskLambdaSpinCorr { auto groupV02 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.index()); auto groupV03 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision2.index()); - size_t rows = groupV03.size() + 20; - size_t cols = groupV01.size() + 20; + size_t rows = groupV03.size() + 1600; + size_t cols = groupV01.size() + 1600; std::vector> pairStatus(rows, std::vector(cols, false)); histos.fill(HIST("hv0Mult"), groupV01.size()); for (auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02))) { From 03ab1da17f2ef0f5030fd5a9c6ae9fb1bcf62997 Mon Sep 17 00:00:00 2001 From: Zhiyong <71517277+Luzhiyongg@users.noreply.github.com> Date: Fri, 13 Jun 2025 03:20:06 +0800 Subject: [PATCH 54/62] [PWGCF] add TPC cross row (#11574) --- PWGCF/Flow/Tasks/flowTask.cxx | 6 ++- .../Tasks/diHadronCor.cxx | 39 ++++++++++++------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index 4390131be3a..7477aa90aed 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -65,7 +65,8 @@ struct FlowTask { O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "Maximal pT for all tracks") O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") - O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 70.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") O2_DEFINE_CONFIGURABLE(cfgCutDCAxyppPass3Enabled, bool, false, "switch of ppPass3 DCAxy pt dependent cut") @@ -477,6 +478,7 @@ struct FlowTask { myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); myTrackSel.SetMinNClustersTPC(cfgCutTPCclu); + myTrackSel.SetMinNCrossedRowsTPC(cfgCutTPCCrossedRows); myTrackSel.SetMinNClustersITS(cfgCutITSclu); if (cfgCutDCAxyppPass3Enabled) myTrackSel.SetMaxDcaXYPtDep([](float pt) { return 0.004f + 0.013f / pt; }); // Tuned on the LHC22f anchored MC LHC23d1d on primary pions. 7 Sigmas of the resolution @@ -686,7 +688,7 @@ struct FlowTask { if (cfgTrkSelSwitch) { return myTrackSel.IsSelected(track); } else { - return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.itsNCls() >= cfgCutITSclu)); + return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgCutITSclu)); } } diff --git a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx index 189e201ef68..e79c61b3096 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -62,7 +62,8 @@ struct DiHadronCor { O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "maximum accepted track pT") O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta cut") O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") - O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 70.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") O2_DEFINE_CONFIGURABLE(cfgCutMerging, float, 0.0, "Merging cut on track merge") @@ -242,7 +243,11 @@ struct DiHadronCor { LOGF(fatal, "Full simulation and on-the-fly processing of mixed event not supported"); } if (doprocessMCSame || doprocessOntheflySame) { - registry.add("MCTrue/MCeventcount", "MCeventcount", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event + registry.add("MCTrue/MCeventcount", "MCeventcount", {HistType::kTH1F, {{5, 0, 5, "bin"}}}); // histogram to see how many events are in the same and mixed event + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(2, "same all"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(3, "same reco"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(4, "mixed all"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(5, "mixed reco"); registry.add("MCTrue/MCCentrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); registry.add("MCTrue/MCNch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); registry.add("MCTrue/MCzVtx", "MCzVtx", {HistType::kTH1D, {axisVertex}}); @@ -254,13 +259,15 @@ struct DiHadronCor { registry.add("MCTrue/MCdeltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); } if (doprocessMCEfficiency) { - registry.add("MCEffeventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); - registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(1, "MC"); - registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(2, "Reco Primary"); - registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(3, "Reco All"); - registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(4, "Fake"); + registry.add("MCEffeventcount", "bin", {HistType::kTH1F, {{5, 0, 5, "bin"}}}); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(1, "All"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(2, "MC"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(3, "Reco Primary"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(4, "Reco All"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(5, "Fake"); } + LOGF(info, "Initializing correlation container"); std::vector corrAxis = {{axisSample, "Sample"}, {axisVertex, "z-vtx (cm)"}, {axisPtTrigger, "p_{T} (GeV/c)"}, @@ -276,6 +283,8 @@ struct DiHadronCor { same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); + + LOGF(info, "End of init"); } int getMagneticField(uint64_t timestamp) @@ -319,7 +328,7 @@ struct DiHadronCor { template bool trackSelected(TTrack track) { - return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.itsNCls() >= cfgCutITSclu)); + return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgCutITSclu)); } template @@ -727,13 +736,14 @@ struct DiHadronCor { void processMCEfficiency(FilteredMcCollisions::iterator const& mcCollision, soa::SmallGroups> const& collisions, FilteredMcParticles const& mcParticles, FilteredTracksWithMCLabels const& tracks) { - if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + registry.fill(HIST("MCEffeventcount"), 0.5); + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { return; } // Primaries for (const auto& mcParticle : mcParticles) { if (mcParticle.isPhysicalPrimary()) { - registry.fill(HIST("MCEffeventcount"), 0.5); + registry.fill(HIST("MCEffeventcount"), 1.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::MC, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); } } @@ -746,16 +756,16 @@ struct DiHadronCor { for (const auto& track : groupedTracks) { if (track.has_mcParticle()) { - const auto& mcParticle = track.mcParticle(); + auto mcParticle = track.mcParticle(); if (mcParticle.isPhysicalPrimary()) { - registry.fill(HIST("MCEffeventcount"), 1.5); + registry.fill(HIST("MCEffeventcount"), 2.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoPrimaries, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); } - registry.fill(HIST("MCEffeventcount"), 2.5); + registry.fill(HIST("MCEffeventcount"), 3.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoAll, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); } else { // fake track - registry.fill(HIST("MCEffeventcount"), 3.5); + registry.fill(HIST("MCEffeventcount"), 4.5); same->getTrackHistEfficiency()->Fill(CorrelationContainer::Fake, track.eta(), track.pt(), 0, 0., mcCollision.posZ()); } } @@ -858,6 +868,7 @@ struct DiHadronCor { continue; } + registry.fill(HIST("MCTrue/MCeventcount"), 4.5); fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); } } From b414ac269c181860f2e52a5b6dd48c2a2169befa Mon Sep 17 00:00:00 2001 From: dajones2 <140733426+dajones2@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:20:09 +0100 Subject: [PATCH 55/62] [PWGJE] Fixing recoil jet response to fill with delta phi (#11578) --- PWGJE/Tasks/jetHadronRecoil.cxx | 108 ++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 33 deletions(-) diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index 71946c49aee..97cd31cfb5c 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -446,17 +446,6 @@ struct JetHadronRecoil { return; } - for (const auto& mcdjetWTA : mcdjetsWTA) { - double djet = RecoDecay::sqrtSumOfSquares(RecoDecay::constrainAngle(jetBase.phi() - mcdjetWTA.phi(), -o2::constants::math::PI), jetBase.eta() - mcdjetWTA.eta()); - if (mcdjetWTA.pt() > pTHatMaxMCD * pTHat) { - continue; - } - if (djet < 0.6 * jetR) { - dR = djet; - break; - } - } - dR = getWTAaxisDifference(jetBase, mcdjetsWTA, tracks, true); if (jetBase.has_matchedJetGeo()) { @@ -481,6 +470,77 @@ struct JetHadronRecoil { } } + template + void fillRecoilJetMatchedHistograms(T const& jetsBase, V const& mcdjetsWTA, W const& mcpjetsWTA, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0) + { + std::vector phiTTAr; + std::vector phiTTArPart; + double phiTT = 0; + double phiTTPart = 0; + int trigNumber = 0; + int nTT = 0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + + for (const auto& track : tracks) { + if (!track.has_mcParticle()) { + continue; + } + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + if (track.pt() > pTHatTrackMaxMCD * pTHat) { + return; + } + if (track.pt() < ptTTsigMax && track.pt() > ptTTsigMin) { + phiTTAr.push_back(track.phi()); + nTT++; + auto particle = track.template mcParticle_as(); + phiTTArPart.push_back(particle.phi()); + } + } + + if (nTT > 0) { + trigNumber = rand->Integer(nTT); + phiTT = phiTTAr[trigNumber]; + phiTTPart = phiTTAr[trigNumber]; + } else { + return; + } + + for (const auto& jetBase : jetsBase) { + double dR = 0; + double dRp = 0; + + if (jetBase.pt() > pTHatMaxMCD * pTHat) { + return; + } + + float dphi = RecoDecay::constrainAngle(jetBase.phi() - phiTT); + dR = getWTAaxisDifference(jetBase, mcdjetsWTA, tracks, true); + + if (jetBase.has_matchedJetGeo()) { + for (const auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + return; + } + + float dphip = RecoDecay::constrainAngle(jetTag.phi() - phiTTPart); + dRp = getWTAaxisDifference(jetTag, mcpjetsWTA, particles, true); + + registry.fill(HIST("hPtMatched"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), weight); + registry.fill(HIST("hPhiMatched"), dphi, dphip, weight); + registry.fill(HIST("hPtResolution"), jetTag.pt(), (jetTag.pt() - (jetBase.pt() - (rho * jetBase.area()))) / jetTag.pt(), weight); + registry.fill(HIST("hPhiResolution"), dphip, dphip - dphi, weight); + registry.fill(HIST("hDeltaRMatched"), dR, dRp, weight); + registry.fill(HIST("hDeltaRResolution"), jetTag.pt(), dRp - dR, weight); + registry.fill(HIST("hFullMatching"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), dphi, dphip, dR, dRp, weight); + registry.fill(HIST("hPtMatched1d"), jetTag.pt(), weight); + registry.fill(HIST("hDeltaRMatched1d"), dRp, weight); + } + } + } + } + void processData(soa::Filtered::iterator const& collision, soa::Filtered> const& jets, soa::Filtered> const& jetsWTA, @@ -711,7 +771,7 @@ struct JetHadronRecoil { soa::Filtered> const& mcdjets, soa::Filtered> const& mcdjetsWTA, soa::Filtered> const& mcpjetsWTA, - soa::Filtered const& tracks, + soa::Filtered const& tracks, soa::Filtered const& particles, aod::JetMcCollisions const&, soa::Filtered> const& mcpjets) @@ -724,16 +784,7 @@ struct JetHadronRecoil { } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - bool ishJetEvent = false; - for (const auto& track : tracks) { - if (track.pt() < ptTTsigMax && track.pt() > ptTTsigMin) { - ishJetEvent = true; - break; - } - } - if (ishJetEvent) { - fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); - } + fillRecoilJetMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); } PROCESS_SWITCH(JetHadronRecoil, processRecoilJetsMCPMCDMatched, "process MC matched (recoil jets)", false); @@ -741,7 +792,7 @@ struct JetHadronRecoil { soa::Filtered> const& mcdjets, soa::Filtered> const& mcdjetsWTA, soa::Filtered> const& mcpjetsWTA, - soa::Filtered const& tracks, + soa::Filtered const& tracks, soa::Filtered const& particles, aod::JetMcCollisions const&, soa::Filtered> const& mcpjets) @@ -754,16 +805,7 @@ struct JetHadronRecoil { } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - bool ishJetEvent = false; - for (const auto& track : tracks) { - if (track.pt() < ptTTsigMax && track.pt() > ptTTsigMin) { - ishJetEvent = true; - break; - } - } - if (ishJetEvent) { - fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight()); - } + fillRecoilJetMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight()); } PROCESS_SWITCH(JetHadronRecoil, processRecoilJetsMCPMCDMatchedWeighted, "process MC matched with event weights (recoil jets)", false); From 732a7296b1cf1a38165b973e9103c060ac8dcc63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 12 Jun 2025 22:35:43 +0200 Subject: [PATCH 56/62] [PWGLF] Update inelGt.h (#11579) Co-authored-by: ALICE Builder --- PWGLF/Utils/inelGt.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PWGLF/Utils/inelGt.h b/PWGLF/Utils/inelGt.h index 2ed513a902c..70c3de8ab4f 100644 --- a/PWGLF/Utils/inelGt.h +++ b/PWGLF/Utils/inelGt.h @@ -19,6 +19,10 @@ #ifndef PWGLF_UTILS_INELGT_H_ #define PWGLF_UTILS_INELGT_H_ +#include "Framework/O2DatabasePDGPlugin.h" + +#include "TParticlePDG.h" + #include namespace o2 From bc8e7de3d8dccd251c696dbafbef36948d5c980a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 12 Jun 2025 22:40:10 +0200 Subject: [PATCH 57/62] [PWGHF,Tutorial] Include What You Use (#11589) --- Tutorials/PWGHF/skimCreatorMini.cxx | 2 -- Tutorials/PWGHF/taskMini.cxx | 1 - 2 files changed, 3 deletions(-) diff --git a/Tutorials/PWGHF/skimCreatorMini.cxx b/Tutorials/PWGHF/skimCreatorMini.cxx index 6fba171cfbf..e3aae5bbaf4 100644 --- a/Tutorials/PWGHF/skimCreatorMini.cxx +++ b/Tutorials/PWGHF/skimCreatorMini.cxx @@ -27,11 +27,9 @@ #include #include #include -#include #include #include #include -#include #include #include diff --git a/Tutorials/PWGHF/taskMini.cxx b/Tutorials/PWGHF/taskMini.cxx index 1876d6230cc..813e9879ce4 100644 --- a/Tutorials/PWGHF/taskMini.cxx +++ b/Tutorials/PWGHF/taskMini.cxx @@ -34,7 +34,6 @@ #include #include #include -#include #include #include From a8caa854f5e02bcaec9cc8fca804a3ee62f76489 Mon Sep 17 00:00:00 2001 From: EmilGorm <50658075+EmilGorm@users.noreply.github.com> Date: Fri, 13 Jun 2025 00:12:51 +0200 Subject: [PATCH 58/62] [PWGCF] Add flag to disable ITS based track selection cuts (#11576) --- PWGCF/Flow/Tasks/flowPtEfficiency.cxx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx index 78dbc0fc731..217b6f7fb36 100644 --- a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx +++ b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx @@ -60,6 +60,7 @@ struct FlowPtEfficiency { O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "DCAz cut for tracks") O2_DEFINE_CONFIGURABLE(cfgCutDCAxyppPass3Enabled, bool, false, "switch of ppPass3 DCAxy pt dependent cut") O2_DEFINE_CONFIGURABLE(cfgCutDCAzPtDepEnabled, bool, false, "switch of DCAz pt dependent cut") + O2_DEFINE_CONFIGURABLE(cfgEnableITSCuts, bool, true, "switch of enabling ITS based track selection cuts") O2_DEFINE_CONFIGURABLE(cfgSelRunNumberEnabled, bool, false, "switch of run number selection") O2_DEFINE_CONFIGURABLE(cfgFlowEnabled, bool, false, "switch of calculating flow") O2_DEFINE_CONFIGURABLE(cfgFlowNbootstrap, int, 30, "Number of subsamples") @@ -219,10 +220,12 @@ struct FlowPtEfficiency { fGFWReco->CreateRegions(); } - if (cfgTrkSelRun3ITSMatch) { - myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSall7Layers, TrackSelection::GlobalTrackRun3DCAxyCut::Default); - } else { - myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + if (cfgEnableITSCuts) { + if (cfgTrkSelRun3ITSMatch) { + myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSall7Layers, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + } else { + myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + } } if (cfgCutDCAxyppPass3Enabled) { myTrackSel.SetMaxDcaXYPtDep([](float pt) { return 0.004f + 0.013f / pt; }); @@ -230,8 +233,9 @@ struct FlowPtEfficiency { myTrackSel.SetMaxDcaXY(cfgCutDCAxy); } myTrackSel.SetMinNClustersTPC(cfgCutTPCclu); - myTrackSel.SetMinNClustersITS(cfgCutITSclu); myTrackSel.SetMinNCrossedRowsTPC(cfgCutTPCcrossedrows); + if (cfgEnableITSCuts) + myTrackSel.SetMinNClustersITS(cfgCutITSclu); if (!cfgCutDCAzPtDepEnabled) myTrackSel.SetMaxDcaZ(cfgCutDCAz); } @@ -358,10 +362,12 @@ struct FlowPtEfficiency { template bool trackSelected(TTrack track) { - if (cfgkIsTrackGlobal && !track.isGlobalTrack()) + if (cfgkIsTrackGlobal && !track.isGlobalTrack()) { return false; - if (cfgCutDCAzPtDepEnabled && (track.dcaZ() > (0.004f + 0.013f / track.pt()))) + } + if (cfgCutDCAzPtDepEnabled && (track.dcaZ() > (0.004f + 0.013f / track.pt()))) { return false; + } return myTrackSel.IsSelected(track); } @@ -378,7 +384,6 @@ struct FlowPtEfficiency { if (!std::count(cfgRunNumberList.value.begin(), cfgRunNumberList.value.end(), runNumber)) return; } - float imp = 0; bool impFetched = false; float evPhi = 0; @@ -393,7 +398,6 @@ struct FlowPtEfficiency { fGFWReco->Clear(); } - for (const auto& track : tracks) { if (!trackSelected(track)) continue; From 01af8e9cbdbe8d0c4f2a5ed51aa2b274f60b65f2 Mon Sep 17 00:00:00 2001 From: Pritam Chakraborty <47203359+prchakra@users.noreply.github.com> Date: Fri, 13 Jun 2025 01:27:43 +0200 Subject: [PATCH 59/62] [PWGCF] FemtoUniverse: Addidng 3D histo of qLCMS vs deta vs deta (#11594) --- .../Core/FemtoUniverseDetaDphiStar.h | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h index 0a06b3513e8..bc4c6f1ea4e 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h @@ -68,6 +68,9 @@ class FemtoUniverseDetaDphiStar histdetadpimixed[0][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); histdetadpimixed[0][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiqlcmssame = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][7])).c_str(), "; #it{q}_{LCMS}; #Delta #eta; #Delta #phi", kTH3F, {{100, 0.0, 0.5}, {100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiqlcmsmixed = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][7])).c_str(), "; #it{q}_{LCMS}; #Delta #eta; #Delta #phi", kTH3F, {{100, 0.0, 0.5}, {100, -0.15, 0.15}, {100, -0.15, 0.15}}); + if (plotForEveryRadii) { for (int i = 0; i < 9; i++) { histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); @@ -407,23 +410,42 @@ class FemtoUniverseDetaDphiStar } } + /// Check if pair is close or not + template + void ClosePairqLCMS(Part const& part1, Part const& part2, float lmagfield, uint8_t ChosenEventType, double qlcms) // add typename Parts and variable parts for adding MClabels + { + magfield = lmagfield; + if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { + auto deta = part1.eta() - part2.eta(); + auto dphiAvg = averagePhiStar(part1, part2, 0); + + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpiqlcmssame->Fill(qlcms, deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpiqlcmsmixed->Fill(qlcms, deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + } + } + private: HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output static constexpr std::string_view DirNames[6] = {"kTrack_kTrack/", "kTrack_kV0/", "kV0_kV0/", "kTrack_kPhi/", "kTrack_kD0/", "kCascade_kCascade/"}; - static constexpr std::string_view HistNamesSame[2][7] = {{"detadphidetadphi0BeforeSame_0", "detadphidetadphi0BeforeSame_1", "detadphidetadphi0BeforeSame_2", + static constexpr std::string_view HistNamesSame[2][8] = {{"detadphidetadphi0BeforeSame_0", "detadphidetadphi0BeforeSame_1", "detadphidetadphi0BeforeSame_2", "detadphidetadphi0BeforeSame_3", "detadphidetadphi0BeforeSame_4", "detadphidetadphi0BeforeSame_5", - "detadphidetadphi0BeforeSame_6"}, + "detadphidetadphi0BeforeSame_6", "detadphidetadphi0BeforeSameqLCMS"}, {"detadphidetadphi0AfterSame_0", "detadphidetadphi0AfterSame_1", "detadphidetadphi0AfterSame_2", "detadphidetadphi0AfterSame_3", "detadphidetadphi0AfterSame_4", "detadphidetadphi0AfterSame_5", - "detadphidetadphi0AfterSame_6"}}; - static constexpr std::string_view HistNamesMixed[2][7] = {{"detadphidetadphi0BeforeMixed_0", "detadphidetadphi0BeforeMixed_1", "detadphidetadphi0BeforeMixed_2", + "detadphidetadphi0AfterSame_6", "detadphidetadphi0AfterSameqLCMS"}}; + static constexpr std::string_view HistNamesMixed[2][8] = {{"detadphidetadphi0BeforeMixed_0", "detadphidetadphi0BeforeMixed_1", "detadphidetadphi0BeforeMixed_2", "detadphidetadphi0BeforeMixed_3", "detadphidetadphi0BeforeMixed_4", "detadphidetadphi0BeforeMixed_5", - "detadphidetadphi0BeforeMixed_6"}, + "detadphidetadphi0BeforeMixed_6", "detadphidetadphi0BeforeMixedqLCMS"}, {"detadphidetadphi0AfterMixed_0", "detadphidetadphi0AfterMixed_1", "detadphidetadphi0AfterMixed_2", "detadphidetadphi0AfterMixed_3", "detadphidetadphi0AfterMixed_4", "detadphidetadphi0AfterMixed_5", - "detadphidetadphi0AfterMixed_6"}}; + "detadphidetadphi0AfterMixed_6", "detadphidetadphi0AfterMixedqLCMS"}}; static constexpr std::string_view HistNamesRadii[7][9] = {{"detadphidetadphi0Before_0_0", "detadphidetadphi0Before_0_1", "detadphidetadphi0Before_0_2", "detadphidetadphi0Before_0_3", "detadphidetadphi0Before_0_4", "detadphidetadphi0Before_0_5", @@ -471,6 +493,9 @@ class FemtoUniverseDetaDphiStar std::array, 2>, 7> histdetadpimixed{}; std::array, 9>, 7> histdetadpiRadii{}; + std::shared_ptr histdetadpiqlcmssame{}; + std::shared_ptr histdetadpiqlcmsmixed{}; + /// Calculate phi at all required radii stored in TmpRadiiTPC /// Magnetic field to be provided in Tesla template From 96a36a29018ebd614ff57b8d843cbb77d4487055 Mon Sep 17 00:00:00 2001 From: Preet-Bhanjan Date: Fri, 13 Jun 2025 01:39:22 +0200 Subject: [PATCH 60/62] [PWGCF] Addition New PID function (#11582) Co-authored-by: Preet Pati Co-authored-by: ALICE Action Bot --- PWGCF/Flow/Tasks/flowPbpbPikp.cxx | 127 ++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 14 deletions(-) diff --git a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx index dfcf5fb42fc..1d979488da3 100644 --- a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx +++ b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx @@ -36,6 +36,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Multiplicity.h" #include "CommonConstants/PhysicsConstants.h" @@ -82,13 +83,14 @@ struct FlowPbpbPikp { O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 3.0f, "Maximal pT for ref tracks") O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") O2_DEFINE_CONFIGURABLE(cfgTpcCluster, int, 70, "Number of TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgTpcCrossRows, int, 70, "Number of TPC clusters") O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5, "Chi2 per TPC clusters") O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") O2_DEFINE_CONFIGURABLE(cfgOutputNUAWeights, bool, true, "Fill and output NUA weights") O2_DEFINE_CONFIGURABLE(cfgOutputRunByRun, bool, true, "Fill and output NUA weights run by run") O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") - O2_DEFINE_CONFIGURABLE(cfgTpcNsigmaCut, float, 2.0f, "TPC N-sigma cut for pions, kaons, protons") + O2_DEFINE_CONFIGURABLE(cfgTpcCut, float, 2.0f, "TPC N-sigma cut for pions, kaons, protons") O2_DEFINE_CONFIGURABLE(cfgTofPtCut, float, 0.5f, "Minimum pt to use TOF N-sigma") O2_DEFINE_CONFIGURABLE(cfgCutDCAxy, float, 2.0f, "DCAxy range for tracks") O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "DCAz range for tracks") @@ -97,18 +99,20 @@ struct FlowPbpbPikp { O2_DEFINE_CONFIGURABLE(cfgCutOccupancyMax, int, 2000, "Maximum occupancy cut") O2_DEFINE_CONFIGURABLE(cfgUseGlobalTrack, bool, true, "use Global track") O2_DEFINE_CONFIGURABLE(cfgITScluster, int, 5, "Number of ITS cluster") - O2_DEFINE_CONFIGURABLE(cfgTrackDensityCorrUse, bool, true, "Use track density efficiency correction") + O2_DEFINE_CONFIGURABLE(cfgTrackDensityCorrUse, bool, false, "Use track density efficiency correction") O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiEtaVtxz, bool, false, "Use Phi, Eta, VertexZ dependent NUA weights") O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiPtCent, bool, false, "Use Phi, Pt, Centrality dependent NUA weights") O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiEtaPt, bool, true, "Use Phi, Eta, Pt dependent NUA weights") O2_DEFINE_CONFIGURABLE(cfgUseStrictPID, bool, true, "Use strict PID cuts for TPC") O2_DEFINE_CONFIGURABLE(cfgV0AT0Acut, int, 5, "V0AT0A cut") + O2_DEFINE_CONFIGURABLE(cfgUseAsymmetricPID, bool, false, "Use asymmetric PID cuts"); Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.7217476707, 0.7384792571, 0.7542625668, 0.7640680200, 0.7701951667, 0.7755299053, 0.7805901710, 0.7849446786, 0.7957356586, 0.8113039262, 0.8211968966, 0.8280558878, 0.8329342135}, "parameter 0 for track density efficiency correction"}; Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-2.169488e-05, -2.191913e-05, -2.295484e-05, -2.556538e-05, -2.754463e-05, -2.816832e-05, -2.846502e-05, -2.843857e-05, -2.705974e-05, -2.477018e-05, -2.321730e-05, -2.203315e-05, -2.109474e-05}, "parameter 1 for track density efficiency correction"}; - Configurable> cfgTofNsigmaCut{"cfgTofNsigmaCut", std::vector{1.5, 1.5, 1.5}, "TOF n-sigma cut for pions, kaons, protons"}; - Configurable> cfgItsNsigmaCut{"cfgItsNsigmaCut", std::vector{3, 2.5, 2}, "ITS n-sigma cut for pions, kaons, protons"}; + Configurable> cfgTofNsigmaCut{"cfgTofNsigmaCut", std::vector{1.5, 1.5, 1.5, -1.5, -1.5, -1.5}, "TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; + Configurable> cfgItsNsigmaCut{"cfgItsNsigmaCut", std::vector{3, 2.5, 2, 3, 2.5, 2}, "ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; + Configurable> cfgTpcNsigmaCut{"cfgTpcNsigmaCut", std::vector{1.5, 1.5, 1.5, -1.5, -1.5, -1.5}, "TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; Configurable> cfgUseEventCuts{"cfgUseEventCuts", std::vector{1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0}, "Switch for various event cuts [kNoTimeFrameBorder, kNoITSROFrameBorder, kNoSameBunchPileup, kIsGoodZvtxFT0vsPV, kNoCollInTimeRangeStandard, kIsGoodITSLayersAll, kNoCollInRofStandard, kNoHighMultCollInPrevRof, Occupancy, Multiplicity correlation, T0AV0A 3 sigma cut, kIsVertexITSTPC, kTVXinTRD]"}; Configurable cfgRegions{"cfgRegions", {{"refN08", "refP08", "full", "poiN", "olN", "poiP", "olP", "poi", "ol", "poiNpi", "olNpi", "poiPpi", "olPpi", "poifullpi", "olfullpi", "poiNka", "olNka", "poiPka", "olPka", "poifullka", "olfullka", "poiNpr", "olNpr", "poiPpr", "olPpr", "poifullpr", "olfullpr"}, {-0.8, 0.4, -0.8, -0.8, -0.8, 0.4, 0.4, -0.8, -0.8, -0.8, -0.8, 0.4, 0.4, -0.8, -0.8, -0.8, -0.8, 0.4, 0.4, -0.8, -0.8, -0.8, -0.8, 0.4, 0.4, -0.8, -0.8}, {-0.4, 0.8, 0.8, -0.4, -0.4, 0.8, 0.8, 0.8, 0.8, -0.4, -0.4, 0.8, 0.8, 0.8, 0.8, -0.4, -0.4, 0.8, 0.8, 0.8, 0.8, -0.4, -0.4, 0.8, 0.8, 0.8, 0.8}, {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 128, 256, 128, 256, 128, 256, 2, 16, 2, 16, 2, 16, 4, 32, 4, 32, 4, 32, 8, 64, 8, 64, 8, 64}}, "Configurations for GFW regions"}; @@ -123,9 +127,11 @@ struct FlowPbpbPikp { ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; ConfigurableAxis axisParticles{"axisParticles", {3, 0, 3}, "axis for different hadrons"}; ConfigurableAxis axisTPCsignal{"axisTPCsignal", {10000, 0, 1000}, "axis for TPC signal"}; + ConfigurableAxis axisTOFbeta{"axisTOFbeta", {200, 0, 2}, "axis for TOF beta"}; std::vector tofNsigmaCut = cfgTofNsigmaCut; std::vector itsNsigmaCut = cfgItsNsigmaCut; + std::vector tpcNsigmaCut = cfgTofNsigmaCut; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); @@ -238,11 +244,15 @@ struct FlowPbpbPikp { histos.add("c24_full_pi", "", {HistType::kTProfile, {axisMultiplicity}}); histos.add("c24_full_ka", "", {HistType::kTProfile, {axisMultiplicity}}); histos.add("c24_full_pr", "", {HistType::kTProfile, {axisMultiplicity}}); + + histos.add("TpcdEdx", "", {HistType::kTH2D, {axisPt, axisTPCsignal}}); + histos.add("TofBeta", "", {HistType::kTH2D, {axisPt, axisTOFbeta}}); + histos.add("TofTpcNsigma_before", "", {HistType::kTHnSparseD, {{axisParticles, axisNsigmaTPC, axisNsigmaTOF, axisPt}}}); histos.add("TofTpcNsigma_after", "", {HistType::kTHnSparseD, {{axisParticles, axisNsigmaTPC, axisNsigmaTOF, axisPt}}}); histos.add("partCount", "", {HistType::kTHnSparseD, {{axisParticles, axisMultiplicity, axisPt}}}); - histos.add("hEventCount", "Number of Event;; Count", {HistType::kTH1D, {{15, 0, 15}}}); + histos.add("hEventCount", "Number of Events;; Count", {HistType::kTH1D, {{15, 0, 15}}}); histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(1, "Filtered event"); histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(2, "After sel8"); histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(3, "kNoTimeFrameBorder"); @@ -259,6 +269,18 @@ struct FlowPbpbPikp { histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(14, "kIsVertexITSTPC"); histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(15, "kTVXinTRD"); + histos.add("hTrackCount", "Number of Tracks;; Count", {HistType::kTH1D, {{10, 0, 10}}}); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(1, "Filtered track"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(2, "Global tracks"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(3, "PV contributor"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(4, "ITS clusters"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(5, "TPC signal"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(6, "TPC clusters"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(7, "TPC crossed rows"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(8, "Pions"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(9, "Kaons"); + histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(10, "Protons"); + if (cfgOutputNUAWeights && !cfgOutputRunByRun) { histos.add("NUA/hPhiEtaVtxz_ref", ";#varphi;#eta;v_{z}", {HistType::kTH3D, {axisPhi, axisEta, axisVertex}}); histos.add("NUA/hPhiEtaVtxz_ch", ";#varphi;#eta;v_{z}", {HistType::kTH3D, {axisPhi, axisEta, axisVertex}}); @@ -386,13 +408,38 @@ struct FlowPbpbPikp { template bool selectionTrack(const TTrack& track) { - if (cfgUseGlobalTrack && !(track.isGlobalTrack() && track.isPVContributor() && track.itsNCls() > cfgITScluster && track.tpcNClsFound() > cfgTpcCluster && track.hasTPC())) { - return false; + histos.fill(HIST("hTrackCount"), 0.5); // Filtered tracks + if (cfgUseGlobalTrack && !(track.isGlobalTrack())) { + return 0; } - if (!cfgUseGlobalTrack && !(track.isPVContributor() && track.itsNCls() > cfgITScluster && track.hasTPC())) { - return false; + if (cfgUseGlobalTrack) + histos.fill(HIST("hTrackCount"), 1.5); // After global track selection + + if (!(track.isPVContributor())) { + return 0; } - return true; + histos.fill(HIST("hTrackCount"), 2.5); // After PV contributor selection + + if (!(track.itsNCls() > cfgITScluster)) { + return 0; + } + histos.fill(HIST("hTrackCount"), 3.5); // After ITS cluster selection + + if (!(track.hasTPC())) { + return 0; + } + histos.fill(HIST("hTrackCount"), 4.5); // If track has TPC signal + + if (!(track.tpcNClsFound() > cfgTpcCluster)) { + return 0; + } + histos.fill(HIST("hTrackCount"), 5.5); // After TPC cluster selection + + if (!(track.tpcNClsCrossedRows() > cfgTpcCrossRows)) { + return 0; + } + histos.fill(HIST("hTrackCount"), 6.5); // After TPC crossed rows selection + return 1; } template @@ -402,6 +449,7 @@ struct FlowPbpbPikp { switch (pidIndex) { case 1: histos.fill(HIST("TofTpcNsigma_after"), pidIndex - 1, track.tpcNSigmaPi(), track.tofNSigmaPi(), track.pt()); + histos.fill(HIST("hTrackCount"), 7.5); // Pion count if (!cfgAcceptance.value.empty() && cfgUseWeightPhiEtaVtxz) histos.fill(HIST("PhiCorrected/hPhiEtaVtxz_pi_corrd"), track.phi(), track.eta(), collision.posZ(), wacc); // pion weights if (!cfgAcceptance.value.empty() && cfgUseWeightPhiPtCent) @@ -411,6 +459,7 @@ struct FlowPbpbPikp { break; case 2: histos.fill(HIST("TofTpcNsigma_after"), pidIndex - 1, track.tpcNSigmaKa(), track.tofNSigmaKa(), track.pt()); + histos.fill(HIST("hTrackCount"), 8.5); // Kaon count if (!cfgAcceptance.value.empty() && cfgUseWeightPhiEtaVtxz) histos.fill(HIST("PhiCorrected/hPhiEtaVtxz_ka_corrd"), track.phi(), track.eta(), collision.posZ(), wacc); // kaon weights if (!cfgAcceptance.value.empty() && cfgUseWeightPhiPtCent) @@ -420,6 +469,7 @@ struct FlowPbpbPikp { break; case 3: histos.fill(HIST("TofTpcNsigma_after"), pidIndex - 1, track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); + histos.fill(HIST("hTrackCount"), 9.5); // Proton count if (!cfgAcceptance.value.empty() && cfgUseWeightPhiEtaVtxz) histos.fill(HIST("PhiCorrected/hPhiEtaVtxz_pr_corrd"), track.phi(), track.eta(), collision.posZ(), wacc); // proton weights if (!cfgAcceptance.value.empty() && cfgUseWeightPhiPtCent) @@ -437,12 +487,12 @@ struct FlowPbpbPikp { std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; std::array nSigmaCombined = {std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi()), std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa()), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())}; int pid = -1; - float nsigma = cfgTpcNsigmaCut; + float nsigma = cfgTpcCut; // Choose which nSigma to use std::array nSigmaToUse = (track.pt() > cfgTofPtCut && track.hasTOF()) ? nSigmaCombined : nSigmaTPC; if (track.pt() > cfgTofPtCut && !track.hasTOF()) - return -1; + return 0; const int numSpecies = 3; int pidCount = 0; @@ -450,7 +500,7 @@ struct FlowPbpbPikp { for (int i = 0; i < numSpecies; ++i) { if (std::abs(nSigmaToUse[i]) < nsigma) { if (pidCount > 0 && cfgUseStrictPID) - return -1; // more than one particle with low nsigma + return 0; // more than one particle with low nsigma pidCount++; pid = i; @@ -461,6 +511,52 @@ struct FlowPbpbPikp { return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton } + template + int getNsigmaPIDTpcTofAssymmetric(TTrack track) + { + // Computing Nsigma arrays for pion, kaon, and protons + std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + std::array nSigmaTOF = {track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()}; + int pid = -1; + + bool isPion, isKaon, isProton; + bool isTpcPion = nSigmaTPC[0] < tpcNsigmaCut[0] && nSigmaTPC[0] > tpcNsigmaCut[0 + 3]; + bool isTpcKaon = nSigmaTPC[1] < tpcNsigmaCut[1] && nSigmaTPC[1] > tpcNsigmaCut[1 + 3]; + bool isTpcProton = nSigmaTPC[2] < tpcNsigmaCut[2] && nSigmaTPC[2] > tpcNsigmaCut[2 + 3]; + + bool isTofPion = nSigmaTOF[0] < tofNsigmaCut[0] && nSigmaTOF[0] > tofNsigmaCut[0 + 3]; + bool isTofKaon = nSigmaTOF[1] < tofNsigmaCut[1] && nSigmaTOF[1] > tofNsigmaCut[1 + 3]; + bool isTofProton = nSigmaTOF[2] < tofNsigmaCut[2] && nSigmaTOF[2] > tofNsigmaCut[2 + 3]; + + if (track.pt() > cfgTofPtCut && !track.hasTOF()) { + return 0; + } else if (track.pt() > cfgTofPtCut && track.hasTOF()) { + isPion = isTofPion && isTpcPion; + isKaon = isTofKaon && isTpcKaon; + isProton = isTofProton && isTpcProton; + } else { + isPion = isTpcPion; + isKaon = isTpcKaon; + isProton = isTpcProton; + } + + if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { + return 0; // more than one particle satisfy the criteria + } + + if (isPion) { + pid = PIONS; + } else if (isKaon) { + pid = KAONS; + } else if (isProton) { + pid = PROTONS; + } else { + return 0; // no particle satisfies the criteria + } + + return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton + } + template void fillProfile(const GFW::CorrConfig& corrconf, const ConstStr& tarName, const double& cent) { @@ -814,6 +910,9 @@ struct FlowPbpbPikp { histos.fill(HIST("hEta"), track.eta()); histos.fill(HIST("hPt"), pt); + histos.fill(HIST("TpcdEdx"), pt, track.tpcSignal()); + histos.fill(HIST("TofBeta"), pt, track.beta()); + histos.fill(HIST("TofTpcNsigma_before"), PIONS, track.tpcNSigmaPi(), track.tofNSigmaPi(), pt); histos.fill(HIST("TofTpcNsigma_before"), KAONS, track.tpcNSigmaKa(), track.tofNSigmaKa(), pt); histos.fill(HIST("TofTpcNsigma_before"), PROTONS, track.tpcNSigmaPr(), track.tofNSigmaPr(), pt); @@ -821,7 +920,7 @@ struct FlowPbpbPikp { bool withinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range bool withinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range - pidIndex = getNsigmaPIDTpcTof(track); + pidIndex = cfgUseAsymmetricPID ? getNsigmaPIDTpcTofAssymmetric(track) : getNsigmaPIDTpcTof(track); weff = 1; // Initializing weff for each track // NUA weights From dcba81e5105e5e5e4bf3089afc81b050926a51e5 Mon Sep 17 00:00:00 2001 From: Roman Lietava Date: Sat, 14 Jun 2025 11:16:05 +0200 Subject: [PATCH 61/62] fix --- PWGLF/Tasks/Strangeness/nonPromptCascade.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index de1857deca3..bb2960e745b 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -306,7 +306,7 @@ struct NonPromptCascadeTask { if (sel) { std::vector toivect = mZorro.getTriggerOfInterestResults(); uint32_t toiMask = 0; - for (int i{0}; i < toivect.size(); i++) { + for (size_t i{0}; i < toivect.size(); i++) { toiMask += toivect[i] << i; } toiMap[bc.globalBC()] = toiMask; From c7c205468e060ba044b948deb52acfa78539e98b Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Sat, 14 Jun 2025 09:18:08 +0000 Subject: [PATCH 62/62] Please consider the following formatting changes --- .../TableProducer/trackDcaCovFillerRun2.cxx | 6 +- Common/TableProducer/zdcTaskInterCalib.cxx | 11 ++-- PWGCF/Flow/Tasks/flowEsePHe3.cxx | 30 +++++---- PWGCF/Flow/Tasks/flowPbpbPikp.cxx | 62 +++++++++---------- PWGHF/Core/HfMlResponseLcToPKPi.h | 7 +-- PWGHF/TableProducer/treeCreatorLcToPKPi.cxx | 18 +++--- .../Nuspex/decay3bodybuilder.cxx | 47 +++++++------- .../Nuspex/reduced3bodyCreator.cxx | 49 ++++++++------- PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx | 14 +++-- .../Strangeness/lambdaJetpolarization.cxx | 53 +++++++++------- PWGLF/Utils/decay3bodyBuilderHelper.h | 22 ++++--- PWGMM/UE/Tasks/dedxAnalysis.cxx | 9 ++- PWGUD/Tasks/analysisMCDPMJetSGv3.cxx | 5 +- 13 files changed, 174 insertions(+), 159 deletions(-) diff --git a/Common/TableProducer/trackDcaCovFillerRun2.cxx b/Common/TableProducer/trackDcaCovFillerRun2.cxx index d07833ae9e0..ca56615dfee 100644 --- a/Common/TableProducer/trackDcaCovFillerRun2.cxx +++ b/Common/TableProducer/trackDcaCovFillerRun2.cxx @@ -15,12 +15,14 @@ // Run 2 AO2Ds cannot have their dcacov filled by the current track-propagation workflow as the workflow isn't designed for them, given Run 2 tracks are already propagated to the PV. // This task fills the DCA Cov (and DCA) tables for Run 2 tracks by "propagating" the tracks (though given they are already at the PV it doesn't actually do the propagation) and retrieving the DCA and DCA cov given by the propagateToDCABxByBz function -#include - #include "TableHelper.h" + #include "Common/Tools/TrackTuner.h" + #include "DataFormatsParameters/GRPObject.h" +#include + using namespace o2; using namespace o2::framework; // using namespace o2::framework::expressions; diff --git a/Common/TableProducer/zdcTaskInterCalib.cxx b/Common/TableProducer/zdcTaskInterCalib.cxx index 78054580b81..c4ed223b67e 100644 --- a/Common/TableProducer/zdcTaskInterCalib.cxx +++ b/Common/TableProducer/zdcTaskInterCalib.cxx @@ -13,17 +13,18 @@ /// \brief Task for ZDC tower inter-calibration /// \author chiara.oppedisano@cern.ch -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Common/DataModel/EventSelection.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/ZDCInterCalib.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + #include "TH1F.h" #include "TH2F.h" diff --git a/PWGCF/Flow/Tasks/flowEsePHe3.cxx b/PWGCF/Flow/Tasks/flowEsePHe3.cxx index 624043a2d31..73a92bea4ef 100644 --- a/PWGCF/Flow/Tasks/flowEsePHe3.cxx +++ b/PWGCF/Flow/Tasks/flowEsePHe3.cxx @@ -27,28 +27,26 @@ #include // o2Physics includes. -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" - -#include "DataFormatsTPC/BetheBlochAleph.h" - -#include "Common/DataModel/Qvectors.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/Core/EventPlaneHelper.h" #include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx index 1d979488da3..86f0d761f8c 100644 --- a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx +++ b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx @@ -13,48 +13,46 @@ /// \brief PID flow using the generic framework /// \author Preet Bhanjan Pati -#include -#include -#include -#include -#include -#include -#include - -#include "Math/Vector4D.h" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/StepTHn.h" +#include "PWGCF/GenericFramework/Core/FlowContainer.h" +#include "PWGCF/GenericFramework/Core/GFW.h" +#include "PWGCF/GenericFramework/Core/GFWConfig.h" +#include "PWGCF/GenericFramework/Core/GFWCumulant.h" +#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" +#include "PWGCF/GenericFramework/Core/GFWWeights.h" +#include "PWGCF/GenericFramework/Core/GFWWeightsList.h" -#include "Common/DataModel/EventSelection.h" #include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/Multiplicity.h" -#include "CommonConstants/PhysicsConstants.h" - -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" -#include "PWGCF/GenericFramework/Core/GFW.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/FlowContainer.h" -#include "PWGCF/GenericFramework/Core/GFWWeights.h" -#include "PWGCF/GenericFramework/Core/GFWWeightsList.h" -#include "PWGCF/GenericFramework/Core/GFWConfig.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "ReconstructionDataFormats/Track.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/Track.h" +#include +#include "Math/Vector4D.h" +#include #include #include -#include + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGHF/Core/HfMlResponseLcToPKPi.h b/PWGHF/Core/HfMlResponseLcToPKPi.h index ae797f32acd..956fff55b28 100644 --- a/PWGHF/Core/HfMlResponseLcToPKPi.h +++ b/PWGHF/Core/HfMlResponseLcToPKPi.h @@ -16,14 +16,13 @@ #ifndef PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ #define PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ +#include "PWGHF/Core/HfMlResponse.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + #include #include #include -#include "PWGHF/DataModel/CandidateReconstructionTables.h" - -#include "PWGHF/Core/HfMlResponse.h" - // Fill the map of available input features // the key is the feature's name (std::string) // the value is the corresponding value in EnumInputFeatures diff --git a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx index 3f53966a973..04b85fa626b 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -17,20 +17,20 @@ /// \author Nicolo' Jacazio , CERN /// \author Luigi Dello Stritto , CERN -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index 77c3e5668a7..d6092270fca 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -16,40 +16,41 @@ /// \author Carolina Reetz // ======================== -#include -#include -#include -#include -#include -#include -#include -#include +#include "TableHelper.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" #include "PWGLF/DataModel/Reduced3BodyTables.h" #include "PWGLF/DataModel/Vtx3BodyTables.h" #include "PWGLF/DataModel/pidTOFGeneric.h" #include "PWGLF/Utils/decay3bodyBuilderHelper.h" + +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "Common/Core/PID/PIDTOF.h" -#include "TableHelper.h" -#include "Tools/KFparticle/KFUtilities.h" - #include "EventFiltering/Zorro.h" #include "EventFiltering/ZorroSummary.h" +#include "Tools/KFparticle/KFUtilities.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include +#include +#include +#include #ifndef HomogeneousField #define HomogeneousField diff --git a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx index 4f52fdd8066..2a15950ae71 100644 --- a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx +++ b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx @@ -14,39 +14,40 @@ /// \author Yuanzhe Wang /// \author Carolina Reetz -#include -#include -#include -#include -#include -#include +#include "TableHelper.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "DCAFitter/DCAFitterN.h" -#include "ReconstructionDataFormats/Track.h" +#include "PWGLF/DataModel/Reduced3BodyTables.h" +#include "PWGLF/DataModel/pidTOFGeneric.h" + +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" -#include "PWGLF/DataModel/Reduced3BodyTables.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" -#include "Common/Core/PID/PIDTOF.h" -#include "Common/Core/RecoDecay.h" -#include "TableHelper.h" -#include "Tools/KFparticle/KFUtilities.h" - #include "EventFiltering/Zorro.h" #include "EventFiltering/ZorroSummary.h" +#include "Tools/KFparticle/KFUtilities.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include +#include #ifndef HomogeneousField #define HomogeneousField diff --git a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx index f00fc314870..dbd999bbaa0 100644 --- a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx @@ -16,8 +16,10 @@ /// /// \author Matthias Herzer , Goethe University Frankfurt /// -#include -#include +#include "PWGLF/DataModel/LFNucleiTables.h" +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/pidTOFGeneric.h" + #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/trackUtilities.h" @@ -26,18 +28,20 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFNucleiTables.h" -#include "PWGLF/DataModel/LFParticleIdentification.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" + #include +#include +#include + namespace o2::aod { namespace h3_data diff --git a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx index cca1bdf193e..62420403d65 100644 --- a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx @@ -11,41 +11,46 @@ /// /// \author Youpeng Su (yousu@cern.ch) -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/lambdaJetpolarization.h" + +#include "PWGJE/Core/JetBkgSubUtils.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" #include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include + #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" -#include -#include -#include -#include "TProfile2D.h" -#include "PWGLF/DataModel/lambdaJetpolarization.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include "Math/GenVector/Boost.h" #include "Math/Vector3D.h" #include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" +#include "TProfile2D.h" +#include +#include +#include +#include +#include #include #include +#include +#include +#include #include #include -#include -#include -#include -#include -#include "PWGJE/Core/JetBkgSubUtils.h" -#include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "PWGJE/DataModel/JetReducedData.h" -#include "PWGJE/DataModel/Jet.h" -#include "Common/Core/trackUtilities.h" + +#include +#include +#include +#include using std::cout; using std::endl; diff --git a/PWGLF/Utils/decay3bodyBuilderHelper.h b/PWGLF/Utils/decay3bodyBuilderHelper.h index 550625f2fc6..54fd2cc4fb8 100644 --- a/PWGLF/Utils/decay3bodyBuilderHelper.h +++ b/PWGLF/Utils/decay3bodyBuilderHelper.h @@ -12,27 +12,29 @@ #ifndef PWGLF_UTILS_DECAY3BODYBUILDERHELPER_H_ #define PWGLF_UTILS_DECAY3BODYBUILDERHELPER_H_ -#include -#include -#include +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Tools/KFparticle/KFUtilities.h" + +#include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" -#include "Framework/AnalysisDataModel.h" -#include "ReconstructionDataFormats/Track.h" #include "DetectorsBase/GeometryManager.h" #include "DetectorsVertexing/SVertexHypothesis.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/trackUtilities.h" -#include "Common/Core/RecoDecay.h" -#include "Tools/KFparticle/KFUtilities.h" +#include "Framework/AnalysisDataModel.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include #ifndef HomogeneousField #define HomogeneousField #endif /// includes KFParticle -#include "KFParticle.h" #include "KFPTrack.h" #include "KFPVertex.h" +#include "KFParticle.h" #include "KFParticleBase.h" #include "KFVertex.h" diff --git a/PWGMM/UE/Tasks/dedxAnalysis.cxx b/PWGMM/UE/Tasks/dedxAnalysis.cxx index 34999be4f7e..cf5baa3f417 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -14,20 +14,23 @@ /// \file dedxAnalysis.cxx /// \brief Analysis to do PID +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Multiplicity.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "ReconstructionDataFormats/Track.h" -#include "Common/Core/TrackSelectionDefaults.h" + #include "TF1.h" using namespace o2; diff --git a/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx b/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx index 4347871377a..6c6bfdfb3ab 100644 --- a/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx +++ b/PWGUD/Tasks/analysisMCDPMJetSGv3.cxx @@ -13,10 +13,11 @@ /// /// \author Simone Ragoni -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" #include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" // #include "TDatabasePDG.h" #include "PWGUD/Core/UPCHelpers.h" #include "PWGUD/DataModel/UDTables.h"