1818#include " Common/DataModel/CollisionAssociationTables.h"
1919#include " Common/DataModel/EventSelection.h"
2020#include " Common/DataModel/Multiplicity.h"
21- #include " Common/DataModel/PIDResponseTOF.h"
22- #include " Common/DataModel/PIDResponseTPC.h"
21+ #include " Common/DataModel/PIDResponse.h"
2322#include " Common/DataModel/TrackSelectionTables.h"
2423
2524#include " CCDB/BasicCCDBManager.h"
@@ -80,10 +79,19 @@ struct FlowEventPlane {
8079 // Tracks
8180 Configurable<float > cTrackMinPt{" cTrackMinPt" , 0.15 , " p_{T} minimum" };
8281 Configurable<float > cTrackMaxPt{" cTrackMaxPt" , 2.0 , " p_{T} maximum" };
82+ Configurable<int > cNEtaBins{" cNEtaBins" , 7 , " # of eta bins" };
8383 Configurable<float > cTrackEtaCut{" cTrackEtaCut" , 0.8 , " Pseudorapidity cut" };
8484 Configurable<bool > cTrackGlobal{" cTrackGlobal" , true , " Global Track" };
8585 Configurable<float > cTrackDcaXYCut{" cTrackDcaXYCut" , 0.1 , " DcaXY Cut" };
8686 Configurable<float > cTrackDcaZCut{" cTrackDcaZCut" , 1 ., " DcaXY Cut" };
87+ Configurable<int > cNRapBins{" cNRapBins" , 5 , " # of y bins" };
88+ Configurable<int > cNInvMassBins{" cNInvMassBins" , 500 , " # of m bins" };
89+
90+ // Track PID
91+ Configurable<float > cTpcNSigmaKa{" cTpcNSigmaKa" , 2 ., " Tpc nsigma Ka" };
92+ Configurable<float > cTpcRejCut{" cTpcRejCut" , 2 ., " Tpc rejection cut" };
93+ Configurable<float > cTofNSigmaKa{" cTofNSigmaKa" , 2 ., " Tof nsigma Ka" };
94+ Configurable<float > cTofRejCut{" cTofRejCut" , 2 ., " Tof rejection cut" };
8795
8896 // Gain calibration
8997 Configurable<bool > cDoGainCalib{" cDoGainCalib" , false , " Gain Calib Flag" };
@@ -131,6 +139,16 @@ struct FlowEventPlane {
131139 {" hYZNCVsCent" , " hYZNCVsVx" , " hYZNCVsVy" , " hYZNCVsVz" }};
132140 std::map<CorrectionType, std::vector<std::vector<std::string>>> corrTypeHistNameMap = {{kFineCorr , vFineCorrHistNames}, {kCoarseCorr , vCoarseCorrHistNames}};
133141
142+ // Container for histograms
143+ struct CorrHistContainer {
144+ TH2F* hGainCalib;
145+ std::array<std::array<THnSparseF*, 1 >, 4 > vCoarseCorrHist;
146+ std::array<std::array<TProfile*, 4 >, 4 > vFineCorrHist;
147+ } CorrHistContainer;
148+
149+ // Run number
150+ int cRunNum = 0 , lRunNum = 0 ;
151+
134152 void init (InitContext const &)
135153 {
136154 // Set CCDB url
@@ -166,10 +184,13 @@ struct FlowEventPlane {
166184 const AxisSpec axisV1{400 , -4 , 4 , " v_{1}" };
167185
168186 const AxisSpec axisTrackPt{100 , 0 ., 10 ., " p_{T} (GeV/#it{c})" };
169- const AxisSpec axisTrackEta{16 , -0.8 , 0.8 , " #eta" };
187+ const AxisSpec axisTrackEta{cNEtaBins, -0.8 , 0.8 , " #eta" };
188+ const AxisSpec axisTrackRap{cNRapBins, -0.5 , 0.5 , " y" };
189+ const AxisSpec axisInvMass{cNInvMassBins, 0.87 , 1.12 , " M_{KK} (GeV/#it{c}^{2}" };
170190
171191 const AxisSpec axisTrackDcaXY{60 , -0.15 , 0.15 , " DCA_{XY}" };
172192 const AxisSpec axisTrackDcaZ{230 , -1.15 , 1.15 , " DCA_{XY}" };
193+ const AxisSpec axisTrackdEdx{360 , 20 , 200 , " #frac{dE}{dx}" };
173194
174195 // Create histograms
175196 histos.add (" Event/hCent" , " FT0C%" , kTH1F , {axisCent});
@@ -216,13 +237,20 @@ struct FlowEventPlane {
216237 histos.add (" Checks/hYaXc" , " Y^{A}_{1}X^{C}_{1}" , kTProfile , {axisCent});
217238 histos.add (" TrackQA/hPtDcaXY" , " DCA_{XY} vs p_{T}" , kTH2F , {axisTrackPt, axisTrackDcaXY});
218239 histos.add (" TrackQA/hPtDcaZ" , " DCA_{Z} vs p_{T}" , kTH2F , {axisTrackPt, axisTrackDcaZ});
240+ histos.add (" TrackQA/hTrackTPCdEdX" , " hTrackTPCdEdX" , kTH2F , {axisTrackPt, axisTrackdEdx});
241+ histos.add (" TrackQA/hUSCentPtInvMass" , " hUSCentPtInvMass" , kTH3F , {axisCent, axisTrackPt, axisInvMass});
242+ histos.add (" TrackQA/hLSCentPtInvMass" , " hLSCentPtInvMass" , kTH3F , {axisCent, axisTrackPt, axisInvMass});
219243 histos.add (" DF/hQaQc" , " X^{A}_{1}X^{C}_{1} + Y^{A}_{1}Y^{C}_{1}" , kTProfile , {axisCent});
220244 histos.add (" DF/hAQu" , " u_{x}X^{A}_{1} + u_{y}Y^{A}_{1}" , kTProfile2D , {axisCent, axisTrackEta});
221245 histos.add (" DF/hCQu" , " u_{x}X^{C}_{1} + u_{y}Y^{C}_{1}" , kTProfile2D , {axisCent, axisTrackEta});
222246 histos.add (" DF/hAQuPos" , " u_{x}X^{A}_{1} + u_{y}Y^{A}_{1}" , kTProfile2D , {axisCent, axisTrackEta});
223247 histos.add (" DF/hCQuPos" , " u_{x}X^{C}_{1} + u_{y}Y^{C}_{1}" , kTProfile2D , {axisCent, axisTrackEta});
224248 histos.add (" DF/hAQuNeg" , " u_{x}X^{A}_{1} + u_{y}Y^{A}_{1}" , kTProfile2D , {axisCent, axisTrackEta});
225249 histos.add (" DF/hCQuNeg" , " u_{x}X^{C}_{1} + u_{y}Y^{C}_{1}" , kTProfile2D , {axisCent, axisTrackEta});
250+ histos.add (" DF/Reso/US/hPhiQuA" , " hPhiQuA" , kTProfile3D , {axisCent, axisTrackRap, axisInvMass});
251+ histos.add (" DF/Reso/US/hPhiQuC" , " hPhiQuC" , kTProfile3D , {axisCent, axisTrackRap, axisInvMass});
252+ histos.add (" DF/Reso/LS/hPhiQuA" , " hPhiQuA" , kTProfile3D , {axisCent, axisTrackRap, axisInvMass});
253+ histos.add (" DF/Reso/LS/hPhiQuC" , " hPhiQuC" , kTProfile3D , {axisCent, axisTrackRap, axisInvMass});
226254 }
227255
228256 template <typename C>
@@ -300,45 +328,52 @@ struct FlowEventPlane {
300328
301329 void gainCalib (float const & vz, int const & runNumber, std::array<float , 4 >& energy, const char * histName = " hZNAEnergy" )
302330 {
303- // Set CCDB path
304- std::string ccdbPath = static_cast <std::string>(cCcdbPath) + " /GainCalib" + " /Run" + std::to_string (runNumber);
331+ if (cRunNum != lRunNum) {
332+ // Set CCDB path
333+ std::string ccdbPath = static_cast <std::string>(cCcdbPath) + " /GainCalib" + " /Run" + std::to_string (runNumber);
305334
306- // Get object from CCDB
307- auto ccdbObj = ccdbService->getForTimeStamp <TList>(ccdbPath, -1 );
335+ // Get object from CCDB
336+ auto ccdbObj = ccdbService->getForTimeStamp <TList>(ccdbPath, -1 );
337+
338+ // Store histogram in container
339+ CorrHistContainer.hGainCalib = reinterpret_cast <TH2F*>(ccdbObj->FindObject (histName));
340+ }
308341
309- // Get gain calibration
310- TH2F* h = reinterpret_cast <TH2F*>(ccdbObj->FindObject (histName));
311342 float v = 0 .;
312343 for (int i = 0 ; i < static_cast <int >(energy.size ()); ++i) {
313- v = h ->GetBinContent (h ->FindBin (i + 0.5 , vz + 0.00001 ));
344+ v = CorrHistContainer. hGainCalib ->GetBinContent (CorrHistContainer. hGainCalib ->FindBin (i + 0.5 , vz + 0.00001 ));
314345 energy[i] *= v;
315346 }
316347 }
317348
318- template <typename C, typename F>
319- std::vector<float > getAvgCorrFactors (const C& ccdbObject, const F& corrType, const std::vector<float >& vCollParam)
349+ std::vector<float > getAvgCorrFactors (CorrectionType const & corrType, const std::vector<float >& vCollParam)
320350 {
321351 std::vector<float > vAvgOutput = {0 ., 0 ., 0 ., 0 .};
322- std::vector<std::vector<std::string>> vHistNames = corrTypeHistNameMap.at (corrType);
323352 int binarray[4 ];
324- int cntrx = 0 ;
325- for (auto const & x : vHistNames) {
326- int cntry = 0 ;
327- for (auto const & y : x) {
328- if (corrType == kFineCorr ) {
329- TProfile* hp = reinterpret_cast <TProfile*>(ccdbObject->FindObject (y.c_str ()));
330- vAvgOutput[cntrx] += hp->GetBinContent (hp->GetXaxis ()->FindBin (vCollParam[cntry]));
331- } else {
332- THnSparseF* hn = reinterpret_cast <THnSparseF*>(ccdbObject->FindObject (y.c_str ()));
333- for (int i = 0 ; i < static_cast <int >(vHistNames.size ()); ++i) {
334- binarray[i] = hn->GetAxis (i)->FindBin (vCollParam[i]);
335- }
336- vAvgOutput[cntrx] += hn->GetBinContent (hn->GetBin (binarray));
353+ if (corrType == kCoarseCorr ) {
354+ int cntrx = 0 ;
355+ for (auto const & v : CorrHistContainer.vCoarseCorrHist ) {
356+ for (auto const & h : v) {
357+ binarray[kCent ] = h->GetAxis (kCent )->FindBin (vCollParam[kCent ] + 0.0001 );
358+ binarray[kVx ] = h->GetAxis (kVx )->FindBin (vCollParam[kVx ] + 0.0001 );
359+ binarray[kVy ] = h->GetAxis (kVy )->FindBin (vCollParam[kVy ] + 0.0001 );
360+ binarray[kVz ] = h->GetAxis (kVz )->FindBin (vCollParam[kVz ] + 0.0001 );
361+ vAvgOutput[cntrx] += h->GetBinContent (h->GetBin (binarray));
362+ }
363+ ++cntrx;
364+ }
365+ } else {
366+ int cntrx = 0 ;
367+ for (auto const & v : CorrHistContainer.vFineCorrHist ) {
368+ int cntry = 0 ;
369+ for (auto const & h : v) {
370+ vAvgOutput[cntrx] += h->GetBinContent (h->GetXaxis ()->FindBin (vCollParam[cntry] + 0.0001 ));
371+ ++cntry;
337372 }
338- ++cntry ;
373+ ++cntrx ;
339374 }
340- ++cntrx;
341375 }
376+
342377 return vAvgOutput;
343378 }
344379
@@ -362,20 +397,39 @@ struct FlowEventPlane {
362397 corrType = kFineCorr ;
363398 }
364399
365- // Set ccdb path
366- ccdbPath = static_cast <std::string>(cCcdbPath) + " /CorrItr_" + std::to_string (i + 1 ) + " /Run" + std::to_string (runNumber);
400+ // Check current and last run number, fetch ccdb object and store corrections in container
401+ if (cRunNum != lRunNum) {
402+ // Set ccdb path
403+ ccdbPath = static_cast <std::string>(cCcdbPath) + " /CorrItr_" + std::to_string (i + 1 ) + " /Run" + std::to_string (runNumber);
367404
368- // Get object from CCDB
369- auto ccdbObj = ccdbService->getForTimeStamp <TList>(ccdbPath, -1 );
405+ // Get object from CCDB
406+ auto ccdbObject = ccdbService->getForTimeStamp <TList>(ccdbPath, -1 );
370407
371- // Check CCDB Object
372- if (!ccdbObj) {
373- LOGF (warning, " CCDB OBJECT NOT FOUND" );
374- return ;
408+ // Check CCDB Object
409+ if (!ccdbObject) {
410+ LOGF (warning, " CCDB OBJECT NOT FOUND" );
411+ return ;
412+ }
413+
414+ // Store histograms in Hist Container
415+ std::vector<std::vector<std::string>> vHistNames = corrTypeHistNameMap.at (corrType);
416+ int cntrx = 0 ;
417+ for (auto const & x : vHistNames) {
418+ int cntry = 0 ;
419+ for (auto const & y : x) {
420+ if (corrType == kFineCorr ) {
421+ CorrHistContainer.vFineCorrHist [cntrx][cntry] = reinterpret_cast <TProfile*>(ccdbObject->FindObject (y.c_str ()));
422+ } else {
423+ CorrHistContainer.vCoarseCorrHist [cntrx][cntry] = reinterpret_cast <THnSparseF*>(ccdbObject->FindObject (y.c_str ()));
424+ }
425+ ++cntry;
426+ }
427+ ++cntrx;
428+ }
375429 }
376430
377431 // Get averages
378- std::vector<float > vAvg = getAvgCorrFactors (ccdbObj, corrType, inputParam);
432+ std::vector<float > vAvg = getAvgCorrFactors (corrType, inputParam);
379433
380434 // Apply correction
381435 outputParam[kXa ] -= vAvg[kXa ];
@@ -385,6 +439,80 @@ struct FlowEventPlane {
385439 }
386440 }
387441
442+ template <typename T>
443+ bool isKaon (T const & track)
444+ {
445+ bool tofFlagKa{false }, tpcFlagKa{false };
446+ // check tof signal
447+ if (track.hasTOF ()) {
448+ if (std::abs (track.tofNSigmaKa ()) < cTofNSigmaKa && std::abs (track.tofNSigmaPi ()) > cTofRejCut && std::abs (track.tofNSigmaPr ()) > cTofRejCut) {
449+ tofFlagKa = true ;
450+ }
451+ if (std::abs (track.tpcNSigmaKa ()) < cTpcNSigmaKa) {
452+ tpcFlagKa = true ;
453+ }
454+ } else { // select from TPC
455+ tofFlagKa = true ;
456+ if (std::abs (track.tpcNSigmaKa ()) < cTpcNSigmaKa && std::abs (track.tpcNSigmaPi ()) > cTpcRejCut && std::abs (track.tpcNSigmaPr ()) > cTpcRejCut) {
457+ tpcFlagKa = true ;
458+ }
459+ }
460+
461+ if (tofFlagKa && tpcFlagKa) {
462+ return true ;
463+ }
464+
465+ return false ;
466+ }
467+
468+ template <typename T>
469+ void getResoFlow (T const & tracks, std::vector<float > const & vSP)
470+ {
471+ float ux = 0 ., uy = 0 ., v1a = 0 ., v1c = 0 .;
472+ for (auto const & [track1, track2] : soa::combinations (soa::CombinationsFullIndexPolicy (tracks, tracks))) {
473+ // Discard same track
474+ if (track1.index () == track2.index ()) {
475+ continue ;
476+ }
477+
478+ // Select track
479+ if (!selectTrack (track1) || !selectTrack (track2)) {
480+ continue ;
481+ }
482+
483+ // Identify track
484+ if (!isKaon (track1) || !isKaon (track2)) {
485+ continue ;
486+ }
487+
488+ histos.fill (HIST (" TrackQA/hTrackTPCdEdX" ), track1.pt (), track1.tpcSignal ());
489+ histos.fill (HIST (" TrackQA/hTrackTPCdEdX" ), track2.pt (), track2.tpcSignal ());
490+
491+ // Reconstruct invariant mass
492+ float p = RecoDecay::p ((track1.px () + track2.px ()), (track1.py () + track2.py ()), (track1.pz () + track2.pz ()));
493+ float e = RecoDecay::e (track1.px (), track1.py (), track1.pz (), MassKaonCharged) + RecoDecay::e (track2.px (), track2.py (), track2.pz (), MassKaonCharged);
494+ float m = std::sqrt (RecoDecay::m2 (p, e));
495+
496+ // Get directed flow
497+ std::array<float , 3 > v = {track1.px () + track2.px (), track1.py () + track2.py (), track1.pz () + track2.pz ()};
498+ ux = std::cos (RecoDecay::phi (v));
499+ uy = std::sin (RecoDecay::phi (v));
500+ v1a = ux * vSP[kXa ] + uy * vSP[kYa ];
501+ v1c = ux * vSP[kXc ] + uy * vSP[kYc ];
502+
503+ // Fill histograms
504+ if (track1.sign () != track2.sign ()) {
505+ histos.fill (HIST (" TrackQA/hUSCentPtInvMass" ), cent, RecoDecay::pt (v), m);
506+ histos.fill (HIST (" DF/Reso/US/hPhiQuA" ), cent, RecoDecay::y (v, MassPhi), m, v1a);
507+ histos.fill (HIST (" DF/Reso/US/hPhiQuC" ), cent, RecoDecay::y (v, MassPhi), m, v1c);
508+ } else {
509+ histos.fill (HIST (" TrackQA/hLSCentPtInvMass" ), cent, RecoDecay::pt (v), m);
510+ histos.fill (HIST (" DF/Reso/LS/hPhiQuA" ), cent, RecoDecay::y (v, MassPhi), m, v1a);
511+ histos.fill (HIST (" DF/Reso/LS/hPhiQuC" ), cent, RecoDecay::y (v, MassPhi), m, v1c);
512+ }
513+ }
514+ }
515+
388516 void fillCorrHist (const std::vector<float >& vCollParam, const std::vector<float >& vSP)
389517 {
390518 histos.fill (HIST (" CorrHist/hWtXZNA" ), vCollParam[kCent ], vCollParam[kVx ], vCollParam[kVy ], vCollParam[kVz ], vSP[kXa ]);
@@ -422,7 +550,7 @@ struct FlowEventPlane {
422550
423551 using BCsRun3 = soa::Join<aod::BCsWithTimestamps, aod::Run3MatchedToBCSparse>;
424552 using CollisionsRun3 = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs, aod::CentFT0Ms, aod::CentFV0As, aod::MultsExtra>;
425- using Tracks = soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA, aod::pidTPCPi, aod::pidTPCPr , aod::pidTOFPi , aod::pidTOFPr, aod::TrackCompColls>;
553+ using Tracks = soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA, aod::pidTPCPi, aod::pidTOFPi , aod::pidTPCKa, aod::pidTOFKa, aod::pidTPCPr , aod::pidTOFPr, aod::TrackCompColls>;
426554
427555 void process (CollisionsRun3::iterator const & collision, BCsRun3 const & /* bcs*/ , aod::Zdcs const &, Tracks const & tracks)
428556 {
@@ -442,7 +570,7 @@ struct FlowEventPlane {
442570
443571 // Get bunch crossing
444572 auto bc = collision.foundBC_as <BCsRun3>();
445- int runNumber = collision.foundBC_as <BCsRun3>().runNumber ();
573+ cRunNum = collision.foundBC_as <BCsRun3>().runNumber ();
446574
447575 // check zdc
448576 if (!bc.has_zdc ()) {
@@ -470,8 +598,8 @@ struct FlowEventPlane {
470598
471599 // Do gain calibration
472600 if (cDoGainCalib) {
473- gainCalib (vCollParam[kVz ], runNumber , znaEnergy, " hZNASignal" );
474- gainCalib (vCollParam[kVz ], runNumber , zncEnergy, " hZNCSignal" );
601+ gainCalib (vCollParam[kVz ], cRunNum , znaEnergy, " hZNASignal" );
602+ gainCalib (vCollParam[kVz ], cRunNum , zncEnergy, " hZNCSignal" );
475603 }
476604
477605 // Fill zdc signal
@@ -519,7 +647,7 @@ struct FlowEventPlane {
519647
520648 // Do corrections
521649 if (cApplyRecentCorr) {
522- applyCorrection (vCollParam, runNumber , vSP);
650+ applyCorrection (vCollParam, cRunNum , vSP);
523651 }
524652
525653 // Fill X and Y histograms for corrections after each iteration
@@ -569,6 +697,12 @@ struct FlowEventPlane {
569697 histos.fill (HIST (" DF/hCQuNeg" ), cent, track.eta (), v1c);
570698 }
571699 }
700+
701+ // Get resonance flow
702+ getResoFlow (tracks, vSP);
703+
704+ // Update run number
705+ lRunNum = cRunNum;
572706 }
573707};
574708
0 commit comments