Skip to content

Commit b5f6824

Browse files
wenyaCernalibuild
andauthored
[PWGCF] Add functions for flow and qn in femto dream (#12946)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 4bc7f94 commit b5f6824

File tree

5 files changed

+615
-34
lines changed

5 files changed

+615
-34
lines changed

PWGCF/DataModel/FemtoDerived.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ enum CollisionBinning {
3535
kMult, //! Bin collision in number of charged tracks for mixing
3636
kMultPercentile, //! Bin collision in multiplicity percentile for mixing
3737
kMultMultPercentile, //! Bin collision in number of charged tracks and multiplicity percentile for mixing
38+
kMultPercentileQn, //! Bin collision in multiplicity percentile an qn value for mixing
3839
kNCollisionBinning
3940
};
4041

@@ -50,6 +51,9 @@ DECLARE_SOA_COLUMN(BitMaskTrackTwo, bitmaskTrackTwo, BitMaskType); //! Bit f
5051
DECLARE_SOA_COLUMN(BitMaskTrackThree, bitmaskTrackThree, BitMaskType); //! Bit for track three
5152

5253
DECLARE_SOA_COLUMN(Downsample, downsample, bool); //! Flag for downsampling
54+
55+
DECLARE_SOA_COLUMN(QnVal, qnVal, int); //! qn values for dividing events
56+
DECLARE_SOA_COLUMN(Occupancy, occupancy, int); //! Occupancy of the event
5357
} // namespace femtodreamcollision
5458

5559
DECLARE_SOA_TABLE_STAGED(FDCollisions, "FDCOLLISION",
@@ -61,6 +65,10 @@ DECLARE_SOA_TABLE_STAGED(FDCollisions, "FDCOLLISION",
6165
femtodreamcollision::MagField);
6266
using FDCollision = FDCollisions::iterator;
6367

68+
DECLARE_SOA_TABLE(FDExtQnCollisions, "AOD", "FDEXTQNCOLLISION",
69+
femtodreamcollision::QnVal,
70+
femtodreamcollision::Occupancy);
71+
6472
DECLARE_SOA_TABLE(FDColMasks, "AOD", "FDCOLMASK",
6573
femtodreamcollision::BitMaskTrackOne,
6674
femtodreamcollision::BitMaskTrackTwo,

PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h

Lines changed: 254 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@
1616
#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_
1717
#define PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_
1818

19-
#include <string>
20-
#include <iostream>
2119
#include "Common/CCDB/TriggerAliases.h"
20+
#include "Common/Core/EventPlaneHelper.h"
2221
#include "Common/DataModel/EventSelection.h"
22+
#include "Common/DataModel/Qvectors.h"
23+
2324
#include "Framework/HistogramRegistry.h"
2425
#include "Framework/Logger.h"
2526

27+
#include <iostream>
28+
#include <string>
29+
#include <vector>
30+
2631
using namespace o2::framework;
2732

2833
namespace o2::analysis::femtoDream
@@ -156,6 +161,36 @@ class FemtoDreamCollisionSelection
156161
return true;
157162
}
158163

164+
/// Pile-up selection of PbPb collisions
165+
/// \tparam T type of the collision
166+
/// \param col Collision
167+
/// \return whether or not the collisions fulfills the specified selections
168+
template <typename C>
169+
bool isPileUpCollisionPbPb(C const& col,
170+
bool noSameBunchPileup, bool isGoodITSLayersAll)
171+
{
172+
if ((noSameBunchPileup && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) || (isGoodITSLayersAll && !col.selection_bit(aod::evsel::kIsGoodITSLayersAll))) {
173+
return false;
174+
}
175+
176+
return true;
177+
}
178+
179+
/// occupancy selection
180+
/// \tparam T type of the collision
181+
/// \param col Collision
182+
/// \return whether or not the collisions fulfills the specified selections
183+
template <typename C>
184+
bool occupancySelection(C const& col,
185+
int tpcOccupancyMin, int tpcOccupancyMax)
186+
{
187+
const auto occupancy = col.trackOccupancyInTimeRange();
188+
if ((occupancy < tpcOccupancyMin || occupancy > tpcOccupancyMax)) {
189+
return false;
190+
}
191+
return true;
192+
}
193+
159194
/// Some basic QA of the event
160195
/// \tparam T type of the collision
161196
/// \param col Collision
@@ -175,6 +210,49 @@ class FemtoDreamCollisionSelection
175210
}
176211
}
177212

213+
/// Initializes histograms for qn bin
214+
/// \param registry Histogram registry to be passed
215+
void initQn(HistogramRegistry* registry, int mumQnBins = 10)
216+
{
217+
mHistogramQn = registry;
218+
mHistogramQn->add("Event/centFT0CBefore", "; cent", kTH1F, {{10, 0, 100}});
219+
mHistogramQn->add("Event/centFT0CAfter", "; cent", kTH1F, {{10, 0, 100}});
220+
mHistogramQn->add("Event/centVsqn", "; cent; qn", kTH2F, {{10, 0, 100}, {100, 0, 1000}});
221+
mHistogramQn->add("Event/centVsqnVsSpher", "; cent; qn; Sphericity", kTH3F, {{10, 0, 100}, {100, 0, 1000}, {100, 0, 1}});
222+
mHistogramQn->add("Event/qnBin", "; qnBin; entries", kTH1F, {{20, 0, 20}});
223+
224+
for (int iqn(0); iqn < mumQnBins; ++iqn) {
225+
qnMults.push_back(mHistogramQn->add(("Qn/mult_" + std::to_string(iqn)).c_str(), "; cent; c22", kTH1F, {{100, 0, 3500}}));
226+
}
227+
return;
228+
}
229+
230+
/// Initializes histograms for the flow calculation
231+
/// \param registry Histogram registry to be passed
232+
void initFlow(HistogramRegistry* registry, bool doQnSeparation, int mumQnBins = 10, int binPt = 100, int binEta = 32)
233+
{
234+
if (!mCutsSet) {
235+
LOGF(error, "Event selection not set - quitting!");
236+
}
237+
mReQthisEvt = new TH2D("ReQthisEvt", "", binPt, 0., 5., binEta, -0.8, 0.8);
238+
mImQthisEvt = new TH2D("ImQthisEvt", "", binPt, 0., 5., binEta, -0.8, 0.8);
239+
mReQ2thisEvt = new TH2D("ReQ2thisEvt", "", binPt, 0., 5., binEta, -0.8, 0.8);
240+
mImQ2thisEvt = new TH2D("ImQ2thisEvt", "", binPt, 0., 5., binEta, -0.8, 0.8);
241+
mMQthisEvt = new TH2D("MQthisEvt", "", binPt, 0., 5., binEta, -0.8, 0.8);
242+
mMQWeightthisEvt = new TH2D("MQWeightthisEvt", "", binPt, 0., 5., binEta, -0.8, 0.8);
243+
244+
mHistogramQn = registry;
245+
mHistogramQn->add<TProfile>("Event/profileC22", "; cent; c22", kTProfile, {{10, 0, 100}});
246+
mHistogramQn->add<TProfile>("Event/profileC24", "; cent; c24", kTProfile, {{10, 0, 100}});
247+
248+
if (doQnSeparation) {
249+
for (int iqn(0); iqn < mumQnBins; ++iqn) {
250+
profilesC22.push_back(mHistogramQn->add<TProfile>(("Qn/profileC22_" + std::to_string(iqn)).c_str(), "; cent; c22", kTProfile, {{10, 0, 100}}));
251+
}
252+
}
253+
return;
254+
}
255+
178256
/// \todo to be implemented!
179257
/// Compute the sphericity of an event
180258
/// Important here is that the filter on tracks does not interfere here!
@@ -246,6 +324,170 @@ class FemtoDreamCollisionSelection
246324
return spt;
247325
}
248326

327+
/// \todo to be implemented!
328+
/// Compute the qn-vector(FT0C) of an event
329+
/// \tparam T type of the collision
330+
/// \param col Collision
331+
/// \return value of the qn-vector of FT0C of the event
332+
template <typename T>
333+
float computeqnVec(T const& col)
334+
{
335+
double qn = std::sqrt(col.qvecFT0CReVec()[0] * col.qvecFT0CReVec()[0] + col.qvecFT0CImVec()[0] * col.qvecFT0CImVec()[0]) * std::sqrt(col.sumAmplFT0C());
336+
return qn;
337+
}
338+
339+
/// \todo to be implemented!
340+
/// \return the 1-d qn-vector separator to 2-d
341+
std::vector<std::vector<float>> getQnBinSeparator2D(std::vector<float> flat, const int numQnBins = 10)
342+
{
343+
size_t nBins = numQnBins + 1;
344+
345+
if (flat.empty() || flat.size() % nBins != 0) {
346+
LOGP(error, "ConfQnBinSeparator size = {} is not divisible by {}",
347+
flat.size(), nBins);
348+
return {{-999, -999}};
349+
}
350+
351+
size_t nCent = flat.size() / nBins;
352+
std::vector<std::vector<float>> res(nCent, std::vector<float>(nBins));
353+
354+
for (size_t i = 0; i < nCent; ++i) {
355+
for (size_t j = 0; j < nBins; ++j) {
356+
res[i][j] = flat[i * nBins + j];
357+
}
358+
}
359+
return res;
360+
}
361+
362+
/// \todo to be implemented!
363+
/// Get the bin number of qn-vector(FT0C) of an event
364+
/// \param centBinWidth centrality bin width, example: per 1%, per 10% ...
365+
/// \return bin number of qn-vector of the event
366+
int myqnBin(float centrality, float centMax, std::vector<float> qnBinSeparator, bool doFillHisto, float fSpher, float qn, const int numQnBins, float mult, float centBinWidth = 1.f)
367+
{
368+
auto twoDSeparator = getQnBinSeparator2D(qnBinSeparator, numQnBins);
369+
if (twoDSeparator.empty() || twoDSeparator[0][0] == -999.) {
370+
LOGP(warning, "ConfQnBinSeparator not set, using default fallback!");
371+
return -999; // safe fallback
372+
}
373+
374+
if (doFillHisto)
375+
mHistogramQn->fill(HIST("Event/centFT0CBefore"), centrality);
376+
377+
int qnBin = -999;
378+
int mycentBin = static_cast<int>(centrality / centBinWidth);
379+
if (mycentBin >= static_cast<int>(centMax / centBinWidth))
380+
return qnBin;
381+
382+
if (mycentBin > static_cast<int>(twoDSeparator.size()) - 1)
383+
return qnBin;
384+
385+
for (int iqn(0); iqn < static_cast<int>(twoDSeparator[mycentBin].size()) - 1; ++iqn) {
386+
if (qn > twoDSeparator[mycentBin][iqn] && qn <= twoDSeparator[mycentBin][iqn + 1]) {
387+
qnBin = iqn;
388+
break;
389+
} else {
390+
continue;
391+
}
392+
}
393+
394+
mQnBin = qnBin;
395+
396+
if (doFillHisto) {
397+
mHistogramQn->fill(HIST("Event/centFT0CAfter"), centrality);
398+
mHistogramQn->fill(HIST("Event/centVsqn"), centrality, qn);
399+
mHistogramQn->fill(HIST("Event/centVsqnVsSpher"), centrality, qn, fSpher);
400+
mHistogramQn->fill(HIST("Event/qnBin"), qnBin);
401+
if (qnBin >= 0 && qnBin < numQnBins) {
402+
std::get<std::shared_ptr<TH1>>(qnMults[qnBin])->Fill(mult);
403+
}
404+
}
405+
406+
return qnBin;
407+
}
408+
409+
/// \todo to be implemented!
410+
/// Fill cumulants histo for flow calculation
411+
/// Reset hists event-by-event
412+
/// \tparam T1 type of the collision
413+
/// \tparam T2 type of the tracks
414+
/// \param tracks All tracks
415+
template <typename T1, typename T2>
416+
bool fillCumulants(T1 const& col, T2 const& tracks, float fHarmonic = 2.f)
417+
{
418+
int numOfTracks = col.numContrib();
419+
if (numOfTracks < 3)
420+
return false;
421+
422+
mReQthisEvt->Reset();
423+
mImQthisEvt->Reset();
424+
mReQ2thisEvt->Reset();
425+
mImQ2thisEvt->Reset();
426+
mMQthisEvt->Reset();
427+
mMQWeightthisEvt->Reset();
428+
429+
for (auto const& track : tracks) {
430+
double weight = 1; // Will implement NUA&NUE correction
431+
double phi = track.phi();
432+
double pt = track.pt();
433+
double eta = track.eta();
434+
double cosnphi = weight * TMath::Cos(fHarmonic * phi);
435+
double sinnphi = weight * TMath::Sin(fHarmonic * phi);
436+
double cos2nphi = weight * TMath::Cos(2 * fHarmonic * phi);
437+
double sin2nphi = weight * TMath::Sin(2 * fHarmonic * phi);
438+
mReQthisEvt->Fill(pt, eta, cosnphi);
439+
mImQthisEvt->Fill(pt, eta, sinnphi);
440+
mReQ2thisEvt->Fill(pt, eta, cos2nphi);
441+
mImQ2thisEvt->Fill(pt, eta, sin2nphi);
442+
mMQthisEvt->Fill(pt, eta);
443+
mMQWeightthisEvt->Fill(pt, eta, weight);
444+
}
445+
return true;
446+
}
447+
448+
/// \todo to be implemented!
449+
/// Do cumulants for flow calculation
450+
/// \tparam T type of the collision
451+
/// \param doQnSeparation to fill flow in divied qn bins
452+
/// \param qnBin should be <int> in 0-9
453+
/// \param fEtaGap eta gap for flow cumulant
454+
template <typename T1, typename T2>
455+
void doCumulants(T1 const& col, T2 const& tracks, float centrality, bool doQnSeparation = false, int numQnBins = 10, float fEtaGap = 0.3f, int binPt = 100, int binEta = 32)
456+
{
457+
if (!fillCumulants(col, tracks))
458+
return;
459+
460+
if (mMQthisEvt->Integral(1, binPt, 1, binEta) < 2)
461+
return;
462+
463+
double allReQ = mReQthisEvt->Integral(1, binPt, 1, binEta);
464+
double allImQ = mImQthisEvt->Integral(1, binPt, 1, binEta);
465+
TComplex Q(allReQ, allImQ);
466+
TComplex QStar = TComplex::Conjugate(Q);
467+
468+
double posEtaRe = mReQthisEvt->Integral(1, binPt, mReQthisEvt->GetYaxis()->FindBin(fEtaGap + 1e-6), binEta);
469+
double posEtaIm = mImQthisEvt->Integral(1, binPt, mImQthisEvt->GetYaxis()->FindBin(fEtaGap + 1e-6), binEta);
470+
if (mMQthisEvt->Integral(1, binPt, mMQthisEvt->GetYaxis()->FindBin(fEtaGap + 1e-6), binEta) < 2)
471+
return;
472+
float posEtaMQ = mMQWeightthisEvt->Integral(1, binPt, mMQthisEvt->GetYaxis()->FindBin(fEtaGap + 1e-6), binEta);
473+
TComplex posEtaQ = TComplex(posEtaRe, posEtaIm);
474+
TComplex posEtaQStar = TComplex::Conjugate(posEtaQ);
475+
476+
double negEtaRe = mReQthisEvt->Integral(1, binPt, 1, mReQthisEvt->GetYaxis()->FindBin(-1 * fEtaGap - 1e-6));
477+
double negEtaIm = mImQthisEvt->Integral(1, binPt, 1, mImQthisEvt->GetYaxis()->FindBin(-1 * fEtaGap - 1e-6));
478+
if (mMQthisEvt->Integral(1, binPt, 1, mMQthisEvt->GetYaxis()->FindBin(-1 * fEtaGap - 1e-6)) < 2)
479+
return;
480+
float negEtaMQ = mMQWeightthisEvt->Integral(1, binPt, 1, mMQthisEvt->GetYaxis()->FindBin(-1 * fEtaGap - 1e-6));
481+
TComplex negEtaQ = TComplex(negEtaRe, negEtaIm);
482+
TComplex negEtaQStar = TComplex::Conjugate(negEtaQ);
483+
484+
mHistogramQn->get<TProfile>(HIST("Event/profileC22"))->Fill(centrality, (negEtaQ * posEtaQStar).Re() / (negEtaMQ * posEtaMQ), (negEtaMQ * posEtaMQ));
485+
if (doQnSeparation && mQnBin >= 0 && mQnBin < numQnBins) {
486+
std::get<std::shared_ptr<TProfile>>(profilesC22[mQnBin])->Fill(centrality, (negEtaQ * posEtaQStar).Re() / (negEtaMQ * posEtaMQ), (negEtaMQ * posEtaMQ));
487+
}
488+
return;
489+
}
490+
249491
private:
250492
HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output
251493
bool mCutsSet = false; ///< Protection against running without cuts
@@ -257,6 +499,16 @@ class FemtoDreamCollisionSelection
257499
float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm)
258500
float mMinSphericity = 0.f;
259501
float mSphericityPtmin = 0.f;
502+
int mQnBin = -999;
503+
HistogramRegistry* mHistogramQn = nullptr; ///< For flow cumulant output
504+
std::vector<HistPtr> qnMults; /// Histograms of multiplicity (TH1F) per Qn bin. Stored as HistPtr (variant of shared_ptr) from HistogramManager.
505+
std::vector<HistPtr> profilesC22; /// Pofile Histograms of c22 per Qn bin
506+
TH2D* mReQthisEvt = nullptr; ///< For flow cumulant in an event
507+
TH2D* mImQthisEvt = nullptr; ///< For flow cumulant in an event
508+
TH2D* mReQ2thisEvt = nullptr; ///< For flow cumulant in an event
509+
TH2D* mImQ2thisEvt = nullptr; ///< For flow cumulant in an event
510+
TH2D* mMQthisEvt = nullptr; ///< For flow cumulant in an event
511+
TH2D* mMQWeightthisEvt = nullptr; ///< For flow cumulant in an event
260512
};
261513
} // namespace o2::analysis::femtoDream
262514

0 commit comments

Comments
 (0)