diff --git a/PWGHF/TableProducer/candidateCreator2Prong.cxx b/PWGHF/TableProducer/candidateCreator2Prong.cxx index a81ebfe2bfd..74628c854de 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -102,6 +102,9 @@ struct HfCandidateCreator2Prong { OutputObj hDcaXYProngs{TH2F("hDcaXYProngs", "DCAxy of 2-prong candidates;#it{p}_{T} (GeV/#it{c};#it{d}_{xy}) (#mum);entries", 100, 0., 20., 200, -500., 500.)}; OutputObj hDcaZProngs{TH2F("hDcaZProngs", "DCAz of 2-prong candidates;#it{p}_{T} (GeV/#it{c};#it{d}_{z}) (#mum);entries", 100, 0., 20., 200, -500., 500.)}; OutputObj hVertexerType{TH1F("hVertexerType", "Use KF or DCAFitterN;Vertexer type;entries", 2, -0.5, 1.5)}; // See o2::aod::hf_cand::VertexerType + OutputObj hCollisions{TH1D("hCollisions", "HF event counter", ValuesEvSel::NEvSel, -0.5f, static_cast(ValuesEvSel::NEvSel) - 0.5f)}; + OutputObj hPosZBeforeEvSel{TH1D("hPosZBeforeEvSel", "PV position Z before ev. selection;posZ (cm);entries", 400, -20, 20)}; + OutputObj hPosZAfterEvSel{TH1D("hPosZAfterEvSel", "PV position Z after ev. selection;posZ (cm);entries", 400, -20, 20)}; void init(InitContext const&) { @@ -115,6 +118,23 @@ struct HfCandidateCreator2Prong { LOGP(fatal, "One and only one process function must be enabled at a time."); } + std::array processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; + const int nProcessesCollisions = std::accumulate(processesCollisions.begin(), processesCollisions.end(), 0); + if (nProcessesCollisions > 1) { + LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); + } + if (nProcessesCollisions == 1) { + if ((doprocessPvRefitWithDCAFitterN || doprocessNoPvRefitWithDCAFitterN || doprocessPvRefitWithKFParticle || doprocessNoPvRefitWithKFParticle) && !doprocessCollisions) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); + } + if ((doprocessPvRefitWithDCAFitterNCentFT0C || doprocessNoPvRefitWithDCAFitterNCentFT0C || doprocessPvRefitWithKFParticleCentFT0C || doprocessNoPvRefitWithKFParticleCentFT0C) && !doprocessCollisionsCentFT0C) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0C\"?"); + } + if ((doprocessPvRefitWithDCAFitterNCentFT0M || doprocessNoPvRefitWithDCAFitterNCentFT0M || doprocessPvRefitWithKFParticleCentFT0M || doprocessNoPvRefitWithKFParticleCentFT0M) && !doprocessCollisionsCentFT0M) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0M\"?"); + } + } + massPi = MassPiPlus; massK = MassKPlus; @@ -139,9 +159,12 @@ struct HfCandidateCreator2Prong { ccdb->setLocalObjectValidityChecking(); lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; + + /// collision monitoring + setLabelHistoEvSel(hCollisions.object); } - template + template void runCreator2ProngWithDCAFitterN(Coll const& collisions, CandType const& rowsTrackIndexProng2, TTracks const& tracks, @@ -150,24 +173,11 @@ struct HfCandidateCreator2Prong { // loop over pairs of track indices for (const auto& rowTrackIndexProng2 : rowsTrackIndexProng2) { - // reject candidates in collisions outside the centrality range + /// reject candidates not satisfying the event selections auto collision = rowTrackIndexProng2.template collision_as(); - float centrality = -1.; - if constexpr (centEstimator != CentralityEstimator::None) { - if constexpr (centEstimator == CentralityEstimator::FT0C) { - centrality = collision.centFT0C(); - } else if constexpr (centEstimator == CentralityEstimator::FT0M) { - centrality = collision.centFT0M(); - } else { - LOGP(fatal, "Centrality estimator different from FT0C and FT0M, fix it!"); - } - if (centrality < centralityMin || centrality > centralityMax) { - continue; - } - } - - /// event selection: sel8, PV posZ, TF border cut - if (!isHfCollisionSelected(collision, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut)) { + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate continue; } @@ -283,7 +293,7 @@ struct HfCandidateCreator2Prong { } } - template + template void runCreator2ProngWithKFParticle(Coll const& collisions, CandType const& rowsTrackIndexProng2, TTracks const& tracks, @@ -292,24 +302,11 @@ struct HfCandidateCreator2Prong { for (const auto& rowTrackIndexProng2 : rowsTrackIndexProng2) { - // reject candidates in collisions outside the centrality range + /// reject candidates in collisions not satisfying the event selections auto collision = rowTrackIndexProng2.template collision_as(); - float centrality = -1.; - if constexpr (centEstimator != CentralityEstimator::None) { - if constexpr (centEstimator == CentralityEstimator::FT0C) { - centrality = collision.centFT0C(); - } else if constexpr (centEstimator == CentralityEstimator::FT0M) { - centrality = collision.centFT0M(); - } else { - LOGP(fatal, "Centrality estimator different from FT0C and FT0M, fix it!"); - } - if (centrality < centralityMin || centrality > centralityMax) { - continue; - } - } - - /// event selection: sel8, PV posZ, TF border cut - if (!isHfCollisionSelected(collision, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut)) { + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate continue; } @@ -572,6 +569,60 @@ struct HfCandidateCreator2Prong { runCreator2ProngWithKFParticle(collisions, rowsTrackIndexProng2, tracks, bcWithTimeStamps); } PROCESS_SWITCH(HfCandidateCreator2Prong, processNoPvRefitWithKFParticleCentFT0M, "Run candidate creator using KFParticle package w/o PV refit and w/ centrality selection on FT0M", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions only for collision monitoring /// + /// /// + /////////////////////////////////////////////////////////// + + /// @brief process function to monitor collisions - no centrality + void processCollisions(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreator2Prong, processCollisions, "Collision monitoring - no centrality", true); + + /// @brief process function to monitor collisions - FT0C centrality + void processCollisionsCentFT0C(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreator2Prong, processCollisionsCentFT0C, "Collision monitoring - FT0C centrality", false); + + /// @brief process function to monitor collisions - FT0M centrality + void processCollisionsCentFT0M(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreator2Prong, processCollisionsCentFT0M, "Collision monitoring - FT0M centrality", false); }; /// Extends the base table with expression columns. diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index ccfa9451593..e6571bcf3a9 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -99,6 +99,9 @@ struct HfCandidateCreator3Prong { OutputObj hCovSVZZ{TH1F("hCovSVZZ", "3-prong candidates;ZZ element of cov. matrix of sec. vtx. position (cm^{2});entries", 100, 0., 0.2)}; OutputObj hDcaXYProngs{TH2F("hDcaXYProngs", "DCAxy of 3-prong candidates;#it{p}_{T} (GeV/#it{c};#it{d}_{xy}) (#mum);entries", 100, 0., 20., 200, -500., 500.)}; OutputObj hDcaZProngs{TH2F("hDcaZProngs", "DCAz of 3-prong candidates;#it{p}_{T} (GeV/#it{c};#it{d}_{z}) (#mum);entries", 100, 0., 20., 200, -500., 500.)}; + OutputObj hCollisions{TH1D("hCollisions", "HF event counter", ValuesEvSel::NEvSel, -0.5f, static_cast(ValuesEvSel::NEvSel) - 0.5f)}; + OutputObj hPosZBeforeEvSel{TH1D("hPosZBeforeEvSel", "PV position Z before ev. selection;posZ (cm);entries", 400, -20, 20)}; + OutputObj hPosZAfterEvSel{TH1D("hPosZAfterEvSel", "PV position Z after ev. selection;posZ (cm);entries", 400, -20, 20)}; void init(InitContext const&) { @@ -109,6 +112,23 @@ struct HfCandidateCreator3Prong { LOGP(fatal, "One and only one process function must be enabled at a time."); } + std::array processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; + const int nProcessesCollisions = std::accumulate(processesCollisions.begin(), processesCollisions.end(), 0); + if (nProcessesCollisions > 1) { + LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); + } + if (nProcessesCollisions == 1) { + if ((doprocessPvRefit || doprocessNoPvRefit) && !doprocessCollisions) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); + } + if ((doprocessPvRefitCentFT0C || doprocessNoPvRefitCentFT0C) && !doprocessCollisionsCentFT0C) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0C\"?"); + } + if ((doprocessPvRefitCentFT0M || doprocessNoPvRefitCentFT0M) && !doprocessCollisionsCentFT0M) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0M\"?"); + } + } + std::array creationFlags = {createDplus, createDs, createLc, createXic}; if (std::accumulate(creationFlags.begin(), creationFlags.end(), 0) == 0) { LOGP(fatal, "At least one particle specie should be enabled for the creation."); @@ -132,9 +152,12 @@ struct HfCandidateCreator3Prong { ccdb->setLocalObjectValidityChecking(); lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; + + /// collision monitoring + setLabelHistoEvSel(hCollisions.object); } - template + template void runCreator3Prong(Coll const& collisions, Cand const& rowsTrackIndexProng3, aod::TracksWCovExtra const& tracks, @@ -143,24 +166,11 @@ struct HfCandidateCreator3Prong { // loop over triplets of track indices for (const auto& rowTrackIndexProng3 : rowsTrackIndexProng3) { - // reject candidates in collisions outside the centrality range + /// reject candidates in collisions not satisfying the event selections auto collision = rowTrackIndexProng3.template collision_as(); - float centrality = -1.; - if constexpr (centEstimator != CentralityEstimator::None) { - if constexpr (centEstimator == CentralityEstimator::FT0C) { - centrality = collision.centFT0C(); - } else if constexpr (centEstimator == CentralityEstimator::FT0M) { - centrality = collision.centFT0M(); - } else { - LOGP(fatal, "Centrality estimator different from FT0C and FT0M, fix it!"); - } - if (centrality < centralityMin || centrality > centralityMax) { - continue; - } - } - - /// event selection: sel8, PV posZ, TF border cut - if (!isHfCollisionSelected(collision, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut)) { + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate continue; } @@ -364,6 +374,60 @@ struct HfCandidateCreator3Prong { runCreator3Prong(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); } PROCESS_SWITCH(HfCandidateCreator3Prong, processNoPvRefitCentFT0M, "Run candidate creator without PV refit and w/ centrality selection on FT0M", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions only for collision monitoring /// + /// /// + /////////////////////////////////////////////////////////// + + /// @brief process function to monitor collisions - no centrality + void processCollisions(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreator3Prong, processCollisions, "Collision monitoring - no centrality", true); + + /// @brief process function to monitor collisions - FT0C centrality + void processCollisionsCentFT0C(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreator3Prong, processCollisionsCentFT0C, "Collision monitoring - FT0C centrality", false); + + /// @brief process function to monitor collisions - FT0M centrality + void processCollisionsCentFT0M(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreator3Prong, processCollisionsCentFT0M, "Collision monitoring - FT0M centrality", false); }; /// Extends the base table with expression columns. diff --git a/PWGHF/TableProducer/candidateCreatorCascade.cxx b/PWGHF/TableProducer/candidateCreatorCascade.cxx index 9c08adb124d..ad63bfa35c6 100644 --- a/PWGHF/TableProducer/candidateCreatorCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorCascade.cxx @@ -81,6 +81,9 @@ struct HfCandidateCreatorCascade { OutputObj hMass2{TH1F("hMass2", "2-prong candidates;inv. mass (p K_{S}^{0}) (GeV/#it{c}^{2});entries", 500, 0., 5.)}; OutputObj hCovPVXX{TH1F("hCovPVXX", "2-prong candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", 100, 0., 1.e-4)}; OutputObj hCovSVXX{TH1F("hCovSVXX", "2-prong candidates;XX element of cov. matrix of sec. vtx. position (cm^{2});entries", 100, 0., 0.2)}; + OutputObj hCollisions{TH1D("hCollisions", "HF event counter", ValuesEvSel::NEvSel, -0.5f, static_cast(ValuesEvSel::NEvSel) - 0.5f)}; + OutputObj hPosZBeforeEvSel{TH1D("hPosZBeforeEvSel", "PV position Z before ev. selection;posZ (cm);entries", 400, -20, 20)}; + OutputObj hPosZAfterEvSel{TH1D("hPosZAfterEvSel", "PV position Z after ev. selection;posZ (cm);entries", 400, -20, 20)}; void init(InitContext const&) { @@ -89,6 +92,23 @@ struct HfCandidateCreatorCascade { LOGP(fatal, "One and only one process function must be enabled at a time."); } + std::array processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; + const int nProcessesCollisions = std::accumulate(processesCollisions.begin(), processesCollisions.end(), 0); + if (nProcessesCollisions > 1) { + LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); + } + if (nProcessesCollisions == 1) { + if (doprocessNoCent && !doprocessCollisions) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); + } + if (doprocessCentFT0C && !doprocessCollisionsCentFT0C) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0C\"?"); + } + if (doprocessCentFT0M && !doprocessCollisionsCentFT0M) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0M\"?"); + } + } + massP = MassProton; massK0s = MassK0Short; massPi = MassPiPlus; @@ -108,9 +128,12 @@ struct HfCandidateCreatorCascade { ccdb->setLocalObjectValidityChecking(); lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; + + /// collision monitoring + setLabelHistoEvSel(hCollisions.object); } - template + template void runCreatorCascade(Coll const&, aod::HfCascades const& rowsTrackIndexCasc, aod::V0sLinked const&, @@ -122,24 +145,11 @@ struct HfCandidateCreatorCascade { // loop over pairs of track indices for (const auto& casc : rowsTrackIndexCasc) { - // reject candidates in collisions outside the centrality range + /// reject candidates in collisions not satisfying the event selections auto collision = casc.template collision_as(); - float centrality = -1.; - if constexpr (centEstimator != CentralityEstimator::None) { - if constexpr (centEstimator == CentralityEstimator::FT0C) { - centrality = collision.centFT0C(); - } else if constexpr (centEstimator == CentralityEstimator::FT0M) { - centrality = collision.centFT0M(); - } else { - LOGP(fatal, "Centrality estimator different from FT0C and FT0M, fix it!"); - } - if (centrality < centralityMin || centrality > centralityMax) { - continue; - } - } - - /// event selection: sel8, PV posZ, TF border cut - if (!isHfCollisionSelected(collision, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut)) { + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate continue; } @@ -344,6 +354,60 @@ struct HfCandidateCreatorCascade { runCreatorCascade(collisions, rowsTrackIndexCasc, v0sLinked, v0Data, v0fCDatas, tracks, bcs); } PROCESS_SWITCH(HfCandidateCreatorCascade, processCentFT0M, " Run candidate creator w/ centrality selection on FT0M", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions only for collision monitoring /// + /// /// + /////////////////////////////////////////////////////////// + + /// @brief process function to monitor collisions - no centrality + void processCollisions(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorCascade, processCollisions, "Collision monitoring - no centrality", true); + + /// @brief process function to monitor collisions - FT0C centrality + void processCollisionsCentFT0C(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorCascade, processCollisionsCentFT0C, "Collision monitoring - FT0C centrality", false); + + /// @brief process function to monitor collisions - FT0M centrality + void processCollisionsCentFT0M(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorCascade, processCollisionsCentFT0M, "Collision monitoring - FT0M centrality", false); }; /// Performs MC matching. diff --git a/PWGHF/TableProducer/candidateCreatorDstar.cxx b/PWGHF/TableProducer/candidateCreatorDstar.cxx index c7322121e98..8017ceee44d 100644 --- a/PWGHF/TableProducer/candidateCreatorDstar.cxx +++ b/PWGHF/TableProducer/candidateCreatorDstar.cxx @@ -107,6 +107,10 @@ struct HfCandidateCreatorDstar { {"QA/hPtD0", "D^{0} candidates", {HistType::kTH1F, {ptAxis}}}, {"QA/hPtDstar", "D* candidates", {HistType::kTH1F, {ptAxis}}}}}; + OutputObj hCollisions{TH1D("hCollisions", "HF event counter", ValuesEvSel::NEvSel, -0.5f, static_cast(ValuesEvSel::NEvSel) - 0.5f)}; + OutputObj hPosZBeforeEvSel{TH1D("hPosZBeforeEvSel", "PV position Z before ev. selection;posZ (cm);entries", 400, -20, 20)}; + OutputObj hPosZAfterEvSel{TH1D("hPosZAfterEvSel", "PV position Z after ev. selection;posZ (cm);entries", 400, -20, 20)}; + /// @brief This function initializes the ccdb setting, vertex fitter and runs function MatLayerCylSet::rectifyPtrFromFile(..args..) void init(InitContext const&) { @@ -116,6 +120,24 @@ struct HfCandidateCreatorDstar { if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } + + std::array processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; + const int nProcessesCollisions = std::accumulate(processesCollisions.begin(), processesCollisions.end(), 0); + if (nProcessesCollisions > 1) { + LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); + } + if (nProcessesCollisions == 1) { + if ((doprocessPvRefit || doprocessNoPvRefit) && !doprocessCollisions) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); + } + if ((doprocessPvRefitCentFT0C || doprocessNoPvRefitCentFT0C) && !doprocessCollisionsCentFT0C) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0C\"?"); + } + if ((doprocessPvRefitCentFT0M || doprocessNoPvRefitCentFT0M) && !doprocessCollisionsCentFT0M) { + LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0M\"?"); + } + } + // LOG(info) << "Init Function Invoked"; massPi = MassPiPlus; massK = MassKPlus; @@ -135,6 +157,9 @@ struct HfCandidateCreatorDstar { ccdb->setLocalObjectValidityChecking(); // set the flag to check object validity before CCDB query runNumber = 0; bz = 0; + + /// collision monitoring + setLabelHistoEvSel(hCollisions.object); } /// @brief function for secondary vertex reconstruction and candidate creator @@ -145,7 +170,7 @@ struct HfCandidateCreatorDstar { /// @param rowsTrackIndexD0 D0 table object from trackIndexSkimCreator.cxx /// @param tracks track table with Cov object /// @param bcWithTimeStamps Bunch Crossing with timestamps - template + template void runCreatorDstar(Coll const& collisions, CandsDstar const& rowsTrackIndexDstar, aod::Hf2Prongs const& rowsTrackIndexD0, @@ -157,24 +182,11 @@ struct HfCandidateCreatorDstar { // loop over suspected Dstar Candidate for (const auto& rowTrackIndexDstar : rowsTrackIndexDstar) { - // reject candidates in collisions outside the centrality range + /// reject candidates in collisions not satisfying the event selections auto collision = rowTrackIndexDstar.template collision_as(); - float centrality = -1.; - if constexpr (centEstimator != CentralityEstimator::None) { - if constexpr (centEstimator == CentralityEstimator::FT0C) { - centrality = collision.centFT0C(); - } else if constexpr (centEstimator == CentralityEstimator::FT0M) { - centrality = collision.centFT0M(); - } else { - LOGP(fatal, "Centrality estimator different from FT0C and FT0M, fix it!"); - } - if (centrality < centralityMin || centrality > centralityMax) { - continue; - } - } - - /// event selection: sel8, PV posZ, TF border cut - if (!isHfCollisionSelected(collision, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut)) { + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate continue; } @@ -413,6 +425,60 @@ struct HfCandidateCreatorDstar { runCreatorDstar(collisions, rowsTrackIndexDstar, rowsTrackIndexD0, tracks, bcWithTimeStamps); } PROCESS_SWITCH(HfCandidateCreatorDstar, processNoPvRefitCentFT0M, " Run candidate creator without PV refit and w/ centrality selection on FT0M", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions only for collision monitoring /// + /// /// + /////////////////////////////////////////////////////////// + + /// @brief process function to monitor collisions - no centrality + void processCollisions(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorDstar, processCollisions, "Collision monitoring - no centrality", true); + + /// @brief process function to monitor collisions - FT0C centrality + void processCollisionsCentFT0C(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorDstar, processCollisionsCentFT0C, "Collision monitoring - FT0C centrality", false); + + /// @brief process function to monitor collisions - FT0M centrality + void processCollisionsCentFT0M(soa::Join const& collisions) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + const auto rejectionMask = getHfCollisionRejectionMask(collision, centralityMin, centralityMax, useSel8Trigger, maxPvPosZ, useTimeFrameBorderCut); + + /// monitor the satisfied event selections + monitorCollision(collision, rejectionMask, hCollisions.object, hPosZBeforeEvSel.object, hPosZAfterEvSel.object); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorDstar, processCollisionsCentFT0M, "Collision monitoring - FT0M centrality", false); }; struct HfCandidateCreatorDstarExpressions { diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index c301130f013..385abbe0312 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -50,6 +50,7 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" using namespace o2; using namespace o2::analysis; @@ -68,19 +69,6 @@ enum CandidateType { NCandidateTypes }; -// event rejection types -enum EventRejection { - Trigger = 0, - TimeFrameBorderCut, - PositionX, - PositionY, - PositionZ, - NContrib, - Chi2, - Centrality, - NEventRejection -}; - // enum for proton PID strategy (only proton for baryons) enum ProtonPidStrategy { NoPid = 0, diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index 0b87373377c..dafa46e1df2 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -16,32 +16,124 @@ #ifndef PWGHF_UTILS_UTILSEVSELHF_H_ #define PWGHF_UTILS_UTILSEVSELHF_H_ +// event rejection types +enum EventRejection { + Trigger = 0, + TimeFrameBorderCut, + PositionX, + PositionY, + PositionZ, + NContrib, + Chi2, + Centrality, + NEventRejection +}; + +enum ValuesEvSel : int { + All = 0, + Cent, + CentSel8, + CentSel8PosZ, + CentSel8PosZTFBorder, + NEvSel +}; + +/// @brief Function to put labels on collision monitoring histogram +/// \param hCollisions is the histogram +template +void setLabelHistoEvSel(Histo& hCollisions) +{ + hCollisions->GetXaxis()->SetBinLabel(ValuesEvSel::All + 1, "All collisions"); + hCollisions->GetXaxis()->SetBinLabel(ValuesEvSel::Cent + 1, "Centrality ok"); + hCollisions->GetXaxis()->SetBinLabel(ValuesEvSel::CentSel8 + 1, "Centrality + sel8 ok"); + hCollisions->GetXaxis()->SetBinLabel(ValuesEvSel::CentSel8PosZ + 1, "Centrality + sel8 + posZ ok"); + hCollisions->GetXaxis()->SetBinLabel(ValuesEvSel::CentSel8PosZTFBorder + 1, "Centrality + sel8 + posZ + TF border ok"); +} + /// \brief Function to apply event selections in HF analyses /// \param collision collision that has to satisfy the selection criteria /// \param useSel8Trigger switch to activate the sel8() event selection /// \param zPvPosMax maximum primary-vertex z /// \param useTimeFrameBorderCut switch to activate the time frame border cut -/// \return true if collision satisfies all criteria, false otherwise -template -bool isHfCollisionSelected(const Coll& collision, bool useSel8Trigger, float maxPvPosZ, bool useTimeFrameBorderCut) +/// \return a bitmask with the event selections not satisfied by the analysed collision +template +uint16_t getHfCollisionRejectionMask(const Coll& collision, float centralityMin, float centralityMax, bool useSel8Trigger, float maxPvPosZ, bool useTimeFrameBorderCut) { + uint16_t statusCollision = 0; // 16 bits, in case new ev. selections will be added + float centrality = -1.; + + if constexpr (centEstimator != o2::aod::hf_collision_centrality::CentralityEstimator::None) { + if constexpr (centEstimator == o2::aod::hf_collision_centrality::CentralityEstimator::FT0C) { + centrality = collision.centFT0C(); + } else if constexpr (centEstimator == o2::aod::hf_collision_centrality::CentralityEstimator::FT0M) { + centrality = collision.centFT0M(); + } else { + LOGP(fatal, "Centrality estimator different from FT0C and FT0M, fix it!"); + } + if (centrality < centralityMin || centrality > centralityMax) { + SETBIT(statusCollision, EventRejection::Centrality); + } + } + /// sel8() condition if (useSel8Trigger && !collision.sel8()) { - return false; + SETBIT(statusCollision, EventRejection::Trigger); } /// primary vertex z if (std::fabs(collision.posZ()) > maxPvPosZ) { - return false; + SETBIT(statusCollision, EventRejection::PositionZ); } /// time frame border cut if (useTimeFrameBorderCut && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return false; + SETBIT(statusCollision, EventRejection::TimeFrameBorderCut); + } + + /// TODO: add other selections, to extend it to the trackIndexSkimCreator + + return statusCollision; +} + +/// @brief function to monitor the event selection satisfied by collisions used for HF analyses +/// \param collision is the analysed collision +/// \param rejectionMask is the bitmask storing the info about which ev. selections are not satisfied by the collision +/// \param hCollisions is a histogram to keep track of the satisfied event selections +/// \param hPosZBeforeEvSel is PV position Z for all analysed collisions +/// \param hPosZAfterEvSel is PV position Z only for collisions satisfying the event selections +template +void monitorCollision(Coll const& collision, const uint16_t rejectionMask, Hist& hCollisions, Hist& hPosZBeforeEvSel, Hist& hPosZAfterEvSel) +{ + + hCollisions->Fill(ValuesEvSel::All); // all collisions + const float posZ = collision.posZ(); + hPosZBeforeEvSel->Fill(posZ); + + /// centrality + if (TESTBIT(rejectionMask, EventRejection::Centrality)) { + return; } + hCollisions->Fill(ValuesEvSel::Cent); // Centrality ok - /// all conditions satisfied - return true; + /// sel8() + if (TESTBIT(rejectionMask, EventRejection::Trigger)) { + return; + } + hCollisions->Fill(ValuesEvSel::CentSel8); // Centrality + sel8 ok + + /// PV position Z + if (TESTBIT(rejectionMask, EventRejection::PositionZ)) { + return; + } + hCollisions->Fill(ValuesEvSel::CentSel8PosZ); // Centrality + sel8 + posZ ok + + /// Time Frame border cut + if (TESTBIT(rejectionMask, EventRejection::TimeFrameBorderCut)) { + return; + } + hCollisions->Fill(ValuesEvSel::CentSel8PosZTFBorder); // Centrality + sel8 + posZ + TF border ok + hPosZAfterEvSel->Fill(posZ); } + #endif // PWGHF_UTILS_UTILSEVSELHF_H_