diff --git a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx index 4cc9a98d524..6baa84ee4ea 100644 --- a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx +++ b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx @@ -15,15 +15,19 @@ /// \author Gyula Bencedi, gyula.bencedi@cern.ch /// \since Nov 2024 -#include -#include -#include -#include -#include -#include +#include "Functions.h" +#include "Index.h" +#include "bestCollisionTable.h" -#include "CCDB/BasicCCDBManager.h" +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/MathConstants.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" @@ -31,22 +35,18 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/RuntimeError.h" #include "Framework/runDataProcessing.h" - -#include "Common/CCDB/ctpRateFetcher.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" - #include "MathUtils/Utils.h" #include "ReconstructionDataFormats/GlobalTrackID.h" + #include "TPDGCode.h" -#include "Functions.h" -#include "Index.h" -#include "bestCollisionTable.h" +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -65,6 +65,7 @@ AxisSpec dcaxyAxis = {500, -1, 50}; AxisSpec phiAxis = {629, 0, TwoPI, "Rad", "#phi"}; AxisSpec etaAxis = {20, -4., -2.}; AxisSpec centAxis{100, 0, 100, "centrality"}; +AxisSpec chiSqAxis = {100, 0., 1000.}; struct DndetaMFTPbPb { SliceCache cache; @@ -83,6 +84,11 @@ struct DndetaMFTPbPb { false, true}; + Configurable cfgDoIR{"cfgDoIR", false, "Flag to retrieve Interaction rate from CCDB"}; + Configurable cfgUseIRCut{"cfgUseIRCut", false, "Flag to cut on IR rate"}; + Configurable cfgIRCrashOnNull{"cfgIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash"}; + Configurable cfgIRSource{"cfgIRSource", "T0VTX", "Estimator of the interaction rate (Pb-Pb: ZNC hadronic)"}; + struct : ConfigurableGroup { Configurable usephiCut{"usephiCut", false, "use azimuthal angle cut"}; Configurable phiCut{"phiCut", 0.1f, @@ -93,6 +99,7 @@ struct DndetaMFTPbPb { Configurable maxEta{"maxEta", -2.5f, ""}; Configurable minNclusterMft{"minNclusterMft", 5, "minimum number of MFT clusters"}; + Configurable useChi2Cut{"useChi2Cut", false, "use track chi2 cut"}; Configurable maxChi2{"maxChi2", 10.f, ""}; Configurable minPt{"minPt", 0., "minimum pT of the MFT tracks"}; Configurable requireCA{ @@ -127,7 +134,6 @@ struct DndetaMFTPbPb { "minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; Configurable maxOccupancy{ "maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; - Configurable cfgSelInteractionRate{"cfgSelInteractionRate", false, " Get Interaction rate from CCDB"}; Configurable minIR{"minIR", -1, "minimum IR (kHz) collisions"}; Configurable maxIR{"maxIR", -1, "maximum IR (kHz) collisions"}; } eventCuts; @@ -154,7 +160,13 @@ struct DndetaMFTPbPb { "latest acceptable timestamp of creation for the object"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + + int mRunNumber{-1}; + uint64_t mSOR{0}; + double mMinSeconds{-1.}; + std::unordered_map gHadronicRate; ctpRateFetcher rateFetcher; + TH2* gCurrentHadronicRate; /// @brief init function, definition of histograms void init(InitContext&) @@ -221,7 +233,7 @@ struct DndetaMFTPbPb { } auto hev = registry.add("hEvtSel", "hEvtSel", HistType::kTH1F, - {{16, -0.5f, +15.5f}}); + {{14, -0.5f, +13.5f}}); hev->GetXaxis()->SetBinLabel(1, "All collisions"); hev->GetXaxis()->SetBinLabel(2, "Ev. sel."); hev->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); @@ -235,8 +247,6 @@ struct DndetaMFTPbPb { hev->GetXaxis()->SetBinLabel(11, "kNoHighMultCollInPrevRof"); hev->GetXaxis()->SetBinLabel(12, "Below min occup."); hev->GetXaxis()->SetBinLabel(13, "Above max occup."); - hev->GetXaxis()->SetBinLabel(14, "Below min IR (kHz)"); - hev->GetXaxis()->SetBinLabel(15, "Above max IR (kHz)"); auto hBcSel = registry.add("hBcSel", "hBcSel", HistType::kTH1F, {{3, -0.5f, +2.5f}}); @@ -257,9 +267,6 @@ struct DndetaMFTPbPb { x->SetBinLabel(1, "All"); x->SetBinLabel(2, "Selected"); - qaregistry.add("hOccIRate", "hOccIRate", HistType::kTH2F, - {occupancyAxis, irBins}); - registry.add({"Events/NtrkZvtx", "; N_{trk}; Z_{vtx} (cm); occupancy", {HistType::kTHnSparseF, {multAxis, zAxis, occupancyAxis}}}); @@ -274,10 +281,10 @@ struct DndetaMFTPbPb { qaregistry.add( {"Tracks/Chi2Eta", "; #chi^{2}; #it{#eta}; occupancy", - {HistType::kTHnSparseF, {{600, 0, 20}, etaAxis, occupancyAxis}}}); + {HistType::kTHnSparseF, {chiSqAxis, etaAxis, occupancyAxis}}}); qaregistry.add({"Tracks/Chi2", "; #chi^{2};", - {HistType::kTH2F, {{600, 0, 20}, occupancyAxis}}}); + {HistType::kTH2F, {chiSqAxis, occupancyAxis}}}); qaregistry.add( {"Tracks/NclustersEta", "; nClusters; #eta; occupancy", @@ -343,9 +350,6 @@ struct DndetaMFTPbPb { hstat->GetAxis(0)->SetBinLabel(1, "All"); hstat->GetAxis(0)->SetBinLabel(2, "Selected"); - qaregistry.add("hCentOccIRate", "hCentOccIRate", HistType::kTHnSparseF, - {centralityAxis, occupancyAxis, irBins}); - qaregistry.add({"Events/Centrality/hCent", "; centrality; occupancy", {HistType::kTH2F, {centAxis, occupancyAxis}}, @@ -375,11 +379,11 @@ struct DndetaMFTPbPb { {"Tracks/Centrality/Chi2Eta", "; #chi^{2}; #it{#eta}; centrality; occupancy", {HistType::kTHnSparseF, - {{600, 0, 20}, etaAxis, centralityAxis, occupancyAxis}}}); + {chiSqAxis, etaAxis, centralityAxis, occupancyAxis}}}); qaregistry.add({"Tracks/Centrality/Chi2", "; #chi^{2}; centrality; occupancy", {HistType::kTHnSparseF, - {{600, 0, 20}, centralityAxis, occupancyAxis}}}); + {chiSqAxis, centralityAxis, occupancyAxis}}}); qaregistry.add({"Tracks/Centrality/NclustersEta", "; nClusters; #eta; centrality; occupancy", {HistType::kTHnSparseF, @@ -735,35 +739,15 @@ struct DndetaMFTPbPb { using FiltBestTracks = soa::Filtered; using FiltParticles = soa::Filtered; - bool isIRSelected(CollBCs::iterator const& bc, bool fillHis = false) - { - double ir = (eventCuts.minIR >= 0 || eventCuts.maxIR >= 0) - ? rateFetcher.fetch(ccdb.service, bc.timestamp(), - bc.runNumber(), "ZNC hadronic") * - 1.e-3 - : -1; - if (eventCuts.minIR >= 0 && ir < eventCuts.minIR) { - return false; - } - if (fillHis) { - registry.fill(HIST("hEvtSel"), 13); - } - if (eventCuts.maxIR >= 0 && ir > eventCuts.maxIR) { - return false; - } - if (fillHis) { - registry.fill(HIST("hEvtSel"), 14); - } - return true; - } - template bool isTrackSelected(const T& track) { if (track.eta() < trackCuts.minEta || track.eta() > trackCuts.maxEta) return false; - if (track.chi2() > trackCuts.maxChi2) - return false; + if (trackCuts.useChi2Cut) { + if (track.chi2() > trackCuts.maxChi2) + return false; + } if (trackCuts.requireCA && !track.isCA()) return false; if (track.nClusters() < trackCuts.minNclusterMft) @@ -928,6 +912,24 @@ struct DndetaMFTPbPb { return -1.f; } + void initHadronicRate(CollBCs::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + mRunNumber = bc.runNumber(); + if (gHadronicRate.find(mRunNumber) == gHadronicRate.end()) { + auto runDuration = ccdb->getRunDuration(mRunNumber); + mSOR = runDuration.first; + mMinSeconds = std::floor(mSOR * 1.e-3); /// round tsSOR to the highest integer lower than tsSOR + double maxSec = std::ceil(runDuration.second * 1.e-3); /// round tsEOR to the lowest integer higher than tsEOR + const AxisSpec axisSeconds{static_cast((maxSec - mMinSeconds) / 20.f), 0, maxSec - mMinSeconds, "Seconds since SOR"}; + int hadronicRateBins = static_cast(eventCuts.maxIR - eventCuts.minIR); + gHadronicRate[mRunNumber] = registry.add(Form("HadronicRate/%i", mRunNumber), ";Time since SOR (s);Hadronic rate (kHz)", kTH2D, {axisSeconds, {hadronicRateBins, eventCuts.minIR, eventCuts.maxIR}}).get(); + } + gCurrentHadronicRate = gHadronicRate[mRunNumber]; + } + template bool isGoodEvent(C const& collision) { @@ -1110,10 +1112,6 @@ struct DndetaMFTPbPb { auto occ = getOccupancy(collision, eventCuts.occupancyEstimator); float c = getRecoCent(collision); auto bc = collision.template foundBC_as(); - double ir = rateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), - "ZNC hadronic") * - 1.e-3; - if constexpr (has_reco_cent) { registry.fill(HIST("Events/Centrality/Selection"), 1., c, occ); } else { @@ -1123,10 +1121,15 @@ struct DndetaMFTPbPb { if (!isGoodEvent(collision)) { return; } - if (eventCuts.cfgSelInteractionRate) { - if (!isIRSelected(bc, true)) { + + if (cfgDoIR) { + initHadronicRate(bc); + double ir = rateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), cfgIRSource, cfgIRCrashOnNull) * 1.e-3; + double seconds = bc.timestamp() * 1.e-3 - mMinSeconds; + if (cfgUseIRCut && (ir < eventCuts.minIR || ir > eventCuts.maxIR)) { // cut on hadronic rate return; } + gCurrentHadronicRate->Fill(seconds, ir); } auto z = collision.posZ(); @@ -1134,10 +1137,7 @@ struct DndetaMFTPbPb { registry.fill(HIST("Events/Centrality/Selection"), 2., c, occ); qaregistry.fill(HIST("Events/Centrality/hZvtxCent"), z, c, occ); qaregistry.fill(HIST("Events/Centrality/hCent"), c, occ); - qaregistry.fill(HIST("hCentOccIRate"), c, occ, ir); - } else { - qaregistry.fill(HIST("hOccIRate"), occ, ir); registry.fill(HIST("Events/Selection"), 2., occ); } @@ -1155,16 +1155,11 @@ struct DndetaMFTPbPb { template void processDatawBestTracks( typename C::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& /*bcs*/) + soa::SmallGroups const& besttracks, CollBCs const& /*bcs*/) { auto occ = getOccupancy(collision, eventCuts.occupancyEstimator); float c = getRecoCent(collision); auto bc = collision.template foundBC_as(); - double ir = rateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), - "ZNC hadronic") * - 1.e-3; - if constexpr (has_reco_cent) { registry.fill(HIST("Events/Centrality/Selection"), 1., c, occ); } else { @@ -1174,19 +1169,22 @@ struct DndetaMFTPbPb { if (!isGoodEvent(collision)) { return; } - if (eventCuts.cfgSelInteractionRate) { - if (!isIRSelected(bc, true)) { + + if (cfgDoIR) { + initHadronicRate(bc); + double ir = rateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), cfgIRSource, cfgIRCrashOnNull) * 1.e-3; + double seconds = bc.timestamp() * 1.e-3 - mMinSeconds; + if (cfgUseIRCut && (ir < eventCuts.minIR || ir > eventCuts.maxIR)) { // cut on hadronic rate return; } + gCurrentHadronicRate->Fill(seconds, ir); } auto z = collision.posZ(); if constexpr (has_reco_cent) { registry.fill(HIST("Events/Centrality/Selection"), 2., c, occ); - qaregistry.fill(HIST("hCentOccIRate"), c, occ, ir); } else { registry.fill(HIST("Events/Selection"), 2., occ); - qaregistry.fill(HIST("hOccIRate"), occ, ir); } auto nBestTrks = countBestTracks(tracks, besttracks, z, c, occ); @@ -1256,8 +1254,7 @@ struct DndetaMFTPbPb { void processDatawBestTracksInclusive( Colls::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& bcs) + soa::SmallGroups const& besttracks, CollBCs const& bcs) { processDatawBestTracks(collision, tracks, besttracks, bcs); } @@ -1268,8 +1265,7 @@ struct DndetaMFTPbPb { void processDatawBestTracksCentFT0C( CollsCentFT0C::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& bcs) + soa::SmallGroups const& besttracks, CollBCs const& bcs) { processDatawBestTracks(collision, tracks, besttracks, bcs); } @@ -1281,11 +1277,9 @@ struct DndetaMFTPbPb { void processDatawBestTracksCentFT0CVariant1( CollsCentFT0CVariant1::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& bcs) + soa::SmallGroups const& besttracks, CollBCs const& bcs) { - processDatawBestTracks(collision, tracks, besttracks, - bcs); + processDatawBestTracks(collision, tracks, besttracks, bcs); } PROCESS_SWITCH(DndetaMFTPbPb, processDatawBestTracksCentFT0CVariant1, @@ -1295,8 +1289,7 @@ struct DndetaMFTPbPb { void processDatawBestTracksCentFT0M( CollsCentFT0M::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& bcs) + soa::SmallGroups const& besttracks, CollBCs const& bcs) { processDatawBestTracks(collision, tracks, besttracks, bcs); } @@ -1307,11 +1300,9 @@ struct DndetaMFTPbPb { void processDatawBestTracksCentNGlobal( CollsCentNGlobal::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& bcs) + soa::SmallGroups const& besttracks, CollBCs const& bcs) { - processDatawBestTracks(collision, tracks, besttracks, - bcs); + processDatawBestTracks(collision, tracks, besttracks, bcs); } PROCESS_SWITCH(DndetaMFTPbPb, processDatawBestTracksCentNGlobal, @@ -1321,8 +1312,7 @@ struct DndetaMFTPbPb { void processDatawBestTracksCentMFT( CollsCentMFT::iterator const& collision, FiltMftTracks const& tracks, - soa::SmallGroups const& besttracks, - CollBCs const& bcs) + soa::SmallGroups const& besttracks, CollBCs const& bcs) { processDatawBestTracks(collision, tracks, besttracks, bcs); }