From 567fa8205db58c0627e3d38895be14f79d994dd3 Mon Sep 17 00:00:00 2001 From: yuanzhe Date: Wed, 19 Feb 2025 16:18:22 +0100 Subject: [PATCH] Update analysis for reduced 3body table and EM --- PWGLF/DataModel/Reduced3BodyTables.h | 2 + .../Nuspex/decay3bodybuilder.cxx | 177 +++++---------- .../Nuspex/threebodyRecoTask.cxx | 212 +++++++++++------- 3 files changed, 180 insertions(+), 211 deletions(-) diff --git a/PWGLF/DataModel/Reduced3BodyTables.h b/PWGLF/DataModel/Reduced3BodyTables.h index 9f963951cf0..2c3b8a47cde 100644 --- a/PWGLF/DataModel/Reduced3BodyTables.h +++ b/PWGLF/DataModel/Reduced3BodyTables.h @@ -16,6 +16,8 @@ #include "Framework/AnalysisDataModel.h" #include "Common/Core/RecoDecay.h" #include "CommonConstants/PhysicsConstants.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" #include "PWGLF/DataModel/Vtx3BodyTables.h" namespace o2::aod diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index 70aa8b61195..ca363ef30b1 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -215,9 +215,8 @@ struct decay3bodyBuilder { 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 + 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 @@ -316,7 +315,6 @@ struct decay3bodyBuilder { Configurable emTpcPidNsigmaCut{"emTpcPidNsigmaCut", 5, "emTpcPidNsigmaCut"}; } EMTrackSel; - Preslice tracksperCol = aod::track::collisionId; SliceCache cache; ConfigurableAxis axisPosZ{"axisPosZ", {40, -10, 10}, "Mixing bins - posZ"}; ConfigurableAxis axisCentrality{"axisCentrality", {10, 0, 100}, "Mixing bins - centrality"}; @@ -403,7 +401,7 @@ struct decay3bodyBuilder { fitter3body.setMatCorrType(matCorr); // Add histograms separately for different process functions - if (doprocessRun3 == true || doprocessRun3Reduced || doprocessRun3EM == true || doprocessRun3EMLikeSign == true) { + if (doprocessRun3 == true || doprocessRun3Reduced || doprocessRun3ReducedEM == true) { registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{1, 0.0f, 1.0f}}); auto hVtx3BodyCounter = registry.add("hVtx3BodyCounter", "hVtx3BodyCounter", HistType::kTH1F, {{6, 0.0f, 6.0f}}); hVtx3BodyCounter->GetXaxis()->SetBinLabel(1, "Total"); @@ -1478,30 +1476,28 @@ struct decay3bodyBuilder { } // end buildVtx3BodyDataTableKFParticle //------------------------------------------------------------------ - void processRun3(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const& /*tracksIU*/, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) + void processRun3(ColwithEvTimes const& collisions, aod::Decay3Bodys const& decay3bodys, TrackExtPIDIUwithEvTimes const&, aod::BCsWithTimestamps const&) { vtxCandidates.clear(); - for (const auto& collision : collisions) { + 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); - registry.fill(HIST("hEventCounter"), 0.5); - - const auto& d3bodys_thisCollision = decay3bodys.sliceBy(perCollision, collision.globalIndex()); - for (const auto& d3body : d3bodys_thisCollision) { - auto t0 = d3body.template track0_as(); - auto t1 = d3body.template track1_as(); - auto t2 = d3body.template track2_as(); - - // 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); + // 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); } for (const auto& candVtx : vtxCandidates) { @@ -1511,7 +1507,7 @@ struct decay3bodyBuilder { PROCESS_SWITCH(decay3bodyBuilder, processRun3, "Produce DCA fitter decay3body tables", true); //------------------------------------------------------------------ - void processRun3Reduced(aod::ReducedCollisions const& collisions, aod::ReducedTracksIU const&, aod::ReducedDecay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) + void processRun3Reduced(aod::ReducedCollisions const& collisions, aod::ReducedDecay3Bodys const& decay3bodys, aod::ReducedTracksIU const&) { vtxCandidates.clear(); @@ -1520,13 +1516,10 @@ struct decay3bodyBuilder { int lastRunNumber = -1; for (const auto& d3body : decay3bodys) { - auto t0 = d3body.template track0_as(); - auto t1 = d3body.template track1_as(); - auto t2 = d3body.template track2_as(); - auto collision = d3body.template collision_as(); - // auto bc = collision.bc_as(); - // initCCDB(bc); - // set magnetic field only when run number changes + auto t0 = d3body.track0_as(); + auto t1 = d3body.track1_as(); + auto t2 = d3body.track2_as(); + auto collision = d3body.collision_as(); if (collision.runNumber() != lastRunNumber) { initCCDBReduced(collision.runNumber()); lastRunNumber = collision.runNumber(); // Update the last run number @@ -1543,106 +1536,37 @@ struct decay3bodyBuilder { //------------------------------------------------------------------ // Event-mixing background - void processRun3EM(FullCols const& collisions, TrackExtPIDIUwithEvTimes const& tracksIU, aod::BCsWithTimestamps const&) + void processRun3ReducedEM(ReducedCollisionsMultsCents const&, aod::ReducedDecay3Bodys const&, aod::ReducedTracksIU const&) { - vtxCandidates.clear(); - auto tracksTuple = std::make_tuple(tracksIU); BinningType binningEvent{{axisPosZ, axisCentrality}, true}; - SameKindPair pair{binningEvent, EMTrackSel.nUseMixedEvent, -1, collisions, tracksTuple, &cache}; - - Partition candProtons = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candAntiProtons = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candPionPlus = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candPionMinus = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candBachelors = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candAntiBachelors = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; - candProtons.bindTable(tracksIU); - candPionPlus.bindTable(tracksIU); - candAntiProtons.bindTable(tracksIU); - candPionMinus.bindTable(tracksIU); - candBachelors.bindTable(tracksIU); - candAntiBachelors.bindTable(tracksIU); - - for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (EMTrackSel.em_event_sel8_selection && (!c1.sel8() || !c2.sel8())) { - continue; - } - auto bc = c1.bc_as(); - initCCDB(bc); - auto protons = candProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto pionsplus = candPionPlus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto antiprotons = candAntiProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto pionsminus = candPionMinus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto bachelors = candBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); - auto antibachelors = candAntiBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); - - for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(protons, pionsminus, bachelors))) { - double tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(tbach); // Recalculate the TOF PID - fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge, tofNSigmaBach); - } - for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(pionsplus, antiprotons, antibachelors))) { - double tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(tbach); // Recalculate the TOF PID - fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge, tofNSigmaBach); - } - } - - // Aviod break of preslice in following workflow - std::sort(vtxCandidates.begin(), vtxCandidates.end(), [](const vtxCandidate a, const vtxCandidate b) { - return a.collisionId < b.collisionId; - }); + SameKindPair pair{binningEvent, EMTrackSel.nUseMixedEvent, -1, &cache}; - for (const auto& candVtx : vtxCandidates) { - fillVtx3BodyTable(candVtx); - } - } - PROCESS_SWITCH(decay3bodyBuilder, processRun3EM, "Produce event-mix background", false); - - //------------------------------------------------------------------ - // Event-mixing background + like-sign (to aviod deuteron with wrong collisionId) - void processRun3EMLikeSign(FullCols const& collisions, TrackExtPIDIUwithEvTimes const& tracksIU, aod::BCsWithTimestamps const&) - { + int lastRunNumber = -1; - vtxCandidates.clear(); + for (const auto& [c0, decay3bodys0, c1, decay3bodys1] : pair) { + for (auto& [d3body0, d3body1] : combinations(soa::CombinationsFullIndexPolicy(decay3bodys0, decay3bodys1))) { + 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(); + + if (c0.runNumber() != lastRunNumber) { + initCCDBReduced(c0.runNumber()); + lastRunNumber = c0.runNumber(); // Update the last run number + LOG(debug) << "CCDB initialized for run " << lastRunNumber; + } + fillVtxCand(c0, tpos0, tneg0, tbach1, -1, bachelorcharge, tbach1.tofNSigmaDe()); - auto tracksTuple = std::make_tuple(tracksIU); - BinningType binningEvent{{axisPosZ, axisCentrality}, true}; - SameKindPair pair{binningEvent, 5, -1, collisions, tracksTuple, &cache}; - - Partition candProtons = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candPionPlus = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candAntiProtons = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candPionMinus = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candBachelors = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; - Partition candAntiBachelors = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; - candProtons.bindTable(tracksIU); - candPionPlus.bindTable(tracksIU); - candAntiProtons.bindTable(tracksIU); - candPionMinus.bindTable(tracksIU); - candBachelors.bindTable(tracksIU); - candAntiBachelors.bindTable(tracksIU); - - for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (EMTrackSel.em_event_sel8_selection && (!c1.sel8() || !c2.sel8())) { - continue; - } - auto bc = c1.bc_as(); - initCCDB(bc); - auto protons = candProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto pionsplus = candPionPlus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto antiprotons = candAntiProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto pionsminus = candPionMinus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); - auto bachelors = candBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); - auto antibachelors = candAntiBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); - - for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(protons, pionsminus, antibachelors))) { - double tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(tbach); // Recalculate the TOF PID - fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge, tofNSigmaBach); - } - for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(pionsplus, antiprotons, bachelors))) { - double tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(tbach); // Recalculate the TOF PID - fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge, tofNSigmaBach); + if (c1.runNumber() != lastRunNumber) { + initCCDBReduced(c1.runNumber()); + lastRunNumber = c1.runNumber(); // Update the last run number + LOG(debug) << "CCDB initialized for run " << lastRunNumber; + } + fillVtxCand(c1, tpos1, tneg1, tbach0, -1, bachelorcharge, tbach0.tofNSigmaDe()); } } @@ -1655,7 +1579,8 @@ struct decay3bodyBuilder { fillVtx3BodyTable(candVtx); } } - PROCESS_SWITCH(decay3bodyBuilder, processRun3EMLikeSign, "Produce event-mix background with like-sign method", false); + PROCESS_SWITCH(decay3bodyBuilder, processRun3ReducedEM, "Produce event-mix background", false); + //------------------------------------------------------------------ void processRun3withKFParticle(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const&, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) @@ -2014,10 +1939,10 @@ struct decay3bodyLabelBuilder { Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - void processDoNotBuildLabels(aod::Collisions::iterator const&) + 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&) diff --git a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx index 624ab1efa1b..8ec606b064b 100644 --- a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx @@ -28,10 +28,8 @@ #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 "PWGLF/DataModel/Reduced3BodyTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" @@ -45,7 +43,8 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using FullTracksExtIU = soa::Join; +using ReducedCols = soa::Join; +using FullTracksExtIU = soa::Join; using MCLabeledTracksIU = soa::Join; struct Candidate3body { @@ -54,6 +53,8 @@ struct Candidate3body { int track0Id; int track1Id; int track2Id; + // Collision + float colCentFT0C; // sv and candidate bool isMatter; float invmass; @@ -99,6 +100,8 @@ struct ThreebodyRecoTask { //------------------------------------------------------------------ Preslice perCollisionVtx3BodyDatas = o2::aod::vtx3body::collisionId; + // 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 @@ -217,7 +220,6 @@ struct ThreebodyRecoTask { void init(InitContext const&) { - zorroSummary.setObject(zorro.getZorroSummary()); mRunNumber = 0; @@ -238,8 +240,8 @@ struct ThreebodyRecoTask { 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) - if (doprocessDataLikeSign == true) { - registry.add("hCorrectMassHypertriton", "hCorrectMassHypertriton", HistType::kTH1F, {{80, 2.96f, 3.04f}}); // check if there are contamination of possible signals which are caused by unexpected PID + 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) { @@ -312,12 +314,40 @@ struct ThreebodyRecoTask { 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 (event_sel8_selection && !collision.sel8()) { + return false; + } + registry.fill(HIST("hEventCounter"), 1.5); + if (event_posZ_selection && 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); + } + } + + 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) { - double cospa = candData.vtxcosPA(collision.posX(), collision.posY(), collision.posZ()); double ct = candData.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassHyperTriton; @@ -335,6 +365,7 @@ struct ThreebodyRecoTask { 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; @@ -482,7 +513,6 @@ struct ThreebodyRecoTask { template void candidateAnalysis(TCollisionTable const& collision, TCandTable const& candData, bool& if_hasvtx, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double MClifetime = -1) { - auto track0 = candData.template track0_as(); auto track1 = candData.template track1_as(); auto track2 = candData.template track2_as(); @@ -500,11 +530,10 @@ struct ThreebodyRecoTask { } //------------------------------------------------------------------ - // Analysis process for like-sign background : (p pi- anti-d) or (anti-p pi+ d) + // 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& if_hasvtx, bool isTrueCand = false, int lLabel = -1, TLorentzVector lmother = {0, 0, 0, 0}, double MClifetime = -1) { - auto track0 = candData.template track0_as(); auto track1 = candData.template track1_as(); auto track2 = candData.template track2_as(); @@ -521,13 +550,76 @@ struct ThreebodyRecoTask { fillCand(collision, candData, trackProton, trackPion, trackDeuteron, isMatter, isTrueCand, lLabel, lmother, MClifetime); // QA for if signals have the possibility to be reconginzed as a like-sign background if (isMatter) { - registry.fill(HIST("hCorrectMassHypertriton"), candData.mHypertriton()); + registry.fill(HIST("hInvMassCorrectSign"), candData.mHypertriton()); } else { - registry.fill(HIST("hCorrectMassHypertriton"), candData.mAntiHypertriton()); + 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) + { + auto track0 = tracks.iteratorAt(candData.track0Id()); + auto track1 = tracks.iteratorAt(candData.track1Id()); + auto track2 = tracks.iteratorAt(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); + } + } + + //------------------------------------------------------------------ + // 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) + { + auto track0 = tracks.iteratorAt(candData.track0Id()); + auto track1 = tracks.iteratorAt(candData.track1Id()); + auto track2 = tracks.iteratorAt(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); + // 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) @@ -582,30 +674,18 @@ struct ThreebodyRecoTask { for (const auto& collision : collisions) { candidates3body.clear(); - auto bc = collision.bc_as(); - initCCDB(bc); - registry.fill(HIST("hEventCounter"), 0.5); - if (event_sel8_selection && !collision.sel8()) { + if (!eventSelection(collision)) { 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); - registry.fill(HIST("hCentFT0C"), collision.centFT0C()); - - if (cfgSkimmedProcessing) { - bool zorroSelected = zorro.isSelected(collision.bc_as().globalBC()); /// Just let Zorro do the accounting - if (zorroSelected) { - registry.fill(HIST("hEventCounter"), 3.5); - } - } bool if_hasvtx = false; auto d3bodyCands = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); for (const auto& vtx : d3bodyCands) { - candidateAnalysis(collision, vtx, if_hasvtx); + if (cfgLikeSignAnalysis) { + likeSignAnalysis(collision, vtx, if_hasvtx); + } else { + candidateAnalysis(collision, vtx, if_hasvtx); + } } if (if_hasvtx) registry.fill(HIST("hEventCounter"), 4.5); @@ -613,72 +693,34 @@ struct ThreebodyRecoTask { resetHistos(); for (const auto& cand3body : candidates3body) { - outputDataTable(collision.centFT0C(), - 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]); + fillOutputDataTable(cand3body); } } } PROCESS_SWITCH(ThreebodyRecoTask, processData, "Real data reconstruction", true); //------------------------------------------------------------------ - // process like-sign signal - void processDataLikeSign(soa::Join const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, FullTracksExtIU const& /*tracks*/) + // process reduced data analysis + void processReducedData(ReducedCols const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, aod::ReducedTracksIU const& tracks) { - for (const auto& collision : collisions) { - candidates3body.clear(); - registry.fill(HIST("hEventCounter"), 0.5); - if (event_sel8_selection && !collision.sel8()) { - 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); - registry.fill(HIST("hCentFT0C"), collision.centFT0C()); - - if (cfgSkimmedProcessing) { - bool zorroSelected = zorro.isSelected(collision.bc_as().globalBC()); /// Just let Zorro do the accounting - if (zorroSelected) { - registry.fill(HIST("hEventCounter"), 3.5); - } - } + candidates3body.clear(); - bool if_hasvtx = false; - auto d3bodyCands = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); - for (const auto& vtx : d3bodyCands) { - likeSignAnalysis(collision, vtx, if_hasvtx); + for (const auto& vtx : vtx3bodydatas) { + const auto& collision = collisions.iteratorAt(vtx.collisionId()); + if (cfgLikeSignAnalysis) { + reducedLikeSignAnalysis(collision, vtx, tracks); + } else { + reducedAnalysis(collision, vtx, tracks); } - if (if_hasvtx) - registry.fill(HIST("hEventCounter"), 4.5); - fillHistos(); - resetHistos(); - for (const auto& cand3body : candidates3body) { - outputDataTable(collision.centFT0C(), - 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]); + fillOutputDataTable(cand3body); } + candidates3body.clear(); } + fillHistos(); + resetHistos(); } - PROCESS_SWITCH(ThreebodyRecoTask, processDataLikeSign, "Like-sign signal reconstruction", false); + PROCESS_SWITCH(ThreebodyRecoTask, processReducedData, "Reduced data reconstruction", false); //------------------------------------------------------------------ // process mc analysis @@ -750,7 +792,7 @@ struct ThreebodyRecoTask { resetHistos(); for (const auto& cand3body : candidates3body) { - outputMCTable(collision.centFT0C(), + 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],