Skip to content

Commit d537962

Browse files
abmodakalibuild
andauthored
[PWGCF] Add long range correlations analysis task (#11329)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 76257f1 commit d537962

File tree

2 files changed

+358
-0
lines changed

2 files changed

+358
-0
lines changed

PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ o2physics_add_dpl_workflow(di-hadron-cor
6363
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore
6464
COMPONENT_NAME Analysis)
6565

66+
o2physics_add_dpl_workflow(longrange-correlation
67+
SOURCES longrangeCorrelation.cxx
68+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore
69+
COMPONENT_NAME Analysis)
70+
6671

6772

6873

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
///
12+
/// \file longrangeCorrelation.cxx
13+
///
14+
/// \brief task for long range correlation analysis
15+
/// \author Abhi Modak (abhi.modak@cern.ch) and Debojit sarkar (debojit.sarkar@cern.ch)
16+
/// \since April 22, 2025
17+
18+
#include <TH1F.h>
19+
#include <chrono>
20+
#include <string>
21+
#include <vector>
22+
#include <TComplex.h>
23+
#include <TMath.h>
24+
#include <cstdio>
25+
26+
#include "Framework/AnalysisDataModel.h"
27+
#include "Framework/AnalysisTask.h"
28+
#include "Framework/runDataProcessing.h"
29+
#include "Framework/HistogramRegistry.h"
30+
#include "Framework/StepTHn.h"
31+
#include "ReconstructionDataFormats/Track.h"
32+
#include "Common/DataModel/PIDResponse.h"
33+
#include "Common/DataModel/Multiplicity.h"
34+
#include "Common/DataModel/Centrality.h"
35+
#include "Common/DataModel/TrackSelectionTables.h"
36+
#include "Common/DataModel/EventSelection.h"
37+
#include "Common/Core/trackUtilities.h"
38+
#include "CommonConstants/PhysicsConstants.h"
39+
#include "Common/Core/TrackSelection.h"
40+
#include "Framework/ASoAHelpers.h"
41+
#include "Common/DataModel/FT0Corrected.h"
42+
#include "Common/Core/RecoDecay.h"
43+
#include "CommonConstants/MathConstants.h"
44+
#include "FT0Base/Geometry.h"
45+
#include "FV0Base/Geometry.h"
46+
#include "PWGCF/DataModel/CorrelationsDerived.h"
47+
#include "Common/DataModel/CollisionAssociationTables.h"
48+
#include "PWGCF/Core/CorrelationContainer.h"
49+
#include "PWGCF/Core/PairCuts.h"
50+
51+
#include "CCDB/CcdbApi.h"
52+
#include "CCDB/BasicCCDBManager.h"
53+
#include "DetectorsCommonDataFormats/AlignParam.h"
54+
55+
using namespace o2;
56+
using namespace o2::framework;
57+
using namespace o2::framework::expressions;
58+
using namespace o2::aod::track;
59+
using namespace o2::aod::evsel;
60+
using namespace o2::constants::math;
61+
62+
static constexpr TrackSelectionFlags::flagtype TrackSelectionIts =
63+
TrackSelectionFlags::kITSNCls | TrackSelectionFlags::kITSChi2NDF |
64+
TrackSelectionFlags::kITSHits;
65+
static constexpr TrackSelectionFlags::flagtype TrackSelectionTpc =
66+
TrackSelectionFlags::kTPCNCls |
67+
TrackSelectionFlags::kTPCCrossedRowsOverNCls |
68+
TrackSelectionFlags::kTPCChi2NDF;
69+
static constexpr TrackSelectionFlags::flagtype TrackSelectionDca =
70+
TrackSelectionFlags::kDCAz | TrackSelectionFlags::kDCAxy;
71+
static constexpr TrackSelectionFlags::flagtype TrackSelectionDcaxyOnly =
72+
TrackSelectionFlags::kDCAxy;
73+
74+
AxisSpec axisEvent{10, 0.5, 9.5, "#Event", "EventAxis"};
75+
AxisSpec amplitudeFT0{5000, 0, 10000, "FT0 amplitude"};
76+
AxisSpec channelFT0Axis{96, 0.0, 96.0, "FT0 channel"};
77+
78+
struct LongrangeCorrelation {
79+
80+
struct : ConfigurableGroup {
81+
Configurable<std::string> cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"};
82+
Configurable<int64_t> noLaterThan{"noLaterThan", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"};
83+
} cfgCcdbParam;
84+
85+
SliceCache cache;
86+
Service<o2::ccdb::BasicCCDBManager> ccdb;
87+
o2::ccdb::CcdbApi ccdbApi;
88+
std::vector<o2::detectors::AlignParam>* offsetFT0;
89+
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
90+
Configurable<float> cfgVtxCut{"cfgVtxCut", 10.0f, "Vertex Z range to consider"};
91+
Configurable<float> cfgEtaCut{"cfgEtaCut", 1.0f, "Eta range to consider"};
92+
Configurable<float> dcaZ{"dcaZ", 0.2f, "Custom DCA Z cut (ignored if negative)"};
93+
Configurable<float> cfgPtCutMin{"cfgPtCutMin", 0.2f, "minimum accepted track pT"};
94+
Configurable<float> cfgPtCutMax{"cfgPtCutMax", 10.0f, "maximum accepted track pT"};
95+
Configurable<int> mixingParameter{"mixingParameter", 5, "how many events are mixed"};
96+
Configurable<int> cfgMinMult{"cfgMinMult", 0, "Minimum multiplicity for collision"};
97+
Configurable<int> cfgMaxMult{"cfgMaxMult", 10, "Maximum multiplicity for collision"};
98+
Configurable<double> cfgSampleSize{"cfgSampleSize", 10, "Sample size for mixed event"};
99+
ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"};
100+
ConfigurableAxis axisDeltaEta{"axisDeltaEta", {40, -6, -2}, "delta eta axis for histograms"};
101+
ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"};
102+
ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt associated axis for histograms"};
103+
ConfigurableAxis axisMultME{"axisMultME", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "Mixing bins - multiplicity"};
104+
ConfigurableAxis axisVtxZME{"axisVtxZME", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Mixing bins - z-vertex"};
105+
ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"};
106+
ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"};
107+
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"};
108+
ConfigurableAxis axisVtxZ{"axisVtxZ", {40, -20, 20}, "vertex axis"};
109+
ConfigurableAxis axisPhi{"axisPhi", {96, 0, TwoPI}, "#phi axis"};
110+
ConfigurableAxis axisEtaTrig{"axisEtaTrig", {40, -1., 1.}, "#eta trig axis"};
111+
ConfigurableAxis axisEtaAssoc{"axisEtaAssoc", {96, 3.5, 4.9}, "#eta assoc axis"};
112+
ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"};
113+
ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "multiplicity / centrality axis for histograms"};
114+
115+
using CollTable = soa::Join<aod::Collisions, aod::EvSels>;
116+
using TrksTable = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection>>;
117+
Preslice<TrksTable> perCollision = aod::track::collisionId;
118+
119+
OutputObj<CorrelationContainer> same{Form("sameEvent_%i_%i", static_cast<int>(cfgMinMult), static_cast<int>(cfgMaxMult))};
120+
OutputObj<CorrelationContainer> mixed{Form("mixedEvent_%i_%i", static_cast<int>(cfgMinMult), static_cast<int>(cfgMaxMult))};
121+
122+
void init(InitContext const&)
123+
{
124+
ccdb->setURL(cfgCcdbParam.cfgURL);
125+
ccdbApi.init("http://alice-ccdb.cern.ch");
126+
ccdb->setCaching(true);
127+
ccdb->setLocalObjectValidityChecking();
128+
ccdb->setCreatedNotAfter(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
129+
LOGF(info, "Getting alignment offsets from the CCDB...");
130+
offsetFT0 = ccdb->getForTimeStamp<std::vector<o2::detectors::AlignParam>>("FT0/Calib/Align", cfgCcdbParam.noLaterThan.value);
131+
LOGF(info, "Offset for FT0A: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[0].getX(), (*offsetFT0)[0].getY(), (*offsetFT0)[0].getZ());
132+
LOGF(info, "Offset for FT0C: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[1].getX(), (*offsetFT0)[1].getY(), (*offsetFT0)[1].getZ());
133+
134+
// QA histos
135+
histos.add("QA/EventHist", "events", kTH1F, {axisEvent}, false);
136+
histos.add("QA/VtxZHist", "v_{z} (cm)", kTH1F, {axisVtxZ}, false);
137+
histos.add("QA/hMEpvz1", ";pvz;Entries", kTH1F, {{30, -15, 15}});
138+
histos.add("QA/hMEpvz2", ";pvz;Entries", kTH1F, {{30, -15, 15}});
139+
histos.add("QA/hMixingQA", "events", kTH1F, {axisEvent}, false);
140+
141+
auto hstat = histos.get<TH1>(HIST("QA/EventHist"));
142+
auto* x = hstat->GetXaxis();
143+
x->SetBinLabel(1, "All events");
144+
x->SetBinLabel(2, "sel8");
145+
x->SetBinLabel(3, "|vz|<10");
146+
147+
histos.add("SE/hMult", "event multiplicity", kTH1D, {axisMultiplicity});
148+
histos.add("SE/Trig_etavsphi", ";#eta;#phi", kTH2D, {axisPhi, axisEtaTrig});
149+
histos.add("SE/Trig_eta", "#eta", kTH1D, {axisEtaTrig});
150+
histos.add("SE/Trig_phi", "#eta", kTH1D, {axisPhi});
151+
histos.add("SE/Trig_pt", "p_{T}", kTH1D, {axisPtTrigger});
152+
histos.add("SE/hMult_used", "event multiplicity", kTH1F, {axisMultiplicity});
153+
histos.add("SE/Trig_hist", "trig hist", kTHnSparseF, {axisSample, axisVtxZ, axisPtTrigger});
154+
histos.add("SE/FT0Amp", "ftoamult", kTH2D, {channelFT0Axis, amplitudeFT0});
155+
histos.add("SE/FT0Aeta", "ft0a;#eta", kTH1D, {axisEtaAssoc});
156+
histos.add("SE/FT0Aphi", "ft0a;#phi", kTH1D, {axisPhi});
157+
histos.add("SE/FT0Aetavsphi", ";ft0a;#eta;#phi", kTH2D, {axisPhi, axisEtaAssoc});
158+
histos.add("SE/deltaEta_deltaPhi", ";#delta#eta;#delta#phi", kTH2D, {axisDeltaPhi, axisDeltaEta});
159+
160+
histos.add("ME/hMult", "event multiplicity", kTH1D, {axisMultiplicity});
161+
histos.add("ME/Trig_etavsphi", ";#eta;#phi", kTH2D, {axisPhi, axisEtaTrig});
162+
histos.add("ME/Trig_eta", "#eta", kTH1D, {axisEtaTrig});
163+
histos.add("ME/Trig_phi", "#eta", kTH1D, {axisPhi});
164+
histos.add("ME/Trig_pt", "p_{T}", kTH1D, {axisPtTrigger});
165+
histos.add("ME/FT0Amp", "ftoamult", kTH2D, {channelFT0Axis, amplitudeFT0});
166+
histos.add("ME/FT0Aeta", "ft0a;#eta", kTH1D, {axisEtaAssoc});
167+
histos.add("ME/FT0Aphi", "ft0a;#phi", kTH1D, {axisPhi});
168+
histos.add("ME/FT0Aetavsphi", ";ft0a;#eta;#phi", kTH2D, {axisPhi, axisEtaAssoc});
169+
histos.add("ME/deltaEta_deltaPhi", ";#delta#eta;#delta#phi", kTH2D, {axisDeltaPhi, axisDeltaEta});
170+
171+
std::vector<AxisSpec> corrAxis = {{axisSample, "Sample"},
172+
{axisVtxZ, "z-vtx (cm)"},
173+
{axisPtTrigger, "p_{T} (GeV/c)"},
174+
{axisPtAssoc, "p_{T} (GeV/c)"},
175+
{axisDeltaPhi, "#Delta#varphi (rad)"},
176+
{axisDeltaEta, "#Delta#eta"}};
177+
std::vector<AxisSpec> effAxis = {{axisVertexEfficiency, "z-vtx (cm)"},
178+
{axisPtEfficiency, "p_{T} (GeV/c)"},
179+
{axisEtaEfficiency, "#eta"}};
180+
181+
std::vector<AxisSpec> userAxis;
182+
183+
same.setObject(new CorrelationContainer(Form("sameEvent_%i_%i", static_cast<int>(cfgMinMult), static_cast<int>(cfgMaxMult)), Form("sameEvent_%i_%i", static_cast<int>(cfgMinMult), static_cast<int>(cfgMaxMult)), corrAxis, effAxis, userAxis));
184+
mixed.setObject(new CorrelationContainer(Form("mixedEvent_%i_%i", static_cast<int>(cfgMinMult), static_cast<int>(cfgMaxMult)), Form("mixedEvent_%i_%i", static_cast<int>(cfgMinMult), static_cast<int>(cfgMaxMult)), corrAxis, effAxis, userAxis));
185+
}
186+
187+
double getPhiFT0(int chno, double offsetX, double offsetY)
188+
{
189+
o2::ft0::Geometry ft0Det;
190+
ft0Det.calculateChannelCenter();
191+
auto chPos = ft0Det.getChannelCenter(chno);
192+
return RecoDecay::phi(chPos.X() + offsetX, chPos.Y() + offsetY);
193+
}
194+
195+
double getEtaFT0(int chno, double offsetX, double offsetY, double offsetZ)
196+
{
197+
o2::ft0::Geometry ft0Det;
198+
ft0Det.calculateChannelCenter();
199+
auto chPos = ft0Det.getChannelCenter(chno);
200+
auto x = chPos.X() + offsetX;
201+
auto y = chPos.Y() + offsetY;
202+
auto z = chPos.Z() + offsetZ;
203+
auto r = std::sqrt(x * x + y * y);
204+
auto theta = std::atan2(r, z);
205+
return -std::log(std::tan(0.5 * theta));
206+
}
207+
208+
Filter fTrackSelectionITS = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) &&
209+
ncheckbit(aod::track::trackCutFlag, TrackSelectionIts);
210+
Filter fTrackSelectionTPC = ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC),
211+
ncheckbit(aod::track::trackCutFlag, TrackSelectionTpc), true);
212+
Filter fTrackSelectionDCA = ifnode(dcaZ.node() > 0.f, nabs(aod::track::dcaZ) <= dcaZ && ncheckbit(aod::track::trackCutFlag, TrackSelectionDcaxyOnly),
213+
ncheckbit(aod::track::trackCutFlag, TrackSelectionDca));
214+
Filter fTracksEta = nabs(aod::track::eta) < cfgEtaCut;
215+
Filter fTracksPt = (aod::track::pt > cfgPtCutMin) && (aod::track::pt < cfgPtCutMax);
216+
217+
template <typename CheckCol>
218+
bool isEventSelected(CheckCol const& col)
219+
{
220+
histos.fill(HIST("QA/EventHist"), 1);
221+
if (!col.sel8()) {
222+
return false;
223+
}
224+
histos.fill(HIST("QA/EventHist"), 2);
225+
if (std::abs(col.posZ()) >= cfgVtxCut) {
226+
return false;
227+
}
228+
histos.fill(HIST("QA/EventHist"), 3);
229+
histos.fill(HIST("QA/VtxZHist"), col.posZ());
230+
return true;
231+
}
232+
233+
template <typename TTracks>
234+
void fillYield(TTracks tracks, bool mixing)
235+
{
236+
if (mixing) {
237+
histos.fill(HIST("ME/hMult"), tracks.size());
238+
for (auto const& triggerTrack : tracks) {
239+
histos.fill(HIST("ME/Trig_etavsphi"), triggerTrack.phi(), triggerTrack.eta());
240+
histos.fill(HIST("ME/Trig_eta"), triggerTrack.eta());
241+
histos.fill(HIST("ME/Trig_phi"), triggerTrack.phi());
242+
histos.fill(HIST("ME/Trig_pt"), triggerTrack.pt());
243+
}
244+
} else {
245+
histos.fill(HIST("SE/hMult"), tracks.size());
246+
for (auto const& triggerTrack : tracks) {
247+
histos.fill(HIST("SE/Trig_etavsphi"), triggerTrack.phi(), triggerTrack.eta());
248+
histos.fill(HIST("SE/Trig_eta"), triggerTrack.eta());
249+
histos.fill(HIST("SE/Trig_phi"), triggerTrack.phi());
250+
histos.fill(HIST("SE/Trig_pt"), triggerTrack.pt());
251+
}
252+
}
253+
}
254+
255+
template <CorrelationContainer::CFStep step, typename TTarget, typename TTriggers, typename TFT0s>
256+
void fillCorrelation(TTarget target, TTriggers const& triggers, TFT0s const& ft0, bool mixing, float vz)
257+
{
258+
int fSampleIndex = gRandom->Uniform(0, cfgSampleSize);
259+
if (!mixing)
260+
histos.fill(HIST("SE/hMult_used"), triggers.size());
261+
for (auto const& triggerTrack : triggers) {
262+
if (!mixing)
263+
histos.fill(HIST("SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt());
264+
265+
auto offsetFT0Ax = (*offsetFT0)[0].getX();
266+
auto offsetFT0Ay = (*offsetFT0)[0].getY();
267+
auto offsetFT0Az = (*offsetFT0)[0].getZ();
268+
for (std::size_t iChA = 0; iChA < ft0.channelA().size(); iChA++) {
269+
auto chanelid = ft0.channelA()[iChA];
270+
float ampl = ft0.amplitudeA()[iChA];
271+
if (ampl <= 0)
272+
continue;
273+
if (mixing)
274+
histos.fill(HIST("ME/FT0Amp"), chanelid, ampl);
275+
else
276+
histos.fill(HIST("SE/FT0Amp"), chanelid, ampl);
277+
278+
auto phiA = getPhiFT0(chanelid, offsetFT0Ax, offsetFT0Ay);
279+
auto etaA = getEtaFT0(chanelid, offsetFT0Ax, offsetFT0Ay, offsetFT0Az);
280+
281+
if (mixing) {
282+
histos.fill(HIST("ME/FT0Aeta"), etaA);
283+
histos.fill(HIST("ME/FT0Aphi"), phiA);
284+
histos.fill(HIST("ME/FT0Aetavsphi"), phiA, etaA);
285+
} else {
286+
histos.fill(HIST("SE/FT0Aeta"), etaA);
287+
histos.fill(HIST("SE/FT0Aphi"), phiA);
288+
histos.fill(HIST("SE/FT0Aetavsphi"), phiA, etaA);
289+
}
290+
float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - phiA, -PIHalf);
291+
float deltaEta = triggerTrack.eta() - etaA;
292+
if (mixing)
293+
histos.fill(HIST("ME/deltaEta_deltaPhi"), deltaPhi, deltaEta);
294+
else
295+
histos.fill(HIST("SE/deltaEta_deltaPhi"), deltaPhi, deltaEta);
296+
target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta);
297+
} // associated ft0 tracks
298+
} // trigger tracks
299+
} // fillCorrelation
300+
301+
void processSE(CollTable::iterator const& col, aod::FT0s const&, TrksTable const& tracks)
302+
{
303+
if (!isEventSelected(col)) {
304+
return;
305+
}
306+
if (col.has_foundFT0()) {
307+
fillYield(tracks, false);
308+
const auto& ft0 = col.foundFT0();
309+
if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) {
310+
return;
311+
}
312+
fillCorrelation<CorrelationContainer::kCFStepReconstructed>(same, tracks, ft0, false, col.posZ());
313+
}
314+
} // same event
315+
316+
void processME(CollTable const& col, aod::FT0s const&, TrksTable const& tracks)
317+
{
318+
auto getTracksSize = [&tracks, this](CollTable::iterator const& collision) {
319+
auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache);
320+
return associatedTracks.size();
321+
};
322+
using MixedBinning = FlexibleBinningPolicy<std::tuple<decltype(getTracksSize)>, aod::collision::PosZ, decltype(getTracksSize)>;
323+
MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxZME, axisMultME}, true};
324+
for (auto const& [col1, col2] : soa::selfCombinations(binningOnVtxAndMult, mixingParameter, -1, col, col)) {
325+
if (!isEventSelected(col1) || !isEventSelected(col2)) {
326+
continue;
327+
}
328+
if (col1.globalIndex() == col2.globalIndex()) {
329+
histos.fill(HIST("QA/hMixingQA"), 1.0); // same-collision pair counting
330+
continue;
331+
}
332+
if (col1.has_foundFT0() && col2.has_foundFT0()) {
333+
histos.fill(HIST("QA/hMEpvz1"), col1.posZ());
334+
histos.fill(HIST("QA/hMEpvz2"), col2.posZ());
335+
auto slicedTriggerTracks = tracks.sliceBy(perCollision, col1.globalIndex());
336+
fillYield(slicedTriggerTracks, true);
337+
const auto& ft0 = col2.foundFT0();
338+
if (slicedTriggerTracks.size() < cfgMinMult || slicedTriggerTracks.size() >= cfgMaxMult) {
339+
continue;
340+
}
341+
fillCorrelation<CorrelationContainer::kCFStepReconstructed>(mixed, slicedTriggerTracks, ft0, true, col1.posZ());
342+
}
343+
}
344+
} // mixed event
345+
346+
PROCESS_SWITCH(LongrangeCorrelation, processSE, "process same event", false);
347+
PROCESS_SWITCH(LongrangeCorrelation, processME, "process mixed event", false);
348+
};
349+
350+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
351+
{
352+
return WorkflowSpec{adaptAnalysisTask<LongrangeCorrelation>(cfgc)};
353+
}

0 commit comments

Comments
 (0)