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+ #include " PWGCF/Core/CorrelationContainer.h"
13+ #include " PWGCF/Core/PairCuts.h"
14+
15+ #include " CommonConstants/MathConstants.h"
16+ #include " Common/DataModel/EventSelection.h"
17+ #include " Common/DataModel/TrackSelectionTables.h"
18+ #include " Common/Core/RecoDecay.h"
19+
20+ #include " CommonConstants/MathConstants.h"
21+ #include " Framework/runDataProcessing.h"
22+ #include " Framework/AnalysisTask.h"
23+ #include " Framework/AnalysisDataModel.h"
24+ #include " Framework/ASoAHelpers.h"
25+ #include " Framework/HistogramRegistry.h"
26+ #include " Framework/RunningWorkflowInfo.h"
27+
28+ using namespace o2 ;
29+ using namespace o2 ::framework;
30+ using namespace o2 ::framework::expressions;
31+
32+ static constexpr float cfgPairCutDefaults[1 ][5 ] = {{-1 , -1 , -1 , -1 , -1 }};
33+ constexpr float kThreeHalfPi = 1 .5f * PI;
34+
35+ struct TwoParticleCorrelations {
36+
37+ // Declare configurables on events/collisions
38+ Configurable<int > minMultiplicity{" minMultiplicity" , 2 , {" Range on multiplicity" }};
39+ Configurable<int > range1Max{" range1Max" , 10 , {" Range on multiplicity" }};
40+ Configurable<int > range2Min{" range2Min" , 11 , {" Range on multiplicity" }};
41+ Configurable<int > range2Max{" range2Max" , 20 , {" Range on multiplicity" }};
42+ Configurable<int > range3Min{" range3Min" , 21 , {" Range on multiplicity" }};
43+ Configurable<int > range3Max{" range3Max" , 30 , {" Range on multiplicity" }};
44+ Configurable<int > range4Min{" range4Min" , 31 , {" Range on multiplicity" }};
45+ Configurable<int > range4Max{" range4Max" , 40 , {" Range on multiplicity" }};
46+ Configurable<int > range5Min{" range5Min" , 41 , {" Range on multiplicity" }};
47+ Configurable<int > range5Max{" range5Max" , 50 , {" Range on multiplicity" }};
48+ // Declare configurables for correlations
49+ Configurable<float > cfgZVtxCut = {" zvtxcut" , 10.0 , " Vertex z cut. Default 10 cm" };
50+ Configurable<float > cfgPtCutMin = {" minpt" , 0.2 , " Minimum accepted track pT. Default 0.2 GeV" };
51+ Configurable<float > cfgPtCutMax = {" maxpt" , 3.0 , " Maximum accepted track pT. Default 3.0 GeV" };
52+ Configurable<float > cfgEtaCut = {" etacut" , 0.8 , " Eta cut. Default 0.8" };
53+ Configurable<LabeledArray<float >> cfgPairCut{" cfgPairCut" ,
54+ {cfgPairCutDefaults[0 ],
55+ 5 ,
56+ {" Photon" , " K0" , " Lambda" , " Phi" , " Rho" }},
57+ " Pair cuts on various particles" };
58+ // Configurable<float> cfgTwoTrackCut{"cfgTwoTrackCut", -1, {"Two track cut"}};
59+ ConfigurableAxis axisVertex{" axisVertex" , {7 , -7 , 7 }, " vertex axis for histograms" };
60+ ConfigurableAxis axisDeltaPhi{" axisDeltaPhi" , {32 , -constants::math::PIHalf, constants::math::PIHalf * 3 }, " delta phi axis for histograms" };
61+ ConfigurableAxis axisDeltaEta{" axisDeltaEta" , {32 , -1.6 , 1.6 }, " delta eta axis for histograms" };
62+ 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" };
63+ ConfigurableAxis axisPtAssoc{" axisPtAssoc" , {VARIABLE_WIDTH, 0.5 , 1.0 , 1.5 , 2.0 , 3.0 , 4.0 , 6.0 }, " pt associated axis for histograms" };
64+ ConfigurableAxis axisMultiplicity{" axisMultiplicity" , {VARIABLE_WIDTH, 0 , 5 , 10 , 20 , 30 , 40 , 50 , 100.1 }," multiplicity / centrality axis for histograms" };
65+ ConfigurableAxis axisVertexEfficiency{" axisVertexEfficiency" , {10 , -10 , 10 }, " vertex axis for efficiency histograms" };
66+ ConfigurableAxis axisEtaEfficiency{" axisEtaEfficiency" , {20 , -1.0 , 1.0 }, " eta axis for efficiency histograms" };
67+ 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" };
68+
69+ // Output definitions
70+ OutputObj<CorrelationContainer> same{" sameEvent" };
71+ OutputObj<CorrelationContainer> mixed{" mixedEvent" };
72+ HistogramRegistry histos{" histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
73+ PairCuts mPairCuts ;
74+ bool doPairCuts = false ;
75+
76+ void init (InitContext&)
77+ {
78+ LOGF (info, " Starting init" );
79+
80+ histos.add (" yields" , " multiplicity/centrality vs pT vs eta" , {HistType::kTH3F , {{100 , 0 , 100 , " /multiplicity/centrality" }, {40 , 0 , 20 , " p_{T}" }, {100 , -2 , 2 , " #eta" }}});
81+ histos.add (" etaphi" , " multiplicity/centrality vs eta vs phi" , {HistType::kTH3F , {{100 , 0 , 100 , " multiplicity/centrality" }, {100 , -2 , 2 , " #eta" }, {200 , 0 , 2 * M_PI, " #varphi" }}});
82+ histos.add (" sameEvent2D" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
83+ histos.add (" sameEvent_2_10" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
84+ histos.add (" sameEvent_11_20" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
85+ histos.add (" sameEvent_21_30" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
86+ histos.add (" sameEvent_31_40" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
87+ histos.add (" sameEvent_41_50" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
88+ histos.add (" mixedEvent2D" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
89+ histos.add (" mixedEvent_2_10" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
90+ histos.add (" mixedEvent_11_20" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
91+ histos.add (" mixedEvent_21_30" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
92+ histos.add (" mixedEvent_31_40" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
93+ histos.add (" mixedEvent_41_50" , " #Delta #eta vs #Delta #phi" , {HistType::kTH2F , {axisDeltaEta, axisDeltaPhi}});
94+
95+ const int maxMixBin = axisMultiplicity->size () * axisVertex->size ();
96+ histos.add (" eventcount" , " bin" , {HistType::kTH1F , {{maxMixBin + 2 , -2.5 , -0.5 + maxMixBin, " bin" }}});
97+ mPairCuts .SetHistogramRegistry (&histos);
98+ if (cfgPairCut->get (" Photon" ) > 0 || cfgPairCut->get (" K0" ) > 0 || cfgPairCut->get (" Lambda" ) > 0 ||
99+ cfgPairCut->get (" Phi" ) > 0 || cfgPairCut->get (" Rho" ) > 0 ) {
100+ mPairCuts .SetPairCut (PairCuts::Photon, cfgPairCut->get (" Photon" ));
101+ mPairCuts .SetPairCut (PairCuts::K0, cfgPairCut->get (" K0" ));
102+ mPairCuts .SetPairCut (PairCuts::Lambda, cfgPairCut->get (" Lambda" ));
103+ mPairCuts .SetPairCut (PairCuts::Phi, cfgPairCut->get (" Phi" ));
104+ mPairCuts .SetPairCut (PairCuts::Rho, cfgPairCut->get (" Rho" ));
105+ doPairCuts = true ;
106+ }
107+
108+ std::vector<AxisSpec> corrAxis = {{axisDeltaEta, " #Delta#eta" },
109+ {axisPtAssoc, " p_{T} (GeV/c)" },
110+ {axisPtTrigger, " p_{T} (GeV/c)" },
111+ {axisMultiplicity, " multiplicity / centrality" },
112+ {axisDeltaPhi, " #Delta#varphi (rad)" },
113+ {axisVertex, " z-vtx (cm)" }};
114+ std::vector<AxisSpec> effAxis = {{axisEtaEfficiency, " #eta" },
115+ {axisEtaEfficiency, " #eta" },
116+ {axisPtEfficiency, " p_{T} (GeV/c)" },
117+ {axisVertexEfficiency, " z-vtx (cm)" }};
118+ same.setObject (new CorrelationContainer (" sameEvent" , " sameEvent" , corrAxis, effAxis, {}));
119+ mixed.setObject (new CorrelationContainer (" mixedEvent" , " mixedEvent" , corrAxis, effAxis, {}));
120+
121+ LOGF (info, " Finishing init" );
122+ }
123+
124+ Filter collisionZVtxFilter = nabs(aod::collision::posZ) < cfgZVtxCut;
125+ Filter trackFilter = (nabs(aod::track::eta) < cfgEtaCut) && (aod::track::pt > cfgPtCutMin) && (aod::track::pt < cfgPtCutMax) && (requireGlobalTrackInFilter() || (aod::track::isGlobalTrackSDD == (uint8_t ) true ));
126+
127+ struct SameEventTag {
128+ };
129+ struct MixedEventTag {
130+ };
131+
132+ template <typename TTracks>
133+ void fillQA (TTracks tracks, float multiplicity)
134+ {
135+ for (auto & track: tracks) {
136+ histos.fill (HIST (" yields" ), multiplicity, track.pt (), track.eta ());
137+ histos.fill (HIST (" etaphi" ), multiplicity, track.eta (), track.phi ());
138+ }
139+ }
140+
141+ template <typename TTarget, typename TCollision>
142+ bool fillCollision (TTarget target, TCollision collision, float multiplicity)
143+ {
144+ target->fillEvent (multiplicity, CorrelationContainer::kCFStepAll );
145+ if (!collision.alias_bit (kINT7 ) || !collision.sel7 ()){
146+ return false ;
147+ }
148+ target->fillEvent (multiplicity, CorrelationContainer::kCFStepReconstructed );
149+ return true ;
150+ }
151+
152+ template <typename TTarget, typename TTracks, typename TTag>
153+ void fillCorrelations (TTarget target, TTracks tracks1, TTracks tracks2, float multiplicity, float posZ)
154+ {
155+ for (const auto & track1 : tracks1) {
156+ if (isTrackCut (track1) == false ) {
157+ return ;
158+ }
159+ float phi1 = phi (track1.px (), track1.py ());
160+ phi1 = RecoDecay::constrainAngle (phi1, 0 .f );
161+ float eta1 = eta (track1.px (), track1.py (), track1.pz ());
162+ target->getTriggerHist ()->Fill (CorrelationContainer::kCFStepReconstructed , track1.pt (), multiplicity, posZ, 1.0 );
163+ for (const auto & track2 : tracks2) {
164+ if (track1 == track2) {
165+ continue ;
166+ }
167+ if (isTrackCut (track2) == false ) {
168+ return ;
169+ }
170+ float phi2 = phi (track2.px (), track2.py ());
171+ phi2 = RecoDecay::constrainAngle (phi2, 0 .f );
172+ float eta2 = eta (track2.px (), track2.py (), track2.pz ());
173+ if (doPairCuts && mPairCuts .conversionCuts (track1, track2)) {
174+ continue ;
175+ }
176+ float deltaPhi = phi1 - phi2;
177+ float deltaEta = eta1 - eta2;
178+ deltaPhi = RecoDecay::constrainAngle (deltaPhi, -PIHalf);
179+ target->getPairHist ()->Fill (CorrelationContainer::kCFStepReconstructed ,
180+ deltaEta,
181+ track2.pt (), track1.pt (),
182+ multiplicity,
183+ deltaPhi,
184+ posZ);
185+ if constexpr (std::is_same_v<TTag, SameEventTag>) {
186+ if (minMultiplicity <= multiplicity) {
187+ histos.fill (HIST (" sameEvent2D" ), deltaEta, deltaPhi);
188+ }
189+ if (minMultiplicity <= multiplicity && multiplicity <= range1Max) {
190+ histos.fill (HIST (" sameEvent_2_10" ), deltaEta, deltaPhi);
191+ }
192+ if (range2Min <= multiplicity && multiplicity <= range2Max) {
193+ histos.fill (HIST (" sameEvent_11_20" ), deltaEta, deltaPhi);
194+ }
195+ if (range3Min <= multiplicity && multiplicity <= range3Max) {
196+ histos.fill (HIST (" sameEvent_21_30" ), deltaEta, deltaPhi);
197+ }
198+ if (range4Min <= multiplicity && multiplicity <= range4Max) {
199+ histos.fill (HIST (" sameEvent_31_40" ), deltaEta, deltaPhi);
200+ }
201+ if (range5Min <= multiplicity && multiplicity <= range5Max) {
202+ histos.fill (HIST (" sameEvent_41_50" ), deltaEta, deltaPhi);
203+ }
204+ } else if constexpr (std::is_same_v<TTag, MixedEventTag>) {
205+ if (minMultiplicity <= multiplicity) {
206+ histos.fill (HIST (" mixedEvent2D" ), deltaEta, deltaPhi);
207+ }
208+ if (minMultiplicity <= multiplicity && multiplicity <= range1Max) {
209+ histos.fill (HIST (" mixedEvent_2_10" ), deltaEta, deltaPhi);
210+ }
211+ if (range2Min <= multiplicity && multiplicity <= range2Max) {
212+ histos.fill (HIST (" mixedEvent_11_20" ), deltaEta, deltaPhi);
213+ }
214+ if (range3Min <= multiplicity && multiplicity <= range3Max) {
215+ histos.fill (HIST (" mixedEvent_21_30" ), deltaEta, deltaPhi);
216+ }
217+ if (range4Min <= multiplicity && multiplicity <= range4Max) {
218+ histos.fill (HIST (" mixedEvent_31_40" ), deltaEta, deltaPhi);
219+ }
220+ if (range5Min <= multiplicity && multiplicity <= range5Max) {
221+ histos.fill (HIST (" mixedEvent_41_50" ), deltaEta, deltaPhi);
222+ }
223+ }
224+ }
225+ }
226+ }
227+
228+ void processSame ()
229+ {
230+ }
231+
232+ void processMixed ()
233+ {
234+ }
235+ void process (aod::Collision const &, aod::Tracks const &)
236+ {
237+ }
238+ };
239+
240+ WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
241+ {
242+ return WorkflowSpec{
243+ adaptAnalysisTask<TwoParticleCorrelations>(cfgc),
244+ };
245+ }
0 commit comments