Skip to content

Commit 4e97659

Browse files
authored
Generic JQVectors class for JCorran (AliceO2Group#5632)
1 parent f628608 commit 4e97659

File tree

4 files changed

+134
-87
lines changed

4 files changed

+134
-87
lines changed

PWGCF/JCorran/Core/JFFlucAnalysis.cxx

+7-7
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ TComplex JFFlucAnalysis::Q(int n, int p)
335335
{
336336
// Return QvectorQC
337337
// Q{-n, p} = Q{n, p}*
338-
return n >= 0 ? QvectorQC[n][p] : C(QvectorQC[-n][p]);
338+
return n >= 0 ? pqvecs->QvectorQC[n][p] : C(pqvecs->QvectorQC[-n][p]);
339339
}
340340

341341
TComplex JFFlucAnalysis::Two(int n1, int n2)
@@ -355,11 +355,11 @@ TComplex JFFlucAnalysis::Four(int n1, int n2, int n3, int n4)
355355
void JFFlucAnalysis::UserExec(Option_t* popt)
356356
{
357357
for (UInt_t ih = 2; ih < kNH; ih++) {
358-
fh_cos_n_phi[ih][fCBin]->Fill(QvectorQC[ih][1].Re() / QvectorQC[0][1].Re());
359-
fh_sin_n_phi[ih][fCBin]->Fill(QvectorQC[ih][1].Im() / QvectorQC[0][1].Re());
358+
fh_cos_n_phi[ih][fCBin]->Fill(pqvecs->QvectorQC[ih][1].Re() / pqvecs->QvectorQC[0][1].Re());
359+
fh_sin_n_phi[ih][fCBin]->Fill(pqvecs->QvectorQC[ih][1].Im() / pqvecs->QvectorQC[0][1].Re());
360360
//
361361
//
362-
Double_t psi = QvectorQC[ih][1].Theta();
362+
Double_t psi = pqvecs->QvectorQC[ih][1].Theta();
363363
fh_psi_n[ih][fCBin]->Fill(psi);
364364
fh_cos_n_psi_n[ih][fCBin]->Fill(TMath::Cos((Double_t)ih * psi));
365365
fh_sin_n_psi_n[ih][fCBin]->Fill(TMath::Sin((Double_t)ih * psi));
@@ -372,7 +372,7 @@ void JFFlucAnalysis::UserExec(Option_t* popt)
372372
TComplex ncorr[kNH][nKL];
373373
TComplex ncorr2[kNH][nKL][kcNH][nKL];
374374

375-
const TComplex(*pQq)[kNH][nKL] = QvectorQCgap;
375+
const TComplex(*pQq)[kNH][nKL] = pqvecs->QvectorQCgap;
376376

377377
for (UInt_t i = 0; i < 2; ++i) {
378378
if ((subeventMask & (1 << i)) == 0)
@@ -531,7 +531,7 @@ void JFFlucAnalysis::UserExec(Option_t* popt)
531531
if (flags & kFlucEbEWeighting) {
532532
event_weight_four = Four(0, 0, 0, 0).Re();
533533
event_weight_two = Two(0, 0).Re();
534-
event_weight_two_gap = (QvectorQCgap[kSubA][0][1] * QvectorQCgap[kSubB][0][1]).Re();
534+
event_weight_two_gap = (pqvecs->QvectorQCgap[kSubA][0][1] * pqvecs->QvectorQCgap[kSubB][0][1]).Re();
535535
}
536536

537537
for (UInt_t ih = 2; ih < kNH; ih++) {
@@ -544,7 +544,7 @@ void JFFlucAnalysis::UserExec(Option_t* popt)
544544
TComplex sctwo = Two(ih, -ih) / Two(0, 0).Re();
545545
fh_SC_with_QC_2corr[ih][fCBin]->Fill(sctwo.Re(), event_weight_two);
546546

547-
TComplex sctwoGap = (QvectorQCgap[kSubA][ih][1] * TComplex::Conjugate(QvectorQCgap[kSubB][ih][1])) / (QvectorQCgap[kSubA][0][1] * QvectorQCgap[kSubB][0][1]).Re();
547+
TComplex sctwoGap = (pqvecs->QvectorQCgap[kSubA][ih][1] * TComplex::Conjugate(pqvecs->QvectorQCgap[kSubB][ih][1])) / (pqvecs->QvectorQCgap[kSubA][0][1] * pqvecs->QvectorQCgap[kSubB][0][1]).Re();
548548
fh_SC_with_QC_2corr_gap[ih][fCBin]->Fill(sctwoGap.Re(), event_weight_two_gap);
549549
}
550550
}

PWGCF/JCorran/Core/JFFlucAnalysis.h

+35-79
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <experimental/type_traits>
1919
#include "JHistManager.h"
20+
#include "JQVectors.h"
2021
#include <TComplex.h>
2122
#include <tuple>
2223

@@ -82,26 +83,34 @@ class JFFlucAnalysis
8283
flags |= _flags;
8384
}
8485

86+
enum { kH0,
87+
kH1,
88+
kH2,
89+
kH3,
90+
kH4,
91+
kH5,
92+
kH6,
93+
kH7,
94+
kH8,
95+
kH9,
96+
kH10,
97+
kH11,
98+
kH12,
99+
kNH }; // harmonics
100+
enum { kK0,
101+
kK1,
102+
kK2,
103+
kK3,
104+
kK4,
105+
nKL }; // order
106+
using JQVectorsT = JQVectors<TComplex, kNH, nKL, true>;
107+
inline void SetJQVectors(const JQVectorsT* _pqvecs) { pqvecs = _pqvecs; }
108+
85109
template <class T>
86110
using hasWeightNUA = decltype(std::declval<T&>().weightNUA());
87111
template <class T>
88112
using hasWeightEff = decltype(std::declval<T&>().weightEff());
89113

90-
template <class JInputClassIter>
91-
inline std::tuple<double, double> GetWeights(const JInputClassIter& track)
92-
{
93-
Double_t phiNUACorr, effCorr;
94-
if constexpr (std::experimental::is_detected<hasWeightNUA, const JInputClassIter>::value)
95-
phiNUACorr = track.weightNUA();
96-
else
97-
phiNUACorr = 1.0;
98-
if constexpr (std::experimental::is_detected<hasWeightEff, const JInputClassIter>::value)
99-
effCorr = track.weightEff();
100-
else
101-
effCorr = 1.0;
102-
return {phiNUACorr, effCorr};
103-
}
104-
105114
template <class JInputClass>
106115
inline void FillQA(JInputClass& inputInst)
107116
{
@@ -122,76 +131,24 @@ class JFFlucAnalysis
122131
if (TMath::Abs(track.eta()) < fEta_min || TMath::Abs(track.eta()) > fEta_max)
123132
continue;
124133

125-
auto [phiNUACorr, effCorr] = GetWeights<const typename JInputClass::iterator>(track);
126-
Double_t effCorrInv = 1.0 / effCorr;
127-
fh_eta[fCBin]->Fill(track.eta(), effCorrInv);
128-
fh_pt[fCBin]->Fill(track.pt(), effCorrInv);
129-
fh_phi[fCBin][(UInt_t)(track.eta() > 0.0)]->Fill(track.phi(), effCorrInv / phiNUACorr);
134+
Double_t corrInv = 1.0;
135+
using JInputClassIter = typename JInputClass::iterator;
136+
if constexpr (std::experimental::is_detected<hasWeightEff, const JInputClassIter>::value)
137+
corrInv /= track.weightEff();
138+
fh_eta[fCBin]->Fill(track.eta(), corrInv);
139+
fh_pt[fCBin]->Fill(track.pt(), corrInv);
140+
if constexpr (std::experimental::is_detected<hasWeightNUA, const JInputClassIter>::value)
141+
corrInv /= track.weightNUA();
142+
fh_phi[fCBin][(UInt_t)(track.eta() > 0.0)]->Fill(track.phi(), corrInv);
130143
}
131144

132145
for (UInt_t iaxis = 0; iaxis < 3; iaxis++)
133146
fh_vertex[iaxis]->Fill(fVertex[iaxis]);
134-
};
135-
136-
#define NK nKL // avoid cpplint "variable size array" error when in reality it is fixed size TComplex q[nKL]
137-
template <class JInputClass>
138-
inline void CalculateQvectorsQC(JInputClass& inputInst)
139-
{
140-
// calculate Q-vector for QC method ( no subgroup )
141-
for (UInt_t ih = 0; ih < kNH; ih++) {
142-
for (UInt_t ik = 0; ik < nKL; ++ik) {
143-
QvectorQC[ih][ik] = TComplex(0, 0);
144-
for (UInt_t isub = 0; isub < 2; isub++)
145-
QvectorQCgap[isub][ih][ik] = TComplex(0, 0);
146-
}
147-
} // for max harmonics
148-
for (auto& track : inputInst) {
149-
// pt cuts already applied in task.
150-
if (track.eta() < -fEta_max || track.eta() > fEta_max)
151-
continue;
152-
153-
auto [phiNUACorr, effCorr] = GetWeights<const typename JInputClass::iterator>(track);
154-
155-
UInt_t isub = (UInt_t)(track.eta() > 0.0);
156-
for (UInt_t ih = 0; ih < kNH; ih++) {
157-
Double_t tf = 1.0;
158-
TComplex q[NK];
159-
for (UInt_t ik = 0; ik < nKL; ik++) {
160-
q[ik] = TComplex(tf * TMath::Cos(ih * track.phi()), tf * TMath::Sin(ih * track.phi()));
161-
QvectorQC[ih][ik] += q[ik];
162-
163-
if (TMath::Abs(track.eta()) > fEta_min)
164-
QvectorQCgap[isub][ih][ik] += q[ik];
165-
166-
tf *= 1.0 / (phiNUACorr * effCorr);
167-
}
168-
}
169-
}
170-
};
147+
}
171148

172149
static Double_t pttJacek[74];
173150
static UInt_t NpttJacek;
174151

175-
enum { kH0,
176-
kH1,
177-
kH2,
178-
kH3,
179-
kH4,
180-
kH5,
181-
kH6,
182-
kH7,
183-
kH8,
184-
kH9,
185-
kH10,
186-
kH11,
187-
kH12,
188-
kNH }; // harmonics
189-
enum { kK0,
190-
kK1,
191-
kK2,
192-
kK3,
193-
kK4,
194-
nKL }; // order
195152
#define kcNH kH6 // max second dimension + 1
196153
private:
197154
const Double_t* fVertex; //!
@@ -209,8 +166,7 @@ class JFFlucAnalysis
209166
Double_t fEta_min;
210167
Double_t fEta_max;
211168

212-
TComplex QvectorQC[kNH][nKL];
213-
TComplex QvectorQCgap[2][kNH][nKL]; // ksub
169+
const JQVectorsT* pqvecs;
214170

215171
JHistManager* fHMG; //!
216172

PWGCF/JCorran/Core/JQVectors.h

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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+
/// \author Dong Jo Kim ([email protected])
12+
/// \author Jasper Parkkila ([email protected])
13+
/// \since Sep 2022
14+
15+
#ifndef PWGCF_JCORRAN_CORE_JQVECTORS_H_
16+
#define PWGCF_JCORRAN_CORE_JQVECTORS_H_
17+
18+
#include <experimental/type_traits>
19+
#include <TMath.h>
20+
21+
template <class Q, UInt_t nh, UInt_t nk>
22+
class JQVectorsGapBase
23+
{
24+
public:
25+
JQVectorsGapBase() {}
26+
virtual ~JQVectorsGapBase() {}
27+
Q QvectorQCgap[2][nh][nk];
28+
};
29+
30+
class JQVectorsEmptyBase
31+
{
32+
public:
33+
//
34+
};
35+
36+
template <class Q, UInt_t nh, UInt_t nk, bool gap>
37+
class JQVectors : public std::conditional_t<gap, JQVectorsGapBase<Q, nh, nk>, JQVectorsEmptyBase>
38+
{
39+
public:
40+
JQVectors() {}
41+
~JQVectors() {}
42+
43+
template <class T>
44+
using hasWeightNUA = decltype(std::declval<T&>().weightNUA());
45+
template <class T>
46+
using hasWeightEff = decltype(std::declval<T&>().weightEff());
47+
48+
template <class JInputClass>
49+
inline void Calculate(JInputClass& inputInst, float etamax, float etamin)
50+
{
51+
// calculate Q-vector for QC method ( no subgroup )
52+
for (UInt_t ih = 0; ih < nh; ++ih) {
53+
for (UInt_t ik = 0; ik < nk; ++ik) {
54+
QvectorQC[ih][ik] = Q(0, 0);
55+
if constexpr (gap) {
56+
for (UInt_t isub = 0; isub < 2; ++isub)
57+
this->QvectorQCgap[isub][ih][ik] = Q(0, 0);
58+
}
59+
}
60+
}
61+
for (auto& track : inputInst) {
62+
if (track.eta() < -etamax || track.eta() > etamax)
63+
continue;
64+
65+
UInt_t isub = (UInt_t)(track.eta() > 0.0);
66+
for (UInt_t ih = 0; ih < nh; ++ih) {
67+
Double_t tf = 1.0;
68+
for (UInt_t ik = 0; ik < nk; ++ik) {
69+
Q q(tf * TMath::Cos(ih * track.phi()), tf * TMath::Sin(ih * track.phi()));
70+
QvectorQC[ih][ik] += q;
71+
72+
if constexpr (gap) {
73+
if (TMath::Abs(track.eta()) > etamin)
74+
this->QvectorQCgap[isub][ih][ik] += q;
75+
}
76+
77+
using JInputClassIter = typename JInputClass::iterator;
78+
if constexpr (std::experimental::is_detected<hasWeightNUA, const JInputClassIter>::value)
79+
tf /= track.weightNUA();
80+
if constexpr (std::experimental::is_detected<hasWeightEff, const JInputClassIter>::value)
81+
tf /= track.weightEff();
82+
}
83+
}
84+
}
85+
}
86+
Q QvectorQC[nh][nk];
87+
};
88+
89+
#endif // PWGCF_JCORRAN_CORE_JQVECTORS_H_

PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx

+3-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ struct jflucAnalysisTask {
184184
{
185185
pcf->Init();
186186
pcf->FillQA(tracks);
187-
pcf->CalculateQvectorsQC(tracks);
187+
qvecs.Calculate(tracks, etamin, etamax);
188+
pcf->SetJQVectors(&qvecs);
188189
const auto& edges = AxisSpec(axisMultiplicity).binEdges;
189190
for (UInt_t i = 0, n = AxisSpec(axisMultiplicity).getNbins(); i < n; ++i)
190191
if (collision.multiplicity() < edges[i + 1]) {
@@ -221,6 +222,7 @@ struct jflucAnalysisTask {
221222
}
222223
PROCESS_SWITCH(jflucAnalysisTask, processCFDerivedCorrected, "Process CF derived data with corrections", false);
223224

225+
JFFlucAnalysis::JQVectorsT qvecs;
224226
JFFlucAnalysis* pcf;
225227
};
226228

0 commit comments

Comments
 (0)