diff --git a/PWGHF/HFC/Tasks/taskFlow.cxx b/PWGHF/HFC/Tasks/taskFlow.cxx index 447c615f7b3..0c7fa65cee4 100644 --- a/PWGHF/HFC/Tasks/taskFlow.cxx +++ b/PWGHF/HFC/Tasks/taskFlow.cxx @@ -16,6 +16,7 @@ /// \author Maja Kabus , CERN #include "PWGCF/Core/CorrelationContainer.h" +#include "PWGCF/Core/PairCuts.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -25,7 +26,6 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/McCollisionExtra.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -78,26 +79,26 @@ using namespace o2::constants::math; using namespace o2::framework; using namespace o2::framework::expressions; -enum MftTrackSelectionStep { - NoSelection = 0, - Eta, - Cluster, - NMftTrackSelectionSteps +enum CorrelationCase { + TpcTpc, + TpcMft, + TpcFv0a, + MftFv0a, + TpcFt0a, + MftFt0a, + TpcFt0c, + Ft0aFt0c }; -enum MftTrackAmbiguityStep { - AllMftTracks = 0, - AfterTrackSelection, - NumberOfAmbiguousTracks, - NumberOfNonAmbiguousTracks, - NMftAmbiguitySteps +enum CorrelatedParticles { + ChPartChPart, + D0ChPart, + LcChPart }; -enum MultiplicityEstimators { - MultNTracksPV = 0, - MultNumContrib, - MultFT0C, - MultFT0M +enum DataType { + Data, + Mc }; enum ReassociationMftTracks { @@ -112,36 +113,46 @@ enum EventSelectionStep { NEventSelectionSteps }; -enum DataType { - Data, - Mc +enum FITIndex { + isFT0A = 0, + isFT0C = 1, + isFV0A = 2 }; -// enum EventType { -// SameEvent, -// MixedEvent -// }; +enum MftTrackAmbiguityStep { + AllMftTracks = 0, + AfterTrackSelection, + NumberOfAmbiguousTracks, + NumberOfNonAmbiguousTracks, + NMftAmbiguitySteps +}; -enum CorrelationCase { - TpcTpc, - TpcMft, - TpcFv0a, - MftFv0a, - TpcFt0a, - MftFt0a +enum MftTrackSelectionStep { + NoSelection = 0, + Eta, + Cluster, + Pt, + NMftTrackSelectionSteps }; -enum CorrelatedParticles { - ChPartChPart, - D0ChPart, - LcChPart +enum MultiplicityEstimators { + MultNTracksPV = 0, + MultNumContrib, + MultFT0C, + MultFT0M +}; + +enum TrackSelection { + TrackSelectionNoCut = 0, + TrackSelectionGlobalTrack }; // static constexpr std::string_view whatEventType[] = {"SameEvent/", "MixedEvent/"}; static constexpr std::string_view WhatDataType[] = {"Data/", "MC/"}; -static constexpr std::string_view WhatCorrelationCase[] = {"TpcTpc/", "TpcMft/", "TpcFv0a/", "MftFv0a/", "TpcFt0a/", "MftFt0a/"}; +static constexpr std::string_view WhatCorrelationCase[] = {"TpcTpc/", "TpcMft/", "TpcFv0a/", "MftFv0a/", "TpcFt0a/", "MftFt0a/", "TpcFt0c/", "Ft0aFt0c/"}; static constexpr std::string_view WhatParticles[] = {"ChPartChPart/", "D0ChPart/", "LcChPart/"}; static constexpr std::string_view WhatMultiplicityEstimator[] = {"multNTracksPV", "multNumContrib", "multFT0C", "multFT0M"}; +auto static constexpr kMinFt0cCell = 96; static constexpr TrackSelectionFlags::flagtype TrackSelectionIts = TrackSelectionFlags::kITSNCls | TrackSelectionFlags::kITSChi2NDF | @@ -155,7 +166,7 @@ static constexpr TrackSelectionFlags::flagtype TrackSelectionDca = static constexpr TrackSelectionFlags::flagtype TrackSelectionDcaxyOnly = TrackSelectionFlags::kDCAxy; -// static constexpr float kPairCutDefaults[1][5] = {{-1, -1, -1, -1, -1}}; +static constexpr float PairCutDefaults[1][5] = {{-1, -1, -1, -1, -1}}; struct HfTaskFlow { @@ -169,33 +180,49 @@ struct HfTaskFlow { struct : ConfigurableGroup { std::string prefix = "ConfigTask_group"; - Configurable centralityBinsForMc{"centralityBinsForMc", false, "false = OFF, true = ON for data like multiplicity/centrality bins for MC steps"}; + Configurable centralityBinsForMc{"centralityBinsForMc", false, "falsce = OFF, true = ON for data like multiplicity/centrality bins for MC steps"}; Configurable doHeavyFlavor{"doHeavyFlavor", false, "Flag to know we in the heavy flavor case or not"}; Configurable doReferenceFlow{"doReferenceFlow", false, "Flag to know if reference flow should be done"}; Configurable isReadoutCenter{"isReadoutCenter", false, "Enable Readout Center"}; - // Configurable doTwoTrackCut{"doTwoTrackCut", -1, "Two track cut: -1 = off; >0 otherwise distance value (suggested: 0.02)"}; - Configurable processMc{"processMc", false, "Flag to run on MC"}; Configurable nMixedEvents{"nMixedEvents", 5, "Number of mixed events per event"}; - // Configurable twoTrackCutMinRadius{"twoTrackCutMinRadius", 0.8f, "Two track cut : radius in m from which two tracks cuts are applied"}; } configTask; // configurables for collisions struct : ConfigurableGroup { std::string prefix = "ConfigCollision_group"; + Configurable isApplyGoodItsLayersAll{"isApplyGoodItsLayersAll", false, "Enable GoodITSLayersAll"}; Configurable isApplyGoodZvtxFT0vsPV{"isApplyGoodZvtxFT0vsPV", false, "Enable GoodZvtxFT0vsPV cut"}; 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 zVertexMax{"zVertexMax", 7.0f, "Accepted z-vertex range"}; + Configurable zVertexMax{"zVertexMax", 10.0f, "Accepted z-vertex range"}; } configCollision; // configurables for central barrel tracks struct : ConfigurableGroup { - std::string prefix = "ConfigCentralTracks_group"; + std::string prefix = "ConfigCentral_group"; + Configurable dcaZCentralTrackMax{"dcaZCentralTrackMax", 0.2f, "max dcaZ of central tracks"}; Configurable etaCentralTrackMax{"etaCentralTrackMax", 0.8f, "max. eta of central tracks"}; + Configurable isApplyConversionCut{"isApplyConversionCut", false, "apply pair conversion cuts"}; + Configurable isApplyTwoTrackCut{"isApplyTwoTrackCut", false, "apply two track cut"}; + Configurable isApplyIndexOrdering{"isApplyIndexOrdering", false, "apply track1.index() <= track2.index() cut"}; + Configurable isApplyPtOrderingSameEvent{"isApplyPtOrderingSameEvent", false, "apply track1.pt() <= track2.pt() cut"}; + Configurable isApplyPtOrderingMixedEvent{"isApplyPtOrderingMixedEvent", false, "apply track1.pt() <= track2.pt() cut"}; + Configurable isApplySameTrackCut{"isApplySameTrackCut", false, "apply track1 == track2 cut"}; + Configurable maxChi2ItsClusters{"maxChi2ItsClusters", 36.f, "max chi2 per ITS clusters"}; + Configurable maxChi2TpcClusters{"maxChi2TpcClusters", 2.5f, "max chi2 per TPC clusters"}; + Configurable maxMergingRadius{"maxMergingRadius", 2.5, "max radius for merging cut"}; + Configurable mergingCut{"mergingCut", 0.02, "merging cut on track merge"}; + Configurable minItsClusters{"minItsClusters", 5.0f, "cut for minimum ITS clusters"}; + Configurable minMergingRadius{"minMergingRadius", 0.8, "max radius for merging cut"}; + Configurable minTpcClusters{"minTpcClusters", 50.0f, "cut for minimum TPC clusters"}; + Configurable minTpcCrossedRows{"minTpcCrossedRows", 70.0f, "cut for minimum TOC crossed rows"}; + Configurable> pairCut{"pairCut", {PairCutDefaults[0], 5, {"Photon", "K0", "Lambda", "Phi", "Rho"}}, "Pair cuts on various particles"}; Configurable ptCentralTrackMin{"ptCentralTrackMin", 0.2f, "min. pT of central tracks"}; Configurable ptCentralTrackMax{"ptCentralTrackMax", 10.0f, "max. pT of central tracks"}; - Configurable dcaZCentralTrackMax{"dcaZCentralTrackMax", 0.2f, "max dcaZ of central tracks"}; + Configurable trackSelectionType{"trackSelectionType", 1, "Track selection: 0 -> kGlobalTrack or isGlobalTrackSDD , 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> No globalTrack selection"}; } configCentral; // configurables for HF candidates @@ -211,15 +238,21 @@ struct HfTaskFlow { // configurables for MFT tracks struct : ConfigurableGroup { std::string prefix = "ConfigMft_group"; - Configurable etaMftTrackMax{"etaMftTrackMax", -2.4f, "Maximum value for the eta of MFT tracks"}; - Configurable etaMftTrackMin{"etaMftTrackMin", -3.36f, "Minimum value for the eta of MFT tracks"}; - Configurable etaMftTrackMaxFilter{"etaMftTrackMaxFilter", -2.0f, "Maximum value for the eta of MFT tracks"}; - Configurable etaMftTrackMinFilter{"etaMftTrackMinFilter", -3.9f, "Minimum value for the eta of MFT tracks"}; + Configurable cutBestCollisionId{"cutBestCollisionId", 0, "cut on the best collision Id used in a filter"}; + Configurable etaMftTrackMax{"etaMftTrackMax", -2.4f, "Maximum value for the eta of MFT tracks when used in cut function"}; + Configurable etaMftTrackMin{"etaMftTrackMin", -3.36f, "Minimum value for the eta of MFT tracks when used in cut function"}; + Configurable etaMftTrackMaxFilter{"etaMftTrackMaxFilter", -2.0f, "Maximum value for the eta of MFT tracks when used in filter"}; + Configurable etaMftTrackMinFilter{"etaMftTrackMinFilter", -3.9f, "Minimum value for the eta of MFT tracks when used in filter"}; Configurable mftMaxDCAxy{"mftMaxDCAxy", 2.0f, "Cut on dcaXY for MFT tracks"}; Configurable mftMaxDCAz{"mftMaxDCAz", 2.0f, "Cut on dcaZ for MFT tracks"}; Configurable nClustersMftTrack{"nClustersMftTrack", 5, "Minimum number of clusters for the reconstruction of MFT tracks"}; + Configurable ptMftTrackMax{"ptMftTrackMax", 10.0f, "max value of MFT tracks pT when used in cut function"}; + Configurable ptMftTrackMin{"ptMftTrackMin", 0.2f, "min value of MFT tracks pT when used in cut function"}; + Configurable useMftPtCut{"useMftPtCut", false, "if true, use the Mft pt function cut"}; } configMft; + TF1* fPtDepDCAxy = nullptr; + HfHelper hfHelper; SliceCache cache; Service pdg; @@ -240,23 +273,6 @@ struct HfTaskFlow { using FilteredTracksWDcaSel = soa::Filtered>; using FilteredMftTracks = soa::Filtered; - // using FilteredMftTracksWColls = soa::Filtered>; - // using FilteredAndReassociatedMftTracks = soa::Filtered>; - - // ========================= - // using declarations : MONTE CARLO - // ========================= - - using FilteredCollisionsWSelMultMcLabels = soa::Filtered>; - using FilteredMcCollisions = soa::Filtered>; - using HfCandidatesSelD0McRec = soa::Join; - using HfCandidatesSelLcMcRec = soa::Join; - using McParticles = aod::McParticles; - using McParticles2ProngMatched = soa::Join; - using McParticles3ProngMatched = soa::Join; - using MftTracksMcLabels = soa::Join; - using FilteredTracksWDcaSelMC = soa::Filtered>; - // using FilteredMftTracksWCollsMcLabels = soa::Filtered>; // ========================= // Filters & partitions : DATA @@ -274,46 +290,27 @@ struct HfTaskFlow { Filter collisionVtxZFilter = nabs(aod::collision::posZ) < configCollision.zVertexMax; // Central tracks filter - Filter centralTrackEtaPtFilter = (nabs(aod::track::eta) < configCentral.etaCentralTrackMax) && (aod::track::pt > configCentral.ptCentralTrackMin); - Filter centralTrackTpcFilter = ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC), - ncheckbit(aod::track::trackCutFlag, TrackSelectionTpc), true); - Filter centralTrackItsFilter = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) && - ncheckbit(aod::track::trackCutFlag, TrackSelectionIts); - Filter centralTrackDcaFilter = ifnode(configCentral.dcaZCentralTrackMax.node() > 0.f, nabs(aod::track::dcaZ) <= configCentral.dcaZCentralTrackMax && ncheckbit(aod::track::trackCutFlag, TrackSelectionDcaxyOnly), - ncheckbit(aod::track::trackCutFlag, TrackSelectionDca)); + Filter trackFilter = (nabs(aod::track::eta) < configCentral.etaCentralTrackMax) && + (aod::track::pt > configCentral.ptCentralTrackMin) && + (aod::track::pt < configCentral.ptCentralTrackMax) && + requireGlobalTrackInFilter(); - Filter mftTrackFilter = (aod::fwdtrack::eta < configMft.etaMftTrackMaxFilter) && - (aod::fwdtrack::eta > configMft.etaMftTrackMinFilter); + Filter centralTrackItsTpcMatchingFilter = ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC), ncheckbit(aod::track::trackCutFlag, TrackSelectionTpc), true) && + ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) && + ncheckbit(aod::track::trackCutFlag, TrackSelectionIts); - // Filters below will be used for uncertainties - Filter mftTrackCollisionIdFilter = (aod::fwdtrack::bestCollisionId >= 0); - Filter mftTrackDcaXYFilter = (nabs(aod::fwdtrack::bestDCAXY) < configMft.mftMaxDCAxy); - // Filter mftTrackDcaZFilter = (nabs(aod::fwdtrack::bestDCAZ) < configMft.mftMaxDCAz); + Filter centralTrackDcaFilter = (ifnode(configCentral.dcaZCentralTrackMax.node() > 0.f, nabs(aod::track::dcaZ) <= configCentral.dcaZCentralTrackMax && ncheckbit(aod::track::trackCutFlag, TrackSelectionDcaxyOnly), ncheckbit(aod::track::trackCutFlag, TrackSelectionDca))); - // ========================= - // Filters & partitions : MC - // ========================= + Filter centralTrackChi2TpcClusterFilter = (aod::track::tpcChi2NCl < configCentral.maxChi2TpcClusters); - Filter candidateFilterD0Mc = (aod::hf_sel_candidate_d0::isRecoHfFlag >= configCandidates.selectionFlagHf) || - (aod::hf_sel_candidate_d0::isRecoHfFlag >= configCandidates.selectionFlagHf); + Filter centralTrackChi2ItsClusterFilter = (aod::track::itsChi2NCl < configCentral.maxChi2ItsClusters); - Filter candidateFilterLcMc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= configCandidates.selectionFlagHf) || - (aod::hf_sel_candidate_lc::isSelLcToPiKP >= configCandidates.selectionFlagHf); + Filter mftTrackEtaFilter = ((aod::fwdtrack::eta < configMft.etaMftTrackMaxFilter) && (aod::fwdtrack::eta > configMft.etaMftTrackMinFilter)); - // From Katarina's code, but not sure if I use it - Filter mcCollisionFilter = nabs(aod::mccollision::posZ) < configCollision.zVertexMax; - - // Filter mcParticlesFilter = (nabs(aod::mcparticle::eta) < configCentral.etaCentralTrackMax) && - // (aod::mcparticle::pt > configCentral.ptCentralTrackMin); - - // I didn't manage to make partitions work with my mixed event, as I am pair my tracks BEFORE looping over collisions - // I am thus not able to group tracks with sliceBy and can't use this method - // For now I am fine as I am doing only TPC-MFT correlations and using only McParticles with MFT acceptance - // However at some point I will have to use tracks from the other side (FV0, FT0-A) and I will have to do something about it - // TO-DO : either change how I do mixed event, or implement isAcceptedTpcMcParticle, isAcceptedMftMcParticle - // Partition mcParticlesMft = (aod::mcparticle::eta > configMft.etaMftTrackMin) && (aod::mcparticle::eta < configMft.etaMftTrackMax); - // Partition mcParticlesTpc = (nabs(aod::mcparticle::eta) < configCentral.etaCentralTrackMax) && - // (aod::mcparticle::pt > configCentral.ptCentralTrackMin); + // Filters below will be used for uncertainties + Filter mftTrackCollisionIdFilter = (aod::fwdtrack::bestCollisionId >= 0); + Filter mftTrackDcaXYFilter = (nabs(aod::fwdtrack::bestDCAXY) < configMft.mftMaxDCAxy); + // Filter mftTrackDcaZFilter = (nabs(aod::fwdtrack::bestDCAZ) < configMft.mftMaxDCAz); // ========================= // Preslice : DATA @@ -324,34 +321,33 @@ struct HfTaskFlow { Preslice perColMftTracks = o2::aod::fwdtrack::collisionId; Preslice perColTracks = aod::track::collisionId; - // ========================= - // Preslice : MC - // ========================= - - Preslice mftTracksPerCollision = aod::fwdtrack::collisionId; - // configurables for containers // TODO: flow of HF will need to be done vs. invariant mass, in the signal and side-band regions // either 1) add invariant mass axis or 2) define several containers for different inv. mass regions // Note: don't forget to check inv. mass separately for D0 and D0bar candidate - ConfigurableAxis axisMass{"axisMass", {120, 1.5848, 2.1848}, "axis of invariant mass of candidates"}; - ConfigurableAxis binsMixingMultiplicity{"binsMixingMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 100.1}, "multiplicity bins for event mixing"}; - ConfigurableAxis binsMixingVertex{"binsMixingVertex", {14, -7, 7}, "vertex bins for event mixing"}; - ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; - ConfigurableAxis axisEtaAssociated{"axisEtaAssociated", {48, -4, -2}, "eta axis for MFT histograms"}; - ConfigurableAxis axisEtaTrigger{"axisEtaTrigger", {48, -1, 1}, "eta axis for TPC histograms"}; - ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; - ConfigurableAxis axisDeltaEta{"axisDeltaEta", {48, -2.4, 2.4}, "delta eta axis for histograms"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 100.1}, "multiplicity axis for histograms"}; - ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "phi axis for histograms"}; - ConfigurableAxis axisPt{"axisPt", {72, 0, 36}, "pt axis for histograms"}; - ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0}, "pt associated axis for histograms"}; - ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; - ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0}, "pt trigger axis for histograms"}; - ConfigurableAxis axisVertex{"axisVertex", {14, -7, 7}, "vertex axis for histograms"}; - ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; + + struct : ConfigurableGroup { + std::string prefix = "ConfigAxis_group"; + ConfigurableAxis axisMass{"axisMass", {120, 1.5848, 2.1848}, "axis of invariant mass of candidates"}; + ConfigurableAxis binsMixingMultiplicity{"binsMixingMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 100.1}, "multiplicity bins for event mixing"}; + ConfigurableAxis binsMixingVertex{"binsMixingVertex", {14, -7, 7}, "vertex bins for event mixing"}; + ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; + ConfigurableAxis axisEtaAssociated{"axisEtaAssociated", {48, -4, -2}, "eta axis for MFT histograms"}; + ConfigurableAxis axisEtaTrigger{"axisEtaTrigger", {48, -1, 1}, "eta axis for TPC histograms"}; + ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; + ConfigurableAxis axisDeltaEta{"axisDeltaEta", {48, -2.4, 2.4}, "delta eta axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 100.1}, "multiplicity axis for histograms"}; + ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "phi axis for histograms"}; + ConfigurableAxis axisPt{"axisPt", {72, 0, 36}, "pt axis for histograms"}; + ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0}, "pt associated axis for histograms"}; + ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; + ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0}, "pt trigger axis for histograms"}; + ConfigurableAxis axisVertex{"axisVertex", {14, -7, 7}, "vertex axis for histograms"}; + ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; + } configAxis; HistogramRegistry registry{"registry"}; + PairCuts mPairCuts; // Correlation containers used for data OutputObj sameEvent{"sameEvent"}; @@ -366,14 +362,55 @@ struct HfTaskFlow { template void addHistograms() { - registry.add(Form("%s%s%shEtaTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {axisEtaTrigger}}); - registry.add(Form("%s%s%shPhiTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {axisPhi}}); - registry.add(Form("%s%s%shPtTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {axisPt}}); - registry.add(Form("%s%s%shYieldsTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaTrigger}}); - registry.add(Form("%s%s%shEtaPhiTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH3F, {axisMultiplicity, axisEtaTrigger, axisPhi}}); - registry.add(Form("%s%s%shEtaAssociated", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add(Form("%s%s%shPhiAssociated", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {axisPhi}}); - registry.add(Form("%s%s%shEtaPhiAssociated", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH3F, {axisMultiplicity, axisEtaAssociated, axisPhi}}); + registry.add(Form("%s%s%shEtaTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {configAxis.axisEtaTrigger}}); + registry.add(Form("%s%s%shPhiTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {configAxis.axisPhi}}); + registry.add(Form("%s%s%shPtTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {configAxis.axisPt}}); + registry.add(Form("%s%s%shYieldsTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH3F, {configAxis.axisMultiplicity, configAxis.axisPt, configAxis.axisEtaTrigger}}); + registry.add(Form("%s%s%shEtaPhiTrigger", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH3F, {configAxis.axisMultiplicity, configAxis.axisEtaTrigger, configAxis.axisPhi}}); + registry.add(Form("%s%s%shEtaAssociated", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {configAxis.axisEtaAssociated}}); + registry.add(Form("%s%s%shPhiAssociated", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH1D, {configAxis.axisPhi}}); + registry.add(Form("%s%s%shEtaPhiAssociated", WhatDataType[DataType].data(), WhatCorrelationCase[CorrelationCase].data(), WhatParticles[CorrelatedParticles].data()), "", {HistType::kTH3F, {configAxis.axisMultiplicity, configAxis.axisEtaAssociated, configAxis.axisPhi}}); + } + + void addMftHistograms() + { + registry.add("Data/Mft/hAmbiguityOfMftTracks", "hAmbiguityOfMftTracks", {HistType::kTH1D, {{MftTrackAmbiguityStep::NMftAmbiguitySteps, -0.5, +MftTrackAmbiguityStep::NMftAmbiguitySteps - 0.5}}}); + std::string labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NMftAmbiguitySteps]; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::AllMftTracks] = "all MFT tracks"; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::AfterTrackSelection] = "MFT tracks after selection"; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NumberOfAmbiguousTracks] = "how much tracks are ambigous"; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NumberOfNonAmbiguousTracks] = "how much tracks are non-ambiguous"; + registry.get(HIST("Data/Mft/hAmbiguityOfMftTracks"))->SetMinimum(0); + + for (int iBin = 0; iBin < MftTrackAmbiguityStep::NMftAmbiguitySteps; iBin++) { + registry.get(HIST("Data/Mft/hAmbiguityOfMftTracks"))->GetXaxis()->SetBinLabel(iBin + 1, labelsAmbiguityOfMftTracks[iBin].data()); + } + + registry.add("Data/Mft/hMftTracksSelection", "hMftTracksSelection", {HistType::kTH1D, {{MftTrackSelectionStep::NMftTrackSelectionSteps, -0.5, +MftTrackSelectionStep::NMftTrackSelectionSteps - 0.5}}}); + std::string labelsMftTracksSelection[MftTrackSelectionStep::NMftTrackSelectionSteps]; + labelsMftTracksSelection[MftTrackSelectionStep::NoSelection] = "all MFT tracks"; + labelsMftTracksSelection[MftTrackSelectionStep::Eta] = "MFT tracks after eta selection"; + labelsMftTracksSelection[MftTrackSelectionStep::Cluster] = "MFT tracks after clusters selection"; + labelsMftTracksSelection[MftTrackSelectionStep::Pt] = "MFT tracks after pT selection"; + registry.get(HIST("Data/Mft/hMftTracksSelection"))->SetMinimum(0); + + for (int iBin = 0; iBin < MftTrackSelectionStep::NMftTrackSelectionSteps; iBin++) { + registry.get(HIST("Data/Mft/hMftTracksSelection"))->GetXaxis()->SetBinLabel(iBin + 1, labelsMftTracksSelection[iBin].data()); + } + + registry.add("Data/Mft/hReassociationMftTracks", "hReassociationMftTracks", {HistType::kTH1D, {{ReassociationMftTracks::NReassociationMftTracksSteps, -0.5, +ReassociationMftTracks::NReassociationMftTracksSteps - 0.5}}}); + std::string labelsReassociationMftTracks[ReassociationMftTracks::NReassociationMftTracksSteps]; + labelsReassociationMftTracks[ReassociationMftTracks::NotReassociatedMftTracks] = "Ambiguous MFT tracks after track selection"; + labelsReassociationMftTracks[ReassociationMftTracks::ReassociatedMftTracks] = "Reassociated MFT tracks by DCAxy method"; + registry.get(HIST("Data/Mft/hReassociationMftTracks"))->SetMinimum(0); + + for (int iBin = 0; iBin < ReassociationMftTracks::NReassociationMftTracksSteps; iBin++) { + registry.get(HIST("Data/Mft/hReassociationMftTracks"))->GetXaxis()->SetBinLabel(iBin + 1, labelsReassociationMftTracks[iBin].data()); + } + + registry.add("Data/Mft/hPtMft", "", {HistType::kTH1D, {configAxis.axisPt}}); + registry.add("Data/Mft/hNMftTracks", "", {HistType::kTH1F, {configAxis.axisMultiplicity}}); + registry.add("Data/Mft/hNBestCollisionFwd", "", {HistType::kTH1F, {configAxis.axisMultiplicity}}); } // ========================= @@ -394,12 +431,15 @@ struct HfTaskFlow { 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 // ========================= - registry.add("Data/hVtxZ", "v_{z} (cm)", {HistType::kTH1D, {axisVertex}}); - registry.add(Form("Data/hMultiplicity_%s", WhatMultiplicityEstimator[configCollision.multiplicityEstimator].data()), "", {HistType::kTH1D, {axisMultiplicity}}); + 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}}); registry.add("Data/hEventCounter", "hEventCounter", {HistType::kTH1D, {{EventSelectionStep::NEventSelectionSteps, -0.5, +EventSelectionStep::NEventSelectionSteps - 0.5}}}); std::string labels[EventSelectionStep::NEventSelectionSteps]; @@ -411,59 +451,29 @@ struct HfTaskFlow { registry.get(HIST("Data/hEventCounter"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } - registry.add("Data/Mft/hAmbiguityOfMftTracks", "hAmbiguityOfMftTracks", {HistType::kTH1D, {{MftTrackAmbiguityStep::NMftAmbiguitySteps, -0.5, +MftTrackAmbiguityStep::NMftAmbiguitySteps - 0.5}}}); - std::string labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NMftAmbiguitySteps]; - labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::AllMftTracks] = "all MFT tracks"; - labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::AfterTrackSelection] = "MFT tracks after selection"; - labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NumberOfAmbiguousTracks] = "how much tracks are ambigous"; - labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NumberOfNonAmbiguousTracks] = "how much tracks are non-ambiguous"; - registry.get(HIST("Data/Mft/hAmbiguityOfMftTracks"))->SetMinimum(0); - - for (int iBin = 0; iBin < MftTrackAmbiguityStep::NMftAmbiguitySteps; iBin++) { - registry.get(HIST("Data/Mft/hAmbiguityOfMftTracks"))->GetXaxis()->SetBinLabel(iBin + 1, labelsAmbiguityOfMftTracks[iBin].data()); - } - - registry.add("Data/Mft/hMftTracksSelection", "hMftTracksSelection", {HistType::kTH1D, {{MftTrackSelectionStep::NMftTrackSelectionSteps, -0.5, +MftTrackSelectionStep::NMftTrackSelectionSteps - 0.5}}}); - std::string labelsMftTracksSelection[MftTrackSelectionStep::NMftTrackSelectionSteps]; - labelsMftTracksSelection[MftTrackSelectionStep::NoSelection] = "all MFT tracks"; - labelsMftTracksSelection[MftTrackSelectionStep::Eta] = "MFT tracks after eta selection"; - labelsMftTracksSelection[MftTrackSelectionStep::Cluster] = "MFT tracks after clusters selection"; - registry.get(HIST("Data/Mft/hMftTracksSelection"))->SetMinimum(0); - - for (int iBin = 0; iBin < MftTrackSelectionStep::NMftTrackSelectionSteps; iBin++) { - registry.get(HIST("Data/Mft/hMftTracksSelection"))->GetXaxis()->SetBinLabel(iBin + 1, labelsMftTracksSelection[iBin].data()); - } - - registry.add("Data/Mft/hReassociationMftTracks", "hReassociationMftTracks", {HistType::kTH1D, {{ReassociationMftTracks::NReassociationMftTracksSteps, -0.5, +ReassociationMftTracks::NReassociationMftTracksSteps - 0.5}}}); - std::string labelsReassociationMftTracks[ReassociationMftTracks::NReassociationMftTracksSteps]; - labelsReassociationMftTracks[ReassociationMftTracks::NotReassociatedMftTracks] = "MFT tracks after track selection"; - labelsReassociationMftTracks[ReassociationMftTracks::ReassociatedMftTracks] = "Reassociated MFT tracks by DCAxy method"; - registry.get(HIST("Data/Mft/hReassociationMftTracks"))->SetMinimum(0); - - for (int iBin = 0; iBin < ReassociationMftTracks::NReassociationMftTracksSteps; iBin++) { - registry.get(HIST("Data/Mft/hReassociationMftTracks"))->GetXaxis()->SetBinLabel(iBin + 1, labelsReassociationMftTracks[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")); + mPairCuts.SetPairCut(PairCuts::K0, configCentral.pairCut->get("K0")); + mPairCuts.SetPairCut(PairCuts::Lambda, configCentral.pairCut->get("Lambda")); + mPairCuts.SetPairCut(PairCuts::Phi, configCentral.pairCut->get("Phi")); + mPairCuts.SetPairCut(PairCuts::Rho, configCentral.pairCut->get("Rho")); } - registry.add("Data/Mft/hNTracks", "", {HistType::kTH1F, {axisMultiplicity}}); - registry.add("Data/Mft/hNMftTracks", "", {HistType::kTH1F, {axisMultiplicity}}); - registry.add("Data/Mft/hNBestCollisionFwd", "", {HistType::kTH1F, {axisMultiplicity}}); - // ========================= // Declaration of correlation containers and their respective axis // ========================= - std::vector const corrAxis = {{axisDeltaEta, "#Delta#eta"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisMultiplicity, "multiplicity"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisVertex, "z-vtx (cm)"}}; - std::vector const effAxis = {{axisEtaEfficiency, "#eta"}, - {axisPtEfficiency, "p_{T} (GeV/c)"}, - {axisVertexEfficiency, "z-vtx (cm)"}}; - std::vector const userAxis = {{axisMass, "m_{inv} (GeV/c^{2})"}}; - - fv0Det = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); + std::vector const corrAxis = {{configAxis.axisDeltaEta, "#Delta#eta"}, + {configAxis.axisPtAssoc, "p_{T} (GeV/c)"}, + {configAxis.axisPtTrigger, "p_{T} (GeV/c)"}, + {configAxis.axisMultiplicity, "multiplicity"}, + {configAxis.axisDeltaPhi, "#Delta#varphi (rad)"}, + {configAxis.axisVertex, "z-vtx (cm)"}}; + 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})"}}; // ========================= // Initialization of histograms and CorrelationContainers for TpcTpc cases @@ -494,14 +504,7 @@ struct HfTaskFlow { // if (doprocessSameTpcMftChCh || doprocessSameTpcMftChChReassociated || doprocessSameTpcMftChChReassociated3d || doprocessSameTpcMftChChNonAmbiguous) { if (doprocessSameTpcMftChCh || doprocessSameTpcMftChChReassociated || doprocessSameTpcMftChChNonAmbiguous) { addHistograms(); - - // All MFT tracks - registry.add("Data/Mft/kCFStepAll/hEta", "eta", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add("Data/Mft/kCFStepAll/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); - - // Only non-ambiguous MFT tracks - registry.add("Data/Mft/kCFStepTracked/hEta", "eta", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add("Data/Mft/kCFStepTracked/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); + addMftHistograms(); sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); @@ -509,14 +512,7 @@ struct HfTaskFlow { if (doprocessSameTpcMftD0Ch || doprocessSameTpcMftD0ChReassociated) { addHistograms(); - - // All MFT tracks - registry.add("Data/Mft/kCFStepAll/hEta", "eta", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add("Data/Mft/kCFStepAll/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); - - // Only non-ambiguous MFT tracks - registry.add("Data/Mft/kCFStepTracked/hEta", "eta", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add("Data/Mft/kCFStepTracked/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); + addMftHistograms(); sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); @@ -524,14 +520,7 @@ struct HfTaskFlow { if (doprocessSameTpcMftLcCh || doprocessSameTpcMftLcChReassociated) { addHistograms(); - - // All MFT tracks - registry.add("Data/Mft/kCFStepAll/hEta", "eta", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add("Data/Mft/kCFStepAll/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); - - // Only non-ambiguous MFT tracks - registry.add("Data/Mft/kCFStepTracked/hEta", "eta", {HistType::kTH1D, {axisEtaAssociated}}); - registry.add("Data/Mft/kCFStepTracked/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); + addMftHistograms(); sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); @@ -569,6 +558,7 @@ struct HfTaskFlow { // if (doprocessSameMftFv0aChCh || doprocessSameMftFv0aChChReassociated || doprocessSameMftFv0aReassociated3d || doprocessSameMftFv0aChChNonAmbiguous) { if (doprocessSameMftFv0aChCh || doprocessSameMftFv0aChChReassociated || doprocessSameMftFv0aChChNonAmbiguous) { addHistograms(); + addMftHistograms(); sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); @@ -605,25 +595,46 @@ struct HfTaskFlow { if (doprocessSameMftFt0aChCh || doprocessSameMftFt0aChChReassociated || doprocessSameMftFt0aChChNonAmbiguous) { addHistograms(); + addMftHistograms(); sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); } // ========================= - // Initialization of histograms and CorrelationContainers for TpcMft MONTE-CARLO cases + // Initialization of histograms and CorrelationContainers for TpcFt0c cases // ========================= - if (doprocessSameTpcMftD0ChMcGen) { - addHistograms(); - sameEventHfMc.setObject(new CorrelationContainer("sameEventHfMc", "sameEventHfMc", corrAxis, effAxis, userAxis)); - mixedEventHfMc.setObject(new CorrelationContainer("mixedEventHfMc", "mixedEventHfMc", corrAxis, effAxis, userAxis)); + if (doprocessSameTpcFt0cChCh) { + addHistograms(); + + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); } - if (doprocessSameTpcMftLcChMcGen) { - addHistograms(); - sameEventHfMc.setObject(new CorrelationContainer("sameEventHfMc", "sameEventHfMc", corrAxis, effAxis, userAxis)); - mixedEventHfMc.setObject(new CorrelationContainer("mixedEventHfMc", "mixedEventHfMc", corrAxis, effAxis, userAxis)); + if (doprocessSameTpcFt0cD0Ch) { + addHistograms(); + + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + } + + if (doprocessSameTpcFt0cLcCh) { + addHistograms(); + + sameEventHf.setObject(new CorrelationContainer("sameEventHf", "sameEventHf", corrAxis, effAxis, userAxis)); + mixedEventHf.setObject(new CorrelationContainer("mixedEventHf", "mixedEventHf", corrAxis, effAxis, userAxis)); + } + + // ========================= + // Initialization of histograms and CorrelationContainers for Ft0aFt0c cases + // ========================= + + if (doprocessSameFt0aFt0cChCh) { + addHistograms(); + + sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); + mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); } } // End of init() function @@ -697,6 +708,45 @@ struct HfTaskFlow { } } + template + float getDPhiStar(TTrack const& track1, TTrackAssoc const& track2, float radius, int magField) + { + float charge1 = track1.sign(); + float charge2 = track2.sign(); + + float phi1 = track1.phi(); + float phi2 = track2.phi(); + + float pt1 = track1.pt(); + float pt2 = track2.pt(); + + int fbSign = (magField > 0) ? 1 : -1; + + float dPhiStar = phi1 - phi2 - charge1 * fbSign * std::asin(0.075 * radius / pt1) + charge2 * fbSign * std::asin(0.075 * radius / pt2); + + if (dPhiStar > constants::math::PI) + dPhiStar = constants::math::TwoPI - dPhiStar; + if (dPhiStar < -constants::math::PI) + dPhiStar = -constants::math::TwoPI - dPhiStar; + + return dPhiStar; + } + + int getMagneticField(uint64_t timestamp) + { + // Get the magnetic field + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("/GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + double getPhiFT0(uint chno, int i) { ft0Det.calculateChannelCenter(); @@ -735,6 +785,9 @@ struct HfTaskFlow { auto x = chPos.X() + (*offsetFT0)[i].getX(); auto y = chPos.Y() + (*offsetFT0)[i].getY(); auto z = chPos.Z() + (*offsetFT0)[i].getZ(); + if (chno >= kMinFt0cCell) { + z = -z; + } auto r = std::sqrt(x * x + y * y); auto theta = std::atan2(r, z); return -std::log(std::tan(0.5 * theta)); @@ -770,6 +823,18 @@ struct HfTaskFlow { return -std::log(std::tan(0.5 * theta)); } + template + void getChannel(TFT0s const& ft0, std::size_t const& iCh, int& id, int fitType) + { + if (fitType == isFT0C) { + id = ft0.channelC()[iCh]; + } else if (fitType == isFT0A) { + id = ft0.channelA()[iCh]; + } else { + LOGF(fatal, "Cor Index %d out of range", fitType); + } + } + // ========================= // Cuts with functions // ========================= @@ -782,23 +847,21 @@ struct HfTaskFlow { registry.fill(HIST("Data/hEventCounter"), EventSelectionStep::AllEvents); } - if (!configTask.processMc) { - if (!collision.sel8()) { - return false; - } + if (!collision.sel8()) { + return false; } - if (configCollision.isApplySameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { return false; } - if (configCollision.isApplyGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; } - if (configCollision.isApplyNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { return false; } + if (configCollision.isApplyGoodItsLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return false; + } if (fillHistograms) { registry.fill(HIST("Data/hEventCounter"), EventSelectionStep::AfterEventSelection); @@ -809,7 +872,21 @@ struct HfTaskFlow { return true; } - // TODO: Check how to put this into a Filter + template + bool isAcceptedCentralTrack(TTrack const& track) + { + if (track.tpcNClsFound() < configCentral.minTpcClusters) { + return false; + } + if (track.tpcNClsCrossedRows() < configCentral.minTpcCrossedRows) { + return false; + } + if (track.itsNCls() < configCentral.minItsClusters) { + return false; + } + return true; + } + template bool isAcceptedCandidate(TTrack const& candidate) { @@ -865,6 +942,15 @@ struct HfTaskFlow { registry.fill(HIST("Data/Mft/hMftTracksSelection"), MftTrackSelectionStep::Cluster); } + // cut on the pT of MFT tracks (for test purposes) + if (configMft.useMftPtCut && (mftTrack.pt() > configMft.ptMftTrackMax || mftTrack.pt() < configMft.ptMftTrackMin)) { + return false; + } + + if (fillHistograms) { + registry.fill(HIST("Data/Mft/hMftTracksSelection"), MftTrackSelectionStep::Pt); + } + return true; } @@ -885,76 +971,6 @@ struct HfTaskFlow { return false; } - // I am not sure if to template McParticles is useful, I'll address this when doing the MC Gen case of HF-h correlations - template - bool isAcceptedMcCandidate(TMcTrack& mcCandidate) - { - auto etaCandidate = mcCandidate.eta(); - - if constexpr (std::is_same_v) { // For now, that means we do D0 - if (std::abs(mcCandidate.flagMcMatchGen()) == 1 << aod::hf_cand_2prong::DecayType::D0ToPiK) { - - if (configCandidates.etaCandidateMax >= 0. && std::abs(etaCandidate) > configCandidates.etaCandidateMax) { - return false; - } - - if (configCandidates.yCandGenMax >= 0. && std::abs(RecoDecay::y(mcCandidate.pVector(), o2::constants::physics::MassD0)) > configCandidates.yCandGenMax) { - return false; - } - - // Later on, if I want to add prompt/non-prompt selection, below is how to select prompt only - // if (!(particle.originMcGen() == RecoDecay::OriginType::Prompt)){ - // return false; - // } - } - } else { // For now, that means we do LambdaC - if (std::abs(mcCandidate.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { - - if (configCandidates.etaCandidateMax >= 0. && std::abs(etaCandidate) > configCandidates.etaCandidateMax) { - return false; - } - - if (configCandidates.yCandGenMax >= 0. && std::abs(RecoDecay::y(mcCandidate.pVector(), o2::constants::physics::MassLambdaCPlus)) > configCandidates.yCandGenMax) { - return false; - } - - // Later on, if I want to add prompt/non-prompt selection, below is how to select prompt only - // if (!(particle.originMcGen() == RecoDecay::OriginType::Prompt)){ - // return false; - // } - } - } - - return true; - } - - // I am not sure if to template McParticles is useful, I'll address this when doing the MC Gen case of HF-h correlations - template - bool isAcceptedMftMcParticle(TMcParticle& mcParticle) - { - // remove MC particles with charge = 0 - TParticlePDG* pdgparticle = pdg->GetParticle(mcParticle.pdgCode()); - if (pdgparticle != nullptr) { - if (pdgparticle->Charge() == 0) { - return false; - } - } - - /* - // MC particle has to be primary - if constexpr (step <= CorrelationContainer::kCFStepAnaTopology) { - return mcParticle.isPhysicalPrimary(); - } - */ - - if (mcParticle.eta() > configMft.etaMftTrackMax || mcParticle.eta() < configMft.etaMftTrackMin) { - return false; - } - - // return true; - return mcParticle.isPhysicalPrimary(); - } - // =============================================================================================================================================================================== // =============================================================================================================================================================================== // Correlation functions @@ -968,20 +984,22 @@ struct HfTaskFlow { template void fillCorrelations(TTarget target, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, - float multiplicity, float posZ, bool sameEvent) + float multiplicity, float posZ, bool sameEvent, int magneticField) { auto triggerWeight = 1; auto associatedWeight = 1; - - // To avoid filling associated tracks QA many times - // I fill it only for the first trigger track of the collision - auto loopCounter = 0; + auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision // TRIGGER PARTICLE for (const auto& track1 : tracks1) { - loopCounter++; + if constexpr (std::is_same_v) { + if (!isAcceptedCentralTrack(track1)) { + continue; + } + } + float const eta1 = track1.eta(); float const pt1 = track1.pt(); float const phi1 = track1.phi(); @@ -1004,20 +1022,6 @@ struct HfTaskFlow { } } - // Selections for MC GENERATED - if constexpr (std::is_same_v || std::is_same_v) { - // TODO: Check how to put this into a Filter -> Pretty sure it cannot be a filter - if (!isAcceptedMcCandidate(track1)) { - continue; - } - fillingHFcontainer = true; - if constexpr (std::is_same_v) { // If D0 - invmass = o2::constants::physics::MassD0; - } else { // If Lc - invmass = o2::constants::physics::MassLambdaCPlus; - } - } - // fill single-track distributions if (!fillingHFcontainer) { // if not HF-h case target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, triggerWeight); @@ -1027,31 +1031,34 @@ struct HfTaskFlow { // FILL QA PLOTS for trigger particle if (sameEvent && (step == CorrelationContainer::kCFStepReconstructed)) { - if (!configTask.processMc) { // If DATA - if constexpr (!std::is_same_v) { // IF TPC-TPC case - if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-TPC D0-h - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-TPC Lc-h - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else { // IF NEITHER D0 NOR LC -> TPC-TPC h-h - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } - } else { // IF TPC-MFT case - if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-MFT D0-h - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-MFT Lc-h - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else { // IF NEITHER D0 NOR LC -> TPC-MFT h-h - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } // end of if condition for TPC-TPC or TPC-MFT case + if constexpr (!std::is_same_v) { // IF TPC-TPC case + if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-TPC D0-h + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-TPC Lc-h + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else { // IF NEITHER D0 NOR LC -> TPC-TPC h-h + fillTriggerQa(multiplicity, eta1, phi1, pt1); } - // Maybe I won't need it for MC (first files are way lighter in MC, but also I need to loop over all tracks in MC GEN) + } else { // IF TPC-MFT case + if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-MFT D0-h + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-MFT Lc-h + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else { // IF NEITHER D0 NOR LC -> TPC-MFT h-h + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } // end of if condition for TPC-TPC or TPC-MFT case } } // ASSOCIATED PARTICLE for (const auto& track2 : tracks2) { + if constexpr (std::is_same_v) { + if (!isAcceptedCentralTrack(track2)) { + continue; + } + } + // apply cuts for MFT tracks if constexpr (std::is_same_v) { @@ -1068,14 +1075,53 @@ struct HfTaskFlow { } } - // case of h-h correlations where the two types of tracks are the same - // this avoids autocorrelations and double counting of particle pairs + if (configCentral.isApplySameTrackCut && (track1 == track2)) { + continue; + } + + if (configCentral.isApplyPtOrderingSameEvent && sameEvent && (track1.pt() <= track2.pt())) { + continue; + } + if (configCentral.isApplyPtOrderingMixedEvent && !sameEvent && (track1.pt() <= track2.pt())) { + continue; + } + + if (configCentral.isApplyIndexOrdering && (track1.index() <= track2.index())) { + continue; + } + + // I have to add this condition, because ConversionCut is template to get the same type of tracks for both tracks if constexpr (std::is_same_v) { - if (track1.index() <= track2.index()) { + if (configCentral.isApplyConversionCut && mPairCuts.conversionCuts(track1, track2)) { continue; } } + // I have to add this condition, because PhiStar need track1.sign() + if constexpr (std::is_same_v) { + if (configCentral.isApplyTwoTrackCut && std::abs(eta1 - track2.eta()) < configCentral.mergingCut) { + + double dPhiStarHigh = getDPhiStar(track1, track2, configCentral.maxMergingRadius, magneticField); + double dPhiStarLow = getDPhiStar(track1, track2, configCentral.minMergingRadius, magneticField); + + const double kLimit = 3.0 * configCentral.mergingCut; + + bool bIsBelow = false; + + if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { + for (double rad(configCentral.minMergingRadius); rad < configCentral.maxMergingRadius; rad += 0.01) { + double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); + if (std::abs(dPhiStar) < kLimit) { + bIsBelow = true; + break; + } + } + if (bIsBelow) + continue; + } + } + } + // in case of HF-h correlations, remove candidate daughters from the pool of associated hadrons // with which the candidate is being correlated (will not have to do it for TPC-MFT case) if constexpr (!std::is_same_v) { // if NOT TPC-MFT case -> TPC-TPC case @@ -1091,14 +1137,6 @@ struct HfTaskFlow { } } - // in case of MC-generated, do additional selection on MCparticles : charge and isPhysicalPrimary - // if (configTask.processMc) { - if constexpr (std::is_same_v || std::is_same_v) { - if (!isAcceptedMftMcParticle(track2)) { - continue; - } - } - float const eta2 = track2.eta(); float const pt2 = track2.pt(); float phi2 = track2.phi(); @@ -1106,8 +1144,6 @@ struct HfTaskFlow { // TODO: add getter for NUE associated efficiency here - // TODO: add pair cuts on phi* - float deltaPhi = phi1 - phi2; // set range of delta phi in (-pi/2 , 3/2*pi) deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); @@ -1128,25 +1164,23 @@ struct HfTaskFlow { fillAssociatedQa(multiplicity, eta2, phi2); } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-TPC Lc-h fillAssociatedQa(multiplicity, eta2, phi2); + } else { + fillAssociatedQa(multiplicity, eta2, phi2); } - // No if condition if it is h-h, because it would be the same plots than for the trigger particle } else { // IF TPC-MFT case if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-MFT D0-h fillAssociatedQa(multiplicity, eta2, phi2); + registry.fill(HIST("Data/Mft/hPtMft"), pt2); } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-MFT Lc-h fillAssociatedQa(multiplicity, eta2, phi2); + registry.fill(HIST("Data/Mft/hPtMft"), pt2); } else { // IF NEITHER D0 NOR LC -> TPC-MFT h-h fillAssociatedQa(multiplicity, eta2, phi2); + registry.fill(HIST("Data/Mft/hPtMft"), pt2); } // end of if condition for TPC-TPC or TPC-MFT case } } - if (sameEvent && (loopCounter == 1) && std::is_same_v) { - // FILL USUAL MFT DISTRIBUTIONS - registry.fill(HIST("Data/Mft/kCFStepAll/hEta"), eta2); - registry.fill(HIST("Data/Mft/kCFStepAll/hPhi"), phi2); - } - } // end of loop over tracks2 } // end of loop over tracks 1 } @@ -1158,16 +1192,18 @@ struct HfTaskFlow { { auto triggerWeight = 1; auto associatedWeight = 1; - - // To avoid filling associated tracks QA many times - // I fill it only for the first trigger track of the collision - auto loopCounter = 0; + auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision // TRIGGER PARTICLE for (const auto& track1 : tracks1) { - loopCounter++; + if constexpr (std::is_same_v) { + if (!isAcceptedCentralTrack(track1)) { + continue; + } + } + float const eta1 = track1.eta(); float const pt1 = track1.pt(); float const phi1 = track1.phi(); @@ -1194,7 +1230,7 @@ struct HfTaskFlow { } // FILL QA PLOTS for trigger particle - if (sameEvent && (!cutAmbiguousTracks)) { + if (sameEvent && (cutAmbiguousTracks == false)) { if constexpr (std::is_same_v) { fillTriggerQa(multiplicity, eta1, phi1, pt1); } else if constexpr (std::is_same_v) { @@ -1221,13 +1257,15 @@ struct HfTaskFlow { // Fill QA plot for MFT tracks after physical selection (eta + clusters) if (!cutAmbiguousTracks && sameEvent && (loopCounter == 1)) { registry.fill(HIST("Data/Mft/hAmbiguityOfMftTracks"), MftTrackAmbiguityStep::AfterTrackSelection); - registry.fill(HIST("Data/Mft/hReassociationMftTracks"), ReassociationMftTracks::NotReassociatedMftTracks); } // We check if the track is ambiguous or non-ambiguous (QA plots are filled in isAmbiguousMftTrack) // Fill plots only if cutAmbiguousTracks is false (to avoid double counting) if (isAmbiguousMftTrack(track2, (!cutAmbiguousTracks && sameEvent && (loopCounter == 1)))) { // If the MFT track is ambiguous we may cut or not on the ambiguous track + if (sameEvent && (loopCounter == 1)) { + registry.fill(HIST("Data/Mft/hReassociationMftTracks"), ReassociationMftTracks::NotReassociatedMftTracks); + } if (cutAmbiguousTracks) { continue; } @@ -1252,15 +1290,28 @@ struct HfTaskFlow { } } - float const eta2 = reassociatedMftTrack.eta(); - float const pt2 = reassociatedMftTrack.pt(); + if (configCentral.isApplySameTrackCut && (track1 == reassociatedMftTrack)) { + continue; + } + + if (configCentral.isApplyPtOrderingSameEvent && sameEvent && (track1.pt() <= reassociatedMftTrack.pt())) { + continue; + } + if (configCentral.isApplyPtOrderingMixedEvent && !sameEvent && (track1.pt() <= reassociatedMftTrack.pt())) { + continue; + } + + if (configCentral.isApplyIndexOrdering && (track1.index() <= reassociatedMftTrack.index())) { + continue; + } + + float eta2 = reassociatedMftTrack.eta(); + float pt2 = reassociatedMftTrack.pt(); float phi2 = reassociatedMftTrack.phi(); o2::math_utils::bringTo02Pi(phi2); // TODO: add getter for NUE associated efficiency here - // TODO: add pair cuts on phi* - float deltaPhi = phi1 - phi2; // set range of delta phi in (-pi/2 , 3/2*pi) deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); @@ -1277,19 +1328,15 @@ struct HfTaskFlow { if (sameEvent && (loopCounter == 1) && (!cutAmbiguousTracks)) { if constexpr (std::is_same_v) { fillAssociatedQa(multiplicity, eta2, phi2); + registry.fill(HIST("Data/Mft/hPtMft"), pt2); } else if constexpr (std::is_same_v) { fillAssociatedQa(multiplicity, eta2, phi2); + registry.fill(HIST("Data/Mft/hPtMft"), pt2); } else { fillAssociatedQa(multiplicity, eta2, phi2); + registry.fill(HIST("Data/Mft/hPtMft"), pt2); } - } - - // QA plots for basic MFT distributions for non-ambiguous tracks only (kCFStepTracked) - if (cutAmbiguousTracks && sameEvent && (loopCounter == 1)) { - registry.fill(HIST("Data/Mft/kCFStepTracked/hEta"), eta2); - registry.fill(HIST("Data/Mft/kCFStepTracked/hPhi"), phi2); - } - + } // end of fill QA } // end of loop over tracks2 } // end of loop over tracks 1 } @@ -1297,20 +1344,26 @@ struct HfTaskFlow { template void fillCorrelationsFIT(TTarget target, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, TFits const&, - float multiplicity, float posZ, bool sameEvent) + float multiplicity, float posZ, bool sameEvent, int fitType) { auto triggerWeight = 1; auto associatedWeight = 1; - - // To avoid filling associated tracks QA many times - // I fill it only for the first trigger track of the collision - auto loopCounter = 0; + auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision // TRIGGER PARTICLE for (auto const& track1 : tracks1) { - loopCounter++; + if constexpr (std::is_same_v) { + if (!isAcceptedCentralTrack(track1)) { + continue; + } + } else if constexpr (std::is_same_v) { + if (!isAcceptedMftTrack(track1, true)) { + continue; + } + } + float const eta1 = track1.eta(); float const pt1 = track1.pt(); float phi1 = track1.phi(); @@ -1341,29 +1394,44 @@ struct HfTaskFlow { // FILL QA PLOTS for trigger particle if (sameEvent && (step == CorrelationContainer::kCFStepReconstructed)) { - if (!configTask.processMc) { // If DATA - if constexpr (!std::is_same_v) { // If not FilteredMftTracks as trigger -> TPC-FV0a correlations - if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-FV0a D0-h - if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC -> - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else if constexpr (std::is_same_v) { + if constexpr (!std::is_same_v) { // If not FilteredMftTracks as trigger -> TPC-FV0a correlations + if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-FV0a D0-h + if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC -> + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else if constexpr (std::is_same_v) { + if (fitType == isFT0A) { fillTriggerQa(multiplicity, eta1, phi1, pt1); } - } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-FV0a Lc-h - if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC -> - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else if constexpr (std::is_same_v) { - fillTriggerQa(multiplicity, eta1, phi1, pt1); + if (fitType == isFT0C) { + fillTriggerQa(multiplicity, eta1, phi1, pt1); } - } else if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC - - fillTriggerQa(multiplicity, eta1, phi1, pt1); + } + } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-FV0a Lc-h + if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC -> + fillTriggerQa(multiplicity, eta1, phi1, pt1); } else if constexpr (std::is_same_v) { + if (fitType == isFT0A) { + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } + if (fitType == isFT0C) { + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } + } + } else if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC - + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else if constexpr (std::is_same_v) { + if (fitType == isFT0A) { fillTriggerQa(multiplicity, eta1, phi1, pt1); } - } else { // If FilteredMftTracks as trigger - if constexpr (std::is_same_v) { - fillTriggerQa(multiplicity, eta1, phi1, pt1); - } else if constexpr (std::is_same_v) { + if (fitType == isFT0C) { + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } + } + } else { // If FilteredMftTracks as trigger + if constexpr (std::is_same_v) { + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } else if constexpr (std::is_same_v) { + if (fitType == isFT0A) { fillTriggerQa(multiplicity, eta1, phi1, pt1); } } @@ -1375,17 +1443,10 @@ struct HfTaskFlow { for (std::size_t indexChannel = 0; indexChannel < tracks2.channel().size(); indexChannel++) { auto channelId = tracks2.channel()[indexChannel]; - // float fv0Amplitude = tracks2.amplitude()[indexChannel]; - // if (fv0Amplitude <= 0) { - // continue; - // } - auto phi2 = getPhiFV0(channelId); auto eta2 = getEtaFV0(channelId); - float deltaPhi = phi1 - phi2; - // set range of delta phi in (-pi/2 , 3/2*pi) - deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); + 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, @@ -1414,20 +1475,25 @@ struct HfTaskFlow { // ASSOCIATED PARTICLE IF USING FT0 if constexpr (std::is_same_v) { - for (std::size_t indexChannel = 0; indexChannel < tracks2.channelA().size(); indexChannel++) { - auto channelId = tracks2.channelA()[indexChannel]; - // float fv0Amplitude = tracks2.amplitudeA()[indexChannel]; - // if (fv0Amplitude <= 0) { - // continue; - // } + // select the right channel size if it is FT0a or FT0c + std::size_t channelSize = 0; + if (fitType == isFT0C) { + channelSize = tracks2.channelC().size(); + } else if (fitType == isFT0A) { + channelSize = tracks2.channelA().size(); + } else { + LOGF(fatal, "Cor Index %d out of range", fitType); + } - auto phi2 = getPhiFT0(channelId, 0); - auto eta2 = getEtaFT0(channelId, 0); + for (std::size_t indexChannel = 0; indexChannel < channelSize; indexChannel++) { + int channelId = 0; + getChannel(tracks2, indexChannel, channelId, fitType); + auto phi2 = getPhiFT0(channelId, fitType); + auto eta2 = getEtaFT0(channelId, fitType); float deltaPhi = phi1 - phi2; - // set range of delta phi in (-pi/2 , 3/2*pi) - deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); + 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, @@ -1441,14 +1507,31 @@ struct HfTaskFlow { if (sameEvent && (loopCounter == 1) && (step == CorrelationContainer::kCFStepReconstructed)) { if constexpr (!std::is_same_v) { // If not FilteredMftTracks as trigger -> TPC-Ft0a correlations if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-FV0a D0-h - fillAssociatedQa(multiplicity, eta2, phi2); + if (fitType == isFT0A) { + fillAssociatedQa(multiplicity, eta2, phi2); + } + if (fitType == isFT0C) { + fillAssociatedQa(multiplicity, eta2, phi2); + } } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-FV0a Lc-h - fillAssociatedQa(multiplicity, eta2, phi2); + if (fitType == isFT0A) { + fillAssociatedQa(multiplicity, eta2, phi2); + } + if (fitType == isFT0C) { + fillAssociatedQa(multiplicity, eta2, phi2); + } } else if constexpr (std::is_same_v) { // IF NEITHER D0 NOR LC -> ch. part. - ch. part - fillAssociatedQa(multiplicity, eta2, phi2); + if (fitType == isFT0A) { + fillAssociatedQa(multiplicity, eta2, phi2); + } + if (fitType == isFT0C) { + fillAssociatedQa(multiplicity, eta2, phi2); + } } } else if constexpr (std::is_same_v) { // If FilteredMftTracks as trigger -> MFT-Ft0a (non reassoc/ambiguous) correlations - fillAssociatedQa(multiplicity, eta2, phi2); + if (fitType == isFT0A) { + fillAssociatedQa(multiplicity, eta2, phi2); + } } } // end of if condition to fill QA plots for associated particle } // end of loop over FT0 channel indices @@ -1459,14 +1542,11 @@ struct HfTaskFlow { template void fillCorrelationsFITReassociatedMftTracks(TTarget target, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, TFits const&, - float multiplicity, float posZ, bool sameEvent, bool cutAmbiguousTracks) + float multiplicity, float posZ, bool sameEvent, bool cutAmbiguousTracks, int fitType) { auto triggerWeight = 1; auto associatedWeight = 1; - - // To avoid filling associated tracks QA many times - // I fill it only for the first trigger track of the collision - auto loopCounter = 0; + auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision // TRIGGER PARTICLE for (auto const& track1 : tracks1) { @@ -1474,14 +1554,11 @@ struct HfTaskFlow { auto reassociatedMftTrack = track1.template mfttrack_as(); - if (!isAcceptedMftTrack(reassociatedMftTrack, false)) { + if (!isAcceptedMftTrack(reassociatedMftTrack, true)) { continue; } - // We check if the track is ambiguous or non-ambiguous (QA plots are filled in isAmbiguousMftTrack) - // Fill plots only if cutAmbiguousTracks is false (to avoid double counting) if (isAmbiguousMftTrack(track1, false)) { - // If the MFT track is ambiguous we may cut or not on the ambiguous track if (cutAmbiguousTracks) { continue; } @@ -1499,7 +1576,9 @@ struct HfTaskFlow { if constexpr (std::is_same_v) { fillTriggerQa(multiplicity, eta1, phi1, pt1); } else if constexpr (std::is_same_v) { - fillTriggerQa(multiplicity, eta1, phi1, pt1); + if (fitType == isFT0A) { + fillTriggerQa(multiplicity, eta1, phi1, pt1); + } } } // end of if condition to fill QA plots for trigger particle @@ -1508,17 +1587,11 @@ struct HfTaskFlow { for (std::size_t indexChannel = 0; indexChannel < tracks2.channel().size(); indexChannel++) { auto channelId = tracks2.channel()[indexChannel]; - // float fv0Amplitude = tracks2.amplitude()[indexChannel]; - // if (fv0Amplitude <= 0) { - // continue; - // } - auto phi2 = getPhiFV0(channelId); auto eta2 = getEtaFV0(channelId); float deltaPhi = phi1 - phi2; - // set range of delta phi in (-pi/2 , 3/2*pi) - deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); + 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); @@ -1532,33 +1605,82 @@ struct HfTaskFlow { // ASSOCIATED PARTICLE FOR FT0s if constexpr (std::is_same_v) { - for (std::size_t indexChannel = 0; indexChannel < tracks2.channelA().size(); indexChannel++) { - auto channelId = tracks2.channelA()[indexChannel]; - // float ft0Amplitude = tracks2.amplitudeA()[indexChannel]; - // if (ft0Amplitude <= 0) { - // continue; - // } + // select the right channel size if it is FT0a or FT0c + std::size_t channelSize = 0; + if (fitType == isFT0C) { + channelSize = tracks2.channelC().size(); + } else if (fitType == isFT0A) { + channelSize = tracks2.channelA().size(); + } else { + LOGF(fatal, "Cor Index %d out of range", fitType); + } - auto phi2 = getPhiFT0(channelId, 0); - auto eta2 = getEtaFT0(channelId, 0); + for (std::size_t indexChannel = 0; indexChannel < channelSize; indexChannel++) { + int channelId = 0; + getChannel(tracks2, indexChannel, channelId, fitType); + auto phi2 = getPhiFT0(channelId, fitType); + auto eta2 = getEtaFT0(channelId, fitType); float deltaPhi = phi1 - phi2; - // set range of delta phi in (-pi/2 , 3/2*pi) - deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); + 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); // FILL QA PLOTS for associated particle if (sameEvent && (loopCounter == 1) && (step == CorrelationContainer::kCFStepReconstructed)) { - fillAssociatedQa(multiplicity, eta2, phi2); + if (fitType == isFT0A) { + fillAssociatedQa(multiplicity, eta2, phi2); + } } // end of if condition to fill QA plots for associated particle } // end of loop over FT0 channel indices } // end of if condition for FT0s } // end of loop over tracks 1 } + template + void fillCorrelationsFt0aFt0c(TTarget target, CorrelationContainer::CFStep step, + TFT0As const& ft0as, TFT0Cs const& ft0cs, + float multiplicity, float posZ, bool sameEvent) + { + 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 + + // TRIGGER PARTICLE FROM FT0A + for (std::size_t indexChannelA = 0; indexChannelA < ft0as.channelA().size(); indexChannelA++) { + loopCounter++; + int channelIdA = 0; + getChannel(ft0as, indexChannelA, channelIdA, isFT0A); + auto phiA = getPhiFT0(channelIdA, isFT0A); + auto etaA = getEtaFT0(channelIdA, isFT0A); + + target->getTriggerHist()->Fill(step, 0.f, multiplicity, posZ, triggerWeight); + + if (sameEvent && (step == CorrelationContainer::kCFStepReconstructed)) { + fillTriggerQa(multiplicity, etaA, phiA, 0.f); + } // end of fill trigger QA + + // ASSOCIATED PARTICLE FROM FT0C + for (std::size_t indexChannelC = 0; indexChannelC < ft0cs.channelC().size(); indexChannelC++) { + + int channelIdC = 0; + getChannel(ft0cs, indexChannelC, channelIdC, isFT0C); + 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); + + if (sameEvent && (loopCounter == 1) && (step == CorrelationContainer::kCFStepReconstructed)) { + fillAssociatedQa(multiplicity, etaC, phiC); + } // end of fill associated QA + } // end of associated loop + } // end of trigger loop + } // end of fillCorrelationsFt0aFt0c + // =============================================================================================================================================================================== // mixCollisions for RECONSTRUCTED events // =============================================================================================================================================================================== @@ -1566,7 +1688,7 @@ struct HfTaskFlow { template void mixCollisions(TCollisions const& collisions, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, - OutputObj& corrContainer) + OutputObj& corrContainer, aod::BCsWithTimestamps const&) { auto getMultiplicity = [this](FilteredCollisionsWSelMult::iterator const& collision) { auto multiplicity = getMultiplicityEstimator(collision, false); @@ -1576,32 +1698,35 @@ struct HfTaskFlow { // The first one that I call "Data" should work for data and mc rec using BinningTypeData = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getMultiplicity)>; - BinningTypeData const binningWithTracksSize{{getMultiplicity}, {binsMixingVertex, binsMixingMultiplicity}, true}; + BinningTypeData binningWithTracksSize{{getMultiplicity}, {configAxis.binsMixingVertex, configAxis.binsMixingMultiplicity}, true}; auto tracksTuple = std::make_tuple(tracks1, tracks2); - Pair const pair{binningWithTracksSize, configTask.nMixedEvents, -1, collisions, tracksTuple, &cache}; + Pair pair{binningWithTracksSize, configTask.nMixedEvents, -1, collisions, tracksTuple, &cache}; for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { - if constexpr (!std::is_same_v) { // if NOT MC -> do collision cut - if (!(isAcceptedCollision(collision1, false))) { - continue; - } - if (!(isAcceptedCollision(collision2, false))) { - continue; - } + if (!(isAcceptedCollision(collision1, false))) { + continue; + } + if (!(isAcceptedCollision(collision2, false))) { + continue; } + auto bc = collision1.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision1, false); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + corrContainer->fillEvent(multiplicity, step); - fillCorrelations(corrContainer, step, tracks1, tracks2, multiplicity, collision1.posZ(), false); + fillCorrelations(corrContainer, step, tracks1, tracks2, multiplicity, collision1.posZ(), false, getMagneticField(bc.timestamp())); } } template void mixCollisionsFIT(TCollisions const& collisions, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, TPreslice const& preslice, - OutputObj& corrContainer) + OutputObj& corrContainer, int fitType) { auto getMultiplicity = [this](FilteredCollisionsWSelMult::iterator const& collision) { auto multiplicity = getMultiplicityEstimator(collision, false); @@ -1609,7 +1734,7 @@ struct HfTaskFlow { }; using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getMultiplicity)>; - MixedBinning const binningOnVtxAndMult{{getMultiplicity}, {binsMixingVertex, binsMixingMultiplicity}, true}; + MixedBinning const binningOnVtxAndMult{{getMultiplicity}, {configAxis.binsMixingVertex, configAxis.binsMixingMultiplicity}, true}; for (auto const& [collision1, collision2] : soa::selfCombinations(binningOnVtxAndMult, configTask.nMixedEvents, -1, collisions, collisions)) { @@ -1625,12 +1750,15 @@ struct HfTaskFlow { if (collision1.has_foundFV0() && collision2.has_foundFV0()) { const auto multiplicity = getMultiplicityEstimator(collision1, false); - auto slicedTriggerTracks = tracks1.sliceBy(preslice, collision1.globalIndex()); const auto& fv0 = collision2.foundFV0(); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + corrContainer->fillEvent(multiplicity, step); - fillCorrelationsFIT(corrContainer, step, slicedTriggerTracks, fv0, tracks2, multiplicity, collision1.posZ(), false); + fillCorrelationsFIT(corrContainer, step, slicedTriggerTracks, fv0, tracks2, multiplicity, collision1.posZ(), false, fitType); } } // end of if condition for FV0s @@ -1638,74 +1766,53 @@ struct HfTaskFlow { if (collision1.has_foundFT0() && collision2.has_foundFT0()) { const auto multiplicity = getMultiplicityEstimator(collision1, false); - auto slicedTriggerTracks = tracks1.sliceBy(preslice, collision1.globalIndex()); const auto& ft0 = collision2.foundFT0(); corrContainer->fillEvent(multiplicity, step); - fillCorrelationsFIT(corrContainer, step, slicedTriggerTracks, ft0, tracks2, multiplicity, collision1.posZ(), false); + fillCorrelationsFIT(corrContainer, step, slicedTriggerTracks, ft0, tracks2, multiplicity, collision1.posZ(), false, fitType); } - } // end of if condition for FT0s + } // end of if condition for TPC-FT0 or MFT-FT0s } // end of for loop } - /* - template - void mixCollisionsReassociatedMftTracks(TCollisions const& collisions, int step, - TTracksTrig const& tracks1, TTracksAssoc const& tracks2, - TLambda getPartsSize, - OutputObj& corrContainer, - bool cutAmbiguousTracks) + template + void mixCollisionsFt0aFt0c(TCollisions const& collisions, CorrelationContainer::CFStep step, + TFT0as const&, TFT0cs const&, + OutputObj& corrContainer) { + auto getMultiplicity = [this](FilteredCollisionsWSelMult::iterator const& collision) { + auto multiplicity = getMultiplicityEstimator(collision, false); + return multiplicity; + }; - // The first one that I call "Data" should work for data and mc rec - using BinningTypeData = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getPartsSize)>; - - BinningTypeData binningWithTracksSize{{getPartsSize}, {binsMixingVertex, binsMixingMultiplicity}, true}; - auto tracksTuple = std::make_tuple(tracks1, tracks2); - Pair pair{binningWithTracksSize, configTask.nMixedEvents, -1, collisions, tracksTuple, &cache}; + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getMultiplicity)>; + MixedBinning const binningOnVtxAndMult{{getMultiplicity}, {configAxis.binsMixingVertex, configAxis.binsMixingMultiplicity}, true}; - for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { + for (auto const& [collision1, collision2] : soa::selfCombinations(binningOnVtxAndMult, configTask.nMixedEvents, -1, collisions, collisions)) { - if constexpr (!std::is_same_v) { // if NOT MC -> do collision cut - if (!(isAcceptedCollision(collision1, false))) { - continue; - } - if (!(isAcceptedCollision(collision2, false))) { - continue; - } + if (!isAcceptedCollision(collision1) || !isAcceptedCollision(collision2)) { + continue; } - const auto multiplicity = collision1.multNTracksPV(); - - corrContainer->fillEvent(multiplicity, step); - fillCorrelationsReassociatedMftTracks(corrContainer, step, tracks1, tracks2, true, multiplicity, collision1.posZ(), false, cutAmbiguousTracks, field ); - } - } - */ - - // =============================================================================================================================================================================== - // mixCollisions for GENERATED events - // =============================================================================================================================================================================== - - template - void mixCollisionsMcTruth(TMcCollisions const& mcCollisions, - TTracksTrig const& tracks1, TTracksAssoc const& tracks2, - TLambda getPartsSize, OutputObj& corrContainer) - { - using BinningTypeMcTruth = FlexibleBinningPolicy, aod::mccollision::PosZ, decltype(getPartsSize)>; + if (collision1.globalIndex() == collision2.globalIndex()) { + continue; + } - BinningTypeMcTruth const binningWithTracksSize{{getPartsSize}, {binsMixingVertex, binsMixingMultiplicity}, true}; - auto tracksTuple = std::make_tuple(tracks1, tracks2); - Pair const pair{binningWithTracksSize, configTask.nMixedEvents, -1, mcCollisions, tracksTuple, &cache}; + if (collision1.has_foundFT0() && collision2.has_foundFT0()) { - for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { + const auto multiplicity = getMultiplicityEstimator(collision1, false); + const auto& ft0as = collision1.foundFT0(); + const auto& ft0cs = collision2.foundFT0(); - const auto multiplicity = collision1.multMCPVz(); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } - corrContainer->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); - fillCorrelations(corrContainer, CorrelationContainer::CFStep::kCFStepAll, tracks1, tracks2, multiplicity, collision1.posZ(), false); - } + corrContainer->fillEvent(multiplicity, step); + fillCorrelationsFt0aFt0c(corrContainer, step, ft0as, ft0cs, multiplicity, collision1.posZ(), true); + } + } // end of for loop } // =================================================================================================================================================================================================================================================================== @@ -1723,22 +1830,23 @@ struct HfTaskFlow { // ===================================== void processSameTpcTpcChCh(FilteredCollisionsWSelMult::iterator const& collision, - FilteredTracksWDcaSel const& tracks) + FilteredTracksWDcaSel const& tracks, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } - // the event histograms below are only filled for h-h case - // because there is a possibility of double-filling if more correlation - // options are ran at the same time - // temporary solution, since other correlation options always have to be ran with h-h, too - // TODO: rewrite it in a more intelligent way + registry.fill(HIST("Data/hNTracks"), tracks.size()); + auto bc = collision.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision, true); - // registry.fill(HIST(Form("Data/hMultiplicity_%s", WhatMultiplicityEstimator[HfTaskFlow::configCollision.multiplicityEstimator].data())), multiplicity); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, tracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, tracks, multiplicity, collision.posZ(), true, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(HfTaskFlow, processSameTpcTpcChCh, "DATA : Process same-event correlations for TPC-TPC h-h case", false); @@ -1748,7 +1856,8 @@ struct HfTaskFlow { void processSameTpcTpcD0Ch(FilteredCollisionsWSelMult::iterator const& collision, FilteredTracksWDcaSel const& tracks, - HfCandidatesSelD0 const& candidates) + HfCandidatesSelD0 const& candidates, + aod::BCsWithTimestamps const&) { auto fillEventSelectionPlots = true; @@ -1761,10 +1870,16 @@ struct HfTaskFlow { return; } + registry.fill(HIST("Data/hNTracks"), tracks.size()); + auto bc = collision.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision, true); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, tracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, tracks, multiplicity, collision.posZ(), true, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(HfTaskFlow, processSameTpcTpcD0Ch, "DATA : Process same-event correlations for TPC-TPC D0-h case", false); @@ -1774,7 +1889,8 @@ struct HfTaskFlow { void processSameTpcTpcLcCh(FilteredCollisionsWSelMult::iterator const& collision, FilteredTracksWDcaSel const& tracks, - HfCandidatesSelLc const& candidates) + HfCandidatesSelLc const& candidates, + aod::BCsWithTimestamps const&) { auto fillEventSelectionPlots = true; @@ -1787,10 +1903,16 @@ struct HfTaskFlow { return; } + registry.fill(HIST("Data/hNTracks"), tracks.size()); + auto bc = collision.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision, true); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, tracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, tracks, multiplicity, collision.posZ(), true, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(HfTaskFlow, processSameTpcTpcLcCh, "DATA : Process same-event correlations for TPC-TPC Lc-h case", false); @@ -1800,18 +1922,23 @@ struct HfTaskFlow { void processSameTpcMftChCh(FilteredCollisionsWSelMult::iterator const& collision, FilteredTracksWDcaSel const& tracks, - FilteredMftTracks const& mftTracks) + FilteredMftTracks const& mftTracks, + aod::BCsWithTimestamps const&) { if (!(isAcceptedCollision(collision, true))) { return; } + registry.fill(HIST("Data/hNTracks"), tracks.size()); + auto bc = collision.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision, true); - // I use kCFStepAll for running my code with all MFTTracks were the reassociation process was not applied - // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, mftTracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, mftTracks, multiplicity, collision.posZ(), true, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftChCh, "DATA : Process same-event correlations for TPC-MFT h-h case", false); @@ -1824,14 +1951,15 @@ struct HfTaskFlow { return; } - registry.fill(HIST("Data/Mft/hNTracks"), tracks.size()); + registry.fill(HIST("Data/hNTracks"), tracks.size()); registry.fill(HIST("Data/Mft/hNMftTracks"), mftTracks.size()); registry.fill(HIST("Data/Mft/hNBestCollisionFwd"), reassociatedMftTracks.size()); - - // const auto multiplicity = collision.multNTracksPV(); const auto multiplicity = getMultiplicityEstimator(collision, true); - // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); } @@ -1847,14 +1975,17 @@ struct HfTaskFlow { return; } - registry.fill(HIST("Data/Mft/hNTracks"), tracks.size()); + registry.fill(HIST("Data/hNTracks"), tracks.size()); registry.fill(HIST("Data/Mft/hNMftTracks"), mftTracks.size()); registry.fill(HIST("Data/Mft/hNBestCollisionFwd"), reassociatedMftTracks.size()); // const auto multiplicity = collision.multNTracksPV(); const auto multiplicity = getMultiplicityEstimator(collision, true); - // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); } @@ -1870,15 +2001,15 @@ struct HfTaskFlow { return; // when process function has iterator } - registry.fill(HIST("Data/Mft/hNTracks"), tracks.size()); + registry.fill(HIST("Data/hNTracks"), tracks.size()); registry.fill(HIST("Data/Mft/hNMftTracks"), mftTracks.size()); registry.fill(HIST("Data/Mft/hNBestCollisionFwd"), reassociatedMftTracks.size()); - const auto multiplicity = getMultiplicityEstimator(collision, true); - // I use kCFStepTracked for running my code with only non-ambiguous MFTTracks - // This is the same as running with reassociatedMftTracks, but applying one more cut in the fillCorrelations function - // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), true, true); } @@ -1891,7 +2022,8 @@ struct HfTaskFlow { void processSameTpcMftD0Ch(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelD0 const& candidates, FilteredTracksWDcaSel const& /*tracks*/, - FilteredMftTracks const& mftTracks) + FilteredMftTracks const& mftTracks, + aod::BCsWithTimestamps const&) { auto fillEventSelectionPlots = true; @@ -1904,10 +2036,15 @@ struct HfTaskFlow { return; } + auto bc = collision.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision, true); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, mftTracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, mftTracks, multiplicity, collision.posZ(), true, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftD0Ch, "DATA : Process same-event correlations for TPC-MFT D0-h case", false); @@ -1922,7 +2059,10 @@ struct HfTaskFlow { const auto multiplicity = getMultiplicityEstimator(collision, true); - // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); fillCorrelationsReassociatedMftTracks(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); } @@ -1935,7 +2075,8 @@ struct HfTaskFlow { void processSameTpcMftLcCh(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelLc const& candidates, FilteredTracksWDcaSel const& /*tracks*/, - FilteredMftTracks const& mftTracks) + FilteredMftTracks const& mftTracks, + aod::BCsWithTimestamps const&) { auto fillEventSelectionPlots = true; @@ -1948,10 +2089,15 @@ struct HfTaskFlow { return; } + auto bc = collision.template bc_as(); const auto multiplicity = getMultiplicityEstimator(collision, true); + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, mftTracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, mftTracks, multiplicity, collision.posZ(), true, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftLcCh, "DATA : Process same-event correlations for TPC-MFT Lc-h case", false); @@ -1966,7 +2112,10 @@ struct HfTaskFlow { const auto multiplicity = getMultiplicityEstimator(collision, true); - // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); fillCorrelationsReassociatedMftTracks(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); } @@ -1984,13 +2133,18 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + registry.fill(HIST("Data/hNTracks"), tracks.size()); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, fv0, fv0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, fv0, fv0as, multiplicity, collision.posZ(), true, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameTpcFv0aChCh, "DATA : Process same-event correlations for TPC-FV0-A h-h case", false); @@ -2007,13 +2161,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, fv0, fv0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, fv0, fv0as, multiplicity, collision.posZ(), true, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameTpcFv0aD0Ch, "DATA : Process same-event correlations for TPC-FV0-A D0-h case", false); @@ -2030,13 +2187,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, fv0, fv0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, fv0, fv0as, multiplicity, collision.posZ(), true, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameTpcFv0aLcCh, "DATA : Process same-event correlations for TPC-FV0-A Lc-h case", false); @@ -2053,13 +2213,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, mftTracks, fv0, fv0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, mftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFv0aChCh, "DATA : Process same-event correlations for MFT-FV0-A h-h case", false); @@ -2073,13 +2236,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, false); + fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, false, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFv0aChChReassociated, "DATA : Process same-event correlations for MFT-FV0a h-h case reassociated", false); @@ -2094,13 +2260,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, false); + fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, false, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFv0aChChReassociated3d, "DATA : Process same-event correlations for MFT-FV0a h-h case 3d reassociated", false); @@ -2115,13 +2284,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFV0()) { const auto& fv0 = collision.foundFV0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, true); + fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, fv0, fv0as, multiplicity, collision.posZ(), true, true, isFV0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFv0aChChNonAmbiguous, "DATA : Process same-event correlations for MFT-FV0a h-h non-ambiguous case", false); @@ -2138,19 +2310,23 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFT0()) { const auto& ft0 = collision.foundFT0(); + registry.fill(HIST("Data/hNTracks"), tracks.size()); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, ft0, ft0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, ft0, ft0as, multiplicity, collision.posZ(), true, isFT0A); } } PROCESS_SWITCH(HfTaskFlow, processSameTpcFt0aChCh, "DATA : Process same-event correlations for TPC-FT0-A h-h case", false); // ===================================== - // DATA : process same event correlations: TPC-FT0A Ch. Part. - Ch. Part + // DATA : process same event correlations: TPC-FT0A D0 - Ch. Part // ===================================== void processSameTpcFt0aD0Ch(FilteredCollisionsWSelMult::iterator const& collision, @@ -2161,19 +2337,22 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFT0()) { const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, ft0, ft0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, ft0, ft0as, multiplicity, collision.posZ(), true, isFT0A); } } PROCESS_SWITCH(HfTaskFlow, processSameTpcFt0aD0Ch, "DATA : Process same-event correlations for TPC-FT0-A D0-h case", false); // ===================================== - // DATA : process same event correlations: TPC-FT0A Ch. Part. - Ch. Part + // DATA : process same event correlations: TPC-FT0A Lc - Ch. Part // ===================================== void processSameTpcFt0aLcCh(FilteredCollisionsWSelMult::iterator const& collision, @@ -2184,13 +2363,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFT0()) { const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, ft0, ft0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, ft0, ft0as, multiplicity, collision.posZ(), true, isFT0A); } } PROCESS_SWITCH(HfTaskFlow, processSameTpcFt0aLcCh, "DATA : Process same-event correlations for TPC-FT0-A Lc-h case", false); @@ -2207,13 +2389,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFT0()) { const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, mftTracks, ft0, ft0as, multiplicity, collision.posZ(), true); + fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, mftTracks, ft0, ft0as, multiplicity, collision.posZ(), true, isFT0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFt0aChCh, "DATA : Process same-event correlations for MFT-FT0-A h-h case", false); @@ -2227,13 +2412,16 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFT0()) { const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, ft0, ft0as, multiplicity, collision.posZ(), true, false); + fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, ft0, ft0as, multiplicity, collision.posZ(), true, false, isFT0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFt0aChChReassociated, "DATA : Process same-event correlations for MFT-FT0-A h-h case reassociated", false); @@ -2247,54 +2435,123 @@ struct HfTaskFlow { return; } - const auto multiplicity = getMultiplicityEstimator(collision, true); - if (collision.has_foundFT0()) { const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, ft0, ft0as, multiplicity, collision.posZ(), true, true); + fillCorrelationsFITReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, reassociatedMftTracks, ft0, ft0as, multiplicity, collision.posZ(), true, true, isFT0A); } } PROCESS_SWITCH(HfTaskFlow, processSameMftFt0aChChNonAmbiguous, "DATA : Process same-event correlations for MFT-FT0-A h-h case non ambiguous", false); - // =================================================================================================================================================================================================================================================================== - // MONTE-CARLO - // =================================================================================================================================================================================================================================================================== + // ===================================== + // DATA : process same event correlations: TPC-FT0C Ch. Part. - Ch. Part + // ===================================== + + void processSameTpcFt0cChCh(FilteredCollisionsWSelMult::iterator const& collision, + FilteredTracksWDcaSel const& tracks, + aod::FT0s const& ft0cs) + { + if (!(isAcceptedCollision(collision, true))) { + return; + } + + if (collision.has_foundFT0()) { + const auto& ft0 = collision.foundFT0(); + registry.fill(HIST("Data/hNTracks"), tracks.size()); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsFIT(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, ft0, ft0cs, multiplicity, collision.posZ(), true, isFT0C); + } + } + PROCESS_SWITCH(HfTaskFlow, processSameTpcFt0cChCh, "DATA : Process same-event correlations for TPC-FT0C h-h case", false); + + // ===================================== + // DATA : process same event correlations: TPC-FT0C D0 - Ch. Part + // ===================================== + + void processSameTpcFt0cD0Ch(FilteredCollisionsWSelMult::iterator const& collision, + HfCandidatesSelD0 const& candidates, + aod::FT0s const& ft0cs) + { + if (!(isAcceptedCollision(collision, true))) { + return; + } + + if (collision.has_foundFT0()) { + const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } + + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, ft0, ft0cs, multiplicity, collision.posZ(), true, isFT0C); + } + } + PROCESS_SWITCH(HfTaskFlow, processSameTpcFt0cD0Ch, "DATA : Process same-event correlations for TPC-FT0C D0-h case", false); // ===================================== - // MONTE-CARLO GENERATED : process same event correlations : TPC-MFT D0-ch. part. case + // DATA : process same event correlations: TPC-FT0C D0 - Ch. Part // ===================================== - void processSameTpcMftD0ChMcGen(FilteredMcCollisions::iterator const& mcCollision, - McParticles2ProngMatched const& mcParticles2Prong, - McParticles const& mcParticles) + void processSameTpcFt0cLcCh(FilteredCollisionsWSelMult::iterator const& collision, + HfCandidatesSelLc const& candidates, + aod::FT0s const& ft0cs) { - const auto multiplicity = mcCollision.multMCPVz(); + if (!(isAcceptedCollision(collision, true))) { + return; + } + + if (collision.has_foundFT0()) { + const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); - BinningPolicyBase<2> const baseBinning{{axisVertex, axisMultiplicity}, true}; + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } - sameEventHfMc->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); - fillCorrelations(sameEventHfMc, CorrelationContainer::CFStep::kCFStepAll, mcParticles2Prong, mcParticles, multiplicity, mcCollision.posZ(), true); + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsFIT(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, ft0, ft0cs, multiplicity, collision.posZ(), true, isFT0C); + } } - PROCESS_SWITCH(HfTaskFlow, processSameTpcMftD0ChMcGen, "MONTE-CARLO : Process same-event correlations for TPC-MFT D0-h case", false); + PROCESS_SWITCH(HfTaskFlow, processSameTpcFt0cLcCh, "DATA : Process same-event correlations for TPC-FT0C Lc-h case", false); // ===================================== - // MONTE-CARLO GENERATED : process same event correlations : TPC-MFT Lc-ch. part. case + // DATA : process same event correlations: FT0A-FT0C Ch. Part. - Ch. Part // ===================================== - void processSameTpcMftLcChMcGen(FilteredMcCollisions::iterator const& mcCollision, - McParticles3ProngMatched const& mcParticles3Prong, - McParticles const& mcParticles) + void processSameFt0aFt0cChCh(FilteredCollisionsWSelMult::iterator const& collision, + aod::FT0s const&) { - const auto multiplicity = mcCollision.multMCPVz(); + if (!(isAcceptedCollision(collision, true))) { + return; + } - BinningPolicyBase<2> const baseBinning{{axisVertex, axisMultiplicity}, true}; + if (collision.has_foundFT0()) { + const auto& ft0 = collision.foundFT0(); + const auto multiplicity = getMultiplicityEstimator(collision, true); + + if (multiplicity < configCollision.minMultiplicity || multiplicity > configCollision.maxMultiplicity) { + return; + } - sameEventHfMc->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); - fillCorrelations(sameEventHfMc, CorrelationContainer::CFStep::kCFStepAll, mcParticles3Prong, mcParticles, multiplicity, mcCollision.posZ(), true); + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsFt0aFt0c(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, ft0, ft0, multiplicity, collision.posZ(), true); + } } - PROCESS_SWITCH(HfTaskFlow, processSameTpcMftLcChMcGen, "MONTE-CARLO : Process same-event correlations for TPC-MFT Lc-h case", false); + PROCESS_SWITCH(HfTaskFlow, processSameFt0aFt0cChCh, "DATA : Process same-event correlations for FT0A-FT0C h-h case", false); // =================================================================================================================================================================================================================================================================== // =================================================================================================================================================================================================================================================================== @@ -2311,9 +2568,10 @@ struct HfTaskFlow { // ===================================== void processMixedTpcTpcChCh(FilteredCollisionsWSelMult const& collisions, - FilteredTracksWDcaSel const& tracks) + FilteredTracksWDcaSel const& tracks, + aod::BCsWithTimestamps const& bcs) { - mixCollisions(collisions, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, tracks, mixedEvent); + mixCollisions(collisions, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, tracks, mixedEvent, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcTpcChCh, "DATA : Process mixed-event correlations for TPC-TPC h-h case", false); @@ -2323,9 +2581,10 @@ struct HfTaskFlow { void processMixedTpcTpcD0Ch(FilteredCollisionsWSelMult const& collisions, FilteredTracksWDcaSel const& tracks, - HfCandidatesSelD0 const& candidates) + HfCandidatesSelD0 const& candidates, + aod::BCsWithTimestamps const& bcs) { - mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, tracks, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, tracks, mixedEventHf, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcTpcD0Ch, "DATA : Process mixed-event correlations for TPC-TPC D0-h case", false); @@ -2335,9 +2594,10 @@ struct HfTaskFlow { void processMixedTpcTpcLcCh(FilteredCollisionsWSelMult const& collisions, FilteredTracksWDcaSel const& tracks, - HfCandidatesSelLc const& candidates) + HfCandidatesSelLc const& candidates, + aod::BCsWithTimestamps const& bcs) { - mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, tracks, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, tracks, mixedEventHf, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcTpcLcCh, "DATA : Process mixed-event correlations for TPC-TPC Lc-h case", false); @@ -2347,18 +2607,10 @@ struct HfTaskFlow { void processMixedTpcMftChCh(FilteredCollisionsWSelMult const& collisions, FilteredTracksWDcaSel const& tracks, - FilteredMftTracks const& mftTracks) + FilteredMftTracks const& mftTracks, + aod::BCsWithTimestamps const& bcs) { - mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, tracks, mftTracks, mixedEvent); - // mixCollisions(collisions, CorrelationContainer::kCFStepAll, tracks, mftTracks, getMultiplicity, mixedEvent); - - // The next following two lines were supposed to be used to do mixed event with the reassociated MFT tracks - // However it seems the O2physics framework cannot handle how these combinations requests grouping according to Anton Alkin - // So I leave them commented for now until it is solved, and put the "normal" mixCollisions back with kCFStepReconstructed - - // mixCollisionsReassociatedMftTracks(collisions, CorrelationContainer::kCFStepReconstructed, tracks, reassociatedMftTracks, getMultiplicity, mixedEvent, false); - - // mixCollisionsReassociatedMftTracks(collisions, CorrelationContainer::kCFStepTracked, tracks, reassociatedMftTracks, getMultiplicity, mixedEvent, true); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, tracks, mftTracks, mixedEvent, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftChCh, "DATA : Process mixed-event correlations for TPC-MFT h-h case", false); @@ -2369,9 +2621,10 @@ struct HfTaskFlow { void processMixedTpcMftD0Ch(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelD0 const& candidates, FilteredMftTracks const& mftTracks, - FilteredTracksWDcaSel const& /*tracks*/) + FilteredTracksWDcaSel const& /*tracks*/, + aod::BCsWithTimestamps const& bcs) { - mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, mftTracks, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, mftTracks, mixedEventHf, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftD0Ch, "DATA : Process mixed-event correlations for TPC-MFT D0-h case", false); @@ -2381,9 +2634,10 @@ struct HfTaskFlow { void processMixedTpcMftLcCh(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelLc const& candidates, - FilteredMftTracks const& mftTracks) + FilteredMftTracks const& mftTracks, + aod::BCsWithTimestamps const& bcs) { - mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, mftTracks, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, mftTracks, mixedEventHf, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftLcCh, "DATA : Process mixed-event correlations for TPC-MFT Lc-h case", false); @@ -2395,7 +2649,7 @@ struct HfTaskFlow { FilteredTracksWDcaSel const& tracks, aod::FV0As const& fv0as) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, fv0as, perColTracks, mixedEvent); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, fv0as, perColTracks, mixedEvent, isFV0A); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFv0aChCh, "DATA : Process mixed-event correlations for TPC-FV0-A h-h case", false); @@ -2407,7 +2661,7 @@ struct HfTaskFlow { HfCandidatesSelD0 const& candidates, aod::FV0As const& fv0as) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, fv0as, perColD0s, mixedEventHf); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, fv0as, perColD0s, mixedEventHf, isFV0A); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFv0aD0Ch, "DATA : Process mixed-event correlations for TPC-FV0-A D0-h case", false); @@ -2419,7 +2673,7 @@ struct HfTaskFlow { HfCandidatesSelLc const& candidates, aod::FV0As const& fv0as) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, fv0as, perColLcs, mixedEventHf); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, fv0as, perColLcs, mixedEventHf, isFV0A); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFv0aLcCh, "DATA : Process mixed-event correlations for TPC-FV0-A Lc-h case", false); @@ -2431,7 +2685,7 @@ struct HfTaskFlow { FilteredMftTracks const& mftTracks, aod::FV0As const& fv0as) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, mftTracks, fv0as, perColMftTracks, mixedEvent); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, mftTracks, fv0as, perColMftTracks, mixedEvent, isFV0A); } PROCESS_SWITCH(HfTaskFlow, processMixedMftFv0aChCh, "DATA : Process mixed-event correlations for Mft-FV0-A h-h case", false); @@ -2443,7 +2697,7 @@ struct HfTaskFlow { FilteredTracksWDcaSel const& tracks, aod::FT0s const& ft0s) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, ft0s, perColTracks, mixedEvent); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, ft0s, perColTracks, mixedEvent, isFT0A); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0aChCh, "DATA : Process mixed-event correlations for TPC-FT0-A h-h case", false); @@ -2455,7 +2709,7 @@ struct HfTaskFlow { HfCandidatesSelD0 const& candidates, aod::FT0s const& ft0s) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColD0s, mixedEventHf); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColD0s, mixedEventHf, isFT0A); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0aD0Ch, "DATA : Process mixed-event correlations for TPC-FT0-A D0-h case", false); @@ -2467,7 +2721,7 @@ struct HfTaskFlow { HfCandidatesSelLc const& candidates, aod::FT0s const& ft0s) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColLcs, mixedEventHf); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColLcs, mixedEventHf, isFT0A); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0aLcCh, "DATA : Process mixed-event correlations for TPC-FT0-A Lc-h case", false); @@ -2479,99 +2733,56 @@ struct HfTaskFlow { FilteredMftTracks const& mftTracks, aod::FT0s const& ft0s) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, mftTracks, ft0s, perColMftTracks, mixedEvent); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, mftTracks, ft0s, perColMftTracks, mixedEvent, isFT0A); } PROCESS_SWITCH(HfTaskFlow, processMixedMftFt0aChCh, "DATA : Process mixed-event correlations for MFT-FT0-A h-h case", false); - // =================================================================================================================================================================================================================================================================== - // MONTE-CARLO - // =================================================================================================================================================================================================================================================================== - // ===================================== - // MONTE-CARLO GENERATED : process mixed event correlations: TPC-MFT D0-ch. part. case + // DATA : process mixed event correlations: TPC-FT0C ch part. - ch. part. case // ===================================== - void processMixedTpcMftD0ChMcGen(FilteredMcCollisions const& mcCollisions, - McParticles2ProngMatched const& mcParticles2Prong, - McParticles const& mcParticles) + void processMixedTpcFt0cChCh(FilteredCollisionsWSelMult const& collisions, + FilteredTracksWDcaSel const& tracks, + aod::FT0s const& ft0s) { - auto getMultiplicity = [](FilteredMcCollisions::iterator const& mcCollision) { - auto multiplicity = mcCollision.multMCPVz(); - return multiplicity; - }; - - mixCollisionsMcTruth(mcCollisions, mcParticles2Prong, mcParticles, getMultiplicity, mixedEventHfMc); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, ft0s, perColTracks, mixedEvent, isFT0C); } - PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftD0ChMcGen, "MONTE-CARLO : Process mixed-event correlations for TPC-MFT D0-h case", false); + PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0cChCh, "DATA : Process mixed-event correlations for TPC-FT0C h-h case", false); // ===================================== - // MONTE-CARLO GENERATED : process mixed event correlations: TPC-MFT Lc-ch. part. case + // DATA : process mixed event correlations: TPC-FT0C D0 - ch. part. case // ===================================== - void processMixedTpcMftLcChMcGen(FilteredMcCollisions const& mcCollisions, - McParticles3ProngMatched const& mcParticles3Prong, - McParticles const& mcParticles) + void processMixedTpcFt0cD0Ch(FilteredCollisionsWSelMult const& collisions, + HfCandidatesSelD0 const& candidates, + aod::FT0s const& ft0s) { - auto getMultiplicity = [](FilteredMcCollisions::iterator const& mcCollision) { - auto multiplicity = mcCollision.multMCPVz(); - return multiplicity; - }; - - mixCollisionsMcTruth(mcCollisions, mcParticles3Prong, mcParticles, getMultiplicity, mixedEventHfMc); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColD0s, mixedEventHf, isFT0C); } - PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftLcChMcGen, "MONTE-CARLO : Process mixed-event correlations for TPC-MFT D0-h case", false); + PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0cD0Ch, "DATA : Process mixed-event correlations for TPC-FT0C D0-h case", false); - // =================================================================================================================================================================================================================================================================== - // =================================================================================================================================================================================================================================================================== - // EFFICIENCIES PROCESS FUNCTIONS - // =================================================================================================================================================================================================================================================================== - // =================================================================================================================================================================================================================================================================== + // ===================================== + // DATA : process mixed event correlations: TPC-FT0C Lc - ch. part. case + // ===================================== - // NOTE SmallGroups includes soa::Filtered always -> in the smallGroups there is the equivalent of FilteredCollisionsWSelMultMcLabels - void processMcEfficiencyMft(FilteredMcCollisions::iterator const& mcCollision, - McParticles const& mcParticles, - soa::SmallGroups> const& collisionsMcLabels, - MftTracksMcLabels const& mftTTracksMcLabels) + void processMixedTpcFt0cLcCh(FilteredCollisionsWSelMult const& collisions, + HfCandidatesSelLc const& candidates, + aod::FT0s const& ft0s) { - LOGF(info, "MC collision at vtx-z = %f with %d mc particles and %d reconstructed collisions", mcCollision.posZ(), mcParticles.size(), collisionsMcLabels.size()); - - auto multiplicity = mcCollision.multMCPVz(); - if (configTask.centralityBinsForMc) { - if (collisionsMcLabels.size() == 0) { - return; - } - for (const auto& collision : collisionsMcLabels) { - multiplicity = collision.multNTracksPV(); - } - } + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColLcs, mixedEventHf, isFT0C); + } + PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0cLcCh, "DATA : Process mixed-event correlations for TPC-FT0C Lc-h case", false); - // Primaries - for (const auto& mcParticle : mcParticles) { - if (!isAcceptedMftMcParticle(mcParticle)) { - sameEventHf->getTrackHistEfficiency()->Fill(CorrelationContainer::MC, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), multiplicity, mcCollision.posZ()); - } - } - for (const auto& collision : collisionsMcLabels) { - auto groupedMftTTracksMcLabels = mftTTracksMcLabels.sliceBy(mftTracksPerCollision, collision.globalIndex()); - LOGF(info, " Reconstructed collision at vtx-z = %f", collision.posZ()); - LOGF(info, " which has %d mft tracks", groupedMftTTracksMcLabels.size()); + // ===================================== + // DATA : process mixed event correlations: FT0A-FT0C ch part. - ch. part. case + // ===================================== - for (const auto& mftTrack : groupedMftTTracksMcLabels) { - if (mftTrack.has_mcParticle()) { - const auto& mcParticle = mftTrack.mcParticle(); - if (!isAcceptedMftMcParticle(mcParticle)) { - sameEventHf->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoPrimaries, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), multiplicity, mcCollision.posZ()); - } - sameEventHf->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoAll, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), multiplicity, mcCollision.posZ()); - } else { - // fake track - // In the MFT the measurement of pT is not precise - sameEventHf->getTrackHistEfficiency()->Fill(CorrelationContainer::Fake, mftTrack.eta(), mftTrack.pt(), 0, multiplicity, mcCollision.posZ()); - } - } - } + void processMixedFt0aFt0cChCh(FilteredCollisionsWSelMult const& collisions, + aod::FT0s const& ft0s) + { + mixCollisionsFt0aFt0c(collisions, CorrelationContainer::kCFStepReconstructed, ft0s, ft0s, mixedEvent); } - PROCESS_SWITCH(HfTaskFlow, processMcEfficiencyMft, "MONTE-CARLO : Extract efficiencies for MFT tracks", false); + PROCESS_SWITCH(HfTaskFlow, processMixedFt0aFt0cChCh, "DATA : Process mixed-event correlations for FT0A-FT0C h-h case", false); }; // End of struct