diff --git a/PWGHF/HFC/Tasks/taskFlow.cxx b/PWGHF/HFC/Tasks/taskFlow.cxx index d54bfda6956..d41aab8e069 100644 --- a/PWGHF/HFC/Tasks/taskFlow.cxx +++ b/PWGHF/HFC/Tasks/taskFlow.cxx @@ -26,6 +26,7 @@ #include "PWGMM/Mult/DataModel/bestCollisionTable.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -74,6 +75,7 @@ using namespace o2; using namespace o2::analysis; using namespace o2::aod::pid_tpc_tof_utils; +using namespace o2::aod::rctsel; using namespace o2::aod::track; using namespace o2::constants::math; using namespace o2::framework; @@ -142,6 +144,21 @@ enum MultiplicityEstimators { MultFT0M }; +enum SpecificEventSelectionStep { + AllEventsPrecise = 0, + IsSel8, + IsNoSameBunchPileup, + IsGoodItsLayersAll, + IsGoodZvtxFT0vsPV, + IsNoCollInRofStandard, + IsNoCollInRofStrict, + IsNoCollInTimeRangeStandard, + IsNoCollInTimeRangeStrict, + IsNoHighMultCollInPrevRof, + IsRctFlagChecked, + NSpecificEventSelectionSteps +}; + enum TrackSelection { TrackSelectionNoCut = 0, TrackSelectionGlobalTrack @@ -185,6 +202,7 @@ struct HfTaskFlow { Configurable doReferenceFlow{"doReferenceFlow", false, "Flag to know if reference flow should be done"}; Configurable isReadoutCenter{"isReadoutCenter", false, "Enable Readout Center"}; Configurable nMixedEvents{"nMixedEvents", 5, "Number of mixed events per event"}; + Configurable nSamples{"nSamples", 10, "number of different samples for correlations"}; } configTask; // configurables for collisions @@ -192,11 +210,21 @@ struct HfTaskFlow { std::string prefix = "ConfigCollision_group"; Configurable isApplyGoodItsLayersAll{"isApplyGoodItsLayersAll", false, "Enable GoodITSLayersAll"}; Configurable isApplyGoodZvtxFT0vsPV{"isApplyGoodZvtxFT0vsPV", false, "Enable GoodZvtxFT0vsPV cut"}; + Configurable isApplyNoCollInRofStandard{"isApplyNoCollInRofStandard", false, ""}; + Configurable isApplyNoCollInRofStrict{"isApplyNoCollInRofStrict", false, ""}; + Configurable isApplyNoCollInTimeRangeStandard{"isApplyNoCollInTimeRangeStandard", false, ""}; + Configurable isApplyNoCollInTimeRangeStrict{"isApplyNoCollInTimeRangeStrict", false, ""}; + Configurable isApplyNoHighMultCollInPrevRof{"isApplyNoHighMultCollInPrevRof", false, ""}; Configurable isApplySameBunchPileup{"isApplySameBunchPileup", false, "Enable SameBunchPileup cut"}; Configurable maxMultiplicity{"maxMultiplicity", 300, "maximum multiplicity selection for collision"}; Configurable minMultiplicity{"minMultiplicity", 0, "minimum multiplicity selection for collision"}; Configurable multiplicityEstimator{"multiplicityEstimator", 0, "0: multNTracksPV, 1: numContrib, 2: multFT0C, 3: multFT0M, 4: centFT0C, 5: centFT0CVariants1s, 6: centFT0M, 7: centFV0A, 8: centNTracksPV, 9: centNGlobal, 10: centMFT"}; - Configurable isApplyNoCollInTimeRangeStrict{"isApplyNoCollInTimeRangeStrict", false, ""}; + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", false, "Check event quality in run condition table"}; + Configurable requireCorrelationAnalysisRCTFlagChecker{"requireCorrelationAnalysisRCTFlagChecker", false, "Check event quality in run condition table for correlation analysis"}; + Configurable setRCTFlagCheckerLabel{"setRCTFlagCheckerLabel", "CBT_muon_global", "Evt sel: RCT flag checker label"}; + Configurable requireRCTFlagCheckerLimitAcceptanceAsBad{"requireRCTFlagCheckerLimitAcceptanceAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + Configurable requireZDCCheck{"requireZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; + Configurable rctFlagCheckerLabel{"rctFlagCheckerLabel", "CBT_fw", "Evt sel: RCT flag checker label"}; Configurable zVertexMax{"zVertexMax", 10.0f, "Accepted z-vertex range"}; } configCollision; @@ -251,6 +279,13 @@ struct HfTaskFlow { Configurable useMftPtCut{"useMftPtCut", false, "if true, use the Mft pt function cut"}; } configMft; + // configurables for MFT tracks + struct : ConfigurableGroup { + std::string prefix = "ConfigFit_group"; + Configurable cfgGainEqPath{"cfgGainEqPath", "Analysis/EventPlane/GainEq", "CCDB path for gain equalization constants"}; + Configurable cfgCorrLevel{"cfgCorrLevel", 1, "calibration step: 0 = no corr, 1 = gain corr"}; + } configFit; + TF1* fPtDepDCAxy = nullptr; SliceCache cache; @@ -261,6 +296,9 @@ struct HfTaskFlow { o2::ccdb::CcdbApi ccdbApi; o2::ft0::Geometry ft0Det; o2::fv0::Geometry* fv0Det{}; + std::vector cstFT0RelGain{}; + RCTFlagsChecker rctChecker; + RCTFlagsChecker correlationAnalysisRctChecker{kFT0Bad, kITSBad, kTPCBadTracking, kMFTBad}; // ========================= // using declarations : DATA @@ -343,6 +381,10 @@ struct HfTaskFlow { ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt trigger axis for histograms"}; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {1, -10, 10}, "vertex axis for efficiency histograms"}; + ConfigurableAxis axisAmplitudeFit{"axisAmplitudeFit", {5000, 0, 1000}, "FT0A amplitude axis"}; + ConfigurableAxis axisChannelFt0a{"axisChannelFt0a", {96, 0.0, 96.0}, "FT0A channel axis"}; + ConfigurableAxis axisSamples{"axisSamples", {10, 0, 10}, "sample axis for correlation containers"}; + ConfigurableAxis axisChID{"axisChID", {220, 0, 220}, "FIT channel ID"}; } configAxis; HistogramRegistry registry{"registry"}; @@ -429,13 +471,15 @@ struct HfTaskFlow { LOGF(info, "Offset for FT0C: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[1].getX(), (*offsetFT0)[1].getY(), (*offsetFT0)[1].getZ()); LOGF(info, "Offset for FV0-left: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[0].getX(), (*offsetFV0)[0].getY(), (*offsetFV0)[0].getZ()); LOGF(info, "Offset for FV0-right: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[1].getX(), (*offsetFV0)[1].getY(), (*offsetFV0)[1].getZ()); - fv0Det = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); // ========================= // Event histograms // ========================= + rctChecker.init(configCollision.setRCTFlagCheckerLabel, configCollision.requireZDCCheck, configCollision.requireRCTFlagCheckerLimitAcceptanceAsBad); + correlationAnalysisRctChecker.init({kFT0Bad, kITSBad, kTPCBadTracking, kMFTBad}, configCollision.requireZDCCheck, configCollision.requireRCTFlagCheckerLimitAcceptanceAsBad); + registry.add("Data/hVtxZ", "v_{z} (cm)", {HistType::kTH1D, {configAxis.axisVertex}}); registry.add("Data/hNTracks", "", {HistType::kTH1F, {configAxis.axisMultiplicity}}); registry.add(Form("Data/hMultiplicity_%s", WhatMultiplicityEstimator[configCollision.multiplicityEstimator].data()), "", {HistType::kTH1D, {configAxis.axisMultiplicity}}); @@ -450,6 +494,25 @@ struct HfTaskFlow { registry.get(HIST("Data/hEventCounter"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } + registry.add("Data/hPreciseEventCounter", "hPreciseEventCounter", {HistType::kTH1D, {{SpecificEventSelectionStep::NSpecificEventSelectionSteps, -0.5, +SpecificEventSelectionStep::NSpecificEventSelectionSteps - 0.5}}}); + std::string labelsPreciseEventSelection[SpecificEventSelectionStep::NSpecificEventSelectionSteps]; + labelsPreciseEventSelection[SpecificEventSelectionStep::AllEventsPrecise] = "all"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsSel8] = "sel8"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsNoSameBunchPileup] = "IsNoSameBunchPileup"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsGoodItsLayersAll] = "IsGoodItsLayersAll"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsGoodZvtxFT0vsPV] = "IsGoodZvtxFT0vsPV"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsNoCollInRofStandard] = "IsNoCollInRofStandard"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsNoCollInRofStrict] = "IsNoCollInRofStrict"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsNoCollInTimeRangeStandard] = "IsNoCollInTimeRangeStandard"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsNoCollInTimeRangeStrict] = "IsNoCollInTimeRangeStrict"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsNoHighMultCollInPrevRof] = "IsNoHighMultCollInPrevRof"; + labelsPreciseEventSelection[SpecificEventSelectionStep::IsRctFlagChecked] = "IsRctFlagChecked"; + registry.get(HIST("Data/hPreciseEventCounter"))->SetMinimum(0); + + for (int iBin = 0; iBin < SpecificEventSelectionStep::NSpecificEventSelectionSteps; iBin++) { + registry.get(HIST("Data/hPreciseEventCounter"))->GetXaxis()->SetBinLabel(iBin + 1, labelsPreciseEventSelection[iBin].data()); + } + mPairCuts.SetHistogramRegistry(®istry); if (configCentral.pairCut->get("Photon") > 0 || configCentral.pairCut->get("K0") > 0 || configCentral.pairCut->get("Lambda") > 0 || configCentral.pairCut->get("Phi") > 0 || configCentral.pairCut->get("Rho") > 0) { mPairCuts.SetPairCut(PairCuts::Photon, configCentral.pairCut->get("Photon")); @@ -472,7 +535,9 @@ struct HfTaskFlow { std::vector const effAxis = {{configAxis.axisEtaEfficiency, "#eta"}, {configAxis.axisPtEfficiency, "p_{T} (GeV/c)"}, {configAxis.axisVertexEfficiency, "z-vtx (cm)"}}; - std::vector const userAxis = {{configAxis.axisMass, "m_{inv} (GeV/c^{2})"}}; + std::vector const userAxis = {{configAxis.axisSamples, "sampling"}}; + std::vector const hfUserAxis = {{configAxis.axisMass, "m_{inv} (GeV/c^{2})"}, + {configAxis.axisSamples, "sampling"}}; // ========================= // Initialization of histograms and CorrelationContainers for TpcTpc cases @@ -480,20 +545,23 @@ struct HfTaskFlow { if (doprocessSameTpcTpcChCh) { addHistograms(); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } if (doprocessSameTpcTpcD0Ch) { addHistograms(); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } if (doprocessSameTpcTpcLcCh) { addHistograms(); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } // ========================= @@ -504,24 +572,24 @@ struct HfTaskFlow { addHistograms(); addMftHistograms(); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } if (doprocessSameTpcMftD0Ch || doprocessSameTpcMftD0ChReassociated) { addHistograms(); addMftHistograms(); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } if (doprocessSameTpcMftLcCh || doprocessSameTpcMftLcChReassociated) { addHistograms(); addMftHistograms(); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } // ========================= @@ -531,22 +599,22 @@ struct HfTaskFlow { if (doprocessSameTpcFv0aChCh) { addHistograms(); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } if (doprocessSameTpcFv0aD0Ch) { addHistograms(); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } if (doprocessSameTpcFv0aLcCh) { addHistograms(); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } // ========================= @@ -558,8 +626,8 @@ struct HfTaskFlow { addHistograms(); addMftHistograms(); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } // ========================= @@ -568,23 +636,29 @@ struct HfTaskFlow { if (doprocessSameTpcFt0aChCh) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } if (doprocessSameTpcFt0aD0Ch) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } if (doprocessSameTpcFt0aLcCh) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } // ========================= @@ -594,9 +668,11 @@ struct HfTaskFlow { if (doprocessSameMftFt0aChCh || doprocessSameMftFt0aChChReassociated || doprocessSameMftFt0aChChReassociated3d || doprocessSameMftFt0aChChNonAmbiguous) { addHistograms(); addMftHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } // ========================= @@ -605,23 +681,29 @@ struct HfTaskFlow { if (doprocessSameTpcFt0cChCh) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } if (doprocessSameTpcFt0cD0Ch) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } if (doprocessSameTpcFt0cLcCh) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); - mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, hfUserAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, hfUserAxis)); } // ========================= @@ -630,9 +712,11 @@ struct HfTaskFlow { if (doprocessSameFt0aFt0cChCh) { addHistograms(); + registry.add("Data/FT0Amp", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); + registry.add("Data/FT0AmpCorr", "", {HistType::kTH2F, {configAxis.axisChID, configAxis.axisAmplitudeFit}}); - sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); } } // End of init() function @@ -822,15 +906,49 @@ struct HfTaskFlow { } template - void getChannel(TFT0s const& ft0, std::size_t const& iCh, int& id, int fitType) + void getChannel(TFT0s const& ft0, std::size_t const& iCh, int& id, int fitType, float& amplitude) { + int rID{0}; if (fitType == isFT0C) { id = ft0.channelC()[iCh] + MinFt0cCell; + rID = id + MinFt0cCell; + amplitude = ft0.amplitudeC()[iCh]; } else if (fitType == isFT0A) { id = ft0.channelA()[iCh]; + rID = id; + amplitude = ft0.amplitudeA()[iCh]; } else { LOGF(fatal, "Cor Index %d out of range", fitType); } + registry.fill(HIST("Data/FT0Amp"), rID, amplitude); + amplitude = amplitude / cstFT0RelGain[iCh]; + registry.fill(HIST("Data/FT0AmpCorr"), rID, amplitude); + } + + void loadGain(aod::BCsWithTimestamps::iterator const& bc) + { + cstFT0RelGain.clear(); + cstFT0RelGain = {}; + std::string fullPath; + + auto timestamp = bc.timestamp(); + constexpr int ChannelsFT0 = 208; + if (configFit.cfgCorrLevel == 0) { + for (auto i{0u}; i < ChannelsFT0; i++) { + cstFT0RelGain.push_back(1.); + } + } else { + fullPath = configFit.cfgGainEqPath; + fullPath += "/FT0"; + const auto objft0Gain = ccdb->getForTimeStamp>(fullPath, timestamp); + if (!objft0Gain) { + for (auto i{0u}; i < ChannelsFT0; i++) { + cstFT0RelGain.push_back(1.); + } + } else { + cstFT0RelGain = *(objft0Gain); + } + } } // ========================= @@ -843,23 +961,72 @@ struct HfTaskFlow { { if (fillHistograms) { registry.fill(HIST("Data/hEventCounter"), EventSelectionStep::AllEvents); + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::AllEventsPrecise); } if (!collision.sel8()) { return false; } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsSel8); + } if (configCollision.isApplySameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { return false; } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsNoSameBunchPileup); + } + if (configCollision.isApplyGoodItsLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return false; + } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsGoodItsLayersAll); + } if (configCollision.isApplyGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsGoodZvtxFT0vsPV); + } + if (configCollision.isApplyNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return false; + } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsNoCollInRofStandard); + } + if (configCollision.isApplyNoCollInRofStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + return false; + } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsNoCollInRofStrict); + } + if (configCollision.isApplyNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsNoCollInTimeRangeStandard); + } if (configCollision.isApplyNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { return false; } - if (configCollision.isApplyGoodItsLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsNoCollInTimeRangeStrict); + } + if (configCollision.isApplyNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + return false; + } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsNoHighMultCollInPrevRof); + } + if (configCollision.requireRCTFlagChecker && !rctChecker(collision)) { return false; } + if (configCollision.requireCorrelationAnalysisRCTFlagChecker && !correlationAnalysisRctChecker(collision)) { + return false; + } + if (fillHistograms) { + registry.fill(HIST("Data/hPreciseEventCounter"), SpecificEventSelectionStep::IsRctFlagChecked); + } if (fillHistograms) { registry.fill(HIST("Data/hEventCounter"), EventSelectionStep::AfterEventSelection); @@ -987,6 +1154,7 @@ struct HfTaskFlow { auto triggerWeight = 1; auto associatedWeight = 1; auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision + int sampleIndex = gRandom->Uniform(0, configTask.nSamples); // TRIGGER PARTICLE for (const auto& track1 : tracks1) { @@ -1022,9 +1190,9 @@ struct HfTaskFlow { // fill single-track distributions if (!fillingHFcontainer) { // if not HF-h case - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, sampleIndex, triggerWeight); } else { - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, sampleIndex, triggerWeight); } // FILL QA PLOTS for trigger particle @@ -1148,10 +1316,10 @@ struct HfTaskFlow { if (!fillingHFcontainer) { // fill pair correlations - target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, triggerWeight * associatedWeight); } else { - target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, invmass, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, invmass, triggerWeight * associatedWeight); } @@ -1191,6 +1359,7 @@ struct HfTaskFlow { auto triggerWeight = 1; auto associatedWeight = 1; auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision + int sampleIndex = gRandom->Uniform(0, configTask.nSamples); // TRIGGER PARTICLE for (const auto& track1 : tracks1) { @@ -1222,9 +1391,9 @@ struct HfTaskFlow { // fill single-track distributions if (!fillingHFcontainer) { // if not HF-h case - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, sampleIndex, triggerWeight); } else { - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, sampleIndex, triggerWeight); } // FILL QA PLOTS for trigger particle @@ -1315,10 +1484,10 @@ struct HfTaskFlow { deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); if (!fillingHFcontainer) { - target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, triggerWeight * associatedWeight); } else { - target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, invmass, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, invmass, triggerWeight * associatedWeight); } @@ -1347,6 +1516,7 @@ struct HfTaskFlow { auto triggerWeight = 1; auto associatedWeight = 1; auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision + int sampleIndex = gRandom->Uniform(0, configTask.nSamples); // TRIGGER PARTICLE for (auto const& track1 : tracks1) { @@ -1385,9 +1555,9 @@ struct HfTaskFlow { // fill single-track distributions if (!fillingHFcontainer) { // if not HF-h case - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, sampleIndex, triggerWeight); } else { - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, sampleIndex, triggerWeight); } // FILL QA PLOTS for trigger particle @@ -1447,10 +1617,10 @@ struct HfTaskFlow { deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); // set range of delta phi in (-pi/2 , 3/2*pi) if (!fillingHFcontainer) { - target->getPairHist()->Fill(step, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, triggerWeight * associatedWeight); } else { - target->getPairHist()->Fill(step, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, invmass, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, invmass, triggerWeight * associatedWeight); } @@ -1487,18 +1657,19 @@ struct HfTaskFlow { for (std::size_t indexChannel = 0; indexChannel < channelSize; indexChannel++) { int channelId = 0; - getChannel(tracks2, indexChannel, channelId, fitType); + float amplitude = 0.; + getChannel(tracks2, indexChannel, channelId, fitType, amplitude); auto phi2 = getPhiFT0(channelId, fitType); auto eta2 = getEtaFT0(channelId, fitType); float deltaPhi = phi1 - phi2; deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); // set range of delta phi in (-pi/2 , 3/2*pi) if (!fillingHFcontainer) { - target->getPairHist()->Fill(step, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, - triggerWeight * associatedWeight); + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, + amplitude * triggerWeight * associatedWeight); } else { - target->getPairHist()->Fill(step, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, invmass, - triggerWeight * associatedWeight); + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, invmass, + amplitude * triggerWeight * associatedWeight); } // FILL QA PLOTS for associated particle @@ -1545,6 +1716,7 @@ struct HfTaskFlow { auto triggerWeight = 1; auto associatedWeight = 1; auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision + int sampleIndex = gRandom->Uniform(0, configTask.nSamples); // TRIGGER PARTICLE for (auto const& track1 : tracks1) { @@ -1567,7 +1739,7 @@ struct HfTaskFlow { float phi1 = reassociatedMftTrack.phi(); o2::math_utils::bringTo02Pi(phi1); - target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, triggerWeight); + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, sampleIndex, triggerWeight); // FILL QA PLOTS for trigger particle if (sameEvent && (step == CorrelationContainer::kCFStepReconstructed)) { @@ -1591,7 +1763,7 @@ struct HfTaskFlow { float deltaPhi = phi1 - phi2; deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); // set range of delta phi in (-pi/2 , 3/2*pi) - target->getPairHist()->Fill(step, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, triggerWeight * associatedWeight); // FILL QA PLOTS for associated particle @@ -1617,14 +1789,15 @@ struct HfTaskFlow { for (std::size_t indexChannel = 0; indexChannel < channelSize; indexChannel++) { int channelId = 0; - getChannel(tracks2, indexChannel, channelId, fitType); + float amplitude = 0.; + getChannel(tracks2, indexChannel, channelId, fitType, amplitude); auto phi2 = getPhiFT0(channelId, fitType); auto eta2 = getEtaFT0(channelId, fitType); float deltaPhi = phi1 - phi2; deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); // set range of delta phi in (-pi/2 , 3/2*pi) - target->getPairHist()->Fill(step, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, - triggerWeight * associatedWeight); + target->getPairHist()->Fill(step, sampleIndex, eta1 - eta2, pt1, pt1, multiplicity, deltaPhi, posZ, + amplitude * triggerWeight * associatedWeight); // FILL QA PLOTS for associated particle if (sameEvent && (loopCounter == 1) && (step == CorrelationContainer::kCFStepReconstructed)) { @@ -1645,16 +1818,18 @@ struct HfTaskFlow { auto triggerWeight = 1; auto associatedWeight = 1; auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision + int sampleIndex = gRandom->Uniform(0, configTask.nSamples); // TRIGGER PARTICLE FROM FT0A for (std::size_t indexChannelA = 0; indexChannelA < ft0as.channelA().size(); indexChannelA++) { loopCounter++; int channelIdA = 0; - getChannel(ft0as, indexChannelA, channelIdA, isFT0A); + float amplitude = 0.; + getChannel(ft0as, indexChannelA, channelIdA, isFT0A, amplitude); auto phiA = getPhiFT0(channelIdA, isFT0A); auto etaA = getEtaFT0(channelIdA, isFT0A); - target->getTriggerHist()->Fill(step, 0.f, multiplicity, posZ, triggerWeight); + target->getTriggerHist()->Fill(step, 0.f, multiplicity, posZ, sampleIndex, amplitude * triggerWeight); if (sameEvent && (step == CorrelationContainer::kCFStepReconstructed)) { fillTriggerQa(multiplicity, etaA, phiA, 0.f); @@ -1664,13 +1839,14 @@ struct HfTaskFlow { for (std::size_t indexChannelC = 0; indexChannelC < ft0cs.channelC().size(); indexChannelC++) { int channelIdC = 0; - getChannel(ft0cs, indexChannelC, channelIdC, isFT0C); + float amplitude = 0.; + getChannel(ft0cs, indexChannelC, channelIdC, isFT0C, amplitude); auto phiC = getPhiFT0(channelIdC, isFT0C); auto etaC = getEtaFT0(channelIdC, isFT0C); float deltaPhi = RecoDecay::constrainAngle(phiA - phiC, -PIHalf); - target->getPairHist()->Fill(step, etaA - etaC, 0.f, 0.f, multiplicity, deltaPhi, posZ, - triggerWeight * associatedWeight); + target->getPairHist()->Fill(step, sampleIndex, etaA - etaC, 0.f, 0.f, multiplicity, deltaPhi, posZ, + amplitude * triggerWeight * associatedWeight); if (sameEvent && (loopCounter == 1) && (step == CorrelationContainer::kCFStepReconstructed)) { fillAssociatedQa(multiplicity, etaC, phiC); @@ -2300,13 +2476,17 @@ struct HfTaskFlow { void processSameTpcFt0aChCh(FilteredCollisionsWSelMult::iterator const& collision, FilteredTracksWDcaSel const& tracks, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); registry.fill(HIST("Data/hNTracks"), tracks.size()); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2327,13 +2507,17 @@ struct HfTaskFlow { void processSameTpcFt0aD0Ch(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelD0 const& candidates, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2353,13 +2537,17 @@ struct HfTaskFlow { void processSameTpcFt0aLcCh(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelLc const& candidates, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2379,13 +2567,17 @@ struct HfTaskFlow { void processSameMftFt0aChCh(FilteredCollisionsWSelMult::iterator const& collision, FilteredMftTracks const& mftTracks, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2402,13 +2594,17 @@ struct HfTaskFlow { void processSameMftFt0aChChReassociated(FilteredCollisionsWSelMult::iterator const& collision, soa::SmallGroups const& reassociatedMftTracks, FilteredMftTracks const&, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2425,13 +2621,17 @@ struct HfTaskFlow { void processSameMftFt0aChChReassociated3d(FilteredCollisionsWSelMult::iterator const& collision, soa::SmallGroups const& reassociatedMftTracks, FilteredMftTracks const&, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2448,13 +2648,17 @@ struct HfTaskFlow { void processSameMftFt0aChChNonAmbiguous(FilteredCollisionsWSelMult::iterator const& collision, soa::SmallGroups const& reassociatedMftTracks, FilteredMftTracks const&, - aod::FT0s const& ft0as) + aod::FT0s const& ft0as, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2474,13 +2678,17 @@ struct HfTaskFlow { void processSameTpcFt0cChCh(FilteredCollisionsWSelMult::iterator const& collision, FilteredTracksWDcaSel const& tracks, - aod::FT0s const& ft0cs) + aod::FT0s const& ft0cs, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); registry.fill(HIST("Data/hNTracks"), tracks.size()); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2501,13 +2709,17 @@ struct HfTaskFlow { void processSameTpcFt0cD0Ch(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelD0 const& candidates, - aod::FT0s const& ft0cs) + aod::FT0s const& ft0cs, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2527,13 +2739,17 @@ struct HfTaskFlow { void processSameTpcFt0cLcCh(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelLc const& candidates, - aod::FT0s const& ft0cs) + aod::FT0s const& ft0cs, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true); @@ -2552,13 +2768,17 @@ struct HfTaskFlow { // ===================================== void processSameFt0aFt0cChCh(FilteredCollisionsWSelMult::iterator const& collision, - aod::FT0s const&) + aod::FT0s const&, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + auto bc = collision.bc_as(); + if (collision.has_foundFT0()) { + loadGain(bc); const auto& ft0 = collision.foundFT0(); const auto multiplicity = getMultiplicityEstimator(collision, true);