Skip to content

Commit a8e06bf

Browse files
authored
Add derived-table-based long range task
1 parent d4a7afa commit a8e06bf

File tree

1 file changed

+327
-0
lines changed

1 file changed

+327
-0
lines changed
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
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 jurisdicstion.
11+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
12+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
13+
// All rights not expressly granted are reserved.
14+
//
15+
// This software is distributed under the terms of the GNU General Public
16+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
17+
//
18+
// In applying this license CERN does not waive the privileges and immunities
19+
// granted to it by virtue of its status as an Intergovernmental Organization
20+
// or submit itself to any jurisdiction.
21+
///
22+
/// \file longrangecorrDerived.cxx
23+
///
24+
/// \brief task for long range correlation analysis
25+
/// \author Abhi Modak (abhi.modak@cern.ch)
26+
/// \since November 02, 2025
27+
28+
#include "PWGCF/Core/CorrelationContainer.h"
29+
#include "PWGCF/Core/PairCuts.h"
30+
#include "PWGCF/DataModel/CorrelationsDerived.h"
31+
#include "PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h"
32+
#include "PWGMM/Mult/DataModel/bestCollisionTable.h"
33+
34+
#include "Common/Core/RecoDecay.h"
35+
#include "Common/Core/TrackSelection.h"
36+
#include "Common/Core/trackUtilities.h"
37+
#include "Common/DataModel/Centrality.h"
38+
#include "Common/DataModel/CollisionAssociationTables.h"
39+
#include "Common/DataModel/EventSelection.h"
40+
#include "Common/DataModel/FT0Corrected.h"
41+
#include "Common/DataModel/Multiplicity.h"
42+
#include "Common/DataModel/PIDResponse.h"
43+
#include "Common/DataModel/PIDResponseITS.h"
44+
#include "Common/DataModel/TrackSelectionTables.h"
45+
46+
#include "CCDB/BasicCCDBManager.h"
47+
#include "CCDB/CcdbApi.h"
48+
#include "CommonConstants/MathConstants.h"
49+
#include "CommonConstants/PhysicsConstants.h"
50+
#include "DetectorsCommonDataFormats/AlignParam.h"
51+
#include "FT0Base/Geometry.h"
52+
#include "FV0Base/Geometry.h"
53+
#include "Framework/ASoAHelpers.h"
54+
#include "Framework/AnalysisDataModel.h"
55+
#include "Framework/AnalysisTask.h"
56+
#include "Framework/HistogramRegistry.h"
57+
#include "Framework/O2DatabasePDGPlugin.h"
58+
#include "Framework/StepTHn.h"
59+
#include "Framework/runDataProcessing.h"
60+
#include "ReconstructionDataFormats/PID.h"
61+
#include "ReconstructionDataFormats/Track.h"
62+
63+
#include <TComplex.h>
64+
#include <TH1F.h>
65+
#include <TMath.h>
66+
#include <TPDGCode.h>
67+
68+
#include <chrono>
69+
#include <cstdio>
70+
#include <string>
71+
#include <vector>
72+
73+
using namespace o2;
74+
using namespace o2::framework;
75+
using namespace o2::framework::expressions;
76+
using namespace o2::aod::track;
77+
using namespace o2::aod::fwdtrack;
78+
using namespace o2::aod::evsel;
79+
using namespace o2::constants::math;
80+
81+
struct LongrangecorrDerived {
82+
83+
SliceCache cache;
84+
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
85+
Configurable<double> cfgSampleSize{"cfgSampleSize", 10, "Sample size for mixed event"};
86+
Configurable<int> cfgNmixedevent{"cfgNmixedevent", 5, "how many events are mixed"};
87+
Configurable<int> cfgPidMask{"cfgPidMask", 0, "Selection bitmask for the TPC particle"};
88+
Configurable<int> cfgV0Mask{"cfgV0Mask", 0, "Selection bitmask for the V0 particle"};
89+
Configurable<float> cfgVtxCut{"cfgVtxCut", 10.0f, "Vertex Z range to consider"};
90+
91+
ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 15, 25, 50, 60, 1000}, "multiplicity axis"};
92+
ConfigurableAxis axisPhi{"axisPhi", {96, 0, TwoPI}, "#phi axis"};
93+
ConfigurableAxis axisEtaTrig{"axisEtaTrig", {40, -1., 1.}, "#eta trig axis"};
94+
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"};
95+
ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt assoc axis for histograms"};
96+
ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"};
97+
ConfigurableAxis axisVtxZ{"axisVtxZ", {40, -20, 20}, "vertex axis"};
98+
ConfigurableAxis channelFt0aAxis{"channelFt0aAxis", {96, 0.0, 96.0}, "FT0A channel"};
99+
ConfigurableAxis amplitudeFt0a{"amplitudeFt0a", {5000, 0, 10000}, "FT0A amplitude"};
100+
ConfigurableAxis axisEtaAssoc{"axisEtaAssoc", {96, 3.5, 4.9}, "#eta assoc axis"};
101+
ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"};
102+
ConfigurableAxis axisDeltaEta{"axisDeltaEta", {40, -6, -2}, "delta eta axis for histograms"};
103+
ConfigurableAxis axisInvMass{"axisInvMass", {VARIABLE_WIDTH, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2.0}, "invariant mass axis"};
104+
ConfigurableAxis axisMultME{"axisMultME", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 1000}, "Mixing bins - multiplicity"};
105+
ConfigurableAxis axisVtxZME{"axisVtxZME", {VARIABLE_WIDTH, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10}, "Mixing bins - z-vertex"};
106+
107+
ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"};
108+
ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"};
109+
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"};
110+
111+
OutputObj<CorrelationContainer> same{"sameEvent"};
112+
OutputObj<CorrelationContainer> mixed{"mixedEvent"};
113+
114+
void init(InitContext const&)
115+
{
116+
std::vector<AxisSpec> corrAxis = {{axisSample, "Sample"},
117+
{axisVtxZ, "z-vtx (cm)"},
118+
{axisPtTrigger, "p_{T} (GeV/c)"},
119+
{axisPtAssoc, "p_{T} (GeV/c)"},
120+
{axisDeltaPhi, "#Delta#varphi (rad)"},
121+
{axisDeltaEta, "#Delta#eta"}};
122+
std::vector<AxisSpec> effAxis = {{axisVertexEfficiency, "z-vtx (cm)"},
123+
{axisPtEfficiency, "p_{T} (GeV/c)"},
124+
{axisEtaEfficiency, "#eta"}};
125+
std::vector<AxisSpec> userAxis = {{axisMultiplicity, "multiplicity"},
126+
{axisInvMass, "m (GeV/c^2)"}};
127+
128+
same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis));
129+
mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis));
130+
131+
histos.add("hMultiplicity", "hMultiplicity", kTH1D, {axisMultiplicity});
132+
histos.add("hCentrality", "hCentrality", kTH1D, {axisMultiplicity});
133+
histos.add("hVertexZ", "hVertexZ", kTH1D, {axisVtxZ});
134+
135+
histos.add("Trig_eta", "Trig_eta", kTH1D, {axisEtaTrig});
136+
histos.add("Trig_phi", "Trig_phi", kTH1D, {axisPhi});
137+
histos.add("Trig_etavsphi", "Trig_etavsphi", kTH2D, {axisPhi, axisEtaTrig});
138+
histos.add("Trig_pt", "Trig_pt", kTH1D, {axisPtTrigger});
139+
histos.add("Trig_hist", "Trig_hist", kTHnSparseF, {axisSample, axisVtxZ, axisPtTrigger, axisMultiplicity, axisInvMass});
140+
141+
histos.add("Assoc_eta", "Assoc_eta", kTH1D, {axisEtaAssoc});
142+
histos.add("Assoc_phi", "Assoc_phi", kTH1D, {axisPhi});
143+
histos.add("Assoc_etavsphi", "Assoc_etavsphi", kTH2D, {axisPhi, axisEtaAssoc});
144+
histos.add("Assoc_pt", "Assoc_pt", kTH1D, {axisPtAssoc});
145+
146+
histos.add("deltaEta_deltaPhi_same", "", kTH2D, {axisDeltaPhi, axisDeltaEta});
147+
histos.add("deltaEta_deltaPhi_mixed", "", kTH2D, {axisDeltaPhi, axisDeltaEta});
148+
}
149+
150+
template <typename TCollision>
151+
void fillCollQA(TCollision const& col)
152+
{
153+
histos.fill(HIST("hMultiplicity"), col.multiplicity());
154+
histos.fill(HIST("hCentrality"), col.centrality());
155+
histos.fill(HIST("hVertexZ"), col.zvtx());
156+
}
157+
158+
template <typename TTrack>
159+
void fillTrigTrackQA(TTrack const& track)
160+
{
161+
histos.fill(HIST("Trig_etavsphi"), track.phi(), track.eta());
162+
histos.fill(HIST("Trig_eta"), track.eta());
163+
histos.fill(HIST("Trig_phi"), track.phi());
164+
histos.fill(HIST("Trig_pt"), track.pt());
165+
}
166+
167+
template <typename TTrack>
168+
void fillAssocTrackQA(TTrack const& track)
169+
{
170+
histos.fill(HIST("Assoc_etavsphi"), track.phi(), track.eta());
171+
histos.fill(HIST("Assoc_eta"), track.eta());
172+
histos.fill(HIST("Assoc_phi"), track.phi());
173+
}
174+
175+
template <class T>
176+
using HasTpcTrack = decltype(std::declval<T&>().trackType());
177+
template <class T>
178+
using HasV0Track = decltype(std::declval<T&>().v0Type());
179+
template <class T>
180+
using HasInvMass = decltype(std::declval<T&>().invMass());
181+
182+
template <CorrelationContainer::CFStep step, typename TTarget, typename TTriggers, typename TAssocs>
183+
void fillCorrHist(TTarget target, TTriggers const& triggers, TAssocs const& assocs, bool mixing, float vz, float multiplicity, float eventWeight)
184+
{
185+
int fSampleIndex = gRandom->Uniform(0, cfgSampleSize);
186+
for (auto const& triggerTrack : triggers) {
187+
if constexpr (std::experimental::is_detected<HasTpcTrack, typename TTriggers::iterator>::value) {
188+
if (cfgPidMask != 0 && (cfgPidMask & (1u << static_cast<uint32_t>(triggerTrack.trackType()))) == 0u)
189+
continue;
190+
} else if constexpr (std::experimental::is_detected<HasV0Track, typename TTriggers::iterator>::value) {
191+
if (cfgV0Mask != 0 && (cfgV0Mask & (1u << static_cast<uint32_t>(triggerTrack.v0Type()))) == 0u)
192+
continue;
193+
}
194+
if (!mixing) {
195+
fillTrigTrackQA(triggerTrack);
196+
if constexpr (std::experimental::is_detected<HasInvMass, typename TTriggers::iterator>::value) {
197+
histos.fill(HIST("Trig_hist"), fSampleIndex, vz, triggerTrack.pt(), multiplicity, triggerTrack.invMass(), eventWeight);
198+
} else {
199+
histos.fill(HIST("Trig_hist"), fSampleIndex, vz, triggerTrack.pt(), multiplicity, 1.0, eventWeight);
200+
}
201+
}
202+
for (auto const& assoTrack : assocs) {
203+
float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - assoTrack.phi(), -PIHalf);
204+
float deltaEta = triggerTrack.eta() - assoTrack.eta();
205+
if (!mixing) {
206+
fillAssocTrackQA(assoTrack);
207+
histos.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta);
208+
} else {
209+
histos.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta);
210+
}
211+
if constexpr (std::experimental::is_detected<HasInvMass, typename TTriggers::iterator>::value) {
212+
target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta, multiplicity, triggerTrack.invMass(), eventWeight);
213+
} else {
214+
target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta, multiplicity, 0., eventWeight);
215+
}
216+
} // associated tracks
217+
} // trigger tracks
218+
} // fill correlation
219+
220+
template <typename TCollision, typename TTriggers, typename TAssocs>
221+
void processSame(TCollision const& col, TTriggers const& triggers, TAssocs const& assocs)
222+
{
223+
if (std::abs(col.zvtx()) >= cfgVtxCut) {
224+
return;
225+
}
226+
fillCollQA(col);
227+
fillCorrHist<CorrelationContainer::kCFStepReconstructed>(same, triggers, assocs, false, col.zvtx(), col.multiplicity(), 1.0);
228+
} // process same
229+
230+
template <typename TCollision, typename... TrackTypes>
231+
void processMixed(TCollision const& col, TrackTypes&&... tracks)
232+
{
233+
auto getMultiplicity = [this](auto& collision) {
234+
return collision.multiplicity();
235+
};
236+
using MixedBinning = FlexibleBinningPolicy<std::tuple<decltype(getMultiplicity)>, aod::lrcorrcolltable::Zvtx, decltype(getMultiplicity)>;
237+
MixedBinning binningOnVtxAndMult{{getMultiplicity}, {axisVtxZME, axisMultME}, true};
238+
auto tracksTuple = std::make_tuple(std::forward<TrackTypes>(tracks)...);
239+
using tA = std::tuple_element<0, decltype(tracksTuple)>::type;
240+
using tB = std::tuple_element<std::tuple_size_v<decltype(tracksTuple)> - 1, decltype(tracksTuple)>::type;
241+
Pair<TCollision, tA, tB, MixedBinning> pairs{binningOnVtxAndMult, cfgNmixedevent, -1, col, tracksTuple, &cache};
242+
for (auto it = pairs.begin(); it != pairs.end(); it++) {
243+
auto& [col1, tracks1, col2, tracks2] = *it;
244+
float eventweight = 1.0f / it.currentWindowNeighbours();
245+
fillCorrHist<CorrelationContainer::kCFStepReconstructed>(mixed, tracks1, tracks2, true, col1.zvtx(), col1.multiplicity(), eventweight);
246+
} // pair loop
247+
} // process mixed
248+
249+
void processTpcft0aSE(aod::CollLRTables::iterator const& col, aod::TrkLRTables const& tracks, aod::Ft0aLRTables const& ft0as)
250+
{
251+
processSame(col, tracks, ft0as);
252+
}
253+
254+
void processTpcft0cSE(aod::CollLRTables::iterator const& col, aod::TrkLRTables const& tracks, aod::Ft0cLRTables const& ft0cs)
255+
{
256+
processSame(col, tracks, ft0cs);
257+
}
258+
259+
void processTpcmftSE(aod::CollLRTables::iterator const& col, aod::TrkLRTables const& tracks, aod::MftTrkLRTables const& mfts)
260+
{
261+
processSame(col, tracks, mfts);
262+
}
263+
264+
void processMftft0aSE(aod::CollLRTables::iterator const& col, aod::MftTrkLRTables const& mfts, aod::Ft0aLRTables const& ft0as)
265+
{
266+
processSame(col, mfts, ft0as);
267+
}
268+
269+
void processV0ft0aSE(aod::CollLRTables::iterator const& col, aod::V0TrkLRTables const& tracks, aod::Ft0aLRTables const& ft0as)
270+
{
271+
processSame(col, tracks, ft0as);
272+
}
273+
274+
void processV0mftSE(aod::CollLRTables::iterator const& col, aod::V0TrkLRTables const& tracks, aod::MftTrkLRTables const& mfts)
275+
{
276+
processSame(col, tracks, mfts);
277+
}
278+
279+
void processTpcft0aME(aod::CollLRTables const& col, aod::TrkLRTables const& tracks, aod::Ft0aLRTables const& ft0as)
280+
{
281+
processMixed(col, tracks, ft0as);
282+
}
283+
284+
void processTpcft0cME(aod::CollLRTables const& col, aod::TrkLRTables const& tracks, aod::Ft0cLRTables const& ft0cs)
285+
{
286+
processMixed(col, tracks, ft0cs);
287+
}
288+
289+
void processTpcmftME(aod::CollLRTables const& col, aod::TrkLRTables const& tracks, aod::MftTrkLRTables const& mfts)
290+
{
291+
processMixed(col, tracks, mfts);
292+
}
293+
294+
void processMftft0aME(aod::CollLRTables const& col, aod::MftTrkLRTables const& mfts, aod::Ft0aLRTables const& ft0as)
295+
{
296+
processMixed(col, mfts, ft0as);
297+
}
298+
299+
void processV0ft0aME(aod::CollLRTables const& col, aod::V0TrkLRTables const& tracks, aod::Ft0aLRTables const& ft0as)
300+
{
301+
processMixed(col, tracks, ft0as);
302+
}
303+
304+
void processV0mftME(aod::CollLRTables const& col, aod::V0TrkLRTables const& tracks, aod::MftTrkLRTables const& mfts)
305+
{
306+
processMixed(col, tracks, mfts);
307+
}
308+
309+
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aSE, "same event TPC vs FT0A", false);
310+
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aME, "mixed event TPC vs FT0A", false);
311+
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0cSE, "same event TPC vs FT0C", false);
312+
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0cME, "mixed event TPC vs FT0C", false);
313+
PROCESS_SWITCH(LongrangecorrDerived, processTpcmftSE, "same event TPC vs MFT", false);
314+
PROCESS_SWITCH(LongrangecorrDerived, processTpcmftME, "mixed event TPC vs MFT", false);
315+
PROCESS_SWITCH(LongrangecorrDerived, processMftft0aSE, "same event MFT vs FT0A", false);
316+
PROCESS_SWITCH(LongrangecorrDerived, processMftft0aME, "mixed event MFT vs FT0A", false);
317+
PROCESS_SWITCH(LongrangecorrDerived, processV0ft0aSE, "same event V0 vs FT0A", false);
318+
PROCESS_SWITCH(LongrangecorrDerived, processV0ft0aME, "mixed event V0 vs FT0A", false);
319+
PROCESS_SWITCH(LongrangecorrDerived, processV0mftSE, "same event V0 vs MFT", false);
320+
PROCESS_SWITCH(LongrangecorrDerived, processV0mftME, "mixed event V0 vs MFT", false);
321+
};
322+
323+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
324+
{
325+
return WorkflowSpec{
326+
adaptAnalysisTask<LongrangecorrDerived>(cfgc)};
327+
}

0 commit comments

Comments
 (0)