Skip to content

Commit a7ce260

Browse files
authored
[PWGCF] Added an option to skip correlating particles in same that are alone in their respective pT bin. (#13880)
1 parent 628b476 commit a7ce260

File tree

1 file changed

+150
-1
lines changed

1 file changed

+150
-1
lines changed

PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ struct DiHadronCor {
100100
O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event")
101101
O2_DEFINE_CONFIGURABLE(cfgUsePtOrder, bool, true, "enable trigger pT < associated pT cut")
102102
O2_DEFINE_CONFIGURABLE(cfgUsePtOrderInMixEvent, bool, true, "enable trigger pT < associated pT cut in mixed event")
103+
O2_DEFINE_CONFIGURABLE(cfgSoloPtTrack, bool, false, "Skip trigger tracks that are alone in their pT bin for same process")
104+
O2_DEFINE_CONFIGURABLE(cfgSingleSoloPtTrack, bool, false, "Skip associated tracks that are alone in their pT bin for same process, works only if cfgSoloPtTrack is enabled")
103105
struct : ConfigurableGroup {
104106
O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut");
105107
O2_DEFINE_CONFIGURABLE(cfgMultCentLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut");
@@ -279,6 +281,13 @@ struct DiHadronCor {
279281
registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}});
280282
registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}});
281283
}
284+
if (cfgSoloPtTrack && doprocessSame) {
285+
registry.add("Nch_final_pt", "pT", {HistType::kTH1D, {axisPtTrigger}});
286+
registry.add("Solo_tracks_trigger", "pT", {HistType::kTH1D, {axisPtTrigger}});
287+
if (!cfgSingleSoloPtTrack) {
288+
registry.add("Solo_tracks_assoc", "pT", {HistType::kTH1D, {axisPtAssoc}});
289+
}
290+
}
282291

283292
registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event
284293
if (doprocessMCSame && doprocessOntheflySame) {
@@ -582,6 +591,103 @@ struct DiHadronCor {
582591
}
583592
}
584593
}
594+
595+
template <CorrelationContainer::CFStep step, typename TTracks, typename TTracksAssoc>
596+
void fillCorrelationsExcludeSoloTracks(TTracks tracks1, TTracksAssoc tracks2, float posZ, int magneticField, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms
597+
{
598+
std::vector<int64_t> tracksSkipIndices;
599+
std::vector<int64_t> tracks2SkipIndices;
600+
601+
findBiasedTracks(tracks1, tracksSkipIndices, posZ);
602+
if (!cfgSingleSoloPtTrack) { // only look for the solo pt tracks if we want to skip both
603+
findBiasedTracks(tracks2, tracks2SkipIndices, posZ);
604+
}
605+
606+
// Cache efficiency for particles (too many FindBin lookups)
607+
if (mEfficiency) {
608+
efficiencyAssociatedCache.clear();
609+
efficiencyAssociatedCache.reserve(tracks2.size());
610+
for (const auto& track2 : tracks2) {
611+
float weff = 1.;
612+
getEfficiencyCorrection(weff, track2.eta(), track2.pt(), posZ);
613+
efficiencyAssociatedCache.push_back(weff);
614+
}
615+
}
616+
617+
if (!cfgCentTableUnavailable)
618+
registry.fill(HIST("Centrality_used"), cent);
619+
registry.fill(HIST("Nch_used"), tracks1.size());
620+
621+
int fSampleIndex = gRandom->Uniform(0, cfgSampleSize);
622+
623+
float triggerWeight = 1.0f;
624+
float associatedWeight = 1.0f;
625+
// loop over all tracks
626+
for (auto const& track1 : tracks1) {
627+
628+
if (!trackSelected(track1))
629+
continue;
630+
if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ))
631+
continue;
632+
633+
registry.fill(HIST("Nch_final_pt"), track1.pt());
634+
635+
if (std::find(tracksSkipIndices.begin(), tracksSkipIndices.end(), track1.globalIndex()) != tracksSkipIndices.end()) {
636+
registry.fill(HIST("Solo_tracks_trigger"), track1.pt());
637+
continue; // Skip the track1 if it is alone in pt bin
638+
}
639+
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight);
640+
641+
for (auto const& track2 : tracks2) {
642+
643+
if (!trackSelected(track2))
644+
continue;
645+
if (mEfficiency) {
646+
associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()];
647+
}
648+
if (!cfgUsePtOrder && track1.globalIndex() == track2.globalIndex())
649+
continue; // For pt-differential correlations, skip if the trigger and associate are the same track
650+
if (cfgUsePtOrder && track1.pt() <= track2.pt())
651+
continue; // Without pt-differential correlations, skip if the trigger pt is less than the associate pt
652+
if (!cfgSingleSoloPtTrack) { // avoid skipping the second track if we only want one
653+
if (std::find(tracks2SkipIndices.begin(), tracks2SkipIndices.end(), track2.globalIndex()) != tracks2SkipIndices.end()) {
654+
registry.fill(HIST("Solo_tracks_assoc"), track2.pt());
655+
continue; // Skip the track2 if it is alone in pt bin
656+
}
657+
}
658+
659+
float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf);
660+
float deltaEta = track1.eta() - track2.eta();
661+
662+
if (std::abs(deltaEta) < cfgCutMerging) {
663+
664+
double dPhiStarHigh = getDPhiStar(track1, track2, cfgRadiusHigh, magneticField);
665+
double dPhiStarLow = getDPhiStar(track1, track2, cfgRadiusLow, magneticField);
666+
667+
const double kLimit = 3.0 * cfgCutMerging;
668+
669+
bool bIsBelow = false;
670+
671+
if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) {
672+
for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) {
673+
double dPhiStar = getDPhiStar(track1, track2, rad, magneticField);
674+
if (std::abs(dPhiStar) < kLimit) {
675+
bIsBelow = true;
676+
break;
677+
}
678+
}
679+
if (bIsBelow)
680+
continue;
681+
}
682+
}
683+
684+
// fill the right sparse and histograms
685+
same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight);
686+
registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight);
687+
}
688+
}
689+
}
690+
585691
template <CorrelationContainer::CFStep step, typename TTracks, typename TTracksAssoc>
586692
void fillMCCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms
587693
{
@@ -729,6 +835,45 @@ struct DiHadronCor {
729835
return 1;
730836
}
731837

838+
void findBiasedTracks(FilteredTracks const& tracks, std::vector<int64_t>& tracksSkipIndices, float posZ)
839+
{
840+
// Find the tracks that are alone in their pT bin
841+
tracksSkipIndices.clear();
842+
static const std::vector<double>& ptBins = axisPtTrigger.value;
843+
static const size_t nPtBins = ptBins.size() - 1;
844+
845+
std::vector<int> numberOfTracksInBin(nPtBins, 0);
846+
std::vector<int64_t> firstTrackIndex(nPtBins, -1);
847+
848+
float triggerWeight = 1.0f;
849+
850+
// Count tracks per bin and remember the first track id in each bin
851+
for (const auto& track : tracks) {
852+
if (!trackSelected(track))
853+
continue;
854+
if (!getEfficiencyCorrection(triggerWeight, track.eta(), track.pt(), posZ))
855+
continue;
856+
double pt = track.pt();
857+
auto binEdgeIt = std::upper_bound(ptBins.begin(), ptBins.end(), pt);
858+
if (binEdgeIt == ptBins.begin() || binEdgeIt == ptBins.end())
859+
continue; // skip pt bins out of range
860+
861+
size_t binIndex = static_cast<size_t>(std::distance(ptBins.begin(), binEdgeIt) - 1);
862+
863+
if (numberOfTracksInBin[binIndex] == 0) {
864+
firstTrackIndex[binIndex] = track.globalIndex();
865+
}
866+
++numberOfTracksInBin[binIndex];
867+
}
868+
869+
// Collect track ids for bins that have exactly one track
870+
for (size_t i = 0; i < nPtBins; ++i) {
871+
if (numberOfTracksInBin[i] == 1) {
872+
tracksSkipIndices.push_back(firstTrackIndex[i]);
873+
}
874+
}
875+
}
876+
732877
void processSame(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::BCsWithTimestamps const&)
733878
{
734879
if (!collision.sel8())
@@ -761,7 +906,11 @@ struct DiHadronCor {
761906
fillYield(collision, tracks);
762907

763908
same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed);
764-
fillCorrelations<CorrelationContainer::kCFStepReconstructed>(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, weightCent);
909+
if (!cfgSoloPtTrack) {
910+
fillCorrelations<CorrelationContainer::kCFStepReconstructed>(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, weightCent);
911+
} else {
912+
fillCorrelationsExcludeSoloTracks<CorrelationContainer::kCFStepReconstructed>(tracks, tracks, collision.posZ(), getMagneticField(bc.timestamp()), cent, weightCent);
913+
}
765914
}
766915
PROCESS_SWITCH(DiHadronCor, processSame, "Process same event", true);
767916

0 commit comments

Comments
 (0)