diff --git a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx index 1a4710576e1..927c13ae023 100644 --- a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx +++ b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx @@ -25,6 +25,7 @@ #include "Common/Core/Zorro.h" #include "Common/Core/ZorroSummary.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" @@ -82,6 +83,8 @@ struct HStrangeCorrelationFilter { Configurable strangedEdxNSigmaTight{"strangedEdxNSigmaTight", 3, "Nsigmas for strange decay daughters"}; Configurable zorroMask{"zorroMask", "", "zorro trigger class to select on (empty: none)"}; Configurable nSigmaNearXiMassCenter{"nSigmaNearXiMassCenter", 0, "for Oemga analysis only, to check if candidate mass is around Xi"}; + Configurable rejectAmbiguousTracks{"rejectAmbiguousTracks", false, "reject tracks compatible with more than one collision (requires track-to-collision-associator with fillTableOfCollIdsPerTrack)"}; + Configurable rejectAmbiguousAssoc{"rejectAmbiguousAssoc", false, "reject V0/cascade candidates having at least one ambiguous daughter track"}; // used for event selections in Pb-Pb Configurable cfgCutOccupancyHigh{"cfgCutOccupancyHigh", 3000, "High cut on TPC occupancy"}; @@ -210,10 +213,10 @@ struct HStrangeCorrelationFilter { // using V0LinkedTagged = soa::Join; // using CascadesLinkedTagged = soa::Join; - using FullTracks = soa::Join; - using FullTracksMC = soa::Join; - using DauTracks = soa::Join; - using DauTracksMC = soa::Join; + using FullTracks = soa::Join; + using FullTracksMC = soa::Join; + using DauTracks = soa::Join; + using DauTracksMC = soa::Join; // using IDTracks= soa::Join; // prepared for Bayesian PID using IDTracks = soa::Join; using IDTracksMC = soa::Join; @@ -300,12 +303,21 @@ struct HStrangeCorrelationFilter { histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axesConfigurations.axisPtQA, axesConfigurations.axisLambdaMass, axesConfigurations.axisMult}); histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axesConfigurations.axisPtQA, axesConfigurations.axisLambdaMass, axesConfigurations.axisMult}); } + if (rejectAmbiguousAssoc && (doprocessV0s || doprocessV0sMC)) { + histos.add("hAmbiguousV0Pt", "hAmbiguousV0Pt", kTH1F, {axesConfigurations.axisPtQA}); + } + if (rejectAmbiguousTracks && (doprocessTriggers || doprocessTriggersMC)) { + histos.add("hAmbiguousTriggerPt", "hAmbiguousTriggerPt", kTH1F, {axesConfigurations.axisPtQA}); + } if (doprocessCascades || doprocessCascadesMC) { histos.add("h3dMassXiMinus", "h3dMassXiMinus", kTH3F, {axesConfigurations.axisPtQA, axesConfigurations.axisXiMass, axesConfigurations.axisMult}); histos.add("h3dMassXiPlus", "h3dMassXiPlus", kTH3F, {axesConfigurations.axisPtQA, axesConfigurations.axisXiMass, axesConfigurations.axisMult}); histos.add("h3dMassOmegaMinus", "h3dMassOmegaMinus", kTH3F, {axesConfigurations.axisPtQA, axesConfigurations.axisOmegaMass, axesConfigurations.axisMult}); histos.add("h3dMassOmegaPlus", "h3dMassOmegaPlus", kTH3F, {axesConfigurations.axisPtQA, axesConfigurations.axisOmegaMass, axesConfigurations.axisMult}); } + if (rejectAmbiguousAssoc && (doprocessCascades || doprocessCascadesMC)) { + histos.add("hAmbiguousCascadePt", "hAmbiguousCascadePt", kTH1F, {axesConfigurations.axisPtQA}); + } } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -410,6 +422,20 @@ struct HStrangeCorrelationFilter { return true; } + // ambiguous track check: the track is compatible with more than one collision, + // or with a collision different from the one it is assigned to (see PWGCF/TableProducer/dptDptFilter.cxx) + template + bool isAmbiguousTrack(TTrack const& track) + { + if (track.compatibleCollIds().size() == 0) { + return false; // no collision association information: not ambiguous + } + if (track.compatibleCollIds().size() == 1) { + return track.collisionId() != track.compatibleCollIds()[0]; + } + return true; // associated to more than one collision + } + // reco-level trigger quality checks (N.B.: DCA is filtered, not selected) template bool isValidTrigger(TTrack const& track) @@ -593,6 +619,10 @@ struct HStrangeCorrelationFilter { if (!isValidTrigger(track)) { continue; } + if (rejectAmbiguousTracks && isAmbiguousTrack(track)) { + histos.fill(HIST("hAmbiguousTriggerPt"), track.pt()); + continue; + } TriggCandidate thisTrigg{}; thisTrigg.pt = track.pt(); thisTrigg.trackId = track.globalIndex(); @@ -634,6 +664,10 @@ struct HStrangeCorrelationFilter { if (!isValidTrigger(track)) { continue; } + if (rejectAmbiguousTracks && isAmbiguousTrack(track)) { + histos.fill(HIST("hAmbiguousTriggerPt"), track.pt()); + continue; + } TriggCandidate thisTrigg{}; thisTrigg.pt = track.pt(); thisTrigg.trackId = track.globalIndex(); @@ -812,6 +846,10 @@ struct HStrangeCorrelationFilter { if (trackSelections.requireClusterInITS && (posdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks || negdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks)) { continue; } + if (rejectAmbiguousAssoc && (isAmbiguousTrack(posdau) || isAmbiguousTrack(negdau))) { + histos.fill(HIST("hAmbiguousV0Pt"), v0.pt()); + continue; + } float dcaDauCutForK0s = v0Selection.dcaDaugToPVForK0s == 0 ? v0Selection.dcaMesonToPV : v0Selection.dcaDaugToPVForK0s; bool isGoodK0Short = (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < v0Selection.lifetimecutK0S && @@ -947,6 +985,10 @@ struct HStrangeCorrelationFilter { if (trackSelections.requireClusterInITS && (posdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks || negdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks)) { continue; } + if (rejectAmbiguousAssoc && (isAmbiguousTrack(posdau) || isAmbiguousTrack(negdau))) { + histos.fill(HIST("hAmbiguousV0Pt"), v0.pt()); + continue; + } float dcaDauCutForK0s = v0Selection.dcaDaugToPVForK0s == 0 ? v0Selection.dcaMesonToPV : v0Selection.dcaDaugToPVForK0s; bool isGoodK0Short = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < v0Selection.lifetimecutK0S && @@ -1101,6 +1143,10 @@ struct HStrangeCorrelationFilter { if (negTrackCast.tpcNClsCrossedRows() < trackSelections.minTPCNCrossedRows) { continue; } + if (rejectAmbiguousAssoc && (isAmbiguousTrack(bachTrackCast) || isAmbiguousTrack(posTrackCast) || isAmbiguousTrack(negTrackCast))) { + histos.fill(HIST("hAmbiguousCascadePt"), casc.pt()); + continue; + } if (!doPPAnalysis && !cascadeSelectedPbPb(casc, collision.posX(), collision.posY(), collision.posZ())) { continue; } @@ -1270,6 +1316,10 @@ struct HStrangeCorrelationFilter { if (negTrackCast.tpcNClsCrossedRows() < trackSelections.minTPCNCrossedRows) { continue; } + if (rejectAmbiguousAssoc && (isAmbiguousTrack(bachTrackCast) || isAmbiguousTrack(posTrackCast) || isAmbiguousTrack(negTrackCast))) { + histos.fill(HIST("hAmbiguousCascadePt"), casc.pt()); + continue; + } if (!doPPAnalysis && !cascadeSelectedPbPb(casc, collision.posX(), collision.posY(), collision.posZ())) { continue; } diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index acab9d529d8..194765d135e 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -222,7 +222,7 @@ struct HStrangeCorrelation { Configurable assocMaxTPCSharedClusters{"assocMaxTPCSharedClusters", 200, "maximum number of shared TPC clusters (inclusive) for assoc primary tracks"}; Configurable triggerRequireL0{"triggerRequireL0", false, "require ITS L0 cluster for trigger"}; Configurable assocRequireL0{"assocRequireL0", true, "require ITS L0 cluster for assoc primary track"}; - Configurable minTPCChi2PerClusterAssociated{"minTPCChi2PerClusterAssociated", 4.0f, "Minimum TPC chi2 per cluster for associated primary tracks"}; + Configurable maxTPCChi2PerClusterAssociated{"maxTPCChi2PerClusterAssociated", 4.0f, "Maximum TPC chi2 per cluster for associated primary tracks"}; Configurable checksRequireTPCChi2{"checksRequireTPCChi2", false, "require TPC chi2 per cluster for trigger and associated primary tracks"}; Configurable requireClusterInITS{"requireClusterInITS", false, "require cluster in ITS for V0 and cascade daughter tracks"}; Configurable minITSClustersForDaughterTracks{"minITSClustersForDaughterTracks", 1, "Minimum number of ITS clusters for V0 daughter tracks"}; @@ -1389,7 +1389,7 @@ struct HStrangeCorrelation { if (postrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated || negtrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated) { continue; } - if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated)) { + if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated)) { continue; } if (trackSelection.requireClusterInITS && (postrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks || negtrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks)) { @@ -1946,7 +1946,7 @@ struct HStrangeCorrelation { if (postrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated || negtrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated || bachtrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated) { continue; } - if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated || bachtrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated)) { + if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated || bachtrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated)) { continue; } if (trackSelection.requireClusterInITS && (postrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks || negtrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks || bachtrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks)) { @@ -3565,7 +3565,7 @@ struct HStrangeCorrelation { if (postrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated || negtrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated) { continue; } - if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated)) { + if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated)) { continue; } if (trackSelection.requireClusterInITS && (postrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks || negtrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks)) { @@ -3779,7 +3779,7 @@ struct HStrangeCorrelation { if (postrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated || negtrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated || bachtrack.tpcNClsCrossedRows() < trackSelection.minTPCNCrossedRowsAssociated) { continue; } - if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated || bachtrack.tpcChi2NCl() < trackSelection.minTPCChi2PerClusterAssociated)) { + if (trackSelection.checksRequireTPCChi2 && (postrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated || negtrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated || bachtrack.tpcChi2NCl() > trackSelection.maxTPCChi2PerClusterAssociated)) { continue; } if (trackSelection.requireClusterInITS && (postrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks || negtrack.itsNCls() < trackSelection.minITSClustersForDaughterTracks)) { @@ -4865,8 +4865,8 @@ struct HStrangeCorrelation { passesFinalSelection = passesFinalSelection && positiveTrack.tpcNClsCrossedRows() >= trackSelection.minTPCNCrossedRowsAssociated && negativeTrack.tpcNClsCrossedRows() >= trackSelection.minTPCNCrossedRowsAssociated; if (trackSelection.checksRequireTPCChi2) { - passesFinalSelection = passesFinalSelection && positiveTrack.tpcChi2NCl() >= trackSelection.minTPCChi2PerClusterAssociated && - negativeTrack.tpcChi2NCl() >= trackSelection.minTPCChi2PerClusterAssociated; + passesFinalSelection = passesFinalSelection && positiveTrack.tpcChi2NCl() <= trackSelection.maxTPCChi2PerClusterAssociated && + negativeTrack.tpcChi2NCl() <= trackSelection.maxTPCChi2PerClusterAssociated; } if (trackSelection.requireClusterInITS) { passesFinalSelection = passesFinalSelection && positiveTrack.itsNCls() >= trackSelection.minITSClustersForDaughterTracks && @@ -5217,8 +5217,8 @@ struct HStrangeCorrelation { passesFinalSelection = passesFinalSelection && positiveTrack.tpcNClsCrossedRows() >= trackSelection.minTPCNCrossedRowsAssociated && negativeTrack.tpcNClsCrossedRows() >= trackSelection.minTPCNCrossedRowsAssociated; if (trackSelection.checksRequireTPCChi2) { - passesFinalSelection = passesFinalSelection && positiveTrack.tpcChi2NCl() >= trackSelection.minTPCChi2PerClusterAssociated && - negativeTrack.tpcChi2NCl() >= trackSelection.minTPCChi2PerClusterAssociated; + passesFinalSelection = passesFinalSelection && positiveTrack.tpcChi2NCl() <= trackSelection.maxTPCChi2PerClusterAssociated && + negativeTrack.tpcChi2NCl() <= trackSelection.maxTPCChi2PerClusterAssociated; } if (trackSelection.requireClusterInITS) { passesFinalSelection = passesFinalSelection && positiveTrack.itsNCls() >= trackSelection.minITSClustersForDaughterTracks && @@ -5756,8 +5756,8 @@ struct HStrangeCorrelation { passesFinalSelection = passesFinalSelection && positiveTrack.tpcNClsCrossedRows() >= trackSelection.minTPCNCrossedRowsAssociated && negativeTrack.tpcNClsCrossedRows() >= trackSelection.minTPCNCrossedRowsAssociated; if (trackSelection.checksRequireTPCChi2) { - passesFinalSelection = passesFinalSelection && positiveTrack.tpcChi2NCl() >= trackSelection.minTPCChi2PerClusterAssociated && - negativeTrack.tpcChi2NCl() >= trackSelection.minTPCChi2PerClusterAssociated; + passesFinalSelection = passesFinalSelection && positiveTrack.tpcChi2NCl() <= trackSelection.maxTPCChi2PerClusterAssociated && + negativeTrack.tpcChi2NCl() <= trackSelection.maxTPCChi2PerClusterAssociated; } if (trackSelection.requireClusterInITS) { passesFinalSelection = passesFinalSelection && positiveTrack.itsNCls() >= trackSelection.minITSClustersForDaughterTracks &&