Skip to content

Conversation

@MartijnLaarhoven
Copy link
Owner

Adding a new task for short range correlations as a function of eta

Adding a new task for short range correlations as a function of eta
Copilot AI review requested due to automatic review settings January 28, 2026 11:52
@github-actions github-actions bot added the pwgcf label Jan 28, 2026
@github-actions github-actions bot changed the title Adding a new task for short range correlations [PWGCF] Adding a new task for short range correlations Jan 28, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new two-particle correlation analysis task/workflow intended to study (short-range) di-hadron correlations as a function of η.

Changes:

  • Introduces a new analysis task EtaDihadron implementing same-/mixed-event correlation filling with η-binned trigger/associated axes.
  • Registers the new workflow eta-dihadron in the Tasks CMake configuration.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx New η-dihadron correlation task implementation (event/track selection, mixing, histograms, CCDB corrections).
PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt Adds build/registration entry for the new eta-dihadron DPL workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

registry.fill(HIST("Solo_tracks_trigger"), track1.pt());
continue; // Skip the track1 if it is alone in pt bin
}
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as in fillCorrelations: Trig_hist is defined with an eta axis but is filled with track1.pt(), leading to incorrect binning/underflow. Update the filled value to match the histogram axis (likely track1.eta() for this eta-based task).

Suggested change
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight);
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.eta(), eventWeight * triggerWeight);

Copilot uses AI. Check for mistakes.
Comment on lines +285 to +288
registry.add("Nch_final_pt", "pT", {HistType::kTH1D, {axisEtaTrigger}});
registry.add("Solo_tracks_trigger", "pT", {HistType::kTH1D, {axisEtaTrigger}});
if (!cfgSingleSoloPtTrack) {
registry.add("Solo_tracks_assoc", "pT", {HistType::kTH1D, {axisEtaAssoc}});
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These histograms use axisEtaTrigger/axisEtaAssoc (eta binning) but are later filled with track.pt(). This causes incorrect binning and under/overflow. Use a pT axis here (e.g. axisPt, or add dedicated pt trigger/assoc axes like diHadronCor.cxx) to match the pT values being filled.

Suggested change
registry.add("Nch_final_pt", "pT", {HistType::kTH1D, {axisEtaTrigger}});
registry.add("Solo_tracks_trigger", "pT", {HistType::kTH1D, {axisEtaTrigger}});
if (!cfgSingleSoloPtTrack) {
registry.add("Solo_tracks_assoc", "pT", {HistType::kTH1D, {axisEtaAssoc}});
registry.add("Nch_final_pt", "pT", {HistType::kTH1D, {axisPt}});
registry.add("Solo_tracks_trigger", "pT", {HistType::kTH1D, {axisPt}});
if (!cfgSingleSoloPtTrack) {
registry.add("Solo_tracks_assoc", "pT", {HistType::kTH1D, {axisPt}});

Copilot uses AI. Check for mistakes.
Comment on lines +267 to +269
if (doprocessSame) {
registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution
registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}});
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deltaEta_deltaPhi_mixed is created only under if (doprocessSame), but it is filled in the mixed-event path. If someone enables mixed processing while disabling same-event processing, this will attempt to fill a non-existent histogram. Create this histogram when doprocessMixed is enabled too (or guard the fill).

Suggested change
if (doprocessSame) {
registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution
registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}});
// Mixed-event histogram must be available whenever mixed processing is enabled,
// even if same-event processing is disabled.
registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}});
if (doprocessSame) {
registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution

Copilot uses AI. Check for mistakes.
Comment on lines +830 to +831
if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A())))
return 0;
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fT0AV0AMean/fT0AV0ASigma are dereferenced here when cfgEvSelV0AT0ACut is enabled, but they are only constructed in init() under if (cfgEvSelMultCorrelation). If cfgEvSelMultCorrelation is disabled while keeping cfgEvSelV0AT0ACut enabled (default), this will crash. Initialize these TF1s based on cfgEvSelV0AT0ACut (or add a null check and fail fast).

Suggested change
if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A())))
return 0;
if (cfgEvSelV0AT0ACut) {
// Fail fast if the required correlation functions are not initialized.
if (!cfgFuncParas.fT0AV0AMean || !cfgFuncParas.fT0AV0ASigma) {
return 0;
}
if (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) >
sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A())) {
return 0;
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +742 to +766
registry.fill(HIST("hEventCountSpecific"), 0.5);
if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) {
// rejects collisions which are associated with the same "found-by-T0" bunch crossing
// https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof
return 0;
}
if (fillCounter && cfgEvSelkNoSameBunchPileup)
registry.fill(HIST("hEventCountSpecific"), 1.5);
if (cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) {
return 0;
}
if (fillCounter && cfgEvSelkNoITSROFrameBorder)
registry.fill(HIST("hEventCountSpecific"), 2.5);
if (cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) {
return 0;
}
if (fillCounter && cfgEvSelkNoTimeFrameBorder)
registry.fill(HIST("hEventCountSpecific"), 3.5);
if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) {
// removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference
// use this cut at low multiplicities with caution
return 0;
}
if (fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV)
registry.fill(HIST("hEventCountSpecific"), 4.5);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eventSelected() always fills hEventCountSpecific, but that histogram is only created in init() when doprocessSame && cfgUseAdditionalEventCut. If someone runs only mixed-event processing with cfgUseAdditionalEventCut=true, this will try to fill a histogram that was never registered. Either always register hEventCountSpecific when cfgUseAdditionalEventCut is true, or guard the fill with the same condition.

Suggested change
registry.fill(HIST("hEventCountSpecific"), 0.5);
if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) {
// rejects collisions which are associated with the same "found-by-T0" bunch crossing
// https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof
return 0;
}
if (fillCounter && cfgEvSelkNoSameBunchPileup)
registry.fill(HIST("hEventCountSpecific"), 1.5);
if (cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) {
return 0;
}
if (fillCounter && cfgEvSelkNoITSROFrameBorder)
registry.fill(HIST("hEventCountSpecific"), 2.5);
if (cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) {
return 0;
}
if (fillCounter && cfgEvSelkNoTimeFrameBorder)
registry.fill(HIST("hEventCountSpecific"), 3.5);
if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) {
// removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference
// use this cut at low multiplicities with caution
return 0;
}
if (fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV)
registry.fill(HIST("hEventCountSpecific"), 4.5);
const bool doFillEventCountSpecific = doprocessSame && cfgUseAdditionalEventCut;
if (doFillEventCountSpecific) {
registry.fill(HIST("hEventCountSpecific"), 0.5);
}
if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) {
// rejects collisions which are associated with the same "found-by-T0" bunch crossing
// https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof
return 0;
}
if (doFillEventCountSpecific && fillCounter && cfgEvSelkNoSameBunchPileup) {
registry.fill(HIST("hEventCountSpecific"), 1.5);
}
if (cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) {
return 0;
}
if (doFillEventCountSpecific && fillCounter && cfgEvSelkNoITSROFrameBorder) {
registry.fill(HIST("hEventCountSpecific"), 2.5);
}
if (cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) {
return 0;
}
if (doFillEventCountSpecific && fillCounter && cfgEvSelkNoTimeFrameBorder) {
registry.fill(HIST("hEventCountSpecific"), 3.5);
}
if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) {
// removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference
// use this cut at low multiplicities with caution
return 0;
}
if (doFillEventCountSpecific && fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV) {
registry.fill(HIST("hEventCountSpecific"), 4.5);
}

Copilot uses AI. Check for mistakes.
Comment on lines +426 to +428
LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCentralityWeight.value.c_str());
}
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log messages for cfgCentralityWeight loading refer to an "efficiency histogram for trigger particles". This is misleading when debugging CCDB issues because this block is loading the centrality-weight histogram. Update the fatal/info messages to mention centrality weights (and ideally the object name expected).

Suggested change
LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCentralityWeight.value.c_str());
}
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight);
LOGF(fatal, "Could not load centrality weight histogram from %s", cfgCentralityWeight.value.c_str());
}
LOGF(info, "Loaded centrality weight histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight);

Copilot uses AI. Check for mistakes.
if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ))
continue;
if (system == SameEvent) {
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trig_hist is configured with axisEtaTrigger (see init), but here it is filled with track1.pt(). This will put almost all entries in under/overflow and breaks the intended trigger-eta normalization for this task. Fill it with track1.eta() (or change the histogram axis to a pT axis if pT is intended).

Suggested change
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight);
registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.eta(), eventWeight * triggerWeight);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant