5252
5353#include < TProfile.h>
5454#include < TRandom3.h>
55+ #include < TF1.h>
5556
5657using namespace o2 ;
5758using namespace o2 ::framework;
@@ -88,6 +89,10 @@ struct FlowPbpbPikp {
8889 O2_DEFINE_CONFIGURABLE (cfgCutOccupancy, int , 3000 , " Occupancy cut" )
8990 O2_DEFINE_CONFIGURABLE (cfgUseGlobalTrack, bool , true , " use Global track" )
9091 O2_DEFINE_CONFIGURABLE (cfgITScluster, int , 0 , " Number of ITS cluster" )
92+ O2_DEFINE_CONFIGURABLE (cfgTrackDensityCorrUse, bool , true , " Use track density efficiency correction" )
93+
94+ Configurable<std::vector<double >> cfgTrackDensityP0{" cfgTrackDensityP0" , std::vector<double >{0.7217476707 , 0.7384792571 , 0.7542625668 , 0.7640680200 , 0.7701951667 , 0.7755299053 , 0.7805901710 , 0.7849446786 , 0.7957356586 , 0.8113039262 , 0.8211968966 , 0.8280558878 , 0.8329342135 }, " parameter 0 for track density efficiency correction" };
95+ Configurable<std::vector<double >> cfgTrackDensityP1{" cfgTrackDensityP1" , std::vector<double >{-2.169488e-05 , -2.191913e-05 , -2.295484e-05 , -2.556538e-05 , -2.754463e-05 , -2.816832e-05 , -2.846502e-05 , -2.843857e-05 , -2.705974e-05 , -2.477018e-05 , -2.321730e-05 , -2.203315e-05 , -2.109474e-05 }, " parameter 1 for track density efficiency correction" };
9196
9297 ConfigurableAxis axisVertex{" axisVertex" , {20 , -10 , 10 }, " vertex axis for histograms" };
9398 ConfigurableAxis axisPhi{" axisPhi" , {60 , 0.0 , constants::math::TwoPI}, " phi axis for histograms" };
@@ -127,6 +132,13 @@ struct FlowPbpbPikp {
127132 std::vector<GFWWeights*> mAcceptance ;
128133 bool correctionsLoaded = false ;
129134
135+ // local track density correction
136+ std::vector<TF1*> funcEff;
137+ TH1D* hFindPtBin;
138+ TF1* funcV2;
139+ TF1* funcV3;
140+ TF1* funcV4;
141+
130142 void init (InitContext const &)
131143 {
132144 ccdb->setURL (ccdbUrl.value );
@@ -199,6 +211,10 @@ struct FlowPbpbPikp {
199211 for (int i = 0 ; i < fPtAxis ->GetNbins (); i++)
200212 oba->Add (new TNamed (Form (" Pr08Gap24_pt_%i" , i + 1 ), " Pr08Gap24_pTDiff" ));
201213
214+ oba->Add (new TNamed (" Pi08BGap22" , " Pi08BGap22" ));
215+ for (int i = 0 ; i < fPtAxis ->GetNbins (); i++)
216+ oba->Add (new TNamed (Form (" Pi08BGap22_pt_%i" , i + 1 ), " Pi08BGap22_pTDiff" ));
217+
202218 fFC ->SetName (" FlowContainer" );
203219 fFC ->SetXAxis (fPtAxis );
204220 fFC ->Initialize (oba, axisMultiplicity, cfgNbootstrap);
@@ -219,6 +235,9 @@ struct FlowPbpbPikp {
219235 fGFW ->AddRegion (" poiNpi" , -0.8 , -0.4 , 1 + fPtAxis ->GetNbins (), 2 );
220236 fGFW ->AddRegion (" olNpi" , -0.8 , -0.4 , 1 + fPtAxis ->GetNbins (), 16 );
221237
238+ fGFW ->AddRegion (" poiPpi" , 0.4 , 0.8 , 1 + fPtAxis ->GetNbins (), 2 );
239+ fGFW ->AddRegion (" olPpi" , 0.4 , 0.8 , 1 + fPtAxis ->GetNbins (), 16 );
240+
222241 // kaon
223242 fGFW ->AddRegion (" poiNk" , -0.8 , -0.4 , 1 + fPtAxis ->GetNbins (), 4 );
224243 fGFW ->AddRegion (" olNk" , -0.8 , -0.4 , 1 + fPtAxis ->GetNbins (), 32 );
@@ -251,7 +270,30 @@ struct FlowPbpbPikp {
251270 corrconfigs.push_back (fGFW ->GetCorrelatorConfig (" poiNk refN08 | olNk {2 2} refP08 {-2 -2}" , " Ka08Gap24" , kTRUE ));
252271 corrconfigs.push_back (fGFW ->GetCorrelatorConfig (" poiNpr refN08 | olNpr {2 2} refP08 {-2 -2}" , " Pr08Gap24" , kTRUE ));
253272
273+ // Backward correlations
274+ corrconfigs.push_back (fGFW ->GetCorrelatorConfig (" refN08 {2} refP08 {-2}" , " Pi08BGap22" , kFALSE ));
275+ corrconfigs.push_back (fGFW ->GetCorrelatorConfig (" poiPpi refP08 | olPpi {2} refN08 {-2}" , " Pi08BGap22" , kTRUE ));
276+
254277 fGFW ->CreateRegions ();
278+
279+ if (cfgTrackDensityCorrUse) {
280+ std::vector<double > pTEffBins = {0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 , 1.4 , 1.8 , 2.2 , 2.6 , 3.0 };
281+ hFindPtBin = new TH1D (" hFindPtBin" , " hFindPtBin" , pTEffBins.size () - 1 , &pTEffBins[0 ]);
282+ funcEff.resize (pTEffBins.size () - 1 );
283+ // LHC24g3 Eff
284+ std::vector<double > f1p0 = cfgTrackDensityP0;
285+ std::vector<double > f1p1 = cfgTrackDensityP1;
286+ for (uint ifunc = 0 ; ifunc < pTEffBins.size () - 1 ; ifunc++) {
287+ funcEff[ifunc] = new TF1 (Form (" funcEff%i" , ifunc), " [0]+[1]*x" , 0 , 3000 );
288+ funcEff[ifunc]->SetParameters (f1p0[ifunc], f1p1[ifunc]);
289+ }
290+ funcV2 = new TF1 (" funcV2" , " [0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x" , 0 , 100 );
291+ funcV2->SetParameters (0.0186111 , 0.00351907 , -4.38264e-05 , 1.35383e-07 , -3.96266e-10 );
292+ funcV3 = new TF1 (" funcV3" , " [0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x" , 0 , 100 );
293+ funcV3->SetParameters (0.0174056 , 0.000703329 , -1.45044e-05 , 1.91991e-07 , -1.62137e-09 );
294+ funcV4 = new TF1 (" funcV4" , " [0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x" , 0 , 100 );
295+ funcV4->SetParameters (0.008845 , 0.000259668 , -3.24435e-06 , 4.54837e-08 , -6.01825e-10 );
296+ }
255297 }
256298
257299 enum Particles {
@@ -286,8 +328,9 @@ struct FlowPbpbPikp {
286328 if (track.pt () >= cfgTofPtCut && !track.hasTOF ())
287329 return -1 ;
288330
331+ const int numSpecies = 3 ;
289332 // Select particle with the lowest nsigma
290- for (int i = 0 ; i < 3 ; ++i) {
333+ for (int i = 0 ; i < numSpecies ; ++i) {
291334 if (std::abs (nSigmaToUse[i]) < nsigma) {
292335 pid = i;
293336 nsigma = std::abs (nSigmaToUse[i]);
@@ -303,8 +346,10 @@ struct FlowPbpbPikp {
303346 int bayesid = -1;
304347 int prob = 0;
305348
306- for (int i = 0; i < 3; ++i) {
307- if (bayesprobs[i] > prob && bayesprobs[i] > 80) {
349+ const int nParts = 3;
350+ const int bayesCut = 80;
351+ for (int i = 0; i < nParts; ++i) {
352+ if (bayesprobs[i] > prob && bayesprobs[i] > bayesCut) {
308353 bayesid = i;
309354 prob = bayesprobs[i];
310355 }
@@ -317,12 +362,13 @@ struct FlowPbpbPikp {
317362 {
318363 int maxProb[3] = {80, 80, 80};
319364 int pidID = -1;
365+ const int nParts = 3;
320366 std::pair<int, int> idprob = getBayesID(track);
321367 if (idprob.first == PIONS || idprob.first == KAONS || idprob.first == PROTONS) { // 0 = pion, 1 = kaon, 2 = proton
322368 pidID = idprob.first;
323369 float nsigmaTPC[3] = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()};
324370 if (idprob.second > maxProb[pidID]) {
325- if (std::fabs(nsigmaTPC[pidID]) > 3 )
371+ if (std::fabs(nsigmaTPC[pidID]) > nParts )
326372 return 0;
327373 return pidID + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton
328374 } else {
@@ -523,6 +569,37 @@ struct FlowPbpbPikp {
523569 int pidIndex;
524570 loadCorrections (bc); // load corrections for the each event
525571
572+ // Track loop for calculating the Qn angles
573+ double psi2Est = 0 , psi3Est = 0 , psi4Est = 0 ;
574+ float wEPeff = 1 ;
575+ double v2 = 0 , v3 = 0 , v4 = 0 ;
576+ // be cautious, this only works for Pb-Pb
577+ // esimate the Qn angles and vn for this event
578+ if (cfgTrackDensityCorrUse) {
579+ double q2x = 0 , q2y = 0 ;
580+ double q3x = 0 , q3y = 0 ;
581+ double q4x = 0 , q4y = 0 ;
582+ for (const auto & track : tracks) {
583+ bool withinPtRef = (cfgCutPtMin < track.pt ()) && (track.pt () < cfgCutPtMax); // within RF pT range
584+ if (withinPtRef) {
585+ q2x += std::cos (2 * track.phi ());
586+ q2y += std::sin (2 * track.phi ());
587+ q3x += std::cos (3 * track.phi ());
588+ q3y += std::sin (3 * track.phi ());
589+ q4x += std::cos (4 * track.phi ());
590+ q4y += std::sin (4 * track.phi ());
591+ }
592+ }
593+ psi2Est = std::atan2 (q2y, q2x) / 2 .;
594+ psi3Est = std::atan2 (q3y, q3x) / 3 .;
595+ psi4Est = std::atan2 (q4y, q4x) / 4 .;
596+
597+ v2 = funcV2->Eval (cent);
598+ v3 = funcV3->Eval (cent);
599+ v4 = funcV4->Eval (cent);
600+ }
601+
602+ // Actual track loop
526603 for (auto const & track : tracks) {
527604 if (!selectionTrack (track))
528605 continue ;
@@ -540,6 +617,9 @@ struct FlowPbpbPikp {
540617
541618 // pidIndex = getBayesPIDIndex(track);
542619 pidIndex = getNsigmaPID (track);
620+
621+ weff = 1 ; // Initializing weff for each track
622+ // NUA weights
543623 if (cfgOutputNUAWeights)
544624 fillWeights (track, vtxz, pidIndex, runNumber);
545625
@@ -550,10 +630,24 @@ struct FlowPbpbPikp {
550630 if (withinPtRef && withinPtPOI && pidIndex)
551631 waccRef = waccPOI; // if particle is both (then it's overlap), override ref with POI
552632
633+ // Track density correction
634+ if (cfgTrackDensityCorrUse && withinPtRef) {
635+ double fphi = v2 * std::cos (2 * (track.phi () - psi2Est)) + v3 * std::cos (3 * (track.phi () - psi3Est)) + v4 * std::cos (4 * (track.phi () - psi4Est));
636+ fphi = (1 + 2 * fphi);
637+ int pTBinForEff = hFindPtBin->FindBin (track.pt ());
638+ if (pTBinForEff >= 1 && pTBinForEff <= hFindPtBin->GetNbinsX ()) {
639+ wEPeff = funcEff[pTBinForEff - 1 ]->Eval (fphi * tracks.size ());
640+ if (wEPeff > 0 .) {
641+ wEPeff = 1 . / wEPeff;
642+ weff *= wEPeff;
643+ }
644+ }
645+ } // end of track density correction loop
646+
553647 if (withinPtRef) {
554648 histos.fill (HIST (" hPhiWeighted" ), track.phi (), waccRef);
555649 fGFW ->Fill (track.eta (), fPtAxis ->FindBin (pt) - 1 , track.phi (), waccRef * weff, 1 );
556- fGFW ->Fill (track.eta (), 1 , track.phi (), waccRef * weff, 512 );
650+ fGFW ->Fill (track.eta (), fPtAxis -> FindBin (pt) - 1 , track.phi (), waccRef * weff, 512 );
557651 }
558652 if (withinPtPOI) {
559653 fGFW ->Fill (track.eta (), fPtAxis ->FindBin (pt) - 1 , track.phi (), waccPOI * weff, 128 );
0 commit comments