diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 2d84a9afdf8..59e4f0f4523 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -64,8 +64,7 @@ struct HfTaskFlowCharmHadrons { Configurable centralityMax{"centralityMax", 100., "Maximum centrality accepted in SP/EP computation (not applied in resolution process)"}; Configurable storeEP{"storeEP", false, "Flag to store EP-related axis"}; Configurable storeMl{"storeMl", false, "Flag to store ML scores"}; - Configurable occEstimator{"occEstimator", 1, "Occupancy estimation (1: ITS, 2: FT0C)"}; - Configurable storeOccupancy{"storeOccupancy", false, "Flag to store TH2 occITS/occFT0C + HfEvSelBitMasks"}; + Configurable occEstimator{"occEstimator", 0, "Occupancy estimation (0: None, 1: ITS, 2: FT0C)"}; Configurable saveEpResoHisto{"saveEpResoHisto", false, "Flag to save event plane resolution histogram"}; 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."}; @@ -81,7 +80,7 @@ struct HfTaskFlowCharmHadrons { ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNumTracksInTimeRange{"thnConfigAxisNumTracksInTimeRange", {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}, ""}; @@ -135,7 +134,7 @@ struct HfTaskFlowCharmHadrons { const AxisSpec thnAxisOccupancyITS{thnConfigAxisOccupancyITS, "OccupancyITS"}; const AxisSpec thnAxisOccupancyFT0C{thnConfigAxisOccupancyFT0C, "OccupancyFT0C"}; const AxisSpec thnAxisNoSameBunchPileup{thnConfigAxisNoSameBunchPileup, "NoSameBunchPileup"}; - const AxisSpec thnAxisNumTracksInTimeRange{thnConfigAxisNumTracksInTimeRange, "NumTracksInTimeRange"}; + const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, "Occupancy"}; const AxisSpec thnAxisNoCollInTimeRangeNarrow{thnConfigAxisNoCollInTimeRangeNarrow, "NoCollInTimeRangeNarrow"}; const AxisSpec thnAxisNoCollInTimeRangeStandard{thnConfigAxisNoCollInTimeRangeStandard, "NoCollInTimeRangeStandard"}; const AxisSpec thnAxisNoCollInRofStandard{thnConfigAxisNoCollInRofStandard, "NoCollInRofStandard"}; @@ -147,18 +146,18 @@ struct HfTaskFlowCharmHadrons { if (storeMl) { axes.insert(axes.end(), {thnAxisMlOne, thnAxisMlTwo}); } - if (storeOccupancy) { + if (occEstimator != 0) { if (occEstimator == 1) { - axes.insert(axes.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisNumTracksInTimeRange, + axes.insert(axes.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy, thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); } else { - axes.insert(axes.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisNumTracksInTimeRange, + axes.insert(axes.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy, thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); } } registry.add("hSparseFlowCharm", "THn for SP", HistType::kTHnSparseF, axes); - if (storeOccupancy) { + if (occEstimator != 0) { registry.add("trackOccVsFT0COcc", "trackOccVsFT0COcc; trackOcc; FT0COcc", {HistType::kTH2F, {thnAxisOccupancyITS, thnAxisOccupancyFT0C}}); } @@ -280,19 +279,19 @@ struct HfTaskFlowCharmHadrons { float& occupancy, uint16_t& hfevselflag) { - if (storeOccupancy) { + if (occEstimator != 0) { if (storeMl) { if (storeEP) { registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, sp, cosNPhi, cosDeltaPhi, outputMl[0], outputMl[1], occupancy, TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoSameBunchPileup), - TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NumTracksInTimeRange), + TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::Occupancy), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeNarrow), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeStandard), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInRofStandard)); } else { registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, sp, outputMl[0], outputMl[1], occupancy, TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoSameBunchPileup), - TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NumTracksInTimeRange), + TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::Occupancy), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeNarrow), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeStandard), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInRofStandard)); @@ -301,14 +300,14 @@ struct HfTaskFlowCharmHadrons { if (storeEP) { registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, sp, cosNPhi, cosDeltaPhi, occupancy, TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoSameBunchPileup), - TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NumTracksInTimeRange), + TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::Occupancy), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeNarrow), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeStandard), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInRofStandard)); } else { registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, sp, occupancy, TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoSameBunchPileup), - TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NumTracksInTimeRange), + TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::Occupancy), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeNarrow), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInTimeRangeStandard), TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoCollInRofStandard)); @@ -331,26 +330,6 @@ struct HfTaskFlowCharmHadrons { } } - /// Get the occupancy - /// \param collision is the collision with the occupancy information - float getOccupancy(CollsWithQvecs::iterator const& collision) - { - float occupancy = -999.; - switch (occEstimator) { - case 1: - occupancy = collision.trackOccupancyInTimeRange(); - break; - case 2: - occupancy = collision.ft0cOccupancyInTimeRange(); - break; - default: - LOG(warning) << "Occupancy estimator not valid. Possible values are ITS or FT0C. Fallback to ITS"; - occupancy = collision.trackOccupancyInTimeRange(); - break; - } - return occupancy; - } - /// Get the centrality /// \param collision is the collision with the centrality information float getCentrality(CollsWithQvecs::iterator const& collision) @@ -380,16 +359,20 @@ struct HfTaskFlowCharmHadrons { /// Check if the collision is selected /// \param collision is the collision with the Q vector information /// \param bc is the bunch crossing with timestamp information + /// \param centrality is the collision centrality /// \return true if the collision is selected, false otherwise template bool isCollSelected(CollsWithQvecs::iterator const& collision, - aod::BCsWithTimestamps const&) + aod::BCsWithTimestamps const&, + float& centrality) { - float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision, occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + centrality = getCentrality(collision); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + registry.fill(HIST("trackOccVsFT0COcc"), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); return rejectionMask == 0; } @@ -454,8 +437,8 @@ struct HfTaskFlowCharmHadrons { } float occupancy = 0.; uint16_t hfevflag; - if (storeOccupancy) { - occupancy = getOccupancy(collision); + if (occEstimator != 0) { + occupancy = hfEvSel.getOccupancy(collision, occEstimator); registry.fill(HIST("trackOccVsFT0COcc"), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); hfevflag = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); } @@ -648,12 +631,12 @@ struct HfTaskFlowCharmHadrons { void processResolution(CollsWithQvecs::iterator const& collision, aod::BCsWithTimestamps const& bcs) { - if (!isCollSelected(collision, bcs)) { + float centrality{-1.f}; + if (!isCollSelected(collision, bcs, centrality)) { // no selection on the centrality is applied on purpose to allow for the resolution study in post-processing return; } - float centrality = getCentrality(collision); // centrality not updated in the rejection mask function float xQVecFT0a = collision.qvecFT0ARe(); float yQVecFT0a = collision.qvecFT0AIm(); float xQVecFT0c = collision.qvecFT0CRe(); diff --git a/PWGHF/TableProducer/candidateCreator2Prong.cxx b/PWGHF/TableProducer/candidateCreator2Prong.cxx index 6d27cfd9021..5b8128182d6 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -625,10 +625,11 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); } /// end loop over collisions } @@ -642,10 +643,11 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); } /// end loop over collisions } @@ -659,10 +661,11 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); } /// end loop over collisions } diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index a14df266590..985e21acee8 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -404,10 +404,11 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); } /// end loop over collisions } @@ -421,10 +422,11 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); } /// end loop over collisions } @@ -438,10 +440,11 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; + float occupancy = hfEvSel.getOccupancy(collision); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); } /// end loop over collisions } diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index 71f0bd0559d..616608116bb 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -44,7 +44,7 @@ enum EventRejection { ItsRofBorderCut, IsGoodZvtxFT0vsPV, NoSameBunchPileup, - NumTracksInTimeRange, + Occupancy, NContrib, Chi2, PositionZ, @@ -72,7 +72,7 @@ void setEventRejectionLabels(Histo& hRejection, std::string softwareTriggerLabel hRejection->GetXaxis()->SetBinLabel(EventRejection::ItsRofBorderCut + 1, "ITS ROF border"); hRejection->GetXaxis()->SetBinLabel(EventRejection::IsGoodZvtxFT0vsPV + 1, "PV #it{z} consistency FT0 timing"); hRejection->GetXaxis()->SetBinLabel(EventRejection::NoSameBunchPileup + 1, "No same-bunch pile-up"); // POTENTIALLY BAD FOR BEAUTY ANALYSES - hRejection->GetXaxis()->SetBinLabel(EventRejection::NumTracksInTimeRange + 1, "Occupancy"); + hRejection->GetXaxis()->SetBinLabel(EventRejection::Occupancy + 1, "Occupancy"); hRejection->GetXaxis()->SetBinLabel(EventRejection::NContrib + 1, "# of PV contributors"); hRejection->GetXaxis()->SetBinLabel(EventRejection::Chi2 + 1, "PV #it{#chi}^{2}"); hRejection->GetXaxis()->SetBinLabel(EventRejection::PositionZ + 1, "PV #it{z}"); @@ -93,10 +93,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable useItsRofBorderCut{"useItsRofBorderCut", true, "Apply ITS ROF border cut"}; o2::framework::Configurable useIsGoodZvtxFT0vsPV{"useIsGoodZvtxFT0vsPV", false, "Check consistency between PVz from central barrel with that from FT0 timing"}; o2::framework::Configurable useNoSameBunchPileup{"useNoSameBunchPileup", false, "Exclude collisions in bunches with more than 1 reco. PV"}; // POTENTIALLY BAD FOR BEAUTY ANALYSES - o2::framework::Configurable useNumTracksInTimeRange{"useNumTracksInTimeRange", false, "Apply occupancy selection (num. ITS tracks with at least 5 clusters in +-100us from current collision)"}; - o2::framework::Configurable useFT0cOccEstimator{"useFT0cOccEstimator", false, "Adopt FT0c amplitudes as occupancy estimator instead of ITS tracks"}; - o2::framework::Configurable numTracksInTimeRangeMin{"numTracksInTimeRangeMin", 0, "Minimum occupancy"}; - o2::framework::Configurable numTracksInTimeRangeMax{"numTracksInTimeRangeMax", 1000000, "Maximum occupancy"}; + o2::framework::Configurable useOccupancyCut{"useOccupancyCut ", false, "Apply occupancy selection (num. ITS tracks with at least 5 clusters or num. of signals in FT0c in +-100us from current collision)"}; + o2::framework::Configurable occEstimator{"occEstimator", 1, "Occupancy estimation (1: ITS, 2: FT0C)"}; + o2::framework::Configurable occupancyMin{"occupancyMin", 0, "Minimum occupancy"}; + o2::framework::Configurable occupancyMax{"occupancyMax", 1000000, "Maximum occupancy"}; o2::framework::Configurable nPvContributorsMin{"nPvContributorsMin", 0, "Minimum number of PV contributors"}; o2::framework::Configurable chi2PvMax{"chi2PvMax", -1.f, "Maximum PV chi2"}; o2::framework::Configurable zPvPosMin{"zPvPosMin", -10.f, "Minimum PV posZ (cm)"}; @@ -107,6 +107,8 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable softwareTrigger{"softwareTrigger", "", "Label of software trigger. Multiple triggers can be selected dividing them by a comma. Set None if you want bcs that are not selected by any trigger"}; o2::framework::Configurable bcMarginForSoftwareTrigger{"bcMarginForSoftwareTrigger", 100, "Number of BCs of margin for software triggers"}; o2::framework::Configurable ccdbPathSoftwareTrigger{"ccdbPathSoftwareTrigger", "Users/m/mpuccio/EventFiltering/OTS/", "ccdb path for ZORRO objects"}; + o2::framework::ConfigurableAxis th2ConfigAxisCent{"th2ConfigAxisCent", {100, 0., 100.}, ""}; + o2::framework::ConfigurableAxis th2ConfigAxisOccupancy{"th2ConfigAxisOccupancy", {14, 0, 140000}, ""}; // histogram names static constexpr char nameHistCollisions[] = "hCollisions"; @@ -116,8 +118,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { static constexpr char nameHistPosXAfterEvSel[] = "hPosXAfterEvSel"; static constexpr char nameHistPosYAfterEvSel[] = "hPosYAfterEvSel"; static constexpr char nameHistNumPvContributorsAfterSel[] = "hNumPvContributorsAfterSel"; + static constexpr char nameHistCollisionsCentOcc[] = "hCollisionsCentOcc"; std::shared_ptr hCollisions, hSelCollisionsCent, hPosZBeforeEvSel, hPosZAfterEvSel, hPosXAfterEvSel, hPosYAfterEvSel, hNumPvContributorsAfterSel; + std::shared_ptr hCollisionsCentOcc; // util to retrieve trigger mask in case of software triggers Zorro zorro; @@ -137,6 +141,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { hNumPvContributorsAfterSel = registry.add(nameHistNumPvContributorsAfterSel, "selected events;#it{y}_{prim. vtx.} (cm);entries", {o2::framework::HistType::kTH1D, {{500, -0.5, 499.5}}}); setEventRejectionLabels(hCollisions, softwareTrigger); + const o2::framework::AxisSpec th2AxisCent{th2ConfigAxisCent, "Centrality"}; + const o2::framework::AxisSpec th2AxisOccupancy{th2ConfigAxisOccupancy, "Occupancy"}; + hCollisionsCentOcc = registry.add(nameHistCollisionsCentOcc, "selected events;Centrality; Occupancy", {o2::framework::HistType::kTH2D, {th2AxisCent, th2AxisOccupancy}}); + // we initialise the summary object if (softwareTrigger.value != "") { zorroSummary.setObject(zorro.getZorroSummary()); @@ -157,17 +165,7 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { uint16_t rejectionMask{0}; // 16 bits, in case new ev. selections will be added if constexpr (centEstimator != o2::hf_centrality::CentralityEstimator::None) { - if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0A) { - centrality = collision.centFT0A(); - } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0C) { - centrality = collision.centFT0C(); - } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0M) { - centrality = collision.centFT0M(); - } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FV0A) { - centrality = collision.centFV0A(); - } else { - LOGP(fatal, "Unsupported centrality estimator!"); - } + centrality = getCentrality(collision); if (centrality < centralityMin || centrality > centralityMax) { SETBIT(rejectionMask, EventRejection::Centrality); } @@ -211,17 +209,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { if (useNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { SETBIT(rejectionMask, EventRejection::NoCollInRofStandard); } - if (useNumTracksInTimeRange) { - float numTracksInTimeRange; - if (useFT0cOccEstimator) { - /// occupancy estimator (FT0c signal amplitudes in +-10us from current collision) - numTracksInTimeRange = collision.ft0cOccupancyInTimeRange(); - } else { - /// occupancy estimator (ITS tracks with at least 5 clusters in +-10us from current collision) - numTracksInTimeRange = static_cast(collision.trackOccupancyInTimeRange()); - } - if (numTracksInTimeRange < numTracksInTimeRangeMin || numTracksInTimeRange > numTracksInTimeRangeMax) { - SETBIT(rejectionMask, EventRejection::NumTracksInTimeRange); + if (useOccupancyCut) { + float occupancy = getOccupancy(collision, occEstimator); + if (occupancy < occupancyMin || occupancy > occupancyMax) { + SETBIT(rejectionMask, EventRejection::Occupancy); } } } @@ -268,11 +259,51 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { return rejectionMask; } + /// Get the occupancy + /// \param collision is the collision with the occupancy information + /// \param occEstimator is the occupancy estimator (1: ITS, 2: FT0C) + template + float getOccupancy(Coll const& collision, int occEstimator = 1) + { + switch (occEstimator) { + case 1: // ITS + return collision.trackOccupancyInTimeRange(); + break; + case 2: // FT0c + return collision.ft0cOccupancyInTimeRange(); + break; + default: + LOG(warning) << "Occupancy estimator not valid. Possible values are ITS or FT0C. Fallback to ITS"; + return collision.trackOccupancyInTimeRange(); + break; + } + } + + /// Get the centrality + /// \param collision is the collision with the centrality information + /// \param centEstimator is the centrality estimator from hf_centrality::CentralityEstimator + template + float getCentrality(Coll const& collision) + { + if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0A) { + return collision.centFT0A(); + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0C) { + return collision.centFT0C(); + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0M) { + return collision.centFT0M(); + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FV0A) { + return collision.centFV0A(); + } else { + LOG(warning) << "Centrality estimator not valid. Possible values are V0A, T0M, T0A, T0C. Fallback to FT0c"; + return collision.centFT0C(); + } + } + /// \brief Fills histograms for monitoring event selections satisfied by the collision. /// \param collision analysed collision /// \param rejectionMask bitmask storing the info about which ev. selections are not satisfied by the collision template - void fillHistograms(Coll const& collision, const uint16_t rejectionMask, float& centrality) + void fillHistograms(Coll const& collision, const uint16_t rejectionMask, float& centrality, float occupancy = -1) { hCollisions->Fill(EventRejection::None); const float posZ = collision.posZ(); @@ -290,6 +321,7 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { hPosZAfterEvSel->Fill(posZ); hNumPvContributorsAfterSel->Fill(collision.numContrib()); hSelCollisionsCent->Fill(centrality); + hCollisionsCentOcc->Fill(centrality, occupancy); } };