Skip to content

Commit 6628e6a

Browse files
wenyaCernmutecho
authored andcommitted
Add functions for flow and qn in femto dream
1 parent 45e2dbd commit 6628e6a

File tree

2 files changed

+211
-5
lines changed

2 files changed

+211
-5
lines changed

PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ class FemtoDreamCollisionSelection
489489
}
490490

491491
private:
492-
HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output
492+
HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output
493493
bool mCutsSet = false; ///< Protection against running without cuts
494494
bool mCheckTrigger = false; ///< Check for trigger
495495
bool mCheckOffline = false; ///< Check for offline criteria (might change)

PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx

Lines changed: 210 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ namespace o2::aod
5555
using FemtoFullCollision = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms>::iterator;
5656
using FemtoFullCollisionMC = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms, aod::McCollisionLabels>::iterator;
5757
using FemtoFullCollision_noCent_MC = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::McCollisionLabels>::iterator;
58+
using FemtoFullCollision_CentPbPb = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms, aod::CentFT0Cs, aod::CentFV0As, aod::QvectorFT0CVecs>::iterator;
5859

5960
using FemtoFullTracks = soa::Join<aod::FullTracks, aod::TracksDCA,
6061
aod::pidTPCFullEl, aod::pidTPCFullMu, aod::pidTPCFullPi, aod::pidTPCFullKa,
@@ -66,6 +67,7 @@ using FemtoFullTracks = soa::Join<aod::FullTracks, aod::TracksDCA,
6667
struct femtoDreamProducerReducedTask {
6768

6869
Produces<aod::FDCollisions> outputCollision;
70+
Produces<aod::FDExtQnCollisions> outputExtQnCollision;
6971
Produces<aod::FDParticles> outputParts;
7072
Produces<aod::FDMCParticles> outputPartsMC;
7173
Produces<aod::FDExtParticles> outputDebugParts;
@@ -104,14 +106,39 @@ struct femtoDreamProducerReducedTask {
104106
Configurable<std::vector<float>> ConfTrkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "ConfTrk"), std::vector<float>{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")};
105107
Configurable<std::vector<float>> ConfTrkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "ConfTrk"), std::vector<float>{0.1f, 0.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; /// here we need an open cut to do the DCA fits later on!
106108
Configurable<std::vector<float>> ConfTrkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "ConfTrk"), std::vector<float>{0.2f, 0.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")};
107-
Configurable<std::vector<float>> ConfTrkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "Conf"), std::vector<float>{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")};
109+
Configurable<std::vector<float>> ConfTrkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "ConfTrk"), std::vector<float>{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")};
108110
// off set the center of the nsigma distribution to deal with bad TPC/TOF calibration
109111
Configurable<float> ConfTrkPIDnSigmaOffsetTPC{"ConfTrkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"};
110112
Configurable<float> ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"};
111113
Configurable<std::vector<int>> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector<int>{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"};
112114

115+
struct : o2::framework::ConfigurableGroup {
116+
Configurable<bool> ConfgFlowCalculate{"ConfgFlowCalculate", false, "Evt sel: Cumulant of flow"}; // To do
117+
Configurable<bool> ConfgQnSeparation{"ConfgQnSeparation", false, "Evt sel: Qn of event"};
118+
Configurable<std::vector<float>> ConfQnBinSeparator{"ConfQnBinSeparator", std::vector<float>{-999.f, -999.f, -999.f}, "Qn bin separator"};
119+
Configurable<float> ConfCentralityMax{"ConfCentralityMax", 80.f, "Evt sel: Maximum Centrality cut"};
120+
Configurable<float> ConfCentBinWidth{"ConfCentBinWidth", 1.f, "Centrality bin length for qn separator"};
121+
Configurable<int> ConfQnBinMin{"ConfQnBinMin", 0, "Minimum qn bin"};
122+
Configurable<int> ConfQnBinMax{"ConfQnBinMax", 10, "Maximum qn bin"};
123+
} qnCal;
124+
125+
struct : o2::framework::ConfigurableGroup {
126+
Configurable<bool> ConfIsPbPb{"ConfIsPbPb", false, "Running on Run3 or Run2"}; // Choose if running on PbPb data
127+
Configurable<bool> ConfIsUsePileUp{"ConfIsUsePileUp", false, "Required for choosing whether to run the pile-up cuts"};
128+
Configurable<bool> ConfEvNoSameBunchPileup{"ConfEvNoSameBunchPileup", false, "Require kNoSameBunchPileup selection on Events."};
129+
Configurable<bool> ConfEvIsGoodZvtxFT0vsPV{"ConfEvIsGoodZvtxFT0vsPV", false, "Require kIsGoodZvtxFT0vsPV selection on Events."};
130+
Configurable<bool> ConfEvIsGoodITSLayersAll{"ConfEvIsGoodITSLayersAll", false, "Require kIsGoodITSLayersAll selection on Events."};
131+
Configurable<bool> ConfEvNoCollInRofStandard{"ConfEvNoCollInRofStandard", false, "Require kNoCollInRofStandard selection on Events."};
132+
Configurable<bool> ConfEvNoHighMultCollInPrevRof{"ConfEvNoHighMultCollInPrevRof", false, "Require kNoHighMultCollInPrevRof selection on Events."};
133+
Configurable<bool> ConfEvNoCollInTimeRangeStandard{"ConfEvNoCollInTimeRangeStandard", false, "Require kNoCollInTimeRangeStandard selection on Events."};
134+
Configurable<bool> ConfEvIsVertexITSTPC{"ConfEvIsVertexITSTPC", false, "Require kIsVertexITSTPC selection on Events"};
135+
Configurable<int> ConfTPCOccupancyMin{"ConfTPCOccupancyMin", 0, "Minimum value for TPC Occupancy selection"};
136+
Configurable<int> ConfTPCOccupancyMax{"ConfTPCOccupancyMax", 1000, "Maximum value for TPC Occupancy selection"};
137+
} evtSel_PbPb;
138+
113139
HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject};
114140
HistogramRegistry Registry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject};
141+
HistogramRegistry FlowRegistry{"QnandFlowInfo", {}, OutputObjHandlingPolicy::AnalysisObject};
115142

116143
int mRunNumber;
117144
float mMagField;
@@ -144,6 +171,11 @@ struct femtoDreamProducerReducedTask {
144171
trackCuts.init<aod::femtodreamparticle::ParticleType::kTrack,
145172
aod::femtodreamparticle::TrackType::kNoChild,
146173
aod::femtodreamparticle::cutContainerType>(&qaRegistry, &Registry);
174+
175+
if (qnCal.ConfgFlowCalculate){
176+
colCuts.initFlow(&FlowRegistry, qnCal.ConfgQnSeparation);
177+
}
178+
147179
mRunNumber = 0;
148180
mMagField = 0.0;
149181
/// Initializing CCDB
@@ -330,8 +362,166 @@ struct femtoDreamProducerReducedTask {
330362
}
331363
}
332364

333-
void
334-
processData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks)
365+
// Centrality (Multiplicity percentile) obtained from FT0C
366+
// Pile-up rejection involved
367+
template <bool isMC, bool useCentrality, typename CollisionType, typename TrackType>
368+
void fillCollisionsAndTracks_PbPb(CollisionType const& col, TrackType const& tracks)
369+
{
370+
const auto vtxZ = col.posZ();
371+
const auto spher = colCuts.computeSphericity(col, tracks);
372+
int mult = 0;
373+
int multNtr = 0;
374+
if (ConfIsRun3) {
375+
if constexpr (useCentrality) {
376+
mult = col.centFT0C();
377+
} else {
378+
mult = 0.;
379+
}
380+
multNtr = col.multNTracksPV();
381+
} else {
382+
mult = 1; // multiplicity percentile is known in Run 2
383+
multNtr = col.multTracklets();
384+
}
385+
if (ConfEvtUseTPCmult) {
386+
multNtr = col.multTPC();
387+
}
388+
colCuts.fillQA(col, mult);
389+
390+
/// First thing to do is to check whether the basic event selection criteria are fulfilled
391+
/// That includes checking if there are any usable tracks in a collision
392+
if (!colCuts.isSelectedCollision(col)) {
393+
return;
394+
}
395+
if (colCuts.isEmptyCollision(col, tracks, trackCuts)) {
396+
return;
397+
}
398+
399+
// Pileup rejection in PbPb data
400+
if (evtSel_PbPb.ConfIsPbPb && evtSel_PbPb.ConfIsUsePileUp &&
401+
!colCuts.isPileUpCollisionPbPb(col, evtSel_PbPb.ConfEvNoSameBunchPileup, evtSel_PbPb.ConfEvIsGoodZvtxFT0vsPV,
402+
evtSel_PbPb.ConfEvIsGoodITSLayersAll, evtSel_PbPb.ConfEvNoCollInRofStandard,
403+
evtSel_PbPb.ConfEvNoHighMultCollInPrevRof, evtSel_PbPb.ConfEvNoCollInTimeRangeStandard,
404+
evtSel_PbPb.ConfEvIsVertexITSTPC,
405+
evtSel_PbPb.ConfTPCOccupancyMin, evtSel_PbPb.ConfTPCOccupancyMax)) {
406+
return;
407+
}
408+
// now the table is filled
409+
outputCollision(vtxZ, mult, multNtr, spher, mMagField);
410+
411+
// these IDs are necessary to keep track of the children
412+
// since this producer only produces the tables for tracks, there are no children
413+
std::vector<int> childIDs = {0, 0};
414+
for (auto& track : tracks) {
415+
/// if the most open selection criteria are not fulfilled there is no point looking further at the track
416+
if (!trackCuts.isSelectedMinimal(track)) {
417+
continue;
418+
}
419+
trackCuts.fillQA<aod::femtodreamparticle::ParticleType::kTrack, aod::femtodreamparticle::TrackType::kNoChild>(track);
420+
// an array of two bit-wise containers of the systematic variations is obtained
421+
// one container for the track quality cuts and one for the PID cuts
422+
auto cutContainer = trackCuts.getCutContainer<true, aod::femtodreamparticle::cutContainerType>(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f)));
423+
424+
// now the table is filled
425+
outputParts(outputCollision.lastIndex(),
426+
track.pt(),
427+
track.eta(),
428+
track.phi(),
429+
aod::femtodreamparticle::ParticleType::kTrack,
430+
cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts),
431+
cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID),
432+
track.dcaXY(), childIDs, 0, 0);
433+
if constexpr (isMC) {
434+
fillMCParticle(col, track, o2::aod::femtodreamparticle::ParticleType::kTrack);
435+
}
436+
437+
if (ConfIsDebug) {
438+
outputDebugParts(track.sign(),
439+
(uint8_t)track.tpcNClsFound(),
440+
track.tpcNClsFindable(),
441+
(uint8_t)track.tpcNClsCrossedRows(),
442+
track.tpcNClsShared(),
443+
track.tpcInnerParam(),
444+
track.itsNCls(),
445+
track.itsNClsInnerBarrel(),
446+
track.dcaXY(),
447+
track.dcaZ(),
448+
track.tpcSignal(),
449+
track.tpcNSigmaEl(),
450+
track.tpcNSigmaPi(),
451+
track.tpcNSigmaKa(),
452+
track.tpcNSigmaPr(),
453+
track.tpcNSigmaDe(),
454+
track.tpcNSigmaTr(),
455+
track.tpcNSigmaHe(),
456+
track.tofNSigmaEl(),
457+
track.tofNSigmaPi(),
458+
track.tofNSigmaKa(),
459+
track.tofNSigmaPr(),
460+
track.tofNSigmaDe(),
461+
track.tofNSigmaTr(),
462+
track.tofNSigmaHe(),
463+
-1,
464+
track.itsNSigmaEl(),
465+
track.itsNSigmaPi(),
466+
track.itsNSigmaKa(),
467+
track.itsNSigmaPr(),
468+
track.itsNSigmaDe(),
469+
track.itsNSigmaTr(),
470+
track.itsNSigmaHe(),
471+
-999., -999., -999., -999., -999., -999.,
472+
-999., -999., -999., -999., -999., -999., -999.);
473+
}
474+
}
475+
}
476+
477+
// Calculate and separate qn bins
478+
// Do and fill cumulant in qn bins
479+
template <bool isMC, typename CollisionType, typename TrackType>
480+
void fillCollisionsFlow(CollisionType const& col, TrackType const& tracks)
481+
{
482+
// get magnetic field for run
483+
484+
const auto spher = colCuts.computeSphericity(col, tracks);
485+
int multNtr = 0;
486+
if (ConfIsRun3) {
487+
multNtr = col.multNTracksPV();
488+
} else {
489+
multNtr = col.multTracklets();
490+
}
491+
if (ConfEvtUseTPCmult) {
492+
multNtr = col.multTPC();
493+
}
494+
495+
/// First thing to do is to check whether the basic event selection criteria are fulfilled
496+
/// That includes checking if there are any usable tracks in a collision
497+
if (!colCuts.isSelectedCollision(col)) {
498+
return;
499+
}
500+
if (colCuts.isEmptyCollision(col, tracks, trackCuts)) {
501+
return;
502+
}
503+
504+
// Pileup rejection in PbPb data
505+
if (evtSel_PbPb.ConfIsPbPb && evtSel_PbPb.ConfIsUsePileUp &&
506+
!colCuts.isPileUpCollisionPbPb(col, evtSel_PbPb.ConfEvNoSameBunchPileup, evtSel_PbPb.ConfEvIsGoodZvtxFT0vsPV,
507+
evtSel_PbPb.ConfEvIsGoodITSLayersAll, evtSel_PbPb.ConfEvNoCollInRofStandard,
508+
evtSel_PbPb.ConfEvNoHighMultCollInPrevRof, evtSel_PbPb.ConfEvNoCollInTimeRangeStandard,
509+
evtSel_PbPb.ConfEvIsVertexITSTPC,
510+
evtSel_PbPb.ConfTPCOccupancyMin, evtSel_PbPb.ConfTPCOccupancyMax)) {
511+
return;
512+
}
513+
514+
// Calculate and fill qnBins
515+
auto qnBin = colCuts.myqnBin(col, qnCal.ConfCentralityMax, qnCal.ConfQnBinSeparator, spher, multNtr, 1.f);
516+
if (qnBin < qnCal.ConfQnBinMin || qnBin > qnCal.ConfQnBinMax){
517+
qnBin = -999;
518+
}
519+
colCuts.fillCumulants(col, tracks);
520+
colCuts.doCumulants(col, qnCal.ConfgQnSeparation, qnBin);
521+
outputExtQnCollision(qnBin);
522+
}
523+
524+
void processData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks)
335525
{
336526
// get magnetic field for run
337527
getMagneticFieldTesla(col.bc_as<aod::BCsWithTimestamps>());
@@ -370,8 +560,24 @@ struct femtoDreamProducerReducedTask {
370560
fillCollisionsAndTracks<true, false>(col, tracksWithItsPid);
371561
}
372562
PROCESS_SWITCH(femtoDreamProducerReducedTask, processMC_noCentrality, "Provide MC data", false);
563+
564+
void processData_FlowCalc(aod::FemtoFullCollision_CentPbPb const& col,
565+
aod::BCsWithTimestamps const&,
566+
aod::FemtoFullTracks const& tracks)
567+
{
568+
// get magnetic field for run
569+
getMagneticFieldTesla(col.bc_as<aod::BCsWithTimestamps>());
570+
auto tracksWithItsPid = soa::Attach<aod::FemtoFullTracks, aod::pidits::ITSNSigmaEl, aod::pidits::ITSNSigmaPi, aod::pidits::ITSNSigmaKa,
571+
aod::pidits::ITSNSigmaPr, aod::pidits::ITSNSigmaDe, aod::pidits::ITSNSigmaTr, aod::pidits::ITSNSigmaHe>(tracks);
572+
// fill the tables
573+
fillCollisionsAndTracks_PbPb<false, true>(col, tracksWithItsPid);
574+
if (qnCal.ConfgQnSeparation){
575+
fillCollisionsFlow<false>(col, tracksWithItsPid);
576+
}
577+
}
578+
PROCESS_SWITCH(femtoDreamProducerReducedTask, processData_FlowCalc,
579+
"Provide experimental data with cumulant flow calculation", false);
373580
};
374-
375581
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
376582
{
377583
WorkflowSpec workflow{adaptAnalysisTask<femtoDreamProducerReducedTask>(cfgc)};

0 commit comments

Comments
 (0)