Skip to content

Commit 58ff590

Browse files
author
Neelkamal Mallick
committed
[PWGCF] JCorran: Add nonflow SPC correlators and a smaller Q-vector fill grid
1 parent 0897bd7 commit 58ff590

5 files changed

Lines changed: 99 additions & 29 deletions

File tree

‎PWGCF/JCorran/Core/FlowJSPCAnalysis.cxx‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,19 @@ void FlowJSPCAnalysis::calculateCorrelators(const int fCentBin)
125125
correlationDenom = 0.;
126126
weightCorrelationDenom = 0.;
127127
}
128+
129+
// N_m = Re(Q_{0,1}); weight M_m. 3SPC → fN3, 4SPC → fN4.
130+
if (mHistRegistry && qvecs) {
131+
const double nSel = qvecs->QvectorQC[0][1].Re();
132+
const float centX = static_cast<float>(fCentBin) + 0.5f;
133+
if (nSel > 0.0 && std::isfinite(nSel)) {
134+
if (mWhichSPC == 0 && fCorrelDenoms[2] > 0.0) {
135+
mHistRegistry->fill(HIST("fN3"), centX, nSel, fCorrelDenoms[2]);
136+
} else if (mWhichSPC == 1 && fCorrelDenoms[3] > 0.0) {
137+
mHistRegistry->fill(HIST("fN4"), centX, nSel, fCorrelDenoms[3]);
138+
}
139+
}
140+
}
128141
}
129142

130143
void FlowJSPCAnalysis::fillHistograms(const int fCentBin, int ind, double cNum, double cDenom, double wNum, double wDenom)

‎PWGCF/JCorran/Core/FlowJSPCAnalysis.h‎

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <Rtypes.h>
3131

32+
#include <cstdint>
3233
#include <cstring>
3334
#include <string_view>
3435
#include <vector>
@@ -42,6 +43,27 @@ class FlowJSPCAnalysis
4243
int getCentBin(float cValue);
4344

4445
using JQVectorsT = JQVectors<TComplex, 113, 15, false>;
46+
/// Fill-grid size for Q_{n,p}: (v8 * nPartDen)+1 harmonics, nPartDen+1 powers.
47+
static constexpr uint32_t Nh3p = 49; // 3-particle SPC, 6-particle denominator
48+
static constexpr uint32_t Nk3p = 7;
49+
static constexpr uint32_t Nh4p = 65; // 4-particle SPC, 8-particle denominator
50+
static constexpr uint32_t Nk4p = 9;
51+
static constexpr uint32_t NhFull = 113;
52+
static constexpr uint32_t NkFull = 15;
53+
void qVectorGrid(int whichSPC, uint32_t& nhUse, uint32_t& nkUse)
54+
{
55+
mWhichSPC = whichSPC;
56+
if (whichSPC == 0) {
57+
nhUse = Nh3p;
58+
nkUse = Nk3p;
59+
} else if (whichSPC == 1) {
60+
nhUse = Nh4p;
61+
nkUse = Nk4p;
62+
} else {
63+
nhUse = NhFull;
64+
nkUse = NkFull;
65+
}
66+
}
4567
inline void setQvectors(const JQVectorsT* _qvecs) { qvecs = _qvecs; }
4668
void correlation(int c_nPart, int c_nHarmo, int* harmo, double* correlData);
4769
void calculateCorrelators(const int fCentBin);
@@ -57,6 +79,9 @@ class FlowJSPCAnalysis
5779
return;
5880
}
5981
mHistRegistry->add("FullCentrality", "FullCentrality", o2::framework::HistType::kTH1D, {{100, 0., 100.}}, true);
82+
// Effective N_m per centrality class, weighted by M_m (arXiv:2606.10258 c0).
83+
mHistRegistry->add("fN3", "Effective N_{3};centrality class;N_{3}", {o2::framework::HistType::kTProfile, {{9, 0., 9.}}}, true);
84+
mHistRegistry->add("fN4", "Effective N_{4};centrality class;N_{4}", {o2::framework::HistType::kTProfile, {{9, 0., 9.}}}, true);
6085
mHistRegistry->add("Centrality_0/fResults", "Numerators and denominators", {o2::framework::HistType::kTProfile, {{24, 0., 24.}}}, true);
6186
mHistRegistry->add("Centrality_0/fCovResults", "Covariance N*D", {o2::framework::HistType::kTProfile, {{48, 0., 48.}}}, true);
6287
mHistRegistry->add("Centrality_0/phiBefore", "Phi before", {o2::framework::HistType::kTH1D, {{100, 0., o2::constants::math::TwoPI}}}, true);
@@ -67,13 +92,13 @@ class FlowJSPCAnalysis
6792
}
6893
}
6994

70-
void setCorrSet(int obsInd, int harmo[8])
95+
void setCorrSet(int obsInd, int const harmo[8])
7196
{
7297
for (int i = 0; i < 8; i++) {
7398
fHarmosArray[obsInd][i] = harmo[i];
7499
}
75100
}
76-
void setFullCorrSet(int harmo[12][8])
101+
void setFullCorrSet(int const harmo[12][8])
77102
{
78103
memcpy(fHarmosArray, harmo, sizeof(int) * 12 * 8);
79104
}
@@ -92,13 +117,14 @@ class FlowJSPCAnalysis
92117
private:
93118
const int mNqHarmos = 113; ///< Highest harmo for Q(n,p): (v8*14part)+1.
94119
const int mNqPowers = 15; ///< Max power for Q(n,p): 14part+1.
95-
const JQVectorsT* qvecs;
120+
const JQVectorsT* qvecs = nullptr;
96121

97122
o2::framework::HistogramRegistry* mHistRegistry = nullptr;
98123

99-
int fHarmosArray[12][8];
124+
int fHarmosArray[12][8] = {{0}};
100125

101-
double fCorrelDenoms[14];
126+
double fCorrelDenoms[14] = {0};
127+
int mWhichSPC = 0;
102128

103129
ClassDefNV(FlowJSPCAnalysis, 1);
104130
};

‎PWGCF/JCorran/Core/FlowJSPCObservables.h‎

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,42 +38,53 @@ class FlowJSPCObservables
3838
switch (index) {
3939
case 0: {
4040
LOGF(info, "Computing three harmonic SPC");
41-
int harmonicArray01[maxNrComb][8] = {
42-
{3, 6, -3, -3, 0, 0, 0, 0},
43-
{3, 4, -2, -2, 0, 0, 0, 0},
41+
// fResults slot j: num at 2j+0.5, denom at 2j+1.5. arXiv:2606.10258 nonflow refs in unused slots.
42+
int const harmonicArray01[maxNrComb][8] = {
43+
{3, 6, -3, -3, 0, 0, 0, 0}, // 0: C633 = <V3 V3 V6*>
44+
{3, 4, -2, -2, 0, 0, 0, 0}, // 1: C422 = <V2 V2 V4*>
4445
{3, 8, -4, -4, 0, 0, 0, 0},
45-
{3, 2, 4, -6, 0, 0, 0, 0},
46-
{3, 2, 3, -5, 0, 0, 0, 0},
46+
{3, 2, 4, -6, 0, 0, 0, 0}, // 3: C246 = <V2 V4 V6*>
47+
{3, 2, 3, -5, 0, 0, 0, 0}, // 4: C235 = <V2 V3 V5*>
4748
{3, 3, 4, -7, 0, 0, 0, 0}, // These are three harmonic SPC!!
4849
{3, 2, 5, -7, 0, 0, 0, 0}, // These are three harmonic SPC!!
4950
{3, 3, 5, -8, 0, 0, 0, 0}, // These are three harmonic SPC!!
50-
{0, 6, -2, -2, -2, 0, 0, 0},
51-
{0, 2, -3, -4, 5, 0, 0, 0},
52-
{0, 2, -3, -3, 4, 0, 0, 0},
53-
{0, 3, 3, -2, -2, -2, 0, 0}};
51+
// {0, 6, -2, -2, -2, 0, 0, 0},
52+
// {0, 2, -3, -4, 5, 0, 0, 0},
53+
// {0, 2, -3, -3, 4, 0, 0, 0},
54+
// {0, 3, 3, -2, -2, -2, 0, 0},
55+
{3, 1, 1, -2, 0, 0, 0, 0}, // 8: C112 = <V1 V1 V2*>, Eqs. (IV.7), (IV.18)
56+
{3, 1, 2, -3, 0, 0, 0, 0}, // 9: C123 = <V1 V2 V3*>, Eqs. (IV.8), (IV.18)
57+
{0, 0, 0, 0, 0, 0, 0, 0},
58+
{0, 0, 0, 0, 0, 0, 0, 0}};
5459

5560
memcpy(harmonicArray, harmonicArray01, sizeof(int) * maxNrComb * 8);
5661
} break;
5762
case 1: {
5863
LOGF(info, "Computing four harmonic SPC");
59-
int harmonicArray02[maxNrComb][8] = {
60-
{4, 6, -2, -2, -2, 0, 0, 0},
64+
// fResults slot j: num at 2j+0.5, denom at 2j+1.5. arXiv:2606.10258: c1{4}=<<4>>-2<<2>>^2 after averaging, Eq. (IV.6).
65+
int const harmonicArray02[maxNrComb][8] = {
66+
{4, 6, -2, -2, -2, 0, 0, 0}, // 0: C6222 = <V2 V2 V2 V6*>
6167
{4, 2, -3, -4, 5, 0, 0, 0},
6268
{4, 2, -3, -3, 4, 0, 0, 0},
6369
{4, 2, 2, 3, -7, 0, 0, 0}, // These are three harmonic SPC!!
6470
{4, 2, 2, 4, -8, 0, 0, 0}, // These are three harmonic SPC!!
6571
{4, 2, 7, -4, -5, 0, 0, 0},
6672
{4, 3, -4, -4, 5, 0, 0, 0},
67-
{0, 0, 0, 0, 0, 0, 0, 0},
68-
{0, 0, 0, 0, 0, 0, 0, 0},
69-
{0, 0, 0, 0, 0, 0, 0, 0},
73+
// {0, 0, 0, 0, 0, 0, 0, 0},
74+
// {0, 0, 0, 0, 0, 0, 0, 0},
75+
// {0, 0, 0, 0, 0, 0, 0, 0},
76+
// {0, 0, 0, 0, 0, 0, 0, 0},
77+
// {0, 0, 0, 0, 0, 0, 0, 0},
78+
{4, 1, 1, -1, -1, 0, 0, 0}, // 7: <<4>>_{1,1,-1,-1} for c1{4}
79+
{2, 1, -1, 0, 0, 0, 0, 0}, // 8: <<2>>_{1,-1} = <V1 V1*>
80+
{3, 1, 1, -2, 0, 0, 0, 0}, // 9: C112 on the 4-particle sample (mixed-order Eq. (IV.19))
7081
{0, 0, 0, 0, 0, 0, 0, 0},
7182
{0, 0, 0, 0, 0, 0, 0, 0}};
7283
memcpy(harmonicArray, harmonicArray02, sizeof(int) * maxNrComb * 8);
7384
} break;
7485
case 2: {
7586
LOGF(info, "Computing five and six harmonic SPC");
76-
int harmonicArray03[maxNrComb][8] = {
87+
int const harmonicArray03[maxNrComb][8] = {
7788
{5, 3, 3, -2, -2, -2, 0, 0},
7889
{5, 2, 2, -3, 4, -5, 0, 0},
7990
{5, 2, 3, 3, -4, -4, 0, 0},
@@ -90,7 +101,7 @@ class FlowJSPCObservables
90101
} break;
91102
case 3: {
92103
LOGF(info, "Computing slected five harmonic SPC");
93-
int harmonicArray04[maxNrComb][8] = {
104+
int const harmonicArray04[maxNrComb][8] = {
94105
{5, 3, 3, -2, -2, -2, 0, 0},
95106
{0, 2, 2, -3, 4, -5, 0, 0},
96107
{5, 2, 3, 3, -4, -4, 0, 0},

‎PWGCF/JCorran/Core/JQVectors.h‎

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <RtypesCore.h>
2121

22+
#include <algorithm>
23+
#include <cstdint>
2224
#include <experimental/type_traits>
2325
#include <type_traits>
2426

@@ -52,19 +54,24 @@ class JQVectors : public std::conditional_t<gap, JQVectorsGapBase<Q, nh, nk>, JQ
5254
using hasInvMass = decltype(std::declval<T&>().invMass());
5355

5456
template <class JInputClass>
55-
inline void Calculate(JInputClass& inputInst, float etamin, float etamax, float massMin = 0.0f, float massMax = 999.9f)
57+
inline void Calculate(JInputClass& inputInst, float etamin, float etamax, float massMin = 0.0f, float massMax = 999.9f,
58+
uint32_t nhUse = nh, uint32_t nkUse = nk)
5659
{
60+
// nhUse/nkUse limit the filled (harmonic, power) grid. Defaults keep the full template size.
61+
const uint32_t nH = std::min(nhUse, nh);
62+
const uint32_t nK = std::min(nkUse, nk);
63+
5764
// calculate Q-vector for QC method ( no subgroup )
58-
for (UInt_t ih = 0; ih < nh; ++ih) {
59-
for (UInt_t ik = 0; ik < nk; ++ik) {
65+
for (UInt_t ih = 0; ih < nH; ++ih) {
66+
for (UInt_t ik = 0; ik < nK; ++ik) {
6067
QvectorQC[ih][ik] = Q(0, 0);
6168
if constexpr (gap) {
6269
for (UInt_t isub = 0; isub < 2; ++isub)
6370
this->QvectorQCgap[isub][ih][ik] = Q(0, 0);
6471
}
6572
}
6673
}
67-
for (auto& track : inputInst) {
74+
for (auto const& track : inputInst) {
6875
if (track.eta() < -etamax || track.eta() > etamax)
6976
continue;
7077
using JInputClassIter = typename JInputClass::iterator;
@@ -74,10 +81,15 @@ class JQVectors : public std::conditional_t<gap, JQVectorsGapBase<Q, nh, nk>, JQ
7481
}
7582

7683
UInt_t isub = (UInt_t)(track.eta() > 0.0);
77-
for (UInt_t ih = 0; ih < nh; ++ih) {
84+
const Double_t phi = track.phi();
85+
const Double_t c1 = TMath::Cos(phi);
86+
const Double_t s1 = TMath::Sin(phi);
87+
Double_t cn = 1.0; // cos(ih * phi), ih = 0
88+
Double_t sn = 0.0; // sin(ih * phi)
89+
for (UInt_t ih = 0; ih < nH; ++ih) {
7890
Double_t tf = 1.0;
79-
for (UInt_t ik = 0; ik < nk; ++ik) {
80-
Q q(tf * TMath::Cos(ih * track.phi()), tf * TMath::Sin(ih * track.phi()));
91+
for (UInt_t ik = 0; ik < nK; ++ik) {
92+
Q q(tf * cn, tf * sn);
8193
QvectorQC[ih][ik] += q;
8294

8395
if constexpr (gap) {
@@ -90,6 +102,10 @@ class JQVectors : public std::conditional_t<gap, JQVectorsGapBase<Q, nh, nk>, JQ
90102
if constexpr (std::experimental::is_detected<hasWeightEff, const JInputClassIter>::value)
91103
tf *= track.weightEff();
92104
}
105+
const Double_t cnNext = cn * c1 - sn * s1;
106+
const Double_t snNext = cn * s1 + sn * c1;
107+
cn = cnNext;
108+
sn = snNext;
93109
}
94110
}
95111
}

‎PWGCF/JCorran/Tasks/flowJSPCAnalysis.cxx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ struct flowJSPCAnalysis {
109109

110110
std::unique_ptr<TFormula> multCutFormula;
111111
std::array<uint, aod::cfmultset::NMultiplicityEstimators> multCutFormulaParamIndex;
112+
uint32_t mNhUse = FlowJSPCAnalysis::NhFull;
113+
uint32_t mNkUse = FlowJSPCAnalysis::NkFull;
112114

113115
void init(InitContext const&)
114116
{
@@ -118,6 +120,8 @@ struct flowJSPCAnalysis {
118120

119121
spcObservables.setSPCObservables(cfgWhichSPC);
120122
spcAnalysis.setFullCorrSet(spcObservables.harmonicArray);
123+
spcAnalysis.qVectorGrid(cfgWhichSPC, mNhUse, mNkUse);
124+
LOGF(info, "Q-vector fill grid: nh=%u nk=%u (cfgWhichSPC=%d)", mNhUse, mNkUse, cfgWhichSPC.value);
121125

122126
histManager.setHistRegistryQA(&qaHistRegistry);
123127
histManager.setDebugLog(false);
@@ -186,7 +190,7 @@ struct flowJSPCAnalysis {
186190
if (cfgFillQA)
187191
histManager.fillEventQA<1>(collision, cBin, cent, nTracks);
188192

189-
jqvecs.Calculate(tracks, 0.0, cfgTrackCuts.cfgEtaMax);
193+
jqvecs.Calculate(tracks, 0.0, cfgTrackCuts.cfgEtaMax, 0.0f, 999.9f, mNhUse, mNkUse);
190194
spcAnalysis.setQvectors(&jqvecs);
191195
spcAnalysis.calculateCorrelators(cBin);
192196
}

0 commit comments

Comments
 (0)