From 14d35cd04b663c1aca80546498cb5ac522304d93 Mon Sep 17 00:00:00 2001 From: Lucamicheletti93 Date: Fri, 9 Jan 2026 21:46:18 +0100 Subject: [PATCH 1/2] Adding code to fill histograms for pileup and normalization --- PWGDQ/TableProducer/tableMaker_withAssoc.cxx | 109 +++++++++++++++---- 1 file changed, 90 insertions(+), 19 deletions(-) diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index b2f61d41df0..817fb1b32b7 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -35,6 +35,7 @@ #include "PWGDQ/DataModel/ReducedInfoTables.h" #include "Common/CCDB/TriggerAliases.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/TableHelper.h" #include "Common/Core/Zorro.h" #include "Common/DataModel/Centrality.h" @@ -54,6 +55,7 @@ #include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsParameters/GRPLHCIFData.h" #include "DetectorsBase/GeometryManager.h" #include "DetectorsBase/Propagator.h" #include "DetectorsVertexing/PVertexerParams.h" @@ -119,7 +121,7 @@ using MyMuonsWithCov = soa::Join; using MyMuonsColl = soa::Join; using MyMuonsCollWithCov = soa::Join; -using MyBCs = soa::Join; +using MyBCs = soa::Join; using ExtBCs = soa::Join; // Declaration of various bit maps containing information on which tables are included in a Join @@ -154,6 +156,7 @@ constexpr static uint32_t gkMFTCovFillMap = VarManager::ObjTypes::TrackMFT | Var // Enum containing the ordering of statistics histograms to be written in the QA file enum SkimStatsHists { kStatsEvent = 0, + kStatsBcs, kStatsTracks, kStatsMuons, kStatsOrphanTracks, @@ -212,6 +215,7 @@ struct TableMaker { // Steer QA output struct : ConfigurableGroup { Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigFillBcStat{"cfgFillBcStat", false, "If true, fill QA histograms for normalization studies (for OO and Pb-Pb)"}; Configurable fConfigDetailedQA{"cfgDetailedQA", false, "If true, include more QA histograms (BeforeCuts classes)"}; Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; @@ -338,6 +342,9 @@ struct TableMaker { Partition tracksPosWithCov = (((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)) && (aod::track::tgl > static_cast(0.05))); Partition tracksNegWithCov = (((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)) && (aod::track::tgl < static_cast(-0.05))); + ctpRateFetcher mRateFetcher; + parameters::GRPLHCIFData* mLHCIFdata = nullptr; + struct { std::map oMeanTimeShortA; std::map oMeanTimeShortC; @@ -569,6 +576,7 @@ struct TableMaker { // Create statistics histograms which will be stored in the QA output // Event statistics: kStatsEvent + // BC statistics + Pileup calculation: kStatsBcs // Track statistics: kStatsTracks // Muon statistics: kStatsMuons // Orphan track statistics: kStatsOrphanTracks @@ -588,6 +596,14 @@ struct TableMaker { histEvents->GetYaxis()->SetBinLabel(o2::aod::evsel::kNsel + 1, "Total"); fStatsList->AddAt(histEvents, kStatsEvent); + std::vector bcLabels{"all", "tvx", "sel8", "sel8 & Cent", "sel8 & Scent", "sel8 & (Cent | Scent)", "sel8 & (ZNA & ZNC)"}; + TH2D* histBcs = new TH2D("BcStats", "Bc statistics;;#mu", bcLabels.size(), -0.5, bcLabels.size() - 0.5, 3000, 0, 0.3); + ib = 1; + for (auto label = bcLabels.begin(); label != bcLabels.end(); label++, ib++) { + histBcs->GetXaxis()->SetBinLabel(ib, (*label).Data()); + } + fStatsList->AddAt(histBcs, kStatsBcs); + // Track statistics: one bin for each track selection and 5 bins for V0 tags (gamma, K0s, Lambda, anti-Lambda, Omega) TH1D* histTracks = new TH1D("TrackStats", "Track statistics", fTrackCuts.size() + 5.0, -0.5, fTrackCuts.size() - 0.5 + 5.0); ib = 1; @@ -794,6 +810,23 @@ struct TableMaker { } // end loop over collisions } + // Function to compute the mu for pileup estimation, taken from EM code + double calculateMu(const auto& bc) + { + auto& ccdbMgr = o2::ccdb::BasicCCDBManager::instance(); + + uint64_t timeStamp = bc.timestamp(); + std::map metadata; + mLHCIFdata = ccdbMgr.getSpecific("GLO/Config/GRPLHCIF", timeStamp, metadata); + + auto bfilling = mLHCIFdata->getBunchFilling(); + double nbc = bfilling.getFilledBCs().size(); + double tvxRate = mRateFetcher.fetch(&ccdbMgr, timeStamp, bc.runNumber(), "T0VTX"); + double nTriggersPerFilledBC = tvxRate / nbc / o2::constants::lhc::LHCRevFreq; + double mu = -std::log(1 - nTriggersPerFilledBC); + return mu; + } + template void skimCollisions(TEvents const& collisions, TBCs const& bcs, TZdcs const& /*zdcs*/, @@ -820,6 +853,44 @@ struct TableMaker { float centFT0A = -1.0; float centFT0M = -1.0; + if (fConfigHistOutput.fConfigFillBcStat) { + for (const auto& bc : bcs) { + double muTVX = calculateMu(bc); + + if (bc.has_ft0()) { + std::bitset<8> fT0Triggers = bc.ft0().triggerMask(); + bool isTvx = fT0Triggers[o2::ft0::Triggers::bitVertex]; + bool isSemiCentral = fT0Triggers[o2::ft0::Triggers::bitSCen]; + bool isCentral = fT0Triggers[o2::ft0::Triggers::bitCen]; + + bool noBorder = bc.selection_bit(aod::evsel::kNoTimeFrameBorder) && bc.selection_bit(aod::evsel::kNoITSROFrameBorder); + //bool isTriggerTVX = bc.selection_bit(aod::evsel::kIsTriggerTVX); // difference w.r.t fT0Triggers[o2::ft0::Triggers::bitVertex] ? + bool isTriggerZNA = bc.selection_bit(aod::evsel::kIsBBZNA); + bool isTriggerZNC = bc.selection_bit(aod::evsel::kIsBBZNC); + + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(0.0, muTVX); + if (isTvx) { + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(1.0, muTVX); + if (noBorder) { + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(2.0, muTVX); + if (isCentral) { + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(3.0, muTVX); + } + if (isSemiCentral) { + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(4.0, muTVX); + } + if (isCentral || isSemiCentral) { + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(5.0, muTVX); + } + if (isTriggerZNA && isTriggerZNC) { + (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(6.0, muTVX); + } + } + } + } + } + } + for (const auto& collision : collisions) { for (int i = 0; i < o2::aod::evsel::kNsel; i++) { @@ -1591,7 +1662,7 @@ struct TableMaker { } // produce the full DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) - void processPPWithFilter(MyEventsWithMultsAndFilter const& collisions, BCsWithTimestamps const& bcs, + void processPPWithFilter(MyEventsWithMultsAndFilter const& collisions, MyBCs const& bcs, MyBarrelTracksWithCov const& tracksBarrel, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, TrackAssoc const& trackAssocs, FwdTrackAssoc const& fwdTrackAssocs, @@ -1609,14 +1680,14 @@ struct TableMaker { } // produce the muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) - void processPPWithFilterMuonOnly(MyEventsWithMultsAndFilter const& collisions, BCsWithTimestamps const& bcs, + void processPPWithFilterMuonOnly(MyEventsWithMultsAndFilter const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, nullptr, nullptr, nullptr); } // produce the muon+mft DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) - void processPPWithFilterMuonMFT(MyEventsWithMultsAndFilter const& collisions, BCsWithTimestamps const& bcs, + void processPPWithFilterMuonMFT(MyEventsWithMultsAndFilter const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { @@ -1640,21 +1711,21 @@ struct TableMaker { } // produce the muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data - void processPPMuonOnly(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + void processPPMuonOnly(MyEventsWithMults const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, nullptr, nullptr, nullptr); } // produce the realigned muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data - void processPPRealignedMuonOnly(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + void processPPRealignedMuonOnly(MyEventsWithMults const& collisions, MyBCs const& bcs, MyMuonsRealignWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, nullptr, nullptr, nullptr); } // produce the muon+mft DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data - void processPPMuonMFT(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + void processPPMuonMFT(MyEventsWithMults const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { @@ -1662,7 +1733,7 @@ struct TableMaker { } // Central barrel multiplicity estimation - void processPPMuonMFTWithMultsExtra(MyEventsWithMultsExtra const& collisions, BCsWithTimestamps const& bcs, + void processPPMuonMFTWithMultsExtra(MyEventsWithMultsExtra const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { @@ -1670,7 +1741,7 @@ struct TableMaker { } // produce the full DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPb(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPb(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyBarrelTracksWithCov const& tracksBarrel, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, TrackAssoc const& trackAssocs, FwdTrackAssoc const& fwdTrackAssocs, @@ -1680,7 +1751,7 @@ struct TableMaker { } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPbBarrelOnly(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPbBarrelOnly(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { @@ -1688,7 +1759,7 @@ struct TableMaker { } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no TOF - void processPbPbBarrelOnlyNoTOF(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPbBarrelOnlyNoTOF(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyBarrelTracksWithCovNoTOF const& tracksBarrel, TrackAssoc const& trackAssocs) { @@ -1706,7 +1777,7 @@ struct TableMaker { } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPbBarrelOnlyWithV0Bits(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPbBarrelOnlyWithV0Bits(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyBarrelTracksWithV0Bits const& tracksBarrel, TrackAssoc const& trackAssocs) { @@ -1715,7 +1786,7 @@ struct TableMaker { } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPbBarrelOnlyWithV0BitsNoTOF(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPbBarrelOnlyWithV0BitsNoTOF(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyBarrelTracksWithV0BitsNoTOF const& tracksBarrel, TrackAssoc const& trackAssocs) { @@ -1724,21 +1795,21 @@ struct TableMaker { } // produce the muon only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPbMuonOnly(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, - MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) + void processPbPbMuonOnly(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, + MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, nullptr, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, ft0s, fv0as, fdds); } // produce the realigned muon only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPbRealignedMuonOnly(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPbRealignedMuonOnly(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyMuonsRealignWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, nullptr, nullptr, nullptr); } // produce the muon+mft DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter - void processPbPbMuonMFT(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + void processPbPbMuonMFT(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { @@ -1746,7 +1817,7 @@ struct TableMaker { } // produce the muon+mft DQ skimmed data model typically including MFT covariances - void processPPMuonRefit(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + void processPPMuonRefit(MyEventsWithMults const& collisions, MyBCs const& bcs, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs, aod::MFTTracksCov const& mftCovs) From f283a171f22f4b9cb9d2fb4e94f33be0ee5d3815 Mon Sep 17 00:00:00 2001 From: Lucamicheletti93 Date: Fri, 9 Jan 2026 22:53:41 +0100 Subject: [PATCH 2/2] Fix clang --- PWGDQ/TableProducer/tableMaker_withAssoc.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index 817fb1b32b7..c6204781686 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -53,9 +53,9 @@ #include "DataFormatsGlobalTracking/RecoContainer.h" #include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" #include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsParameters/GRPLHCIFData.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPLHCIFData.h" #include "DetectorsBase/GeometryManager.h" #include "DetectorsBase/Propagator.h" #include "DetectorsVertexing/PVertexerParams.h" @@ -344,7 +344,7 @@ struct TableMaker { ctpRateFetcher mRateFetcher; parameters::GRPLHCIFData* mLHCIFdata = nullptr; - + struct { std::map oMeanTimeShortA; std::map oMeanTimeShortC; @@ -864,7 +864,7 @@ struct TableMaker { bool isCentral = fT0Triggers[o2::ft0::Triggers::bitCen]; bool noBorder = bc.selection_bit(aod::evsel::kNoTimeFrameBorder) && bc.selection_bit(aod::evsel::kNoITSROFrameBorder); - //bool isTriggerTVX = bc.selection_bit(aod::evsel::kIsTriggerTVX); // difference w.r.t fT0Triggers[o2::ft0::Triggers::bitVertex] ? + // bool isTriggerTVX = bc.selection_bit(aod::evsel::kIsTriggerTVX); // difference w.r.t fT0Triggers[o2::ft0::Triggers::bitVertex] ? bool isTriggerZNA = bc.selection_bit(aod::evsel::kIsBBZNA); bool isTriggerZNC = bc.selection_bit(aod::evsel::kIsBBZNC);