diff --git a/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx index 04b2a51a18a..d1ff0dc929a 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx @@ -1784,7 +1784,13 @@ struct FlowDecorrelation { } } - if (cfgSelCollByNch && (mcParticles.size() < cfgGeneralCuts.cfgCutMultMin || mcParticles.size() >= cfgGeneralCuts.cfgCutMultMax)) { + int tpcMult = 0; + for (const auto& track : mcParticles) { + if (std::abs(track.eta()) < cfgMcTrue.cfgEtaTpcCut) + tpcMult += 1; + } + + if (cfgSelCollByNch && (tpcMult < cfgGeneralCuts.cfgCutMultMin || tpcMult >= cfgGeneralCuts.cfgCutMultMax)) { return; } if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgGeneralCuts.cfgCutCentMin || cent >= cfgGeneralCuts.cfgCutCentMax)) { @@ -1794,7 +1800,7 @@ struct FlowDecorrelation { registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin if (!cfgCentTableUnavailable) registry.fill(HIST("MCTrue/MCCentrality"), cent); - registry.fill(HIST("MCTrue/MCNch"), mcParticles.size()); + registry.fill(HIST("MCTrue/MCNch"), tpcMult); registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); for (const auto& mcParticle : mcParticles) { if (mcParticle.isPhysicalPrimary()) { @@ -1804,12 +1810,12 @@ struct FlowDecorrelation { } } if (cfgMcTrue.cfgUseCFStepAll) { - same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); + same->fillEvent(tpcMult, CorrelationContainer::kCFStepAll); fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0C); } registry.fill(HIST("MCTrue/MCeventcount"), 2.5); - same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); + same->fillEvent(tpcMult, CorrelationContainer::kCFStepTrackedOnlyPrim); fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0C); } PROCESS_SWITCH(FlowDecorrelation, processMcSameTpcFt0c, "Process MC same event", false); @@ -1818,8 +1824,12 @@ struct FlowDecorrelation { { auto getTracksSize = [&mcParticles, this](FilteredMcCollisions::iterator const& mcCollision) { auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; + int tpcMult = 0; + for (const auto& track : associatedTracks) { + if (std::abs(track.eta()) < cfgMcTrue.cfgEtaTpcCut) + tpcMult += 1; + } + return tpcMult; }; using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; @@ -1831,22 +1841,20 @@ struct FlowDecorrelation { for (auto it = pairs.begin(); it != pairs.end(); it++) { auto& [collision1, tracks1, collision2, tracks2] = *it; - if (cfgSelCollByNch && (tracks1.size() < cfgGeneralCuts.cfgCutMultMin || tracks1.size() >= cfgGeneralCuts.cfgCutMultMax)) - continue; - - if (cfgSelCollByNch && (tracks2.size() < cfgGeneralCuts.cfgCutMultMin || tracks2.size() >= cfgGeneralCuts.cfgCutMultMax)) - continue; - - auto groupedCollisions = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); - - float cent = -1; + auto groupedCollisions1 = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); + auto groupedCollisions2 = collisions.sliceBy(collisionPerMCCollision, collision2.globalIndex()); + float cent1 = -1; + float cent2 = -1; if (!cfgCentTableUnavailable) { - for (const auto& collision : groupedCollisions) { - cent = getCentrality(collision); + for (const auto& collision : groupedCollisions1) { + cent1 = getCentrality(collision); + } + for (const auto& collision : groupedCollisions2) { + cent2 = getCentrality(collision); } } - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgGeneralCuts.cfgCutCentMin || cent >= cfgGeneralCuts.cfgCutCentMax)) + if (!cfgSelCollByNch && !cfgCentTableUnavailable && ((cent1 < cfgGeneralCuts.cfgCutCentMin || cent1 >= cfgGeneralCuts.cfgCutCentMax) || (cent2 < cfgGeneralCuts.cfgCutCentMin || cent2 >= cfgGeneralCuts.cfgCutCentMax))) continue; registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin @@ -1874,7 +1882,13 @@ struct FlowDecorrelation { } } - if (cfgSelCollByNch && (mcParticles.size() < cfgGeneralCuts.cfgCutMultMin || mcParticles.size() >= cfgGeneralCuts.cfgCutMultMax)) { + int tpcMult = 0; + for (const auto& track : mcParticles) { + if (std::abs(track.eta()) < cfgMcTrue.cfgEtaTpcCut) + tpcMult += 1; + } + + if (cfgSelCollByNch && (tpcMult < cfgGeneralCuts.cfgCutMultMin || tpcMult >= cfgGeneralCuts.cfgCutMultMax)) { return; } if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgGeneralCuts.cfgCutCentMin || cent >= cfgGeneralCuts.cfgCutCentMax)) { @@ -1884,7 +1898,7 @@ struct FlowDecorrelation { registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin if (!cfgCentTableUnavailable) registry.fill(HIST("MCTrue/MCCentrality"), cent); - registry.fill(HIST("MCTrue/MCNch"), mcParticles.size()); + registry.fill(HIST("MCTrue/MCNch"), tpcMult); registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); for (const auto& mcParticle : mcParticles) { if (mcParticle.isPhysicalPrimary()) { @@ -1894,12 +1908,12 @@ struct FlowDecorrelation { } } if (cfgMcTrue.cfgUseCFStepAll) { - same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); + same->fillEvent(tpcMult, CorrelationContainer::kCFStepAll); fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0A); } registry.fill(HIST("MCTrue/MCeventcount"), 2.5); - same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); + same->fillEvent(tpcMult, CorrelationContainer::kCFStepTrackedOnlyPrim); fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0A); } PROCESS_SWITCH(FlowDecorrelation, processMcSameTpcFt0a, "Process MC same event", false); @@ -1908,8 +1922,12 @@ struct FlowDecorrelation { { auto getTracksSize = [&mcParticles, this](FilteredMcCollisions::iterator const& mcCollision) { auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; + int tpcMult = 0; + for (const auto& track : associatedTracks) { + if (std::abs(track.eta()) < cfgMcTrue.cfgEtaTpcCut) + tpcMult += 1; + } + return tpcMult; }; using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; @@ -1927,16 +1945,20 @@ struct FlowDecorrelation { if (cfgSelCollByNch && (tracks2.size() < cfgGeneralCuts.cfgCutMultMin || tracks2.size() >= cfgGeneralCuts.cfgCutMultMax)) continue; - auto groupedCollisions = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); - - float cent = -1; + auto groupedCollisions1 = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); + auto groupedCollisions2 = collisions.sliceBy(collisionPerMCCollision, collision2.globalIndex()); + float cent1 = -1; + float cent2 = -1; if (!cfgCentTableUnavailable) { - for (const auto& collision : groupedCollisions) { - cent = getCentrality(collision); + for (const auto& collision : groupedCollisions1) { + cent1 = getCentrality(collision); + } + for (const auto& collision : groupedCollisions2) { + cent2 = getCentrality(collision); } } - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgGeneralCuts.cfgCutCentMin || cent >= cfgGeneralCuts.cfgCutCentMax)) + if (!cfgSelCollByNch && !cfgCentTableUnavailable && ((cent1 < cfgGeneralCuts.cfgCutCentMin || cent1 >= cfgGeneralCuts.cfgCutCentMax) || (cent2 < cfgGeneralCuts.cfgCutCentMin || cent2 >= cfgGeneralCuts.cfgCutCentMax))) continue; registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx index e688c05684d..513ed42dbd8 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx @@ -84,45 +84,52 @@ static constexpr float LongArrayFloat[3][6] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3} struct LongRangeDihadronCor { Service ccdb; o2::aod::ITSResponse itsResponse; - - O2_DEFINE_CONFIGURABLE(cfgCutVtxZ, float, 10.0f, "Accepted z-vertex range") - O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "minimum accepted track pT") - O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "maximum accepted track pT") - O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta cut") - O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") - O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") - O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") - O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") - O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") - O2_DEFINE_CONFIGURABLE(cfgSelCollByNch, bool, true, "Select collisions by Nch or centrality") - O2_DEFINE_CONFIGURABLE(cfgCutMultMin, int, 0, "Minimum multiplicity for collision") - O2_DEFINE_CONFIGURABLE(cfgCutMultMax, int, 10, "Maximum multiplicity for collision") - O2_DEFINE_CONFIGURABLE(cfgCutCentMin, float, 60.0f, "Minimum centrality for collision") - O2_DEFINE_CONFIGURABLE(cfgCutCentMax, float, 80.0f, "Maximum centrality for collision") - O2_DEFINE_CONFIGURABLE(cfgMixEventNumMin, int, 5, "Minimum number of events to mix") - O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") - O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") - O2_DEFINE_CONFIGURABLE(cfgCentTableUnavailable, bool, false, "if a dataset does not provide centrality information") - O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoITSROFrameBorder, bool, false, "reject events at ITS ROF border") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoTimeFrameBorder, bool, false, "reject events at TF border") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, true, "cut time intervals with dead ITS staves") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayer0123, bool, false, "cut time intervals with dead ITS staves (layers 0-3 only, for pp)") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") - O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") - O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") - O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, true, "Occupancy cut") - O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") - O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") - O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") - O2_DEFINE_CONFIGURABLE(cfgCentralityWeight, std::string, "", "CCDB path to centrality weight object") - O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") - O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") - O2_DEFINE_CONFIGURABLE(cfgDrawEtaPhiDis, bool, false, "draw eta-phi distribution for detectors in used") + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgCutVtxZ, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "minimum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "maximum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") + O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") + O2_DEFINE_CONFIGURABLE(cfgCutDCAxy, float, 7.0f, "max DCA to vertex xy") + O2_DEFINE_CONFIGURABLE(cfgCutMultMin, int, 0, "Minimum multiplicity for collision") + O2_DEFINE_CONFIGURABLE(cfgCutMultMax, int, 10, "Maximum multiplicity for collision") + O2_DEFINE_CONFIGURABLE(cfgCutCentMin, float, 60.0f, "Minimum centrality for collision") + O2_DEFINE_CONFIGURABLE(cfgCutCentMax, float, 80.0f, "Maximum centrality for collision") + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta cut") + O2_DEFINE_CONFIGURABLE(cfgSelCollByNch, bool, true, "Select collisions by Nch or centrality") + O2_DEFINE_CONFIGURABLE(cfgMixEventNumMin, int, 5, "Minimum number of events to mix") + O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") + O2_DEFINE_CONFIGURABLE(cfgCentTableUnavailable, bool, false, "if a dataset does not provide centrality information") + O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoITSROFrameBorder, bool, false, "reject events at ITS ROF border") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoTimeFrameBorder, bool, false, "reject events at TF border") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, true, "cut time intervals with dead ITS staves") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayer0123, bool, false, "cut time intervals with dead ITS staves (layers 0-3 only, for pp)") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, true, "Occupancy cut") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgCentralityWeight, std::string, "", "CCDB path to centrality weight object") + O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") + O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") + O2_DEFINE_CONFIGURABLE(cfgDrawEtaPhiDis, bool, false, "draw eta-phi distribution for detectors in used"); + O2_DEFINE_CONFIGURABLE(cfgEtaTpcCut, float, 0.8f, "Eta cut of TPC MC particles") + O2_DEFINE_CONFIGURABLE(cfgMinEtaFt0Cut, float, 0.0f, "Min eta cut of FT0 MC particles") + O2_DEFINE_CONFIGURABLE(cfgMaxEtaFt0Cut, float, 0.0f, "Max eta cut of FT0 MC particles") + O2_DEFINE_CONFIGURABLE(cfgUseFt0Structure, bool, true, "Use the true structure of FT0 in MC-true") + O2_DEFINE_CONFIGURABLE(cfgUseCFStepAll, bool, true, "Use CFStepAll in addition to primry"); + } cfgGeneral; struct : ConfigurableGroup { O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); O2_DEFINE_CONFIGURABLE(cfgMultCentLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); @@ -195,7 +202,7 @@ struct LongRangeDihadronCor { ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt associated axis for histograms"}; ConfigurableAxis axisVtxMix{"axisVtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity / centrality axis for mixed event histograms"}; - ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; + ConfigurableAxis axisSample{"axisSample", {cfgGeneral.cfgSampleSize, 0, cfgGeneral.cfgSampleSize}, "sample axis for histograms"}; ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; @@ -209,11 +216,24 @@ struct LongRangeDihadronCor { AxisSpec axisFit{cfgaxisFITamp, "fit amplitude"}; AxisSpec axisChID = {220, 0, 220}; // make the filters and cuts. - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == static_cast(true))) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgGeneral.cfgCutVtxZ); + Filter trackFilter = (nabs(aod::track::eta) < cfgGeneral.cfgCutEta) && (aod::track::pt > cfgGeneral.cfgCutPtMin) && (aod::track::pt < cfgGeneral.cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == static_cast(true))) && (aod::track::tpcChi2NCl < cfgGeneral.cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgGeneral.cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; + Filter particleFilter = (nabs(aod::mcparticle::eta) < cfgGeneral.cfgEtaTpcCut || ((aod::mcparticle::eta > cfgGeneral.cfgMinEtaFt0Cut) && (aod::mcparticle::eta < cfgGeneral.cfgMaxEtaFt0Cut))) && (aod::mcparticle::pt > cfgGeneral.cfgCutPtMin) && (aod::mcparticle::pt < cfgGeneral.cfgCutPtMax); + using FilteredMcParticles = soa::Filtered; + + // Filter for MCcollisions + Filter mccollisionFilter = nabs(aod::mccollision::posZ) < cfgGeneral.cfgCutVtxZ; + using FilteredMcCollisions = soa::Filtered; + + using SmallGroupMcCollisions = soa::SmallGroups>; + + PresliceUnsorted collisionPerMCCollision = aod::mccollisionlabel::mcCollisionId; + Preslice perCollision = aod::track::collisionId; + Preslice perColMc = o2::aod::mcparticle::mcCollisionId; + // FT0 geometry o2::ft0::Geometry ft0Det; static constexpr uint64_t Ft0IndexA = 96; @@ -301,18 +321,39 @@ struct LongRangeDihadronCor { std::array tofNsigmaCut; std::array itsNsigmaCut; std::array tpcNsigmaCut; + + struct Ft0cCConstants { + double zFt0cDistance = -83.44; + double maxWidth = 12.; + double minWidthX = 18.25; + double minWidhtY = 18.175; + double insideWidthX = 6.825; + double insideWidthY = 6.675; + }; + struct Ft0aCConstants { + double zFt0aDistance = 338.43; + double offSetX = 0.588; + double offSetY = 1.468; + double blockFar = 14.875; + double blockClose = 2.65; + double rectOffSet = 1.325; + }; + Ft0cCConstants Ft0cLocations{}; + Ft0aCConstants Ft0aLocations{}; + int lastRunNumber = -1; std::vector runNumbers; std::map> histAmpCorrectPerRun; // map of TH3 histograms for all runs void init(InitContext&) { - if (cfgCentTableUnavailable && !cfgSelCollByNch) { + if (cfgGeneral.cfgCentTableUnavailable && !cfgGeneral.cfgSelCollByNch) { LOGF(fatal, "Centrality table is unavailable, cannot select collisions by centrality"); } const AxisSpec axisPhi{72, 0.0, constants::math::TwoPI, "#varphi"}; const AxisSpec axisEta{40, -1., 1., "#eta"}; const AxisSpec axisEtaFull{90, -4., 5., "#eta"}; + const AxisSpec axisCentrality{20, 0., 100., "cent"}; ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); @@ -344,7 +385,7 @@ struct LongRangeDihadronCor { itsNsigmaCut[kProtonLow] = cfgPIDConfig.nSigmas->getData()[kITS][kProtonLow]; // Event Counter - if ((doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameFt0aFt0c) && cfgUseAdditionalEventCut) { + if ((doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameFt0aFt0c || doprocessSemiMcSameTpcFt0c || doprocessSemiMcSameTpcFt0a) && cfgGeneral.cfgUseAdditionalEventCut) { registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{13, 0, 13}}}); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); @@ -358,10 +399,33 @@ struct LongRangeDihadronCor { registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "kNoHighMultCollInPrevRof"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(11, "occupancy"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(12, "MultCorrelation"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(13, "cfgEvSelV0AT0ACut"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(13, "cfgGeneral.cfgEvSelV0AT0ACut"); + } + if (doprocessMcSameTpcFt0c || doprocessMcSameTpcFt0a || doprocessSemiMcSameTpcFt0c || doprocessSemiMcSameTpcFt0a) { + registry.add("MCTrue/MCeventcount", "MCeventcount", {HistType::kTH1F, {{5, 0, 5, "bin"}}}); // histogram to see how many events are in the same and mixed event + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(2, "same all"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(3, "same reco"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(4, "mixed all"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(5, "mixed reco"); + registry.add("MCTrue/MCCentrality", "cent", {HistType::kTH1D, {axisCentrality}}); + registry.add("MCTrue/MCNch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("MCTrue/MCzVtx", "MCzVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("MCTrue/MCPhi", "MCPhi", {HistType::kTH1D, {axisPhi}}); + registry.add("MCTrue/MCEta", "MCEta", {HistType::kTH1D, {axisEtaFull}}); + registry.add("MCTrue/MCEtaTrueShape", "MCEta", {HistType::kTH1D, {axisEtaFull}}); + registry.add("MCTrue/MCpT", "MCpT", {HistType::kTH1D, {axisPtEfficiency}}); + registry.add("MCTrue/MCTrig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtEfficiency}}}); + if (doprocessMcSameTpcFt0c || doprocessSemiMcSameTpcFt0c) { + registry.add("MCTrue/MCdeltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); // check to see the delta eta and delta phi distribution + registry.add("MCTrue/MCdeltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); + } + if (doprocessMcSameTpcFt0a || doprocessSemiMcSameTpcFt0a) { + registry.add("MCTrue/MCdeltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); // check to see the delta eta and delta phi distribution + registry.add("MCTrue/MCdeltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); + } } - if (cfgEvSelMultCorrelation) { + if (cfgGeneral.cfgEvSelMultCorrelation) { cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; @@ -392,9 +456,9 @@ struct LongRangeDihadronCor { cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); } - std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); + std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgGeneral.cfgCentEstimator); // Make histograms to check the distributions after cuts - if (doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameFt0aFt0c) { + if (doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameFt0aFt0c || doprocessSemiMcSameTpcFt0c || doprocessSemiMcSameTpcFt0a) { registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); @@ -409,18 +473,18 @@ struct LongRangeDihadronCor { registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); registry.add("FT0Amp", "", {HistType::kTH2F, {axisChID, axisFit}}); registry.add("FT0AmpCorrect", "", {HistType::kTH2F, {axisChID, axisFit}}); - if (cfgDrawEtaPhiDis) { + if (cfgGeneral.cfgDrawEtaPhiDis) { registry.add("EtaPhi", "", {HistType::kTH2F, {axisEtaFull, axisPhi}}); } } - if (doprocessSameTpcFt0a) { + if (doprocessSameTpcFt0a || doprocessSemiMcSameTpcFt0a) { registry.add("deltaEta_deltaPhi_same_TPC_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); // check to see the delta eta and delta phi distribution registry.add("deltaEta_deltaPhi_mixed_TPC_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); registry.add("Assoc_amp_same_TPC_FT0A", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); registry.add("Assoc_amp_mixed_TPC_FT0A", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); registry.add("Trig_hist_TPC_FT0A", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); } - if (doprocessSameTpcFt0c) { + if (doprocessSameTpcFt0c || doprocessSemiMcSameTpcFt0c) { registry.add("deltaEta_deltaPhi_same_TPC_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); // check to see the delta eta and delta phi distribution registry.add("deltaEta_deltaPhi_mixed_TPC_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); registry.add("Assoc_amp_same_TPC_FT0C", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); @@ -461,11 +525,11 @@ struct LongRangeDihadronCor { {axisDeltaPhi, "#Delta#varphi (rad)"}, {axisDeltaEtaFt0aFt0c, "#Delta#eta"}}; - if (doprocessSameTpcFt0a) { + if (doprocessSameTpcFt0a || doprocessMcSameTpcFt0a || doprocessSemiMcSameTpcFt0a) { sameTpcFt0a.setObject(new CorrelationContainer("sameEvent_TPC_FT0A", "sameEvent_TPC_FT0A", corrAxisTpcFt0a, effAxis, userAxis)); mixedTpcFt0a.setObject(new CorrelationContainer("mixedEvent_TPC_FT0A", "mixedEvent_TPC_FT0A", corrAxisTpcFt0a, effAxis, userAxis)); } - if (doprocessSameTpcFt0c) { + if (doprocessSameTpcFt0c || doprocessMcSameTpcFt0c || doprocessSemiMcSameTpcFt0c) { sameTpcFt0c.setObject(new CorrelationContainer("sameEvent_TPC_FT0C", "sameEvent_TPC_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); mixedTpcFt0c.setObject(new CorrelationContainer("mixedEvent_TPC_FT0C", "mixedEvent_TPC_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); } @@ -474,7 +538,7 @@ struct LongRangeDihadronCor { mixedFt0aFt0c.setObject(new CorrelationContainer("mixedEvent_FT0A_FT0C", "mixedEvent_FT0A_FT0C", corrAxisFt0aFt0c, effAxis, userAxis)); } - if (cfgCumulantConfig.gfwOutput && doprocessSameTpcFt0a && doprocessSameTpcFt0c) { + if (cfgCumulantConfig.gfwOutput && (doprocessSameTpcFt0a && doprocessSameTpcFt0c)) { LOGF(fatal, "If you enable gfwOutput, you can only enable processSameTpcFt0a or processSameTpcFt0c, NOT both."); } if (cfgCumulantConfig.gfwOutput) { @@ -587,7 +651,7 @@ struct LongRangeDihadronCor { float getCentrality(TCollision const& collision) { float cent; - switch (cfgCentEstimator) { + switch (cfgGeneral.cfgCentEstimator) { case kCentFT0C: cent = collision.centFT0C(); break; @@ -609,7 +673,7 @@ struct LongRangeDihadronCor { template bool trackSelected(TTrack track) { - return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgCutITSclu)); + return ((track.tpcNClsFound() >= cfgGeneral.cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgGeneral.cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgGeneral.cfgCutITSclu)); } template @@ -703,24 +767,24 @@ struct LongRangeDihadronCor { if (correctionsLoaded) { return; } - if (cfgEfficiency.value.empty() == false) { - if (cfgLocalEfficiency > 0) { - TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiency.value.c_str(), "READ"); + if (cfgGeneral.cfgEfficiency.value.empty() == false) { + if (cfgGeneral.cfgLocalEfficiency > 0) { + TFile* fEfficiencyTrigger = TFile::Open(cfgGeneral.cfgEfficiency.value.c_str(), "READ"); mEfficiency = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); } else { - mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + mEfficiency = ccdb->getForTimeStamp(cfgGeneral.cfgEfficiency, timestamp); } if (mEfficiency == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgGeneral.cfgEfficiency.value.c_str()); } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)mEfficiency); + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgGeneral.cfgEfficiency.value.c_str(), (void*)mEfficiency); } - if (cfgCentralityWeight.value.empty() == false) { - mCentralityWeight = ccdb->getForTimeStamp(cfgCentralityWeight, timestamp); + if (cfgGeneral.cfgCentralityWeight.value.empty() == false) { + mCentralityWeight = ccdb->getForTimeStamp(cfgGeneral.cfgCentralityWeight, timestamp); if (mCentralityWeight == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCentralityWeight.value.c_str()); + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgGeneral.cfgCentralityWeight.value.c_str()); } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight); + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgGeneral.cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight); } if (cfgCumulantConfig.gfwOutput && cfgCumulantConfig.gfwAcceptance.value.empty() == false) { mAcceptance = ccdb->getForTimeStamp(cfgCumulantConfig.gfwAcceptance, timestamp); @@ -909,12 +973,12 @@ struct LongRangeDihadronCor { void fillCorrelationsTPCFT0(TTracks tracks1, TFT0s const& ft0, float posZ, int system, int corType, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { if (system == SameEvent) { - if (!cfgCentTableUnavailable) + if (!cfgGeneral.cfgCentTableUnavailable) registry.fill(HIST("Centrality_used"), cent); registry.fill(HIST("Nch_used"), tracks1.size()); } - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + int fSampleIndex = gRandom->Uniform(0, cfgGeneral.cfgSampleSize); float triggerWeight = 1.0f; // loop over all tracks @@ -932,7 +996,7 @@ struct LongRangeDihadronCor { } else if (corType == kFT0A) { registry.fill(HIST("Trig_hist_TPC_FT0A"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); } - if (cfgDrawEtaPhiDis && corType == kFT0A) { + if (cfgGeneral.cfgDrawEtaPhiDis && corType == kFT0A) { registry.fill(HIST("EtaPhi"), track1.eta(), track1.phi(), eventWeight * triggerWeight); } } @@ -962,7 +1026,7 @@ struct LongRangeDihadronCor { auto phi = getPhiFT0(chanelid, corType); auto eta = getEtaFT0(chanelid, corType); - if (cfgDrawEtaPhiDis && system == SameEvent) { + if (cfgGeneral.cfgDrawEtaPhiDis && system == SameEvent) { registry.fill(HIST("EtaPhi"), eta, phi, ampl * eventWeight); if (mirrorChannel) registry.fill(HIST("EtaPhi"), eta, 4 * PIHalf - phi, ampl * eventWeight); @@ -1006,7 +1070,7 @@ struct LongRangeDihadronCor { template void fillCorrelationsFT0AFT0C(TFT0s const& ft0Col1, TFT0s const& ft0Col2, float posZ, int system, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + int fSampleIndex = gRandom->Uniform(0, cfgGeneral.cfgSampleSize); float triggerWeight = 1.0f; std::size_t channelASize = ft0Col1.channelA().size(); @@ -1067,80 +1131,253 @@ struct LongRangeDihadronCor { } } + template + void fillMCCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, float eventWeight, int corType) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + int fSampleIndex = gRandom->Uniform(0, cfgGeneral.cfgSampleSize); + double tpcEtaAcceptance = 0.8001; + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all FT0 tracks + for (auto const& track1 : tracks1) { + + if (corType == kFT0C && !cfgGeneral.cfgUseFt0Structure) { + if (std::abs(track1.eta()) < tpcEtaAcceptance) + continue; + } + if (corType == kFT0C && cfgGeneral.cfgUseFt0Structure && !ft0cCollisionCourse(track1.eta(), track1.phi(), posZ)) { + continue; + } + if (corType == kFT0A && !cfgGeneral.cfgUseFt0Structure) { + if (std::abs(track1.eta()) < tpcEtaAcceptance) + continue; + } + if (corType == kFT0A && cfgGeneral.cfgUseFt0Structure && !ft0aCollisionCourse(track1.eta(), track1.phi(), posZ)) { + continue; + } + + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track1.isPhysicalPrimary()) + continue; + + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && system == SameEvent) + registry.fill(HIST("MCTrue/MCEtaTrueShape"), track1.eta()); + + if (system == SameEvent && (doprocessMcSameTpcFt0c || doprocessMcSameTpcFt0a)) + registry.fill(HIST("MCTrue/MCTrig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + + // loop over all TPC tracks + for (auto const& track2 : tracks2) { + + if (std::abs(track2.eta()) > tpcEtaAcceptance) + continue; + + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track2.isPhysicalPrimary()) + continue; + + if (track1.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger and associate are the same track + + float deltaPhi = RecoDecay::constrainAngle(track2.phi() - track1.phi(), -PIHalf); + float deltaEta = track2.eta() - track1.eta(); + + // fill the right sparse and histograms + if (system == SameEvent) { + if (corType == kFT0C) { + sameTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track2.pt(), track1.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + if (corType == kFT0A) { + sameTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track2.pt(), track1.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } else if (system == MixedEvent) { + if (corType == kFT0C) { + mixedTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track2.pt(), track1.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + if (corType == kFT0A) { + mixedTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track2.pt(), track1.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + } + } + + template + void fillSemiMcCorrelations(TTracks tracks1, TFT0s const& ft0, float posZ, int system, int corType, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + if (system == SameEvent) { + if (!cfgGeneral.cfgCentTableUnavailable) + registry.fill(HIST("Centrality_used"), cent); + registry.fill(HIST("Nch_used"), tracks1.size()); + } + + int fSampleIndex = gRandom->Uniform(0, cfgGeneral.cfgSampleSize); + double tpcEtaAcceptance = 0.8001; + + float triggerWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + + if (std::abs(track1.eta()) > tpcEtaAcceptance) + continue; + if (!track1.isPhysicalPrimary()) + continue; + + if (system == SameEvent) { + if (corType == kFT0C) { + registry.fill(HIST("Trig_hist_TPC_FT0C"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + } else if (corType == kFT0A) { + registry.fill(HIST("Trig_hist_TPC_FT0A"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + } + } + + std::size_t channelSize = 0; + if (corType == kFT0C) { + channelSize = ft0.channelC().size(); + } else if (corType == kFT0A) { + channelSize = ft0.channelA().size(); + } else { + LOGF(fatal, "Cor Index %d out of range", corType); + } + + if (channelSize == 0) + continue; + + for (std::size_t iCh = 0; iCh < channelSize; iCh++) { + int chanelid = 0; + float ampl = 0.; + getChannel(ft0, iCh, chanelid, ampl, corType, system); + if (corType == kFT0C) { + if ((cfgFwdConfig.cfgRejectFT0CInside && (chanelid >= kFT0CInnerRingMin && chanelid <= kFT0CInnerRingMax)) || (cfgFwdConfig.cfgRejectFT0COutside && (chanelid >= kFT0COuterRingMin && chanelid <= kFT0COuterRingMax))) + continue; + } else if (corType == kFT0A) { + if ((cfgFwdConfig.cfgRejectFT0AInside && (chanelid >= kFT0AInnerRingMin && chanelid <= kFT0AInnerRingMax)) || (cfgFwdConfig.cfgRejectFT0AOutside && (chanelid >= kFT0AOuterRingMin && chanelid <= kFT0AOuterRingMax))) + continue; + } + bool mirrorChannel = false; + if ((corType == kFT0A && cfgFwdConfig.cfgMirrorFT0ADeadChannels) || (corType == kFT0C && cfgFwdConfig.cfgMirrorFT0CDeadChannels)) + mirrorChannel = isMirrorId(chanelid, corType); + + auto phi = getPhiFT0(chanelid, corType); + auto eta = getEtaFT0(chanelid, corType); + if (cfgGeneral.cfgDrawEtaPhiDis && system == SameEvent) { + registry.fill(HIST("EtaPhi"), eta, phi, ampl * eventWeight); + if (mirrorChannel) + registry.fill(HIST("EtaPhi"), eta, 4 * PIHalf - phi, ampl * eventWeight); + } + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - phi, -PIHalf); + float deltaEta = track1.eta() - eta; + // fill the right sparse and histograms + if (system == SameEvent) { + if (corType == kFT0A) { + registry.fill(HIST("Assoc_amp_same_TPC_FT0A"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0A"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + sameTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + if (mirrorChannel) + sameTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), RecoDecay::constrainAngle(track1.phi() - phi - 2 * PIHalf, -PIHalf), deltaEta, ampl * eventWeight * triggerWeight); + } else if (corType == kFT0C) { + registry.fill(HIST("Assoc_amp_same_TPC_FT0C"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0C"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + sameTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + if (mirrorChannel) + sameTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), RecoDecay::constrainAngle(track1.phi() - phi - 2 * PIHalf, -PIHalf), deltaEta, ampl * eventWeight * triggerWeight); + } + } else if (system == MixedEvent) { + if (corType == kFT0A) { + registry.fill(HIST("Assoc_amp_mixed_TPC_FT0A"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FT0A"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + mixedTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + if (mirrorChannel) + mixedTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), RecoDecay::constrainAngle(track1.phi() - phi - 2 * PIHalf, -PIHalf), deltaEta, ampl * eventWeight * triggerWeight); + } else if (corType == kFT0C) { + registry.fill(HIST("Assoc_amp_mixed_TPC_FT0C"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FT0C"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + mixedTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + if (mirrorChannel) + mixedTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), RecoDecay::constrainAngle(track1.phi() - phi - 2 * PIHalf, -PIHalf), deltaEta, ampl * eventWeight * triggerWeight); + } + } + } + } + } + template bool eventSelected(TCollision collision, const int multTrk, const float centrality, const bool fillCounter) { registry.fill(HIST("hEventCountSpecific"), 0.5); - if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + if (cfgGeneral.cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { // rejects collisions which are associated with the same "found-by-T0" bunch crossing // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof return 0; } - if (fillCounter && cfgEvSelkNoSameBunchPileup) + if (fillCounter && cfgGeneral.cfgEvSelkNoSameBunchPileup) registry.fill(HIST("hEventCountSpecific"), 1.5); - if (cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + if (cfgGeneral.cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { return 0; } - if (fillCounter && cfgEvSelkNoITSROFrameBorder) + if (fillCounter && cfgGeneral.cfgEvSelkNoITSROFrameBorder) registry.fill(HIST("hEventCountSpecific"), 2.5); - if (cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + if (cfgGeneral.cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { return 0; } - if (fillCounter && cfgEvSelkNoTimeFrameBorder) + if (fillCounter && cfgGeneral.cfgEvSelkNoTimeFrameBorder) registry.fill(HIST("hEventCountSpecific"), 3.5); - if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (cfgGeneral.cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference // use this cut at low multiplicities with caution return 0; } - if (fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV) + if (fillCounter && cfgGeneral.cfgEvSelkIsGoodZvtxFT0vsPV) registry.fill(HIST("hEventCountSpecific"), 4.5); - if (cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + if (cfgGeneral.cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { // no collisions in specified time range return 0; } - if (fillCounter && cfgEvSelkNoCollInTimeRangeStandard) + if (fillCounter && cfgGeneral.cfgEvSelkNoCollInTimeRangeStandard) registry.fill(HIST("hEventCountSpecific"), 5.5); - if (cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (cfgGeneral.cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { // from Jan 9 2025 AOT meeting // cut time intervals with dead ITS staves return 0; } - if (fillCounter && cfgEvSelkIsGoodITSLayersAll) + if (fillCounter && cfgGeneral.cfgEvSelkIsGoodITSLayersAll) registry.fill(HIST("hEventCountSpecific"), 6.5); - if (cfgEvSelkIsGoodITSLayer0123 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { + if (cfgGeneral.cfgEvSelkIsGoodITSLayer0123 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { // for pp: cut time intervals with dead ITS staves on layers 0-3 only return 0; } - if (fillCounter && cfgEvSelkIsGoodITSLayer0123) + if (fillCounter && cfgGeneral.cfgEvSelkIsGoodITSLayer0123) registry.fill(HIST("hEventCountSpecific"), 7.5); - if (cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + if (cfgGeneral.cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { // no other collisions in this Readout Frame with per-collision multiplicity above threshold return 0; } - if (fillCounter && cfgEvSelkNoCollInRofStandard) + if (fillCounter && cfgGeneral.cfgEvSelkNoCollInRofStandard) registry.fill(HIST("hEventCountSpecific"), 8.5); - if (cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + if (cfgGeneral.cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { // veto an event if FT0C amplitude in previous ITS ROF is above threshold return 0; } - if (fillCounter && cfgEvSelkNoHighMultCollInPrevRof) + if (fillCounter && cfgGeneral.cfgEvSelkNoHighMultCollInPrevRof) registry.fill(HIST("hEventCountSpecific"), 9.5); auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) + if (cfgGeneral.cfgEvSelOccupancy && (occupancy < cfgGeneral.cfgCutOccupancyLow || occupancy > cfgGeneral.cfgCutOccupancyHigh)) return 0; - if (fillCounter && cfgEvSelOccupancy) + if (fillCounter && cfgGeneral.cfgEvSelOccupancy) registry.fill(HIST("hEventCountSpecific"), 10.5); auto multNTracksPV = collision.multNTracksPV(); - if (cfgEvSelMultCorrelation) { - if (cfgFuncParas.cfgMultPVT0CCutEnabled && !cfgCentTableUnavailable) { + if (cfgGeneral.cfgEvSelMultCorrelation) { + if (cfgFuncParas.cfgMultPVT0CCutEnabled && !cfgGeneral.cfgCentTableUnavailable) { if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(centrality)) return 0; if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(centrality)) return 0; } - if (cfgFuncParas.cfgMultT0CCutEnabled && !cfgCentTableUnavailable) { + if (cfgFuncParas.cfgMultT0CCutEnabled && !cfgGeneral.cfgCentTableUnavailable) { if (multTrk < cfgFuncParas.fMultT0CCutLow->Eval(centrality)) return 0; if (multTrk > cfgFuncParas.fMultT0CCutHigh->Eval(centrality)) @@ -1159,19 +1396,100 @@ struct LongRangeDihadronCor { return 0; } } - if (fillCounter && cfgEvSelMultCorrelation) + if (fillCounter && cfgGeneral.cfgEvSelMultCorrelation) registry.fill(HIST("hEventCountSpecific"), 11.5); // V0A T0A 5 sigma cut float sigma = 5.0; - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) + if (cfgGeneral.cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; - if (fillCounter && cfgEvSelV0AT0ACut) + if (fillCounter && cfgGeneral.cfgEvSelV0AT0ACut) registry.fill(HIST("hEventCountSpecific"), 12.5); return 1; } + bool ft0cCollisionCourse(float eta, float phi, float vtxZ) + { + double theta = 2 * std::atan(std::exp(-eta)); + double vx = std::sin(theta) * std::cos(phi); // veloctiy component along x + double vy = std::sin(theta) * std::sin(phi); // veloctiy component along y + double vz = std::cos(theta); // veloctiy component along z + + if (vz > 0.) + return false; + + double x = vx * ((Ft0cLocations.zFt0cDistance - vtxZ) / vz); // location of particle on x at FT0C distance from vertex + double y = vy * ((Ft0cLocations.zFt0cDistance - vtxZ) / vz); // location of particle on x at FT0C distance from vertex + + if (std::abs(x) < Ft0cLocations.maxWidth && (std::abs(y) > Ft0cLocations.insideWidthX && std::abs(y) < Ft0cLocations.minWidthX)) + return true; + if (std::abs(y) < Ft0cLocations.maxWidth && (std::abs(x) > Ft0cLocations.insideWidthY && std::abs(x) < Ft0cLocations.minWidhtY)) + return true; + return false; + } + + bool ft0aCollisionCourse(float eta, float phi, float vtxZ) + { + double theta = 2 * std::atan(std::exp(-eta)); + double vx = std::sin(theta) * std::cos(phi); // veloctiy component along x + double vy = std::sin(theta) * std::sin(phi); // veloctiy component along y + double vz = std::cos(theta); // veloctiy component along z + + if (vz < 0.) + return false; + + double x = vx * ((Ft0aLocations.zFt0aDistance - vtxZ) / vz); // location of particle on x at FT0C distance from vertex + double y = vy * ((Ft0aLocations.zFt0aDistance - vtxZ) / vz); // location of particle on x at FT0C distance from vertex + + if (x < (Ft0aLocations.blockFar + Ft0aLocations.offSetX) && x > (Ft0aLocations.blockClose + Ft0aLocations.offSetX)) { + if (y < (Ft0aLocations.blockFar + Ft0aLocations.offSetY) && y > (Ft0aLocations.blockClose + Ft0aLocations.offSetY)) { + return true; + } + } + if (x < (Ft0aLocations.blockFar + Ft0aLocations.offSetX) && x > (Ft0aLocations.blockClose + Ft0aLocations.offSetX)) { + if (y > (-Ft0aLocations.blockFar + Ft0aLocations.offSetY) && y < (-Ft0aLocations.blockClose + Ft0aLocations.offSetY)) { + return true; + } + } + + if (x > (-Ft0aLocations.blockFar + Ft0aLocations.offSetX) && x < (-Ft0aLocations.blockClose + Ft0aLocations.offSetX)) { + if (y < (Ft0aLocations.blockFar + Ft0aLocations.offSetY) && y > (Ft0aLocations.blockClose + Ft0aLocations.offSetY)) { + return true; + } + } + if (x > (-Ft0aLocations.blockFar + Ft0aLocations.offSetX) && x < (-Ft0aLocations.blockClose + Ft0aLocations.offSetX)) { + if (y > (-Ft0aLocations.blockFar + Ft0aLocations.offSetY) && y < (-Ft0aLocations.blockClose + Ft0aLocations.offSetY)) { + return true; + } + } + + if (x < (Ft0aLocations.blockClose + Ft0aLocations.offSetX) && x > (-Ft0aLocations.blockClose + Ft0aLocations.offSetX)) { + if (y > (-Ft0aLocations.blockFar + Ft0aLocations.offSetY - Ft0aLocations.rectOffSet) && y < (-Ft0aLocations.blockClose + Ft0aLocations.offSetY - Ft0aLocations.rectOffSet)) { + return true; + } + } + + if (x < (Ft0aLocations.blockClose + Ft0aLocations.offSetX) && x > (-Ft0aLocations.blockClose + Ft0aLocations.offSetX)) { + if (y < (Ft0aLocations.blockFar + Ft0aLocations.offSetY + Ft0aLocations.rectOffSet) && y > (Ft0aLocations.blockClose + Ft0aLocations.offSetY + Ft0aLocations.rectOffSet)) { + return true; + } + } + + if (y < (Ft0aLocations.blockClose + Ft0aLocations.offSetY) && y > (-Ft0aLocations.blockClose + Ft0aLocations.offSetY)) { + if (x > (-Ft0aLocations.blockFar + Ft0aLocations.offSetX - Ft0aLocations.rectOffSet) && x < (-Ft0aLocations.blockClose + Ft0aLocations.offSetX - Ft0aLocations.rectOffSet)) { + return true; + } + } + + if (y < (Ft0aLocations.blockClose + Ft0aLocations.offSetY) && y > (-Ft0aLocations.blockClose + Ft0aLocations.offSetY)) { + if (x < (Ft0aLocations.blockFar + Ft0aLocations.offSetX + Ft0aLocations.rectOffSet) && x > (Ft0aLocations.blockClose + Ft0aLocations.offSetX + Ft0aLocations.rectOffSet)) { + return true; + } + } + return false; + } + void processSameTpcFt0a(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) { if (!collision.sel8()) @@ -1179,17 +1497,17 @@ struct LongRangeDihadronCor { auto bc = collision.bc_as(); float cent = -1.; float weightCent = 1.0f; - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { cent = getCentrality(collision); } - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) return; if (!collision.has_foundFT0()) return; loadAlignParam(bc.timestamp()); loadGain(bc); loadCorrection(bc.timestamp()); - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { getCentralityWeight(weightCent, cent); registry.fill(HIST("Centrality"), cent); registry.fill(HIST("CentralityWeighted"), cent, weightCent); @@ -1231,10 +1549,10 @@ struct LongRangeDihadronCor { } } - if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + if (cfgGeneral.cfgSelCollByNch && (tracks.size() < cfgGeneral.cfgCutMultMin || tracks.size() >= cfgGeneral.cfgCutMultMax)) { return; } - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { return; } @@ -1277,33 +1595,33 @@ struct LongRangeDihadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto it = pairs.begin(); it != pairs.end(); it++) { auto& [collision1, tracks1, collision2, tracks2] = *it; if (!collision1.sel8() || !collision2.sel8()) continue; - if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + if (cfgGeneral.cfgSelCollByNch && (tracks1.size() < cfgGeneral.cfgCutMultMin || tracks1.size() >= cfgGeneral.cfgCutMultMax)) continue; - if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + if (cfgGeneral.cfgSelCollByNch && (tracks2.size() < cfgGeneral.cfgCutMultMin || tracks2.size() >= cfgGeneral.cfgCutMultMax)) continue; float cent1 = -1; float cent2 = -1; - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { cent1 = getCentrality(collision1); cent2 = getCentrality(collision2); } - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) continue; - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) continue; - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax)) continue; - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax)) continue; if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) @@ -1314,11 +1632,11 @@ struct LongRangeDihadronCor { loadAlignParam(bc.timestamp()); loadCorrection(bc.timestamp()); float eventWeight = 1.0f; - if (cfgUseEventWeights) { + if (cfgGeneral.cfgUseEventWeights) { eventWeight = 1.0f / it.currentWindowNeighbours(); } float weightCent = 1.0f; - if (!cfgCentTableUnavailable) + if (!cfgGeneral.cfgCentTableUnavailable) getCentralityWeight(weightCent, cent1); const auto& ft0 = collision2.foundFT0(); fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, kFT0A, cent1, eventWeight * weightCent); @@ -1333,17 +1651,17 @@ struct LongRangeDihadronCor { auto bc = collision.bc_as(); float cent = -1.; float weightCent = 1.0f; - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { cent = getCentrality(collision); } - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) return; if (!collision.has_foundFT0()) return; loadAlignParam(bc.timestamp()); loadGain(bc); loadCorrection(bc.timestamp()); - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { getCentralityWeight(weightCent, cent); registry.fill(HIST("Centrality"), cent); registry.fill(HIST("CentralityWeighted"), cent, weightCent); @@ -1385,10 +1703,10 @@ struct LongRangeDihadronCor { } } - if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + if (cfgGeneral.cfgSelCollByNch && (tracks.size() < cfgGeneral.cfgCutMultMin || tracks.size() >= cfgGeneral.cfgCutMultMax)) { return; } - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { return; } @@ -1431,33 +1749,33 @@ struct LongRangeDihadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto it = pairs.begin(); it != pairs.end(); it++) { auto& [collision1, tracks1, collision2, tracks2] = *it; if (!collision1.sel8() || !collision2.sel8()) continue; - if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + if (cfgGeneral.cfgSelCollByNch && (tracks1.size() < cfgGeneral.cfgCutMultMin || tracks1.size() >= cfgGeneral.cfgCutMultMax)) continue; - if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + if (cfgGeneral.cfgSelCollByNch && (tracks2.size() < cfgGeneral.cfgCutMultMin || tracks2.size() >= cfgGeneral.cfgCutMultMax)) continue; float cent1 = -1; float cent2 = -1; - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { cent1 = getCentrality(collision1); cent2 = getCentrality(collision2); } - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) continue; - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) continue; - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax)) continue; - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax)) continue; if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) @@ -1468,11 +1786,11 @@ struct LongRangeDihadronCor { loadAlignParam(bc.timestamp()); loadCorrection(bc.timestamp()); float eventWeight = 1.0f; - if (cfgUseEventWeights) { + if (cfgGeneral.cfgUseEventWeights) { eventWeight = 1.0f / it.currentWindowNeighbours(); } float weightCent = 1.0f; - if (!cfgCentTableUnavailable) + if (!cfgGeneral.cfgCentTableUnavailable) getCentralityWeight(weightCent, cent1); const auto& ft0 = collision2.foundFT0(); fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, kFT0C, cent1, eventWeight * weightCent); @@ -1487,10 +1805,10 @@ struct LongRangeDihadronCor { auto bc = collision.bc_as(); float cent = -1.; float weightCent = 1.0f; - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { cent = getCentrality(collision); } - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) return; if (!collision.has_foundFT0()) return; @@ -1499,10 +1817,10 @@ struct LongRangeDihadronCor { loadCorrection(bc.timestamp()); // should have the same event to TPC-FT0A/C correlations - if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + if (cfgGeneral.cfgSelCollByNch && (tracks.size() < cfgGeneral.cfgCutMultMin || tracks.size() >= cfgGeneral.cfgCutMultMax)) { return; } - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { return; } @@ -1542,30 +1860,30 @@ struct LongRangeDihadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto it = pairs.begin(); it != pairs.end(); it++) { auto& [collision1, tracks1, collision2, tracks2] = *it; // should have the same event to TPC-FT0A/C correlations if (!collision1.sel8() || !collision2.sel8()) continue; - if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + if (cfgGeneral.cfgSelCollByNch && (tracks1.size() < cfgGeneral.cfgCutMultMin || tracks1.size() >= cfgGeneral.cfgCutMultMax)) continue; - if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + if (cfgGeneral.cfgSelCollByNch && (tracks2.size() < cfgGeneral.cfgCutMultMin || tracks2.size() >= cfgGeneral.cfgCutMultMax)) continue; float cent1 = -1; float cent2 = -1; - if (!cfgCentTableUnavailable) { + if (!cfgGeneral.cfgCentTableUnavailable) { cent1 = getCentrality(collision1); cent2 = getCentrality(collision2); } - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) continue; - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) continue; - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax)) continue; - if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax)) continue; if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) @@ -1575,11 +1893,11 @@ struct LongRangeDihadronCor { loadAlignParam(bc.timestamp()); loadCorrection(bc.timestamp()); float eventWeight = 1.0f; - if (cfgUseEventWeights) { + if (cfgGeneral.cfgUseEventWeights) { eventWeight = 1.0f / it.currentWindowNeighbours(); } float weightCent = 1.0f; - if (!cfgCentTableUnavailable) + if (!cfgGeneral.cfgCentTableUnavailable) getCentralityWeight(weightCent, cent1); const auto& ft0Col1 = collision1.foundFT0(); const auto& ft0Col2 = collision2.foundFT0(); @@ -1587,6 +1905,562 @@ struct LongRangeDihadronCor { } } PROCESS_SWITCH(LongRangeDihadronCor, processMixedFt0aFt0c, "Process mixed events for FT0A-FT0C correlation", false); + + void processMcSameTpcFt0c(FilteredMcCollisions::iterator const& mcCollision, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + float cent = -1; + if (!cfgGeneral.cfgCentTableUnavailable) { + for (const auto& collision : collisions) { + cent = getCentrality(collision); + } + } + + int tpcMult = 0; + for (const auto& track : mcParticles) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + + if (cfgCumulantConfig.gfwOutput) { + cfgCumulantConfig.fGFW->Clear(); + float lRandom = cfgCumulantConfig.fRndm->Rndm(); + float independent = cent; + if (cfgCumulantConfig.gfwUseNch) + independent = static_cast(tpcMult); + + // fill TPC Q-vector + for (const auto& track : mcParticles) { + if (std::abs(track.eta()) > cfgGeneral.cfgEtaTpcCut) + continue; + if (!track.isPhysicalPrimary()) + continue; + if (std::abs(track.eta()) > cfgGeneral.cfgEtaTpcCut) + continue; + bool withinPtPOI = (0.2 < track.pt()) && (track.pt() < 10.0); // o2-linter: disable=magic-number (within POI pT range) + bool withinPtRef = (0.2 < track.pt()) && (track.pt() < 3.0); // o2-linter: disable=magic-number (within RF pT range) + if (withinPtRef) + cfgCumulantConfig.fGFW->Fill(track.eta(), cfgCumulantConfig.fPtAxis->FindBin(track.pt()) - 1, track.phi(), 1., 1); + if (withinPtPOI) + cfgCumulantConfig.fGFW->Fill(track.eta(), cfgCumulantConfig.fPtAxis->FindBin(track.pt()) - 1, track.phi(), 1., 2); + if (withinPtPOI && withinPtRef) + cfgCumulantConfig.fGFW->Fill(track.eta(), cfgCumulantConfig.fPtAxis->FindBin(track.pt()) - 1, track.phi(), 1., 4); + } + // fill FT0 Q-vector + for (const auto& tackFT : mcParticles) { + if (std::abs(tackFT.eta()) < cfgGeneral.cfgEtaTpcCut) + continue; + + if (cfgGeneral.cfgUseFt0Structure && !ft0cCollisionCourse(tackFT.eta(), tackFT.phi(), mcCollision.posZ())) { + continue; + } + if (!tackFT.isPhysicalPrimary()) + continue; + + cfgCumulantConfig.fGFW->Fill(tackFT.eta(), 1, tackFT.phi(), 1., 1); + } + + // Filling Flow Container + for (uint l_ind = 0; l_ind < cfgCumulantConfig.corrconfigs.size(); l_ind++) { + fillFC(cfgCumulantConfig.corrconfigs.at(l_ind), independent, lRandom); + } + } + + if (cfgGeneral.cfgSelCollByNch && (tpcMult < cfgGeneral.cfgCutMultMin || tpcMult >= cfgGeneral.cfgCutMultMax)) { + return; + } + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + if (!cfgGeneral.cfgCentTableUnavailable) + registry.fill(HIST("MCTrue/MCCentrality"), cent); + registry.fill(HIST("MCTrue/MCNch"), tpcMult); + registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), mcParticle.phi()); + registry.fill(HIST("MCTrue/MCEta"), mcParticle.eta()); + registry.fill(HIST("MCTrue/MCpT"), mcParticle.pt()); + } + } + if (cfgGeneral.cfgUseCFStepAll) { + sameTpcFt0c->fillEvent(tpcMult, CorrelationContainer::kCFStepAll); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0C); + } + + registry.fill(HIST("MCTrue/MCeventcount"), 2.5); + sameTpcFt0c->fillEvent(tpcMult, CorrelationContainer::kCFStepTrackedOnlyPrim); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0C); + } + PROCESS_SWITCH(LongRangeDihadronCor, processMcSameTpcFt0c, "Process MC same event", false); + + void processMcSameTpcFt0a(FilteredMcCollisions::iterator const& mcCollision, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + float cent = -1; + if (!cfgGeneral.cfgCentTableUnavailable) { + for (const auto& collision : collisions) { + cent = getCentrality(collision); + } + } + + int tpcMult = 0; + for (const auto& track : mcParticles) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + + if (cfgCumulantConfig.gfwOutput) { + cfgCumulantConfig.fGFW->Clear(); + float lRandom = cfgCumulantConfig.fRndm->Rndm(); + float independent = cent; + if (cfgCumulantConfig.gfwUseNch) + independent = static_cast(tpcMult); + + // fill TPC Q-vector + for (const auto& track : mcParticles) { + if (std::abs(track.eta()) > cfgGeneral.cfgEtaTpcCut) + continue; + if (!track.isPhysicalPrimary()) + continue; + if (std::abs(track.eta()) > cfgGeneral.cfgEtaTpcCut) + continue; + bool withinPtPOI = (0.2 < track.pt()) && (track.pt() < 10.0); // o2-linter: disable=magic-number (within POI pT range) + bool withinPtRef = (0.2 < track.pt()) && (track.pt() < 3.0); // o2-linter: disable=magic-number (within RF pT range) + if (withinPtRef) + cfgCumulantConfig.fGFW->Fill(track.eta(), cfgCumulantConfig.fPtAxis->FindBin(track.pt()) - 1, track.phi(), 1., 1); + if (withinPtPOI) + cfgCumulantConfig.fGFW->Fill(track.eta(), cfgCumulantConfig.fPtAxis->FindBin(track.pt()) - 1, track.phi(), 1., 2); + if (withinPtPOI && withinPtRef) + cfgCumulantConfig.fGFW->Fill(track.eta(), cfgCumulantConfig.fPtAxis->FindBin(track.pt()) - 1, track.phi(), 1., 4); + } + // fill FT0 Q-vector + for (const auto& tackFT : mcParticles) { + if (std::abs(tackFT.eta()) < cfgGeneral.cfgEtaTpcCut) + continue; + + if (cfgGeneral.cfgUseFt0Structure && !ft0aCollisionCourse(tackFT.eta(), tackFT.phi(), mcCollision.posZ())) { + continue; + } + if (!tackFT.isPhysicalPrimary()) + continue; + + cfgCumulantConfig.fGFW->Fill(tackFT.eta(), 1, tackFT.phi(), 1., 1); + } + + // Filling Flow Container + for (uint l_ind = 0; l_ind < cfgCumulantConfig.corrconfigs.size(); l_ind++) { + fillFC(cfgCumulantConfig.corrconfigs.at(l_ind), independent, lRandom); + } + } + + if (cfgGeneral.cfgSelCollByNch && (tpcMult < cfgGeneral.cfgCutMultMin || tpcMult >= cfgGeneral.cfgCutMultMax)) { + return; + } + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + if (!cfgGeneral.cfgCentTableUnavailable) + registry.fill(HIST("MCTrue/MCCentrality"), cent); + registry.fill(HIST("MCTrue/MCNch"), tpcMult); + registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), mcParticle.phi()); + registry.fill(HIST("MCTrue/MCEta"), mcParticle.eta()); + registry.fill(HIST("MCTrue/MCpT"), mcParticle.pt()); + } + } + if (cfgGeneral.cfgUseCFStepAll) { + sameTpcFt0a->fillEvent(tpcMult, CorrelationContainer::kCFStepAll); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0A); + } + + registry.fill(HIST("MCTrue/MCeventcount"), 2.5); + sameTpcFt0a->fillEvent(tpcMult, CorrelationContainer::kCFStepTrackedOnlyPrim); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f, kFT0A); + } + PROCESS_SWITCH(LongRangeDihadronCor, processMcSameTpcFt0a, "Process MC same event", false); + + void processMcMixedTpcFt0c(FilteredMcCollisions const& mcCollisions, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + auto getTracksSize = [&mcParticles, this](FilteredMcCollisions::iterator const& mcCollision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); + int tpcMult = 0; + for (const auto& track : associatedTracks) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + return tpcMult; + }; + + using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + + if (cfgGeneral.cfgSelCollByNch && (tracks1.size() < cfgGeneral.cfgCutMultMin || tracks1.size() >= cfgGeneral.cfgCutMultMax)) + continue; + + if (cfgGeneral.cfgSelCollByNch && (tracks2.size() < cfgGeneral.cfgCutMultMin || tracks2.size() >= cfgGeneral.cfgCutMultMax)) + continue; + + auto groupedCollisions1 = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); + auto groupedCollisions2 = collisions.sliceBy(collisionPerMCCollision, collision2.globalIndex()); + float cent1 = -1; + float cent2 = -1; + if (!cfgGeneral.cfgCentTableUnavailable) { + for (const auto& collision : groupedCollisions1) { + cent1 = getCentrality(collision); + } + for (const auto& collision : groupedCollisions2) { + cent2 = getCentrality(collision); + } + } + + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && ((cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax) || (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax))) + continue; + + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + float eventWeight = 1.0f; + if (cfgGeneral.cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + + if (cfgGeneral.cfgUseCFStepAll) { + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight, kFT0C); + } + + registry.fill(HIST("MCTrue/MCeventcount"), 4.5); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight, kFT0C); + } + } + PROCESS_SWITCH(LongRangeDihadronCor, processMcMixedTpcFt0c, "Process MC mixed events", false); + + void processMcMixedTpcFt0a(FilteredMcCollisions const& mcCollisions, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + auto getTracksSize = [&mcParticles, this](FilteredMcCollisions::iterator const& mcCollision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); + int tpcMult = 0; + for (const auto& track : associatedTracks) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + return tpcMult; + }; + + using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + + if (cfgGeneral.cfgSelCollByNch && (tracks1.size() < cfgGeneral.cfgCutMultMin || tracks1.size() >= cfgGeneral.cfgCutMultMax)) + continue; + + if (cfgGeneral.cfgSelCollByNch && (tracks2.size() < cfgGeneral.cfgCutMultMin || tracks2.size() >= cfgGeneral.cfgCutMultMax)) + continue; + + auto groupedCollisions1 = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); + auto groupedCollisions2 = collisions.sliceBy(collisionPerMCCollision, collision2.globalIndex()); + float cent1 = -1; + float cent2 = -1; + if (!cfgGeneral.cfgCentTableUnavailable) { + for (const auto& collision : groupedCollisions1) { + cent1 = getCentrality(collision); + } + for (const auto& collision : groupedCollisions2) { + cent2 = getCentrality(collision); + } + } + + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && ((cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax) || (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax))) + continue; + + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + float eventWeight = 1.0f; + if (cfgGeneral.cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + + if (cfgGeneral.cfgUseCFStepAll) { + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight, kFT0A); + } + + registry.fill(HIST("MCTrue/MCeventcount"), 4.5); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight, kFT0A); + } + } + PROCESS_SWITCH(LongRangeDihadronCor, processMcMixedTpcFt0a, "Process MC mixed events", false); + + void processSemiMcSameTpcFt0c(FilteredMcParticles const& mcParticles, FilteredCollisions const& collisions, aod::FT0s const&, aod::BCsWithTimestamps const&) + { + for (const auto& collision : collisions) { + auto tracks1 = mcParticles.sliceBy(perColMc, collision.globalIndex()); // TPC MC-truth + + if (!collision.sel8()) + return; + auto bc = collision.bc_as(); + + int tpcMult = 0; + for (const auto& track : tracks1) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + + float cent = -1.; + float weightCent = 1.0f; + if (!cfgGeneral.cfgCentTableUnavailable) { + cent = getCentrality(collision); + } + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision, tpcMult, cent, true)) + return; + if (!collision.has_foundFT0()) + return; + + loadAlignParam(bc.timestamp()); + loadGain(bc); + loadCorrection(bc.timestamp()); + if (!cfgGeneral.cfgCentTableUnavailable) { + getCentralityWeight(weightCent, cent); + registry.fill(HIST("Centrality"), cent); + registry.fill(HIST("CentralityWeighted"), cent, weightCent); + } + registry.fill(HIST("Nch"), tpcMult); + registry.fill(HIST("zVtx"), collision.posZ()); + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + if (!cfgGeneral.cfgCentTableUnavailable) + registry.fill(HIST("MCTrue/MCCentrality"), cent); + registry.fill(HIST("MCTrue/MCNch"), tpcMult); + for (const auto& track1 : tracks1) { + if (track1.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), track1.phi()); + registry.fill(HIST("MCTrue/MCEta"), track1.eta()); + registry.fill(HIST("MCTrue/MCpT"), track1.pt()); + } + } + + if (cfgGeneral.cfgSelCollByNch && (tpcMult < cfgGeneral.cfgCutMultMin || tpcMult >= cfgGeneral.cfgCutMultMax)) { + return; + } + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { + return; + } + + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + + sameTpcFt0c->fillEvent(tpcMult, CorrelationContainer::kCFStepReconstructed); + const auto& ft0 = collision.foundFT0(); + fillSemiMcCorrelations(tracks1, ft0, collision.posZ(), SameEvent, kFT0C, cent, weightCent); + } + } + PROCESS_SWITCH(LongRangeDihadronCor, processSemiMcSameTpcFt0c, "Process truth-TPC and recon-FT0C same events", false); + + void processSemiMcSameTpcFt0a(FilteredMcParticles const& mcParticles, FilteredCollisions const& collisions, aod::FT0s const&, aod::BCsWithTimestamps const&) + { + for (const auto& collision : collisions) { + auto tracks1 = mcParticles.sliceBy(perColMc, collision.globalIndex()); // TPC MC-truth + + if (!collision.sel8()) + return; + auto bc = collision.bc_as(); + + int tpcMult = 0; + for (const auto& track : tracks1) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + + float cent = -1.; + float weightCent = 1.0f; + if (!cfgGeneral.cfgCentTableUnavailable) { + cent = getCentrality(collision); + } + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision, tpcMult, cent, true)) + return; + if (!collision.has_foundFT0()) + return; + + loadAlignParam(bc.timestamp()); + loadGain(bc); + loadCorrection(bc.timestamp()); + if (!cfgGeneral.cfgCentTableUnavailable) { + getCentralityWeight(weightCent, cent); + registry.fill(HIST("Centrality"), cent); + registry.fill(HIST("CentralityWeighted"), cent, weightCent); + } + registry.fill(HIST("Nch"), tpcMult); + registry.fill(HIST("zVtx"), collision.posZ()); + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + if (!cfgGeneral.cfgCentTableUnavailable) + registry.fill(HIST("MCTrue/MCCentrality"), cent); + registry.fill(HIST("MCTrue/MCNch"), tpcMult); + for (const auto& track1 : tracks1) { + if (track1.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), track1.phi()); + registry.fill(HIST("MCTrue/MCEta"), track1.eta()); + registry.fill(HIST("MCTrue/MCpT"), track1.pt()); + } + } + + if (cfgGeneral.cfgSelCollByNch && (tpcMult < cfgGeneral.cfgCutMultMin || tpcMult >= cfgGeneral.cfgCutMultMax)) { + return; + } + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent < cfgGeneral.cfgCutCentMin || cent >= cfgGeneral.cfgCutCentMax)) { + return; + } + + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + + sameTpcFt0a->fillEvent(tpcMult, CorrelationContainer::kCFStepReconstructed); + const auto& ft0 = collision.foundFT0(); + fillSemiMcCorrelations(tracks1, ft0, collision.posZ(), SameEvent, kFT0A, cent, weightCent); + } + } + PROCESS_SWITCH(LongRangeDihadronCor, processSemiMcSameTpcFt0a, "Process truth-TPC and recon-FT0A same events", false); + + void processSemiMcMixedTpcFt0c(FilteredMcParticles const& mcParticles, FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) + { + + auto getTracksSize = [&mcParticles, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, collision.globalIndex(), this->cache); + int tpcMult = 0; + for (const auto& track : associatedTracks) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + return tpcMult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(tracks, tracks); + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracksRecon1, collision2, tracksRecon2] = *it; + + auto tracksTruth1 = mcParticles.sliceBy(perColMc, collision1.globalIndex()); // TPC MC-truth + + if (!collision1.sel8() || !collision2.sel8()) + continue; + + float cent1 = -1; + float cent2 = -1; + if (!cfgGeneral.cfgCentTableUnavailable) { + cent1 = getCentrality(collision1); + cent2 = getCentrality(collision2); + } + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision1, tracksRecon1.size(), cent1, false)) + continue; + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision2, tracksRecon2.size(), cent2, false)) + continue; + + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax)) + continue; + + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax)) + continue; + + if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) + continue; + + auto bc = collision1.bc_as(); + loadAlignParam(bc.timestamp()); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + if (cfgGeneral.cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + registry.fill(HIST("MCTrue/MCeventcount"), 4.5); + float weightCent = 1.0f; + if (!cfgGeneral.cfgCentTableUnavailable) + getCentralityWeight(weightCent, cent1); + const auto& ft0 = collision2.foundFT0(); + + fillSemiMcCorrelations(tracksTruth1, ft0, collision1.posZ(), MixedEvent, kFT0C, cent1, eventWeight * weightCent); + } + } + PROCESS_SWITCH(LongRangeDihadronCor, processSemiMcMixedTpcFt0c, "Process MC mixed events for TPC(truth)-FT0C(recon)", false); + + void processSemiMcMixedTpcFt0a(FilteredMcParticles const& mcParticles, FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) + { + + auto getTracksSize = [&mcParticles, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, collision.globalIndex(), this->cache); + int tpcMult = 0; + for (const auto& track : associatedTracks) { + if (std::abs(track.eta()) < cfgGeneral.cfgEtaTpcCut) + tpcMult += 1; + } + return tpcMult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(tracks, tracks); + Pair pairs{binningOnVtxAndMult, cfgGeneral.cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracksRecon1, collision2, tracksRecon2] = *it; + + auto tracksTruth1 = mcParticles.sliceBy(perColMc, collision1.globalIndex()); // TPC MC-truth + + if (!collision1.sel8() || !collision2.sel8()) + continue; + + float cent1 = -1; + float cent2 = -1; + if (!cfgGeneral.cfgCentTableUnavailable) { + cent1 = getCentrality(collision1); + cent2 = getCentrality(collision2); + } + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision1, tracksRecon1.size(), cent1, false)) + continue; + if (cfgGeneral.cfgUseAdditionalEventCut && !eventSelected(collision2, tracksRecon2.size(), cent2, false)) + continue; + + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent1 < cfgGeneral.cfgCutCentMin || cent1 >= cfgGeneral.cfgCutCentMax)) + continue; + + if (!cfgGeneral.cfgSelCollByNch && !cfgGeneral.cfgCentTableUnavailable && (cent2 < cfgGeneral.cfgCutCentMin || cent2 >= cfgGeneral.cfgCutCentMax)) + continue; + + if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) + continue; + + auto bc = collision1.bc_as(); + loadAlignParam(bc.timestamp()); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + if (cfgGeneral.cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + registry.fill(HIST("MCTrue/MCeventcount"), 4.5); + float weightCent = 1.0f; + if (!cfgGeneral.cfgCentTableUnavailable) + getCentralityWeight(weightCent, cent1); + const auto& ft0 = collision2.foundFT0(); + + fillSemiMcCorrelations(tracksTruth1, ft0, collision1.posZ(), MixedEvent, kFT0A, cent1, eventWeight * weightCent); + } + } + PROCESS_SWITCH(LongRangeDihadronCor, processSemiMcMixedTpcFt0a, "Process MC mixed events for TPC(truth)-FT0A(recon)", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)