diff --git a/PWGCF/Flow/Tasks/flowEventPlane.cxx b/PWGCF/Flow/Tasks/flowEventPlane.cxx index 4e9ac6cd514..502da4810b2 100644 --- a/PWGCF/Flow/Tasks/flowEventPlane.cxx +++ b/PWGCF/Flow/Tasks/flowEventPlane.cxx @@ -16,7 +16,6 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/CCDB/EventSelectionParams.h" -#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" @@ -25,11 +24,8 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include -#include #include #include -#include #include #include #include @@ -38,21 +34,12 @@ #include #include #include -#include #include -#include -#include -#include -#include - #include -#include #include #include -#include #include -#include #include using namespace o2; @@ -63,72 +50,87 @@ using namespace o2::constants::math; namespace o2::aod { -namespace colspext +namespace colsp { -DECLARE_SOA_COLUMN(SelColFlag, selColFlag, bool); -DECLARE_SOA_COLUMN(Xa, xa, float); -DECLARE_SOA_COLUMN(Ya, ya, float); -DECLARE_SOA_COLUMN(Xc, xc, float); -DECLARE_SOA_COLUMN(Yc, yc, float); -} // namespace colspext -DECLARE_SOA_TABLE(ColSPExt, "AOD", "COLSPEXT", o2::soa::Index<>, - colspext::SelColFlag, - colspext::Xa, - colspext::Ya, - colspext::Xc, - colspext::Yc); +DECLARE_SOA_COLUMN(RunNumber, runNumber, int); +DECLARE_SOA_COLUMN(Timestamp, timestamp, uint64_t); +DECLARE_SOA_COLUMN(Cent, cent, float); +DECLARE_SOA_COLUMN(Vx, vx, float); +DECLARE_SOA_COLUMN(Vy, vy, float); +DECLARE_SOA_COLUMN(Vz, vz, float); +DECLARE_SOA_COLUMN(ZnaEnergyCommon, znaEnergyCommon, float); +DECLARE_SOA_COLUMN(ZncEnergyCommon, zncEnergyCommon, float); +DECLARE_SOA_COLUMN(ZnaEnergy, znaEnergy, float[4]); +DECLARE_SOA_COLUMN(ZncEnergy, zncEnergy, float[4]); +} // namespace colsp +DECLARE_SOA_TABLE(ColSps, "AOD", "COLSPS", o2::soa::Index<>, + colsp::RunNumber, + colsp::Timestamp, + colsp::Cent, + colsp::Vx, + colsp::Vy, + colsp::Vz, + colsp::ZnaEnergyCommon, + colsp::ZncEnergyCommon, + colsp::ZnaEnergy, + colsp::ZncEnergy); + +using ColSp = ColSps::iterator; namespace tracksid { -DECLARE_SOA_COLUMN(IsCharged, isCharged, bool); -DECLARE_SOA_COLUMN(IsPion, isPion, bool); -DECLARE_SOA_COLUMN(IsKaon, isKaon, bool); -DECLARE_SOA_COLUMN(IsProton, isProton, bool); +DECLARE_SOA_INDEX_COLUMN(ColSp, colSp); +DECLARE_SOA_COLUMN(Px, px, float); +DECLARE_SOA_COLUMN(Py, py, float); +DECLARE_SOA_COLUMN(Pz, pz, float); +DECLARE_SOA_COLUMN(Charge, charge, int8_t); +DECLARE_SOA_COLUMN(TpcInfo, tpcInfo, float[4]); +DECLARE_SOA_COLUMN(TofInfo, tofInfo, float[4]); +DECLARE_SOA_COLUMN(Dca, dca, float[2]); } // namespace tracksid DECLARE_SOA_TABLE(TracksId, "AOD", "TRACKSID", o2::soa::Index<>, - tracksid::IsCharged, - tracksid::IsPion, - tracksid::IsKaon, - tracksid::IsProton); + tracksid::ColSpId, + tracksid::Px, + tracksid::Py, + tracksid::Pz, + tracksid::Charge, + tracksid::TpcInfo, + tracksid::TofInfo, + tracksid::Dca); +using TrackId = TracksId::iterator; + +namespace v0track +{ +DECLARE_SOA_INDEX_COLUMN(ColSp, colSp); +DECLARE_SOA_COLUMN(Px, px, float); +DECLARE_SOA_COLUMN(Py, py, float); +DECLARE_SOA_COLUMN(Pz, pz, float); +DECLARE_SOA_COLUMN(CosPA, cosPA, float); +DECLARE_SOA_COLUMN(Ctau, ctau, float); +DECLARE_SOA_COLUMN(Mass, mass, float); +DECLARE_SOA_COLUMN(Species, species, uint8_t); +DECLARE_SOA_COLUMN(DcaDau, dcaDau, float[2]); +DECLARE_SOA_COLUMN(TpcDau, tpcDau, float[2]); +} // namespace v0track +DECLARE_SOA_TABLE(V0Tracks, "AOD", "V0TRACKS", o2::soa::Index<>, + v0track::ColSpId, + v0track::Px, + v0track::Py, + v0track::Pz, + v0track::CosPA, + v0track::Ctau, + v0track::Mass, + v0track::Species, + v0track::DcaDau, + v0track::TpcDau); +using V0Track = V0Tracks::iterator; } // namespace o2::aod -enum GainClibCorr { - kGainCalibA = 0, - kGainCalibC, - kNGainCalib -}; - -enum CorrectionType { - kFineCorr = 0, - kCoarseCorr, - kNCorr -}; - -enum CollisionParameterType { - kCent = 0, - kVx, - kVy, - kVz -}; - -enum ZDCXYType { - kXa = 0, - kYa, - kXc, - kYc, - kXYAC -}; - -enum ParticleType { - kPi = 0, +enum TrackType { + kCharged = 0, + kPi, kKa, - kPr, - kNPart -}; - -enum ResoType { - kPhi0 = 0, - kKStar + kPr }; enum V0Type { @@ -137,10 +139,11 @@ enum V0Type { kAntiLambda }; -struct SpectatorPlaneTableProducer { +struct FlowEventPlane { // Table producer - Produces colSPExtTable; + Produces colSpTable; Produces tracksIdTable; + Produces v0sTable; // Configurables // Collisions @@ -149,45 +152,15 @@ struct SpectatorPlaneTableProducer { Configurable cMinCent{"cMinCent", 0., "Minumum Centrality"}; Configurable cMaxCent{"cMaxCent", 100.0, "Maximum Centrality"}; Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; - Configurable cTriggerTvxSel{"cTriggerTvxSel", false, "Trigger Time and Vertex Selection"}; - Configurable cTFBorder{"cTFBorder", false, "Timeframe Border Selection"}; - Configurable cNoItsROBorder{"cNoItsROBorder", false, "No ITSRO Border Cut"}; - Configurable cItsTpcVtx{"cItsTpcVtx", false, "ITS+TPC Vertex Selection"}; Configurable cPileupReject{"cPileupReject", true, "Pileup rejection"}; - Configurable cZVtxTimeDiff{"cZVtxTimeDiff", false, "z-vtx time diff selection"}; + Configurable cZVtxTimeDiff{"cZVtxTimeDiff", true, "z-vtx time diff selection"}; Configurable cIsGoodITSLayers{"cIsGoodITSLayers", true, "Good ITS Layers All"}; Configurable cMinOccupancy{"cMinOccupancy", 0, "Minimum FT0C Occupancy"}; Configurable cMaxOccupancy{"cMaxOccupancy", 1e6, "Maximum FT0C Occupancy"}; - // Gain calibration - Configurable cDoGainCalib{"cDoGainCalib", false, "Gain Calib Flag"}; - Configurable cUseAlphaZDC{"cUseAlphaZDC", true, "Use Alpha ZDC"}; - - // Coarse binning factor - Configurable cAxisCBF{"cAxisCBF", 5, "Coarse Bin Factor"}; - - // Cent Vx Vy Vz Bins - Configurable cAxisCentBins{"cAxisCentBins", 20, "NBins Centrality"}; - Configurable cAxisVxyBins{"cAxisVxyBins", 20, "NBins Vx Vy"}; - Configurable cAxisVzBins{"cAxisVzBins", 20, "NBins Vz"}; - Configurable cAxisVxMin{"cAxisVxMin", -0.06, "Vx Min"}; - Configurable cAxisVxMax{"cAxisVxMax", -0.02, "Vx Max"}; - Configurable cAxisVyMin{"cAxisVyMin", -0.01, "Vy Min"}; - Configurable cAxisVyMax{"cAxisVyMax", 0.006, "Vy Max"}; - - // Corrections - Configurable cApplyRecentCorr{"cApplyRecentCorr", false, "Apply recentering"}; - Configurable> cCorrFlagVector{"cCorrFlagVector", {0, 0, 0, 0, 0, 0}, "Correction Flag"}; - - // CCDB - Configurable cCcdbUrl{"cCcdbUrl", "http://ccdb-test.cern.ch:8080", "url of ccdb"}; - Configurable cCcdbPath{"cCcdbPath", "Users/y/ypatley/DFOO", "Path for ccdb-object"}; - Configurable nolaterthan{"nolaterthan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - // Tracks Configurable cTrackMinPt{"cTrackMinPt", 0.1, "p_{T} minimum"}; Configurable cTrackMaxPt{"cTrackMaxPt", 10.0, "p_{T} maximum"}; - Configurable cNEtaBins{"cNEtaBins", 7, "# of eta bins"}; Configurable cTrackEtaCut{"cTrackEtaCut", 0.8, "Pseudorapidity cut"}; Configurable cTrackGlobal{"cTrackGlobal", true, "Global Track"}; Configurable cTrackDcaXYCut{"cTrackDcaXYCut", 0.1, "DcaXY Cut"}; @@ -196,132 +169,58 @@ struct SpectatorPlaneTableProducer { // Track PID Configurable cTpcElRejCutMin{"cTpcElRejCutMin", -3., "Electron Rejection Cut Minimum"}; Configurable cTpcElRejCutMax{"cTpcElRejCutMax", 5., "Electron Rejection Cut Maximum"}; - Configurable cTpcNSigmaCut{"cTpcNSigmaCut", 2, "TPC NSigma Cut"}; + Configurable cTpcNSigmaCut{"cTpcNSigmaCut", 5, "TPC NSigma Cut"}; Configurable cTpcRejCut{"cTpcRejCut", 3, "TPC Rej Cut"}; - Configurable cTofNSigmaCut{"cTofNSigmaCut", 2, "TOF NSigma Cut"}; + Configurable cTofNSigmaCut{"cTofNSigmaCut", 5, "TOF NSigma Cut"}; Configurable cTofRejCut{"cTofRejCut", 3, "TOF Rej Cut"}; - Configurable cPionPtCut{"cPionPtCut", 0.6, "Pion TPC pT cutoff"}; - Configurable cKaonPtCut{"cKaonPtCut", 0.6, "Kaon TPC pT cutoff"}; - Configurable cProtonPtCut{"cProtonPtCut", 1.1, "Proton TPC pT cutoff"}; - // Initialize CCDB Service - Service ccdbService; + // V0s + Configurable cV0TypeSelection{"cV0TypeSelection", 1, "V0 Type Selection"}; + Configurable cMinDcaProtonToPV{"cMinDcaProtonToPV", 0.02, "Minimum Proton DCAr to PV"}; + Configurable cMinDcaPionToPV{"cMinDcaPionToPV", 0.06, "Minimum Pion DCAr to PV"}; + Configurable cDcaV0Dau{"cDcaV0Dau", 1., "DCA between V0 daughters"}; + Configurable cMinV0Radius{"cMinV0Radius", 0.5, "Minimum V0 radius from PV"}; + Configurable cV0CTau{"cV0CTau", 50.0, "Decay length selection"}; + Configurable cV0CosPA{"cV0CosPA", 0.95, "CosPA selection"}; + Configurable cArmPodSel{"cArmPodSel", 0.2, "Armentros-Podolanski Selection for K0S"}; + Configurable cV0EtaCut{"cV0EtaCut", 0.8, "V0 eta cut"}; - // Histogram registry: an object to hold your histograms + // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - // Global objects - const float zdcDenThrs = 1e-4; - float cent = 0., mult = 0.; - float posX = 0., posY = 0., posZ = 0.; - std::vector> vCoarseCorrHistNames = { - {"hXZNAVsCentVxVyVz"}, - {"hYZNAVsCentVxVyVz"}, - {"hXZNCVsCentVxVyVz"}, - {"hYZNCVsCentVxVyVz"}}; - std::vector> vFineCorrHistNames = { - {"hXZNAVsCent", "hXZNAVsVx", "hXZNAVsVy", "hXZNAVsVz"}, - {"hYZNAVsCent", "hYZNAVsVx", "hYZNAVsVy", "hYZNAVsVz"}, - {"hXZNCVsCent", "hXZNCVsVx", "hXZNCVsVy", "hXZNCVsVz"}, - {"hYZNCVsCent", "hYZNCVsVx", "hYZNCVsVy", "hYZNCVsVz"}}; - std::map>> corrTypeHistNameMap = {{kFineCorr, vFineCorrHistNames}, {kCoarseCorr, vCoarseCorrHistNames}}; - - // Container for histograms - struct CorrectionHistContainer { - std::array hGainCalib; - std::array, 4>, 6> vCoarseCorrHist; - std::array, 4>, 6> vFineCorrHist; - } CorrectionHistContainer; - // Run number - int cRunNum = 0, lRunNum = 0; + uint64_t runNum = 0, timestamp = 0; + int64_t colIdx = 0; + float mult = 0., cent = 0., posX = 0., posY = 0., posZ = 0.; void init(InitContext const&) { - // Set CCDB url - ccdbService->setURL(cCcdbUrl.value); - ccdbService->setCaching(true); - ccdbService->setLocalObjectValidityChecking(); - ccdbService->setCreatedNotAfter(nolaterthan.value); + // Axis collision + const AxisSpec axisCent{100, 0., 100, "FT0C%"}; - // Define axes - const AxisSpec axisZDCEnergy{500, 0, 500, "ZD[AC] Signal"}; + const AxisSpec axisTrackPt(40, 0, 4, "p_{T} (GeV/#it{c})"); + const AxisSpec axisTrackDcaZ(220, -1.1, 1.1, "dca_{Z} (cm)"); + const AxisSpec axisTrackDcaXY(80, -0.2, 0.2, "dca_{XY} (cm)"); + const AxisSpec axisTrackdEdx(360, 20, 200, "#frac{dE}{dx}"); + const AxisSpec axisTrackTofSignal(240, 0, 1.2, "#beta"); - const AxisSpec axisCent{100, 0., 100, "FT0C%"}; - const AxisSpec axisVx{cAxisVxyBins, cAxisVxMin, cAxisVxMax, "V_{X}(cm)"}; - const AxisSpec axisVy{cAxisVxyBins, cAxisVyMin, cAxisVyMax, "V_{Y}(cm)"}; - const AxisSpec axisVz{cAxisVzBins, cMinZVtx, cMaxZVtx, "V_{Z}(cm)"}; - - const AxisSpec axisCoarseCent{cAxisCentBins / cAxisCBF, cMinCent, cMaxCent, "FT0C%"}; - const AxisSpec axisCoarseVx{cAxisVxyBins / cAxisCBF, cAxisVxMin, cAxisVxMax, "V_{x}"}; - const AxisSpec axisCoarseVy{cAxisVxyBins / cAxisCBF, cAxisVyMin, cAxisVyMax, "V_{y}"}; - const AxisSpec axisCoarseVz{cAxisVzBins / cAxisCBF, cMinZVtx, cMaxZVtx, "V_{z}"}; - - const AxisSpec axisFineCent{cAxisCentBins, cMinCent, cMaxCent, "FT0C%"}; - const AxisSpec axisFineVx{cAxisVxyBins, cAxisVxMin, cAxisVxMax, "V_{x}"}; - const AxisSpec axisFineVy{cAxisVxyBins, cAxisVyMin, cAxisVyMax, "V_{x}"}; - const AxisSpec axisFineVz{cAxisVzBins, cMinZVtx, cMaxZVtx, "V_{z}"}; - - const AxisSpec axisXa{40, -1, 1, "X^{ZNA}_{1}"}; - const AxisSpec axisYa{40, -1, 1, "Y^{ZNA}_{1}"}; - const AxisSpec axisXc{40, -1, 1, "X^{ZNC}_{1}"}; - const AxisSpec axisYc{40, -1, 1, "Y^{ZNC}_{1}"}; - - const AxisSpec axisPsi{18, -PIHalf, PIHalf, "#Psi_{SP}"}; - - // Create histograms - // Event - histos.add("Event/hCent", "FT0C%", kTH1F, {axisCent}); - histos.add("Event/hVx", "V_{x}", kTH1F, {axisVx}); - histos.add("Event/hVy", "V_{y}", kTH1F, {axisVy}); - histos.add("Event/hVz", "V_{z}", kTH1F, {axisVz}); - - // Gain calib - histos.add("QA/GainCalib/hZNASignal", "ZNA Signal", kTH2F, {{4, 0, 4}, {axisZDCEnergy}}); - histos.add("QA/GainCalib/hZNCSignal", "ZNC Signal", kTH2F, {{4, 0, 4}, {axisZDCEnergy}}); - histos.add("QA/hZNASignal", "ZNA Signal", kTProfile2D, {{4, 0, 4}, {axisVz}}); - histos.add("QA/hZNCSignal", "ZNC Signal", kTProfile2D, {{4, 0, 4}, {axisVz}}); - histos.add("QA/hZNAEnergyCommon", "ZNA Energy Common", kTProfile, {axisVz}); - histos.add("QA/hZNCEnergyCommon", "ZNC Energy Common", kTProfile, {axisVz}); - - // Corrections - histos.add("CorrHist/hWtXZNA", "X^{ZNA}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hWtYZNA", "Y^{ZNA}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hWtXZNC", "X^{ZNC}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hWtYZNC", "Y^{ZNC}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hUWtXZNA", "X^{ZNA}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hUWtYZNA", "Y^{ZNA}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hUWtXZNC", "X^{ZNC}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hUWtYZNC", "Y^{ZNC}_{1}", kTHnSparseF, {axisCoarseCent, axisCoarseVx, axisCoarseVy, axisCoarseVz}); - histos.add("CorrHist/hXZNAVsCent", "X^{ZNA}_{1} Vs Cent", kTProfile, {axisFineCent}); - histos.add("CorrHist/hXZNAVsVx", "X^{ZNA}_{1} Vs V_{x}", kTProfile, {axisFineVx}); - histos.add("CorrHist/hXZNAVsVy", "X^{ZNA}_{1} Vs V_{y}", kTProfile, {axisFineVy}); - histos.add("CorrHist/hXZNAVsVz", "X^{ZNA}_{1} Vs V_{z}", kTProfile, {axisFineVz}); - histos.add("CorrHist/hYZNAVsCent", "Y^{ZNA}_{1} Vs Cent", kTProfile, {axisFineCent}); - histos.add("CorrHist/hYZNAVsVx", "Y^{ZNA}_{1} Vs V_{x}", kTProfile, {axisFineVx}); - histos.add("CorrHist/hYZNAVsVy", "Y^{ZNA}_{1} Vs V_{y}", kTProfile, {axisFineVy}); - histos.add("CorrHist/hYZNAVsVz", "Y^{ZNA}_{1} Vs V_{z}", kTProfile, {axisFineVz}); - histos.add("CorrHist/hXZNCVsCent", "X^{ZNC}_{1} Vs Cent", kTProfile, {axisFineCent}); - histos.add("CorrHist/hXZNCVsVx", "X^{ZNC}_{1} Vs V_{x}", kTProfile, {axisFineVx}); - histos.add("CorrHist/hXZNCVsVy", "X^{ZNC}_{1} Vs V_{y}", kTProfile, {axisFineVy}); - histos.add("CorrHist/hXZNCVsVz", "X^{ZNC}_{1} Vs V_{z}", kTProfile, {axisFineVz}); - histos.add("CorrHist/hYZNCVsCent", "Y^{ZNC}_{1} Vs Cent", kTProfile, {axisFineCent}); - histos.add("CorrHist/hYZNCVsVx", "Y^{ZNC}_{1} Vs V_{x}", kTProfile, {axisFineVx}); - histos.add("CorrHist/hYZNCVsVy", "Y^{ZNC}_{1} Vs V_{y}", kTProfile, {axisFineVy}); - histos.add("CorrHist/hYZNCVsVz", "Y^{ZNC}_{1} Vs V_{z}", kTProfile, {axisFineVz}); - - // Checks - histos.add("Checks/hPsiSPA", "#Psi_{SP}^{A} distribution", kTH2F, {axisCent, axisPsi}); - histos.add("Checks/hPsiSPC", "#Psi_{SP}^{C} distribution", kTH2F, {axisCent, axisPsi}); - histos.add("Checks/hCosPsiSPAC", "Cos(#Psi_{SP}^{A} #minus #Psi_{SP}^{C}) distribution", kTProfile, {axisCent}); - histos.add("Checks/hSinPsiSPAC", "Sin(#Psi_{SP}^{A} #minus #Psi_{SP}^{C}) distribution", kTProfile, {axisCent}); - histos.add("Checks/hXaXc", "X^{A}_{1}X^{C}_{1}", kTProfile, {axisCent}); - histos.add("Checks/hYaYc", "Y^{A}_{1}Y^{C}_{1}", kTProfile, {axisCent}); - histos.add("Checks/hXaYc", "X^{A}_{1}Y^{C}_{1}", kTProfile, {axisCent}); - histos.add("Checks/hYaXc", "Y^{A}_{1}X^{C}_{1}", kTProfile, {axisCent}); - - // Directed flow QXY vector - histos.add("DF/hQaQc", "X^{A}_{1}X^{C}_{1} + Y^{A}_{1}Y^{C}_{1}", kTProfile, {axisCent}); + const AxisSpec axisAlpha(40, -1, 1, "#alpha"); + const AxisSpec axisQtarm(40, 0, 0.4, "q_{T}"); + + // Histogram collision + histos.add("hCent", "Centrality", kTH1F, {axisCent}); + + // Tracks QA + histos.add("QA/hDcaXY", "DCA_{XY} vs pT", kTH2F, {axisTrackPt, axisTrackDcaXY}); + histos.add("QA/hDcaZ", "DCA_{Z} vs p_{T}", kTH2F, {axisTrackPt, axisTrackDcaZ}); + histos.add("QA/hdEdX", "dE/dx vs pT", kTH2F, {axisTrackPt, axisTrackdEdx}); + histos.add("QA/hTOFSignal", "#beta_{TOF} vs p_{T}", kTH2F, {axisTrackPt, axisTrackTofSignal}); + + // V0s QA + histos.add("QA/h2f_armpod_before_sel", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); + histos.add("QA/h2f_armpod_K0s", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); + histos.add("QA/h2f_armpod_Lambda", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); + histos.add("QA/h2f_armpod_AntiLambda", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); } template @@ -344,22 +243,6 @@ struct SpectatorPlaneTableProducer { return false; } - if (cTriggerTvxSel && !col.selection_bit(aod::evsel::kIsTriggerTVX)) { // Time and Vertex trigger - return false; - } - - if (cTFBorder && !col.selection_bit(aod::evsel::kNoTimeFrameBorder)) { // Time frame border - return false; - } - - if (cNoItsROBorder && !col.selection_bit(aod::evsel::kNoITSROFrameBorder)) { // ITS Readout frame border - return false; - } - - if (cItsTpcVtx && !col.selection_bit(aod::evsel::kIsVertexITSTPC)) { // ITS+TPC Vertex - return false; - } - if (cPileupReject && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) { // Pile-up rejection return false; } @@ -373,270 +256,8 @@ struct SpectatorPlaneTableProducer { } // Set Multiplicity - mult = col.multNTracksHasTPC(); - - return true; - } - - // Load Gain Calibrations and ZDC Q-Vector Recentering Corrections - void loadCorrections() - { - // Load ZDC gain calibration - if (cDoGainCalib) { - std::string ccdbPath = static_cast(cCcdbPath) + "/GainCalib" + "/Run" + std::to_string(cRunNum); - auto ccdbObj = ccdbService->getForTimeStamp(ccdbPath, nolaterthan.value); - CorrectionHistContainer.hGainCalib[0] = reinterpret_cast(ccdbObj->FindObject("hZNASignal")); - CorrectionHistContainer.hGainCalib[1] = reinterpret_cast(ccdbObj->FindObject("hZNCSignal")); - } - - // Load shift corrections for ZDC Q-Vectors - if (cApplyRecentCorr) { - std::vector vCorrFlags = static_cast>(cCorrFlagVector); - int nitr = vCorrFlags.size(); - CorrectionType corrType = kFineCorr; - - for (int i = 0; i < nitr; ++i) { - // Skip correction if corrFlag != 1 - if (vCorrFlags[i] != 1) { - continue; - } - - // Set correction type - if (i % kNCorr == 0) { - corrType = kCoarseCorr; - } else { - corrType = kFineCorr; - } - - // Set ccdb path - std::string ccdbPath = static_cast(cCcdbPath) + "/CorrItr_" + std::to_string(i + 1) + "/Run" + std::to_string(cRunNum); - - // Get object from CCDB - auto ccdbObject = ccdbService->getForTimeStamp(ccdbPath, nolaterthan.value); - - // Check CCDB Object - if (!ccdbObject) { - LOGF(warning, "CCDB OBJECT NOT FOUND"); - return; - } - - // Store histograms in Hist Container - std::vector> vHistNames = corrTypeHistNameMap.at(corrType); - int cntrx = 0; - for (auto const& x : vHistNames) { - int cntry = 0; - for (auto const& y : x) { - if (corrType == kFineCorr) { - CorrectionHistContainer.vFineCorrHist[i][cntrx][cntry] = reinterpret_cast(ccdbObject->FindObject(y.c_str())); - } else { - CorrectionHistContainer.vCoarseCorrHist[i][cntrx][cntry] = reinterpret_cast(ccdbObject->FindObject(y.c_str())); - } - ++cntry; - } - ++cntrx; - } - } - } - } - - // Apply gain calibrations - void gainCalib(float const& vz, std::array& eA, std::array& eC) - { - float vA = 0., vC = 0.; - for (int i = 0; i < static_cast(eA.size()); ++i) { - vA = CorrectionHistContainer.hGainCalib[0]->GetBinContent(CorrectionHistContainer.hGainCalib[0]->FindBin(i + 0.5, vz + 0.00001)); - vC = CorrectionHistContainer.hGainCalib[1]->GetBinContent(CorrectionHistContainer.hGainCalib[1]->FindBin(i + 0.5, vz + 0.00001)); - eA[i] *= vA; - eC[i] *= vC; - } - } - - std::vector getAvgCorrFactors(int const& itr, CorrectionType const& corrType, std::array const& vCollParam) - { - std::vector vAvgOutput = {0., 0., 0., 0.}; - int binarray[4]; - if (corrType == kCoarseCorr) { - int cntrx = 0; - for (auto const& v : CorrectionHistContainer.vCoarseCorrHist[itr]) { - for (auto const& h : v) { - binarray[kCent] = h->GetAxis(kCent)->FindBin(vCollParam[kCent] + 0.0001); - binarray[kVx] = h->GetAxis(kVx)->FindBin(vCollParam[kVx] + 0.0001); - binarray[kVy] = h->GetAxis(kVy)->FindBin(vCollParam[kVy] + 0.0001); - binarray[kVz] = h->GetAxis(kVz)->FindBin(vCollParam[kVz] + 0.0001); - vAvgOutput[cntrx] += h->GetBinContent(h->GetBin(binarray)); - } - ++cntrx; - } - } else { - int cntrx = 0; - for (auto const& v : CorrectionHistContainer.vFineCorrHist[itr]) { - int cntry = 0; - for (auto const& h : v) { - vAvgOutput[cntrx] += h->GetBinContent(h->GetXaxis()->FindBin(vCollParam[cntry] + 0.0001)); - ++cntry; - } - ++cntrx; - } - } - - return vAvgOutput; - } - - void applyCorrection(std::array const& inputParam, std::array& outputParam) - { - std::vector vCorrFlags = static_cast>(cCorrFlagVector); - int nitr = vCorrFlags.size(); - CorrectionType corrType = kFineCorr; - - // Correction iterations - for (int i = 0; i < nitr; ++i) { - // Don't correct if corrFlag != 1 - if (vCorrFlags[i] != 1) { - continue; - } - - // Set correction type - if (i % kNCorr == 0) { - corrType = kCoarseCorr; - } else { - corrType = kFineCorr; - } - - // Get averages - std::vector vAvg = getAvgCorrFactors(i, corrType, inputParam); - - // Apply correction - outputParam[kXa] -= vAvg[kXa]; - outputParam[kYa] -= vAvg[kYa]; - outputParam[kXc] -= vAvg[kXc]; - outputParam[kYc] -= vAvg[kYc]; - } - } - - void fillCorrHist(std::array const& vCollParam, std::array const& vSP) - { - histos.fill(HIST("CorrHist/hWtXZNA"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz], vSP[kXa]); - histos.fill(HIST("CorrHist/hWtYZNA"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz], vSP[kYa]); - histos.fill(HIST("CorrHist/hWtXZNC"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz], vSP[kXc]); - histos.fill(HIST("CorrHist/hWtYZNC"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz], vSP[kYc]); - histos.fill(HIST("CorrHist/hUWtXZNA"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz]); - histos.fill(HIST("CorrHist/hUWtYZNA"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz]); - histos.fill(HIST("CorrHist/hUWtXZNC"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz]); - histos.fill(HIST("CorrHist/hUWtYZNC"), vCollParam[kCent], vCollParam[kVx], vCollParam[kVy], vCollParam[kVz]); - histos.fill(HIST("CorrHist/hXZNAVsCent"), vCollParam[kCent], vSP[kXa]); - histos.fill(HIST("CorrHist/hXZNAVsVx"), vCollParam[kVx], vSP[kXa]); - histos.fill(HIST("CorrHist/hXZNAVsVy"), vCollParam[kVy], vSP[kXa]); - histos.fill(HIST("CorrHist/hXZNAVsVz"), vCollParam[kVz], vSP[kXa]); - histos.fill(HIST("CorrHist/hYZNAVsCent"), vCollParam[kCent], vSP[kYa]); - histos.fill(HIST("CorrHist/hYZNAVsVx"), vCollParam[kVx], vSP[kYa]); - histos.fill(HIST("CorrHist/hYZNAVsVy"), vCollParam[kVy], vSP[kYa]); - histos.fill(HIST("CorrHist/hYZNAVsVz"), vCollParam[kVz], vSP[kYa]); - histos.fill(HIST("CorrHist/hXZNCVsCent"), vCollParam[kCent], vSP[kXc]); - histos.fill(HIST("CorrHist/hXZNCVsVx"), vCollParam[kVx], vSP[kXc]); - histos.fill(HIST("CorrHist/hXZNCVsVy"), vCollParam[kVy], vSP[kXc]); - histos.fill(HIST("CorrHist/hXZNCVsVz"), vCollParam[kVz], vSP[kXc]); - histos.fill(HIST("CorrHist/hYZNCVsCent"), vCollParam[kCent], vSP[kYc]); - histos.fill(HIST("CorrHist/hYZNCVsVx"), vCollParam[kVx], vSP[kYc]); - histos.fill(HIST("CorrHist/hYZNCVsVy"), vCollParam[kVy], vSP[kYc]); - histos.fill(HIST("CorrHist/hYZNCVsVz"), vCollParam[kVz], vSP[kYc]); - } - - template - bool analyzeCollision(B const& bc, C const& collision, std::array& vSP) - { - // Event selection - if (!selCollision(collision)) { - return false; - } - posX = collision.posX(); - posY = collision.posY(); - posZ = collision.posZ(); - std::array vCollParam = {cent, posX, posY, posZ}; - - // Fill event QA - histos.fill(HIST("Event/hCent"), cent); - histos.fill(HIST("Event/hVx"), posX); - histos.fill(HIST("Event/hVy"), posY); - histos.fill(HIST("Event/hVz"), posZ); - - // check zdc - if (!bc.has_zdc()) { - return false; - } - - auto zdc = bc.zdc(); - auto znaEnergy = zdc.energySectorZNA(); - auto zncEnergy = zdc.energySectorZNC(); - auto znaEnergyCommon = zdc.energyCommonZNA(); - auto zncEnergyCommon = zdc.energyCommonZNC(); - - // check energy deposits - if (znaEnergyCommon <= 0 || zncEnergyCommon <= 0 || znaEnergy[0] <= 0 || znaEnergy[1] <= 0 || znaEnergy[2] <= 0 || znaEnergy[3] <= 0 || zncEnergy[0] <= 0 || zncEnergy[1] <= 0 || zncEnergy[2] <= 0 || zncEnergy[3] <= 0) { - return false; - } - - // Fill gain calib histograms - for (int iCh = 0; iCh < kXYAC; ++iCh) { - histos.fill(HIST("QA/hZNASignal"), iCh + 0.5, vCollParam[kVz], znaEnergy[iCh]); - histos.fill(HIST("QA/hZNCSignal"), iCh + 0.5, vCollParam[kVz], zncEnergy[iCh]); - histos.fill(HIST("QA/hZNAEnergyCommon"), vCollParam[kVz], znaEnergyCommon); - histos.fill(HIST("QA/hZNCEnergyCommon"), vCollParam[kVz], zncEnergyCommon); - } + mult = col.multTPC(); - // Do gain calibration - if (cDoGainCalib) { - gainCalib(vCollParam[kVz], znaEnergy, zncEnergy); - } - - // Fill zdc signal - for (int iCh = 0; iCh < kXYAC; ++iCh) { - histos.fill(HIST("QA/GainCalib/hZNASignal"), iCh + 0.5, znaEnergy[iCh]); - histos.fill(HIST("QA/GainCalib/hZNCSignal"), iCh + 0.5, zncEnergy[iCh]); - } - - auto alphaZDC = 0.395; - const double x[4] = {-1.75, 1.75, -1.75, 1.75}; - const double y[4] = {-1.75, -1.75, 1.75, 1.75}; - - // Calculate X and Y - float znaXNum = 0., znaYNum = 0., zncXNum = 0., zncYNum = 0.; - float znaDen = 0., zncDen = 0.; - float znaWt = 0., zncWt = 0.; - - // Loop over zdc sectors - for (int i = 0; i < kXYAC; ++i) { - if (cUseAlphaZDC) { - znaWt = std::pow(znaEnergy[i], alphaZDC); - zncWt = std::pow(zncEnergy[i], alphaZDC); - } else { - znaWt = znaEnergy[i]; - zncWt = zncEnergy[i]; - } - znaXNum -= znaWt * x[i]; - znaYNum += znaWt * y[i]; - zncXNum += zncWt * x[i]; - zncYNum += zncWt * y[i]; - znaDen += znaWt; - zncDen += zncWt; - } - - if (znaDen < zdcDenThrs || zncDen < zdcDenThrs) { - return false; - } - - // Get X and Y for A and C side ZNA - vSP[kXa] = znaXNum / znaDen; - vSP[kYa] = znaYNum / znaDen; - vSP[kXc] = zncXNum / zncDen; - vSP[kYc] = zncYNum / zncDen; - - // Do corrections - if (cApplyRecentCorr) { - applyCorrection(vCollParam, vSP); - } - - // Fill X and Y histograms for corrections after each iteration - fillCorrHist(vCollParam, vSP); return true; } @@ -659,329 +280,77 @@ struct SpectatorPlaneTableProducer { return true; } - template - bool checkTrackPid(float const& ptCut, float const& trackPt, std::vector const& vTpcNsig, std::vector const& vTofNsig, bool const& tofFlag) - { - bool retFlag = false; - if (tofFlag) { - if (vTofNsig[part1] < cTofNSigmaCut && vTofNsig[part2] > cTofRejCut && vTofNsig[part3] > cTofRejCut && vTpcNsig[part1] < cTpcNSigmaCut) { - retFlag = true; - } - } else { - if (trackPt < ptCut && vTpcNsig[part1] < cTpcNSigmaCut && vTpcNsig[part2] > cTpcRejCut && vTpcNsig[part3] > cTpcRejCut) { - retFlag = true; - } - } - return retFlag; - } - - template - bool identifyTrack(T const& track) + // PID + template + void identifyTrack(T const& track, std::array& nstpc, std::array& nstof) { // Electron rejection if (std::abs(track.tpcNSigmaPi()) > cTpcRejCut && std::abs(track.tpcNSigmaKa()) > cTpcRejCut && std::abs(track.tpcNSigmaPr()) > cTpcRejCut && track.tpcNSigmaEl() > cTpcElRejCutMin && track.tpcNSigmaEl() < cTpcElRejCutMax) { - return false; + return; } - // Pion, Kaon, Proton Identification - std::vector vPtCut = {cPionPtCut, cKaonPtCut, cProtonPtCut}; - std::vector vTpcNsig = {std::abs(track.tpcNSigmaPi()), std::abs(track.tpcNSigmaKa()), std::abs(track.tpcNSigmaPr())}; - std::vector vTofNsig = {std::abs(track.tofNSigmaPi()), std::abs(track.tofNSigmaKa()), std::abs(track.tofNSigmaPr())}; - bool retFlag = false; - - if (partType == kPi && checkTrackPid(vPtCut[kPi], track.pt(), vTpcNsig, vTofNsig, track.hasTOF())) { - retFlag = true; - } else if (partType == kKa && checkTrackPid(vPtCut[kKa], track.pt(), vTpcNsig, vTofNsig, track.hasTOF())) { - retFlag = true; - } else if (partType == kPr && checkTrackPid(vPtCut[kPr], track.pt(), vTpcNsig, vTofNsig, track.hasTOF())) { - retFlag = true; - } else { - return false; + // Check track for pion + if (std::abs(track.tpcNSigmaPi()) < cTpcNSigmaCut) { + nstpc[kPi] = track.tpcNSigmaPi(); + if (track.hasTOF() && std::abs(track.tofNSigmaPi()) < cTofNSigmaCut) { + nstof[kPi] = track.tofNSigmaPi(); + } } - return retFlag; - } - - using BCsRun3 = soa::Join; - using CollisionsRun3 = soa::Join; - using Tracks = soa::Join; - - void processSpectatorPlane(CollisionsRun3::iterator const& collision, BCsRun3 const&, aod::Zdcs const&) - { - // Get bunch crossing - auto bc = collision.template foundBC_as(); - cRunNum = collision.template foundBC_as().runNumber(); - - if (lRunNum != cRunNum) { - loadCorrections(); + // Check track for kaon + if (std::abs(track.tpcNSigmaKa()) < cTpcNSigmaCut) { + nstpc[kKa] = track.tpcNSigmaKa(); + if (track.hasTOF() && std::abs(track.tofNSigmaKa()) < cTofNSigmaCut) { + nstof[kKa] = track.tofNSigmaKa(); + } } - // Analyze collision and get Spectator Plane Vector - std::array vSP = {0., 0., 0., 0.}; - bool colSPExtFlag = analyzeCollision(bc, collision, vSP); - - // Update run number - lRunNum = cRunNum; - - // Fill histograms if SP flag is true - if (colSPExtFlag) { - // Evaluate spectator plane angle and [X,Y] correlations - float psiA = std::atan2(vSP[kYa], vSP[kXa]); - float psiC = std::atan2(vSP[kYc], vSP[kXc]); - histos.fill(HIST("Checks/hPsiSPA"), cent, psiA); - histos.fill(HIST("Checks/hPsiSPC"), cent, psiC); - histos.fill(HIST("Checks/hCosPsiSPAC"), cent, std::cos(psiA - psiC)); - histos.fill(HIST("Checks/hSinPsiSPAC"), cent, std::sin(psiA - psiC)); - histos.fill(HIST("Checks/hXaXc"), cent, (vSP[kXa] * vSP[kXc])); - histos.fill(HIST("Checks/hYaYc"), cent, (vSP[kYa] * vSP[kYc])); - histos.fill(HIST("Checks/hXaYc"), cent, (vSP[kXa] * vSP[kYc])); - histos.fill(HIST("Checks/hYaXc"), cent, (vSP[kYa] * vSP[kXc])); - - // Directed flow QXY vector - float qac = (vSP[kXa] * vSP[kXc]) + (vSP[kYa] * vSP[kYc]); - histos.fill(HIST("DF/hQaQc"), cent, qac); + // Check track for proton + if (std::abs(track.tpcNSigmaPr()) < cTpcNSigmaCut) { + nstpc[kPr] = track.tpcNSigmaPr(); + if (track.hasTOF() && std::abs(track.tofNSigmaPr()) < cTofNSigmaCut) { + nstof[kPr] = track.tofNSigmaPr(); + } } - - // Fill table - colSPExtTable(colSPExtFlag, vSP[kXa], vSP[kYa], vSP[kXc], vSP[kYc]); } - PROCESS_SWITCH(SpectatorPlaneTableProducer, processSpectatorPlane, "Spectator Plane Process", true); - - void processIdHadrons(Tracks const& tracks) + // Id track table + template + void analyzeIdHadrons(T const& tracks) { for (auto const& track : tracks) { - bool chargedFlag = selectTrack(track); - bool pionFlag = identifyTrack(track); - bool kaonFlag = identifyTrack(track); - bool protonFlag = identifyTrack(track); - tracksIdTable(chargedFlag, pionFlag, kaonFlag, protonFlag); - } - } - - PROCESS_SWITCH(SpectatorPlaneTableProducer, processIdHadrons, "Hadron Id Process", false); -}; - -struct FlowEventPlane { - // Tracks - Configurable cNEtaBins{"cNEtaBins", 5, "# of eta bins"}; - - // Pi,Ka,Pr - Configurable cMinPtPi{"cMinPtPi", 0.2, "Pion min pT"}; - Configurable cMinPtKa{"cMinPtKa", 0.3, "Kaon min pT"}; - Configurable cMinPtPr{"cMinPtPr", 0.5, "Proton min pT"}; - - // Resonance - Configurable cNRapBins{"cNRapBins", 5, "# of y bins"}; - Configurable cPhiInvMassBins{"cPhiInvMassBins", 500, "# of Phi mass bins"}; - Configurable cKStarInvMassBins{"cKStarInvMassBins", 200, "# of Phi mass bins"}; - Configurable cResRapCut{"cResRapCut", 0.5, "Resonance rapidity cut"}; - - // V0 - // Tracks - Configurable cTrackPtCut{"cTrackPtCut", 0.1, "p_{T} minimum"}; - Configurable cTrackEtaCut{"cTrackEtaCut", 0.8, "Pseudorapidity cut"}; - Configurable cTpcNsigmaCut{"cTpcNsigmaCut", 3.0, "TPC NSigma Selection Cut"}; - - // V0s - Configurable cV0TypeSelection{"cV0TypeSelection", 1, "V0 Type Selection"}; - Configurable cMinDcaProtonToPV{"cMinDcaProtonToPV", 0.01, "Minimum Proton DCAr to PV"}; - Configurable cMinDcaPionToPV{"cMinDcaPionToPV", 0.1, "Minimum Pion DCAr to PV"}; - Configurable cDcaV0Dau{"cDcaV0Dau", 1., "DCA between V0 daughters"}; - Configurable cDcaV0ToPv{"cDcaV0ToPv", 0.1, "DCA V0 to PV"}; - Configurable cMinV0Radius{"cMinV0Radius", 0.5, "Minimum V0 radius from PV"}; - Configurable cK0ShortCTau{"cK0ShortCTau", 20.0, "Decay length cut K0Short"}; - Configurable cLambdaCTau{"cLambdaCTau", 30.0, "Decay length cut Lambda"}; - Configurable cK0ShortCosPA{"cK0ShortCosPA", 0.97, "K0Short CosPA"}; - Configurable cLambdaCosPA{"cLambdaCosPA", 0.98, "Lambda CosPA"}; - Configurable cK0SMassRej{"cK0SMassRej", 0.01, "Reject K0Short Candidates"}; - Configurable cArmPodSel{"cArmPodSel", 0.2, "Armentros-Podolanski Selection for K0S"}; - Configurable cV0RapCut{"cV0RapCut", 0.8, "V0 rap cut"}; - Configurable cK0SMinPt{"cK0SMinPt", 0.4, "K0S Min pT"}; - Configurable cK0SMaxPt{"cK0SMaxPt", 6.0, "K0S Max pT"}; - Configurable cLambdaMinPt{"cLambdaMinPt", 0.6, "Lambda Min pT"}; - Configurable cLambdaMaxPt{"cLambdaMaxPt", 6.0, "Lambda Max pT"}; - - // Histogram registry: an object to hold your histograms - HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - // Global objects - float cent = 0.; - std::array vSP = {0., 0., 0., 0.}; - std::map> mResoDauMass = {{kPhi0, {MassKaonCharged, MassKaonCharged}}, {kKStar, {MassPionCharged, MassKaonCharged}}}; - std::map mResoMass = {{kPhi0, MassPhi}, {kKStar, MassKaonCharged}}; - - void init(InitContext const&) - { - // Define axes - const AxisSpec axisCent{100, 0., 100, "FT0C%"}; - - const AxisSpec axisXYac{600, -6, 6, "Q^{t}Q^{p}"}; - const AxisSpec axisV1{400, -4, 4, "v_{1}"}; - - const AxisSpec axisTrackPt{100, 0., 10., "p_{T} (GeV/#it{c})"}; - const AxisSpec axisTrackEta{cNEtaBins, -0.8, 0.8, "#eta"}; - const AxisSpec axisTrackDcaXY{60, -0.15, 0.15, "DCA_{XY}"}; - const AxisSpec axisTrackDcaZ{230, -1.15, 1.15, "DCA_{XY}"}; - const AxisSpec axisTrackdEdx{360, 20, 200, "#frac{dE}{dx}"}; - const AxisSpec axisTrackNSigma{161, -4.025, 4.025, {"n#sigma"}}; - - const AxisSpec axisPhiInvMass{cPhiInvMassBins, 0.99, 1.12, "M_{KK} (GeV/#it{c}^{2}"}; - const AxisSpec axisKStarInvMass{cKStarInvMassBins, 0.8, 1.2, "M_{#piK} (GeV/#it{c}^{2}"}; - const AxisSpec axisMomPID(80, 0, 4, "p_{T} (GeV/#it{c})"); - const AxisSpec axisNsigma(401, -10.025, 10.025, {"n#sigma"}); - const AxisSpec axisdEdx(360, 20, 200, "#frac{dE}{dx}"); - const AxisSpec axisTrackTofSignal(240, 0, 1.2, "#beta"); - const AxisSpec axisRadius(2000, 0, 200, "r(cm)"); - const AxisSpec axisCosPA(300, 0.97, 1.0, "cos(#theta_{PA})"); - const AxisSpec axisDcaV0PV(1000, 0., 10., "dca (cm)"); - const AxisSpec axisDcaProngPV(5000, -50., 50., "dca (cm)"); - const AxisSpec axisDcaDau(75, 0., 1.5, "Daug DCA (#sigma)"); - const AxisSpec axisCTau(2000, 0, 200, "c#tau (cm)"); - const AxisSpec axisAlpha(40, -1, 1, "#alpha"); - const AxisSpec axisQtarm(40, 0, 0.4, "q_{T}"); - const AxisSpec axisLambdaInvMass(140, 1.08, 1.15, "M_{p#pi} (GeV/#it{c}^{2})"); - const AxisSpec axisK0ShortInvMass(200, 0.4, 0.6, "M_{#pi#pi} (GeV/#it{c}^{2})"); - - // Create histograms - // Charged particles - if (doprocessChargedFlow) { - histos.add("TrackQA/hPtDcaXY", "DCA_{XY} vs p_{T}", kTH2F, {axisTrackPt, axisTrackDcaXY}); - histos.add("TrackQA/hPtDcaZ", "DCA_{Z} vs p_{T}", kTH2F, {axisTrackPt, axisTrackDcaZ}); - histos.add("TrackQA/hTrackTPCdEdX", "hTrackTPCdEdX", kTH2F, {axisMomPID, axisdEdx}); - histos.add("DF/hAQu", "u_{x}X^{A}_{1} + u_{y}Y^{A}_{1}", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("DF/hCQu", "u_{x}X^{C}_{1} + u_{y}Y^{C}_{1}", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("DF/hAQuPos", "u_{x}X^{A}_{1} + u_{y}Y^{A}_{1}", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("DF/hCQuPos", "u_{x}X^{C}_{1} + u_{y}Y^{C}_{1}", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("DF/hAQuNeg", "u_{x}X^{A}_{1} + u_{y}Y^{A}_{1}", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("DF/hCQuNeg", "u_{x}X^{C}_{1} + u_{y}Y^{C}_{1}", kTProfile2D, {axisCent, axisTrackEta}); - } - - // Identified hadrons - if (doprocessIdFlow) { - histos.add("PartId/Pion/hdEdX", "dE/dx vs pT", kTH2F, {axisMomPID, axisTrackdEdx}); - histos.add("PartId/Pion/hTOFSignal", "#beta_{TOF} vs p_{T}", kTH2F, {axisMomPID, axisTrackTofSignal}); - histos.add("PartId/Pion/hTPCNSigma", "n#sigma_{TPC} vs p_{T}", kTH2F, {axisMomPID, axisTrackNSigma}); - histos.add("PartId/Pion/hTOFNSigma", "n#sigma_{TOF} vs p_{T}", kTH2F, {axisMomPID, axisTrackNSigma}); - histos.add("PartId/Pion/hAQuPos", "PartId/Pion/hAQuPos", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("PartId/Pion/hAQuNeg", "PartId/Pion/hAQuNeg", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("PartId/Pion/hCQuPos", "PartId/Pion/hCQuPos", kTProfile2D, {axisCent, axisTrackEta}); - histos.add("PartId/Pion/hCQuNeg", "PartId/Pion/hCQuNeg", kTProfile2D, {axisCent, axisTrackEta}); - histos.addClone("PartId/Pion/", "PartId/Kaon/"); - histos.addClone("PartId/Pion/", "PartId/Proton/"); - } - - // Resonance - if (doprocessResoFlow) { - histos.add("Reso/Phi/hSigCentEtaInvMass", "hUSCentEtaInvMass", kTH3F, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/Phi/hBkgCentEtaInvMass", "hLSCentEtaInvMass", kTH3F, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/Phi/Sig/hQuA", "hPhiQuA", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/Phi/Sig/hQuC", "hPhiQuC", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/Phi/Bkg/hQuA", "hPhiQuA", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/Phi/Bkg/hQuC", "hPhiQuC", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/KStar/hSigCentEtaInvMass", "hUSCentEtaInvMass", kTH3F, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/hBkgCentEtaInvMass", "hLSCentEtaInvMass", kTH3F, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Sig/hQuA", "hKStarQuA", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Sig/hQuC", "hKStarQuC", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Bkg/hQuA", "hKStarQuA", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Bkg/hQuC", "hKStarQuC", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - } - - // Lambda - if (doprocessV0Flow) { - histos.add("V0/Lambda/QA/hQtVsAlpha", "Armentros-Podolanski Plot", kTH2F, {axisAlpha, axisQtarm}); - histos.add("V0/Lambda/QA/hDcaV0Dau", "DCA between V0 daughters", kTH1F, {axisDcaDau}); - histos.add("V0/Lambda/QA/hDcaPosToPv", "DCA positive prong to PV", kTH1F, {axisDcaProngPV}); - histos.add("V0/Lambda/QA/hDcaNegToPv", "DCA negative prong to PV", kTH1F, {axisDcaProngPV}); - histos.add("V0/Lambda/QA/hDcaV0ToPv", "DCA V0 to PV", kTH1F, {axisDcaV0PV}); - histos.add("V0/Lambda/QA/hCosPa", "cos(#theta_{PA})", kTH1F, {axisCosPA}); - histos.add("V0/Lambda/QA/hRxy", "V_{0} Decay Radius in XY plane", kTH1F, {axisRadius}); - histos.add("V0/Lambda/QA/hCTau", "V_{0} c#tau", kTH1F, {axisCTau}); - histos.add("V0/Lambda/QA/hPosdEdXVsP", "TPC Signal Pos-Prong", kTH2F, {axisMomPID, axisdEdx}); - histos.add("V0/Lambda/QA/hNegdEdXVsP", "TPC Signal Neg-Prong", kTH2F, {axisMomPID, axisdEdx}); - histos.add("V0/Lambda/QA/hPosNsigPrVsP", "TPC n#sigma Pos Prong", kTH2F, {axisMomPID, axisNsigma}); - histos.add("V0/Lambda/QA/hNegNsigPrVsP", "TPC n#sigma Neg Prong", kTH2F, {axisMomPID, axisNsigma}); - histos.add("V0/Lambda/QA/hPosNsigPiVsP", "TPC n#sigma Pos Prong", kTH2F, {axisMomPID, axisNsigma}); - histos.add("V0/Lambda/QA/hNegNsigPiVsP", "TPC n#sigma Neg Prong", kTH2F, {axisMomPID, axisNsigma}); - histos.addClone("V0/Lambda/", "V0/K0Short/"); - histos.add("V0/Lambda/hMassVsRap", "hMassVsRap", kTH3F, {axisCent, axisLambdaInvMass, axisTrackEta}); - histos.add("V0/Lambda/Flow/hQuA", "hQuA", kTProfile3D, {axisCent, axisTrackEta, axisLambdaInvMass}); - histos.add("V0/Lambda/Flow/hQuC", "hQuC", kTProfile3D, {axisCent, axisTrackEta, axisLambdaInvMass}); - histos.addClone("V0/Lambda/", "V0/AntiLambda/"); - histos.addClone("V0/Lambda/", "V0/LambdaAntiLambda/"); - histos.add("V0/K0Short/hMassVsRap", "hMassVsRap", kTH3F, {axisCent, axisK0ShortInvMass, axisTrackEta}); - histos.add("V0/K0Short/Flow/hQuA", "hQuA", kTProfile3D, {axisCent, axisTrackEta, axisK0ShortInvMass}); - histos.add("V0/K0Short/Flow/hQuC", "hQuC", kTProfile3D, {axisCent, axisTrackEta, axisK0ShortInvMass}); - } - } - - template - bool selCollision(C const& collision, std::array& v) - { - // Check collision - if (!collision.selColFlag()) { - return false; - } - - // Set centrality - cent = collision.centFT0C(); - - // Flow vectors - v[kXa] = collision.xa(); - v[kYa] = collision.ya(); - v[kXc] = collision.xc(); - v[kYc] = collision.yc(); + // Global track selection + if (!selectTrack(track)) { + continue; + } - return true; - } + // Dca + std::array dca = {track.dcaXY(), track.dcaZ()}; - template - void getIdFlow(T const& tracks) - { - float ux = 0., uy = 0., v1a = 0., v1c = 0.; - float tpcNsigma = 0., tofNsigma = 0.; - for (auto const& track : tracks) { - static constexpr std::string_view SubDir[] = {"Pion/", "Kaon/", "Proton/"}; - if (part == kPi && track.pt() > cMinPtPi) { - tpcNsigma = track.tpcNSigmaPi(); - tofNsigma = track.tofNSigmaPi(); - } else if (part == kKa && track.pt() > cMinPtKa) { - tpcNsigma = track.tpcNSigmaKa(); - tofNsigma = track.tofNSigmaKa(); - } else if (part == kPr && track.pt() > cMinPtPr) { - tpcNsigma = track.tpcNSigmaPr(); - tofNsigma = track.tofNSigmaPr(); - } else { - return; - } - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hdEdX"), track.pt(), track.tpcSignal()); - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hTPCNSigma"), track.pt(), tpcNsigma); + // QA plots + histos.fill(HIST("QA/hDcaXY"), track.pt(), track.dcaXY()); + histos.fill(HIST("QA/hDcaZ"), track.pt(), track.dcaZ()); + histos.fill(HIST("QA/hdEdX"), track.pt(), track.tpcSignal()); if (track.hasTOF()) { - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hTOFSignal"), track.pt(), track.beta()); - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hTOFNSigma"), track.pt(), tofNsigma); + histos.fill(HIST("QA/hTOFSignal"), track.pt(), track.beta()); } - // Directed flow - ux = std::cos(track.phi()); - uy = std::sin(track.phi()); - v1a = ux * vSP[kXa] + uy * vSP[kYa]; - v1c = ux * vSP[kXc] + uy * vSP[kYc]; + // Identify track + std::array tpc = {track.tpcSignal(), -99., -99., -99.}; + std::array tof = {track.beta(), -99., -99., -99.}; + identifyTrack(track, tpc, tof); - if (track.sign() > 0) { - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hAQuPos"), cent, track.eta(), v1a); - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hCQuPos"), cent, track.eta(), v1c); - } else { - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hAQuNeg"), cent, track.eta(), v1a); - histos.fill(HIST("PartId/") + HIST(SubDir[part]) + HIST("hCQuNeg"), cent, track.eta(), v1c); - } + // Fill track table + tracksIdTable(colIdx, track.px(), track.py(), track.pz(), track.sign(), tpc.data(), tof.data(), dca.data()); } } + // V0 daughter track selection template - bool selV0DauTracks(V const& v0, T const& postrack, T const& negtrack) + bool selV0DauTracks(V const& v0, T const& postrack, T const& negtrack, float& tpcNSigmaPosDau, float& tpcNSigmaNegDau) { // Kinematic selection - if (postrack.pt() <= cTrackPtCut || negtrack.pt() <= cTrackPtCut || std::abs(postrack.eta()) >= cTrackEtaCut || std::abs(negtrack.eta()) >= cTrackEtaCut) { + if (postrack.pt() <= cTrackMinPt || negtrack.pt() <= cTrackMinPt || std::abs(postrack.eta()) >= cTrackEtaCut || std::abs(negtrack.eta()) >= cTrackEtaCut) { return false; } @@ -1002,274 +371,181 @@ struct FlowEventPlane { return false; } - // Daughter track PID [Dau1 = PosTrack, Dau2 = NegTrack] - float tpcNSigmaDau1 = 0., tpcNSigmaDau2 = 0.; - + // Daughter track PID switch (part) { - // Dau1 = Proton, Dau2 = Pion - case kLambda: - tpcNSigmaDau1 = postrack.tpcNSigmaPr(); - tpcNSigmaDau2 = negtrack.tpcNSigmaPi(); + // PosDau = Pion, NegDau = Pion + case kK0S: + tpcNSigmaPosDau = postrack.tpcNSigmaPi(); + tpcNSigmaNegDau = negtrack.tpcNSigmaPi(); break; - // Dau1 = Pion, Dau2 = Proton - case kAntiLambda: - tpcNSigmaDau1 = postrack.tpcNSigmaPi(); - tpcNSigmaDau2 = negtrack.tpcNSigmaPr(); + // PosDau = Proton, NegDau = Pion + case kLambda: + tpcNSigmaPosDau = postrack.tpcNSigmaPr(); + tpcNSigmaNegDau = negtrack.tpcNSigmaPi(); break; - // Dau1 = Pion, Dau2 = Pion - case kK0S: - tpcNSigmaDau1 = postrack.tpcNSigmaPi(); - tpcNSigmaDau2 = negtrack.tpcNSigmaPi(); + // PosDau = Pion, NegDau = Proton + case kAntiLambda: + tpcNSigmaPosDau = postrack.tpcNSigmaPi(); + tpcNSigmaNegDau = negtrack.tpcNSigmaPr(); break; } - if (std::abs(tpcNSigmaDau1) >= cTpcNsigmaCut || std::abs(tpcNSigmaDau2) >= cTpcNsigmaCut) { + if (std::abs(tpcNSigmaPosDau) >= cTpcNSigmaCut || std::abs(tpcNSigmaNegDau) >= cTpcNSigmaCut) { return false; } + // All checks passed return true; } - template - void fillV0QAHist(C const& col, V const& v0, T const&) + // V0 table + template + void fillV0Table(V const& v0, T const&) { - static constexpr std::string_view SubDir[] = {"V0/K0Short/QA/", "V0/Lambda/QA/", "V0/AntiLambda/QA/"}; - - // daugthers + // V0 parameters + float mass = 0., ctau = 0., tpcNSigmaPosDau = 0., tpcNSigmaNegDau = 0.; auto postrack = v0.template posTrack_as(); auto negtrack = v0.template negTrack_as(); - // ctau - float mPDG = 0, ctau = 0; - if (part == kK0S) { - mPDG = MassKaonNeutral; - } else { - mPDG = MassLambda0; - } - ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * mPDG; - - histos.fill(HIST(SubDir[part]) + HIST("hQtVsAlpha"), v0.alpha(), v0.qtarm()); - histos.fill(HIST(SubDir[part]) + HIST("hDcaV0Dau"), v0.dcaV0daughters()); - histos.fill(HIST(SubDir[part]) + HIST("hDcaPosToPv"), v0.dcapostopv()); - histos.fill(HIST(SubDir[part]) + HIST("hDcaNegToPv"), v0.dcanegtopv()); - histos.fill(HIST(SubDir[part]) + HIST("hDcaV0ToPv"), v0.dcav0topv()); - histos.fill(HIST(SubDir[part]) + HIST("hCosPa"), v0.v0cosPA()); - histos.fill(HIST(SubDir[part]) + HIST("hRxy"), v0.v0radius()); - histos.fill(HIST(SubDir[part]) + HIST("hCTau"), ctau); - histos.fill(HIST(SubDir[part]) + HIST("hPosdEdXVsP"), postrack.tpcInnerParam(), postrack.tpcSignal()); - histos.fill(HIST(SubDir[part]) + HIST("hNegdEdXVsP"), negtrack.tpcInnerParam(), negtrack.tpcSignal()); - histos.fill(HIST(SubDir[part]) + HIST("hPosNsigPrVsP"), postrack.tpcInnerParam(), postrack.tpcNSigmaPr()); - histos.fill(HIST(SubDir[part]) + HIST("hNegNsigPrVsP"), negtrack.tpcInnerParam(), negtrack.tpcNSigmaPr()); - histos.fill(HIST(SubDir[part]) + HIST("hPosNsigPiVsP"), postrack.tpcInnerParam(), postrack.tpcNSigmaPi()); - histos.fill(HIST(SubDir[part]) + HIST("hNegNsigPiVsP"), negtrack.tpcInnerParam(), negtrack.tpcNSigmaPi()); - } - - template - void getResoFlow(T const& tracks1, T const& tracks2, std::array const& vSP) - { - float ux = 0., uy = 0., v1a = 0., v1c = 0.; - std::array vMassDau = mResoDauMass.at(rt); - for (auto const& [track1, track2] : soa::combinations(soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - // Discard same track - if (track1.index() == track2.index()) { - continue; + if (v0type == kK0S) { + if (!selV0DauTracks(v0, postrack, negtrack, tpcNSigmaPosDau, tpcNSigmaNegDau)) { + return; } - - // Discard same charge track - if (track1.sign() == track2.sign()) { - continue; + mass = v0.mK0Short(); + ctau = v0.distovertotmom(posX, posY, posZ) * MassKaonNeutral; + } else if (v0type == kLambda) { + if (!selV0DauTracks(v0, postrack, negtrack, tpcNSigmaPosDau, tpcNSigmaNegDau)) { + return; } - - // Apply pseudo-rapidity acceptance - std::array v = {track1.px() + track2.px(), track1.py() + track2.py(), track1.pz() + track2.pz()}; - if (std::abs(RecoDecay::eta(v)) >= cResRapCut) { - continue; + mass = v0.mLambda(); + ctau = v0.distovertotmom(posX, posY, posZ) * MassLambda0; + } else if (v0type == kAntiLambda) { + if (!selV0DauTracks(v0, postrack, negtrack, tpcNSigmaPosDau, tpcNSigmaNegDau)) { + return; } + mass = v0.mAntiLambda(); + ctau = v0.distovertotmom(posX, posY, posZ) * MassLambda0; + } else { + return; + } - // Reconstruct resonance - float p = RecoDecay::p((track1.px() + track2.px()), (track1.py() + track2.py()), (track1.pz() + track2.pz())); - float e = RecoDecay::e(track1.px(), track1.py(), track1.pz(), vMassDau[0]) + RecoDecay::e(track2.px(), track2.py(), track2.pz(), vMassDau[1]); - float m = std::sqrt(RecoDecay::m2(p, e)); - - // Get directed flow - ux = std::cos(RecoDecay::phi(v)); - uy = std::sin(RecoDecay::phi(v)); - v1a = ux * vSP[kXa] + uy * vSP[kYa]; - v1c = ux * vSP[kXc] + uy * vSP[kYc]; - - // Histograms - static constexpr std::string_view SubDir[] = {"Reso/Phi/", "Reso/KStar/"}; - - // Fill signal histogram - histos.fill(HIST(SubDir[rt]) + HIST("hSigCentEtaInvMass"), cent, RecoDecay::eta(v), m); - histos.fill(HIST(SubDir[rt]) + HIST("Sig/hQuA"), cent, RecoDecay::eta(v), m, v1a); - histos.fill(HIST(SubDir[rt]) + HIST("Sig/hQuC"), cent, RecoDecay::eta(v), m, v1c); - - // Get background - p = RecoDecay::p((track1.px() - track2.px()), (track1.py() - track2.py()), (track1.pz() - track2.pz())); - m = std::sqrt(RecoDecay::m2(p, e)); - v[0] = track1.px() - track2.px(); - v[1] = track1.py() - track2.py(); - v[2] = track1.pz() - track2.pz(); - ux = std::cos(RecoDecay::phi(v)); - uy = std::sin(RecoDecay::phi(v)); - v1a = ux * vSP[kXa] + uy * vSP[kYa]; - v1c = ux * vSP[kXc] + uy * vSP[kYc]; - - // Fill bkg histogram - histos.fill(HIST(SubDir[rt]) + HIST("hBkgCentEtaInvMass"), cent, RecoDecay::eta(v), m); - histos.fill(HIST(SubDir[rt]) + HIST("Bkg/hQuA"), cent, RecoDecay::eta(v), m, v1a); - histos.fill(HIST(SubDir[rt]) + HIST("Bkg/hQuC"), cent, RecoDecay::eta(v), m, v1c); + // Apply V0 selection + if (ctau > cV0CTau || v0.v0cosPA() < cV0CosPA) { + return; } - } - using CollisionsRun3 = soa::Join; - using Tracks = soa::Join; - using TracksV0s = soa::Join; + // Dca daughters + std::array dcaDau = {v0.dcapostopv(), v0.dcanegtopv()}; - // Partitions - SliceCache cache; - Partition chargedTrackPartition = (aod::tracksid::isCharged == true); - Partition pionTrackPartition = (aod::tracksid::isCharged == true) && (aod::tracksid::isPion == true); - Partition kaonTrackPartition = (aod::tracksid::isCharged == true) && (aod::tracksid::isKaon == true); - Partition protonTrackPartition = (aod::tracksid::isCharged == true) && (aod::tracksid::isProton == true); + // Tpc daughters + std::array tpcDau = {tpcNSigmaPosDau, tpcNSigmaNegDau}; - void processDummy(CollisionsRun3::iterator const&) {} + // Fill QA Plots + if (v0type == kK0S) { + histos.fill(HIST("QA/h2f_armpod_K0s"), v0.alpha(), v0.qtarm()); + } else if (v0type == kLambda) { + histos.fill(HIST("QA/h2f_armpod_Lambda"), v0.alpha(), v0.qtarm()); + } else if (v0type == kAntiLambda) { + histos.fill(HIST("QA/h2f_armpod_AntiLambda"), v0.alpha(), v0.qtarm()); + } - PROCESS_SWITCH(FlowEventPlane, processDummy, "Dummy process", true); + // Fill V0 table + v0sTable(colIdx, v0.px(), v0.py(), v0.pz(), v0.v0cosPA(), ctau, mass, (uint8_t)v0type, dcaDau.data(), tpcDau.data()); + } - void processChargedFlow(CollisionsRun3::iterator const& collision, Tracks const&) + // V0s + template + void analyzeV0s(V const& V0s, T const& tracks) { - // Check collision - if (!selCollision(collision, vSP)) { - return; - } - // Loop over tracks - auto chargedTracks = chargedTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - float ux = 0., uy = 0., v1a = 0., v1c = 0.; - for (auto const& track : chargedTracks) { - // Fill track QA - histos.fill(HIST("TrackQA/hPtDcaZ"), track.pt(), track.dcaZ()); - histos.fill(HIST("TrackQA/hPtDcaXY"), track.pt(), track.dcaXY()); - histos.fill(HIST("TrackQA/hTrackTPCdEdX"), track.pt(), track.tpcSignal()); - - // Get directed flow - ux = std::cos(track.phi()); - uy = std::sin(track.phi()); - v1a = ux * vSP[kXa] + uy * vSP[kYa]; - v1c = ux * vSP[kXc] + uy * vSP[kYc]; - - // Charged particle directed flow - histos.fill(HIST("DF/hAQu"), cent, track.eta(), v1a); - histos.fill(HIST("DF/hCQu"), cent, track.eta(), v1c); - if (track.sign() > 0) { - histos.fill(HIST("DF/hAQuPos"), cent, track.eta(), v1a); - histos.fill(HIST("DF/hCQuPos"), cent, track.eta(), v1c); + for (auto const& v0 : V0s) { + // Topological and kinematic selections + if (std::abs(v0.eta()) >= cV0EtaCut || v0.dcaV0daughters() >= cDcaV0Dau || v0.v0radius() <= cMinV0Radius || v0.v0Type() != cV0TypeSelection) { + continue; + } + + // Armenteros-Podolanski Selections + histos.fill(HIST("QA/h2f_armpod_before_sel"), v0.alpha(), v0.qtarm()); + + // K0s, Lambda, Anti-Lambda + if (v0.qtarm() >= cArmPodSel * std::abs(v0.alpha())) { // K0s + fillV0Table(v0, tracks); + } else if ((v0.qtarm() < cArmPodSel * std::abs(v0.alpha())) && (v0.alpha() > 0)) { // Lambda + fillV0Table(v0, tracks); + } else if ((v0.qtarm() < cArmPodSel * std::abs(v0.alpha())) && (v0.alpha() < 0)) { // Anti-Lambda + fillV0Table(v0, tracks); } else { - histos.fill(HIST("DF/hAQuNeg"), cent, track.eta(), v1a); - histos.fill(HIST("DF/hCQuNeg"), cent, track.eta(), v1c); + return; } } } - PROCESS_SWITCH(FlowEventPlane, processChargedFlow, "Charged particle flow process", false); - - void processIdFlow(CollisionsRun3::iterator const& collision, Tracks const&) + template + void analyzeCollision(B const& bc, C const& collision, T const& tracks, V const& V0s) { - if (!selCollision(collision, vSP)) { + // Event selection + if (!selCollision(collision)) { return; } - // Loop over tracks - auto pionTracks = pionTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto kaonTracks = kaonTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto protonTracks = protonTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - getIdFlow(pionTracks); - getIdFlow(kaonTracks); - getIdFlow(protonTracks); - } - - PROCESS_SWITCH(FlowEventPlane, processIdFlow, "Identified particle flow process", false); + posX = collision.posX(); + posY = collision.posY(); + posZ = collision.posZ(); - void processResoFlow(CollisionsRun3::iterator const& collision, Tracks const&) - { - if (!selCollision(collision, vSP)) { + // check zdc + if (!bc.has_zdc()) { return; } - // Track partitions - auto pionTracks = pionTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto kaonTracks = kaonTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - - // Resonance flow - getResoFlow(kaonTracks, kaonTracks, vSP); - getResoFlow(pionTracks, kaonTracks, vSP); - } - PROCESS_SWITCH(FlowEventPlane, processResoFlow, "Resonance flow process", false); + auto zdc = bc.zdc(); + auto znaEnergy = zdc.energySectorZNA(); + auto zncEnergy = zdc.energySectorZNC(); + auto znaEnergyCommon = zdc.energyCommonZNA(); + auto zncEnergyCommon = zdc.energyCommonZNC(); - void processV0Flow(CollisionsRun3::iterator const& collision, aod::V0Datas const& V0s, TracksV0s const& tracks) - { - if (!selCollision(collision, vSP)) { + // check energy deposits + if (znaEnergyCommon <= 0 || zncEnergyCommon <= 0 || znaEnergy[0] <= 0 || znaEnergy[1] <= 0 || znaEnergy[2] <= 0 || znaEnergy[3] <= 0 || zncEnergy[0] <= 0 || zncEnergy[1] <= 0 || zncEnergy[2] <= 0 || zncEnergy[3] <= 0) { return; } - // Loop over v0s - for (auto const& v0 : V0s) { - // Topological and kinematic selections - if (std::abs(v0.eta()) >= cV0RapCut || v0.dcaV0daughters() >= cDcaV0Dau || v0.dcav0topv() >= cDcaV0ToPv || v0.v0radius() <= cMinV0Radius || v0.v0Type() != cV0TypeSelection) { - continue; - } + // Fill collision table + histos.fill(HIST("hCent"), cent); + colSpTable(runNum, timestamp, cent, posX, posY, posZ, znaEnergyCommon, zncEnergyCommon, znaEnergy.data(), zncEnergy.data()); + colIdx = colSpTable.lastIndex(); - // Directed flow - float ux = std::cos(v0.phi()); - float uy = std::sin(v0.phi()); - float v1a = ux * vSP[kXa] + uy * vSP[kYa]; - float v1c = ux * vSP[kXc] + uy * vSP[kYc]; - - // Initialize selection objects - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); - float ctauK0Short = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassKaonNeutral; - float ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda0; - - // K0Short - if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > cK0ShortCosPA && ctauK0Short < cK0ShortCTau && v0.qtarm() >= cArmPodSel * std::abs(v0.alpha()) && v0.pt() >= cK0SMinPt && v0.pt() < cK0SMaxPt) { - fillV0QAHist(collision, v0, tracks); - histos.fill(HIST("V0/K0Short/hMassVsRap"), cent, v0.mK0Short(), v0.eta()); - histos.fill(HIST("V0/K0Short/Flow/hQuA"), cent, v0.eta(), v0.mK0Short(), v1a); - histos.fill(HIST("V0/K0Short/Flow/hQuC"), cent, v0.eta(), v0.mK0Short(), v1c); - } + // Analyze Tracks [charged, pi, K, p] + analyzeIdHadrons(tracks); - // Lambda - if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > cLambdaCosPA && ctauLambda < cLambdaCTau && std::abs(v0.mK0Short() - MassK0Short) >= cK0SMassRej && v0.pt() >= cLambdaMinPt && v0.pt() < cLambdaMaxPt) { - fillV0QAHist(collision, v0, tracks); - histos.fill(HIST("V0/Lambda/hMassVsRap"), cent, v0.mLambda(), v0.eta()); - histos.fill(HIST("V0/Lambda/Flow/hQuA"), cent, v0.eta(), v0.mLambda(), v1a); - histos.fill(HIST("V0/Lambda/Flow/hQuC"), cent, v0.eta(), v0.mLambda(), v1c); - histos.fill(HIST("V0/LambdaAntiLambda/hMassVsRap"), cent, v0.mLambda(), v0.eta()); - histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuA"), cent, v0.eta(), v0.mLambda(), v1a); - histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuC"), cent, v0.eta(), v0.mLambda(), v1c); - } + // Analyze V0s [Lambda, K0S] + analyzeV0s(V0s, tracks); - // AntiLambda - if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > cLambdaCosPA && ctauLambda < cLambdaCTau && std::abs(v0.mK0Short() - MassK0Short) >= cK0SMassRej && v0.pt() >= cLambdaMinPt && v0.pt() < cLambdaMaxPt) { - fillV0QAHist(collision, v0, tracks); - histos.fill(HIST("V0/AntiLambda/hMassVsRap"), cent, v0.mAntiLambda(), v0.eta()); - histos.fill(HIST("V0/AntiLambda/Flow/hQuA"), cent, v0.eta(), v0.mAntiLambda(), v1a); - histos.fill(HIST("V0/AntiLambda/Flow/hQuC"), cent, v0.eta(), v0.mAntiLambda(), v1c); - histos.fill(HIST("V0/LambdaAntiLambda/hMassVsRap"), cent, v0.mAntiLambda(), v0.eta()); - histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuA"), cent, v0.eta(), v0.mAntiLambda(), v1a); - histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuC"), cent, v0.eta(), v0.mAntiLambda(), v1c); - } - } + // Done + return; } - PROCESS_SWITCH(FlowEventPlane, processV0Flow, "Lambda flow process", false); + + using BCsRun3 = soa::Join; + using CollisionsRun3 = soa::Join; + using Tracks = soa::Join; + + void processDummy(CollisionsRun3::iterator const&) {} + + PROCESS_SWITCH(FlowEventPlane, processDummy, "Dummy process", true); + + void processFEP(CollisionsRun3::iterator const& collision, BCsRun3 const&, aod::Zdcs const&, + Tracks const& tracks, aod::V0Datas const& v0s) + { + // Get bunch crossing + auto bc = collision.template foundBC_as(); + runNum = collision.template foundBC_as().runNumber(); + timestamp = collision.template foundBC_as().timestamp(); + analyzeCollision(bc, collision, tracks, v0s); + } + + PROCESS_SWITCH(FlowEventPlane, processFEP, "Flow Event Plane Table Producer", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; }