diff --git a/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h index 538675f3a9d..8a455f073eb 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h @@ -223,6 +223,10 @@ class FemtoDreamCollisionSelection mHistogramQn->add("Event/centVsqnVsSpher", "; cent; qn; Sphericity", kTH3F, {{10, 0, 100}, {100, 0, 1000}, {100, 0, 1}}); mHistogramQn->add("Event/qnBin", "; qnBin; entries", kTH1F, {{20, 0, 20}}); mHistogramQn->add("Event/psiEP", "; #Psi_{EP} (deg); entries", kTH1F, {{100, 0, 180}}); + mHistogramQn->add("Event/epReso_FT0CTPC", "; cent; qnBin; reso_ft0c_tpc", kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/epReso_FT0ATPC", "; cent; qnBin; reso_ft0a_tpc", kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/epReso_FT0CFT0A", "; cent; qnBin; reso_ft0c_ft0a", kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/epReso_count", "; cent; qnBin; count", kTH2F, {{10, 0, 100}, {10, 0, 10}}); return; } @@ -330,9 +334,17 @@ class FemtoDreamCollisionSelection /// \param col Collision /// \return value of the qn-vector of FT0C of the event template - float computeqnVec(T const& col) + float computeqnVec(T const& col, int qvecMod = 0) { - double qn = std::sqrt(col.qvecFT0CReVec()[0] * col.qvecFT0CReVec()[0] + col.qvecFT0CImVec()[0] * col.qvecFT0CImVec()[0]) * std::sqrt(col.sumAmplFT0C()); + double qn = -999.f; + if (qvecMod == 0) { + qn = std::sqrt(col.qvecFT0CReVec()[0] * col.qvecFT0CReVec()[0] + col.qvecFT0CImVec()[0] * col.qvecFT0CImVec()[0]) * std::sqrt(col.sumAmplFT0C()); + } else if (qvecMod == 1) { + qn = std::sqrt(col.qvecFT0AReVec()[0] * col.qvecFT0AReVec()[0] + col.qvecFT0AImVec()[0] * col.qvecFT0AImVec()[0]) * std::sqrt(col.sumAmplFT0A()); + } else { + LOGP(error, "no selected detector of Qvec for ESE "); + return qn; + } return qn; } @@ -342,15 +354,43 @@ class FemtoDreamCollisionSelection /// \param nmode EP in which harmonic(default 2nd harmonic) /// \return angle of the event plane (rad) of FT0C of the event template - float computeEP(T const& col, int nmode) + float computeEP(T const& col, int nmode, int qvecMod) { - double EP = ((1. / nmode) * (TMath::ATan2(col.qvecFT0CImVec()[0], col.qvecFT0CReVec()[0]))); - if (EP < 0) + double EP = -999.f; + if (qvecMod == 0) { + EP = ((1. / nmode) * (TMath::ATan2(col.qvecFT0CImVec()[0], col.qvecFT0CReVec()[0]))); + } else if (qvecMod == 1) { + EP = ((1. / nmode) * (TMath::ATan2(col.qvecFT0AImVec()[0], col.qvecFT0AReVec()[0]))); + } else if (qvecMod == 2) { + EP = ((1. / nmode) * (TMath::ATan2(col.qvecTPCallImVec()[0], col.qvecTPCallReVec()[0]))); + } else { + LOGP(error, "no selected detector of Qvec for EP"); + return EP; + } + + if (EP < 0) { EP += TMath::Pi(); - // atan2 return in rad -pi/2-pi/2, then make it 0-pi + } // atan2 return in rad -pi/2-pi/2, then make it 0-pi return EP; } + /// Compute the event plane resolution of 3 sub-events + /// \tparam T type of the collision + /// \param col Collision + /// \param nmode EP in which harmonic(default 2nd harmonic) + template + void fillEPReso(T const& col, int nmode, float centrality) + { + const float psi_ft0c = ((1. / nmode) * (TMath::ATan2(col.qvecFT0CImVec()[0], col.qvecFT0CReVec()[0]))); + const float psi_ft0a = ((1. / nmode) * (TMath::ATan2(col.qvecFT0AImVec()[0], col.qvecFT0AReVec()[0]))); + const float psi_tpc = ((1. / nmode) * (TMath::ATan2(col.qvecTPCallImVec()[0], col.qvecTPCallReVec()[0]))); + + mHistogramQn->fill(HIST("Event/epReso_FT0CTPC"), centrality, mQnBin + 0.f, std::cos((psi_ft0c - psi_tpc) * nmode)); + mHistogramQn->fill(HIST("Event/epReso_FT0ATPC"), centrality, mQnBin + 0.f, std::cos((psi_ft0a - psi_tpc) * nmode)); + mHistogramQn->fill(HIST("Event/epReso_FT0CFT0A"), centrality, mQnBin + 0.f, std::cos((psi_ft0c - psi_ft0a) * nmode)); + mHistogramQn->fill(HIST("Event/epReso_count"), centrality, mQnBin + 0.f); + } + /// \return the 1-d qn-vector separator to 2-d std::vector> getQnBinSeparator2D(std::vector flat, const int numQnBins = 10) { @@ -413,13 +453,15 @@ class FemtoDreamCollisionSelection } /// \fill event-wise informations - void fillEPQA(float centrality, float fSpher, float qn, float psiEP) + template + void fillEPQA(T& col, float centrality, float fSpher, float qn, float psiEP, int nmode = 2) { mHistogramQn->fill(HIST("Event/centFT0CBeforeQn"), centrality); mHistogramQn->fill(HIST("Event/centVsqn"), centrality, qn); mHistogramQn->fill(HIST("Event/centVsqnVsSpher"), centrality, qn, fSpher); mHistogramQn->fill(HIST("Event/qnBin"), mQnBin + 0.f); mHistogramQn->fill(HIST("Event/psiEP"), psiEP); + fillEPReso(col, nmode, centrality); } /// \todo to be implemented! diff --git a/PWGCF/FemtoDream/Core/femtoDreamContainer.h b/PWGCF/FemtoDream/Core/femtoDreamContainer.h index a12b36fd8a2..4c3a5b24be0 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamContainer.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainer.h @@ -223,10 +223,26 @@ class FemtoDreamContainer mHistogramRegistry->add((folderName + "/relPair3dRmTMultPercentileQnPairphi").c_str(), ("; " + femtoDKout + femtoDKside + femtoDKlong + "; #it{m}_{T} (GeV/#it{c}); Centrality; qn; #varphi_{pair} - #Psi_{EP}").c_str(), kTHnSparseF, {femtoDKoutAxis, femtoDKsideAxis, femtoDKlongAxis, mTAxi4D, multPercentileAxis4D, qnAxis, pairPhiAxis}); } + template + void init_3Dqn_MC(std::string folderName, std::string femtoDKout, std::string femtoDKside, std::string femtoDKlong, + T& femtoDKoutAxis, T& femtoDKsideAxis, T& femtoDKlongAxis, bool smearingByOrigin = false) + { + mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); + if (smearingByOrigin) { + const int nOriginBins = o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes; + mHistogramRegistry->add((folderName + "/relPair3dresolution").c_str(), (";" + femtoDKout + "mctruth;" + femtoDKout + "_reco;" + femtoDKside + "mctruth;" + femtoDKside + "_reco;" + femtoDKlong + "mctruth;" + femtoDKlong + "_reco;" + "MC origin particle 1; MC origin particle 2;").c_str(), + kTHnSparseF, {femtoDKoutAxis, femtoDKoutAxis, femtoDKsideAxis, femtoDKsideAxis, femtoDKlongAxis, femtoDKlongAxis, {nOriginBins, 0, nOriginBins}, {nOriginBins, 0, nOriginBins}}); + } else { + mHistogramRegistry->add((folderName + "/relPair3dresolution").c_str(), (";" + femtoDKout + "mctruth;" + femtoDKside + "mctruth;" + femtoDKlong + "mctruth;" + femtoDKout + "_reco;" + femtoDKside + "_reco;" + femtoDKlong + "_reco;").c_str(), + kTHnSparseF, {femtoDKoutAxis, femtoDKoutAxis, femtoDKsideAxis, femtoDKsideAxis, femtoDKlongAxis, femtoDKlongAxis}); + } + } + template void init_3Dqn(HistogramRegistry* registry, T& DKoutBins, T& DKsideBins, T& DKlongBins, T& mTBins4D, T& multPercentileBins4D, - bool isMC, ConfigurableAxis qnBins = {"qnBins", {10, 0, 10}, "qn binning"}, ConfigurableAxis pairPhiBins = {"phiBins", {10, 0 - 0.05, TMath::Pi() + 0.05}, "pair phi binning"}) + bool isMC, ConfigurableAxis qnBins = {"qnBins", {10, 0, 10}, "qn binning"}, ConfigurableAxis pairPhiBins = {"phiBins", {10, 0 - 0.05, TMath::Pi() + 0.05}, "pair phi binning"}, bool smearingByOrigin = false) { mHistogramRegistry = registry; @@ -251,6 +267,8 @@ class FemtoDreamContainer folderName = static_cast(mFolderSuffix[mEventType]) + static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]) + static_cast("_3Dqn"); init_base_3Dqn(folderName, femtoObsDKout, femtoObsDKside, femtoObsDKlong, DKoutAxis, DKsideAxis, DKlongAxis, mTAxis4D, multPercentileAxis4D, qnAxis, pairPhiAxis); + init_3Dqn_MC(folderName, femtoObsDKout, femtoObsDKside, femtoObsDKlong, + DKoutAxis, DKsideAxis, DKlongAxis, smearingByOrigin); } } @@ -484,11 +502,26 @@ class FemtoDreamContainer mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("_3Dqn") + HIST("/relPair3dRmTMultPercentileQnPairphi"), femtoDKout, femtoDKside, femtoDKlong, mT, multPercentile, myQnBin, pairPhiEP); } + /// Called by setPair_3Dqn only in case of Monte Carlo truth + /// Fills resolution of DKout, DKside, DKlong + void setPair_3Dqn_MC(std::vector k3dMC, std::vector k3d, const int originPart1, const int originPart2, bool smearingByOrigin) + { + if (smearingByOrigin) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]) + HIST("_3Dqn") + HIST("/relPair3dresolution"), k3dMC[1], k3d[1], k3dMC[2], k3d[2], k3dMC[3], k3d[3], originPart1, originPart2); + } else { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]) + HIST("_3Dqn") + HIST("/relPair3dresolution"), k3dMC[1], k3d[1], k3dMC[2], k3d[2], k3dMC[3], k3d[3]); + } + } + template - void setPair_3Dqn(T1 const& part1, T2 const& part2, const float multPercentile, bool IsSameSpecies, const float myQnBin, const float eventPlane) + void setPair_3Dqn(T1 const& part1, T2 const& part2, const float multPercentile, bool IsSameSpecies, const float myQnBin, const float eventPlane, bool smearingByOrigin = false) { std::vector k3d = FemtoDreamMath::newpairfunc(part1, mMassOne, part2, mMassTwo, IsSameSpecies); + if (k3d.size() < 4) { + LOG(error) << "newpairfunc returned size=" << k3d.size(); + return; + } float DKout = k3d[1]; float DKside = k3d[2]; float DKlong = k3d[3]; @@ -503,12 +536,17 @@ class FemtoDreamContainer if constexpr (isMC) { if (part1.has_fdMCParticle() && part2.has_fdMCParticle()) { - std::vector k3dMC = FemtoDreamMath::newpairfunc(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo, IsSameSpecies); + std::vector k3dMC = FemtoDreamMath::newpairfuncMC(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo, IsSameSpecies); + if (k3dMC.size() < 4) { + LOG(error) << "newpairfunc returned size=" << k3d.size(); + return; + } const float mTMC = FemtoDreamMath::getmT(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo); const float pairPhiEPMC = FemtoDreamMath::getPairPhiEP(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo, eventPlane); if (std::abs(part1.fdMCParticle().pdgMCTruth()) == mPDGOne && std::abs(part2.fdMCParticle().pdgMCTruth()) == mPDGTwo) { // Note: all pair-histogramms are filled with MC truth information ONLY in case of non-fake candidates setPair_3Dqn_base(k3dMC[1], k3dMC[2], k3dMC[3], mTMC, multPercentile, myQnBin, pairPhiEPMC); + setPair_3Dqn_MC(k3dMC, k3d, part1.fdMCParticle().partOriginMCTruth(), part2.fdMCParticle().partOriginMCTruth(), smearingByOrigin); } else { mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]) + HIST("/hFakePairsCounter"), 0); } @@ -521,10 +559,14 @@ class FemtoDreamContainer } template - void setPair_3Dqn(T1 const& part1, T2 const& part2, const float multPercentile, bool IsSameSpecies, const float myQnBin, const float EP1, const float EP2) + void setPair_3Dqn(T1 const& part1, T2 const& part2, const float multPercentile, bool IsSameSpecies, const float myQnBin, const float EP1, const float EP2, bool smearingByOrigin = false) { std::vector k3d = FemtoDreamMath::newpairfunc(part1, mMassOne, part2, mMassTwo, IsSameSpecies); + if (k3d.size() < 4) { + LOG(error) << "newpairfunc returned size=" << k3d.size(); + return; + } float DKout = k3d[1]; float DKside = k3d[2]; float DKlong = k3d[3]; @@ -539,12 +581,17 @@ class FemtoDreamContainer if constexpr (isMC) { if (part1.has_fdMCParticle() && part2.has_fdMCParticle()) { - std::vector k3dMC = FemtoDreamMath::newpairfunc(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo, IsSameSpecies); + std::vector k3dMC = FemtoDreamMath::newpairfuncMC(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo, IsSameSpecies); + if (k3dMC.size() < 4) { + LOG(error) << "newpairfunc returned size=" << k3d.size(); + return; + } const float mTMC = FemtoDreamMath::getmT(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo); const float pairPhiEPMC = FemtoDreamMath::getPairPhiEP(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo, EP1, EP2); if (std::abs(part1.fdMCParticle().pdgMCTruth()) == mPDGOne && std::abs(part2.fdMCParticle().pdgMCTruth()) == mPDGTwo) { // Note: all pair-histogramms are filled with MC truth information ONLY in case of non-fake candidates setPair_3Dqn_base(k3dMC[1], k3dMC[2], k3dMC[3], mTMC, multPercentile, myQnBin, pairPhiEPMC); + setPair_3Dqn_MC(k3dMC, k3d, part1.fdMCParticle().partOriginMCTruth(), part2.fdMCParticle().partOriginMCTruth(), smearingByOrigin); } else { mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]) + HIST("/hFakePairsCounter"), 0); } diff --git a/PWGCF/FemtoDream/Core/femtoDreamMath.h b/PWGCF/FemtoDream/Core/femtoDreamMath.h index 867f519ba79..cbb8257f590 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamMath.h +++ b/PWGCF/FemtoDream/Core/femtoDreamMath.h @@ -249,6 +249,98 @@ class FemtoDreamMath return vect; } + /// Compute the 3d components of the pair momentum in LCMS and PRF + /// Copy from femto universe + /// \tparam T type of tracks + /// \param part1 Particle 1 + /// \param mass1 Mass of particle 1 + /// \param part2 Particle 2 + /// \param mass2 Mass of particle 2 + /// \param isiden Identical or non-identical particle pair + template + static std::vector newpairfuncMC(const T& part1, const float mass1, const T& part2, const float mass2, bool isiden) + { + const double trkPx1 = part1.pt() * std::cos(part1.phi()); + const double trkPy1 = part1.pt() * std::sin(part1.phi()); + const double trkPz1 = part1.pt() * std::sinh(part1.eta()); + + const double trkPx2 = part2.pt() * std::cos(part2.phi()); + const double trkPy2 = part2.pt() * std::sin(part2.phi()); + const double trkPz2 = part2.pt() * std::sinh(part2.eta()); + + const double e1 = std::sqrt(std::pow(trkPx1, 2) + std::pow(trkPy1, 2) + std::pow(trkPz1, 2) + std::pow(mass1, 2)); + const double e2 = std::sqrt(std::pow(trkPx2, 2) + std::pow(trkPy2, 2) + std::pow(trkPz2, 2) + std::pow(mass2, 2)); + + const ROOT::Math::PxPyPzEVector vecpart1(trkPx1, trkPy1, trkPz1, e1); + const ROOT::Math::PxPyPzEVector vecpart2(trkPx2, trkPy2, trkPz2, e2); + const ROOT::Math::PxPyPzEVector trackSum = vecpart1 + vecpart2; + + std::vector vect; + + const double tPx = trackSum.px(); + const double tPy = trackSum.py(); + const double tPz = trackSum.pz(); + const double tE = trackSum.E(); + + const double tPtSq = (tPx * tPx + tPy * tPy); + const double tMtSq = (tE * tE - tPz * tPz); + const double tM = std::sqrt(tMtSq - tPtSq); + const double tMt = std::sqrt(tMtSq); + const double tPt = std::sqrt(tPtSq); + + // Boost to LCMS + + const double beta_LCMS = tPz / tE; + const double gamma_LCMS = tE / tMt; + + const double fDKOut = (trkPx1 * tPx + trkPy1 * tPy) / tPt; + const double fDKSide = (-trkPx1 * tPy + trkPy1 * tPx) / tPt; + const double fDKLong = gamma_LCMS * (trkPz1 - beta_LCMS * e1); + const double fDE = gamma_LCMS * (e1 - beta_LCMS * trkPz1); + + const double px1LCMS = fDKOut; + const double py1LCMS = fDKSide; + const double pz1LCMS = fDKLong; + const double pE1LCMS = fDE; + + const double px2LCMS = (trkPx2 * tPx + trkPy2 * tPy) / tPt; + const double py2LCMS = (trkPy2 * tPx - trkPx2 * tPy) / tPt; + const double pz2LCMS = gamma_LCMS * (trkPz2 - beta_LCMS * e2); + const double pE2LCMS = gamma_LCMS * (e2 - beta_LCMS * trkPz2); + + const double fDKOutLCMS = px1LCMS - px2LCMS; + const double fDKSideLCMS = py1LCMS - py2LCMS; + const double fDKLongLCMS = pz1LCMS - pz2LCMS; + + // Boost to PRF + + const double betaOut = tPt / tMt; + const double gammaOut = tMt / tM; + + const double fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * (pE1LCMS - pE2LCMS)); + const double fDKSidePRF = fDKSideLCMS; + const double fDKLongPRF = fDKLongLCMS; + const double fKOut = gammaOut * (fDKOut - betaOut * fDE); + + const double qlcms = std::sqrt(fDKOutLCMS * fDKOutLCMS + fDKSideLCMS * fDKSideLCMS + fDKLongLCMS * fDKLongLCMS); + const double qinv = std::sqrt(fDKOutPRF * fDKOutPRF + fDKSidePRF * fDKSidePRF + fDKLongPRF * fDKLongPRF); + const double kstar = std::sqrt(fKOut * fKOut + fDKSide * fDKSide + fDKLong * fDKLong); + + if (isiden) { + vect.push_back(qinv); + vect.push_back(fDKOutLCMS); + vect.push_back(fDKSideLCMS); + vect.push_back(fDKLongLCMS); + vect.push_back(qlcms); + } else { + vect.push_back(kstar); + vect.push_back(fDKOut); + vect.push_back(fDKSide); + vect.push_back(fDKLong); + } + return vect; + } + /// Compute the phi angular of a pair with respect to the event plane /// \tparam T type of tracks /// \param part1 Particle 1 diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index b8c1f48be09..15686d79e9b 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -61,10 +61,11 @@ namespace o2::aod using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollision_noCent = soa::Join::iterator; using FemtoFullCollision_CentPbPb = soa::Join::iterator; -using FemtoFullCollision_CentPbPb_qvec = soa::Join::iterator; +using FemtoFullCollision_CentPbPb_qvec = soa::Join::iterator; using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullCollision_noCent_MC = soa::Join::iterator; using FemtoFullCollisionMC_CentPbPb = soa::Join::iterator; +using FemtoFullCollisionMC_CentPbPb_qvec = soa::Join::iterator; using FemtoFullMCgenCollisions = soa::Join; using FemtoFullMCgenCollision = FemtoFullMCgenCollisions::iterator; @@ -281,6 +282,9 @@ struct femtoDreamProducerTask { Configurable ConfCentralityMax{"ConfCentralityMax", 100.f, "Evt sel: Maximum Centrality cut"}; Configurable ConfCentBinWidth{"ConfCentBinWidth", 1.f, "Centrality bin length for qn separator"}; Configurable ConfNumQnBins{"ConfNumQnBins", 10, "Number of qn bins"}; + Configurable ConfMCQvec{"ConfMCQvec", false, "Enable Q vector table for Monte Carlo"}; + Configurable ConfQvecDetector{"ConfQvecDetector", 0, "Q-vec detector selection; 0 : FT0C; 1 : FT0A"}; + Configurable ConfEPDetector{"ConfEPDetector", 0, "Event-plane detector selection; 0 : FT0C; 1 : FT0A; 2 : TPC"}; } epCal; struct : o2::framework::ConfigurableGroup { @@ -307,10 +311,10 @@ struct femtoDreamProducerTask { void init(InitContext&) { - if (doprocessData == false && doprocessData_noCentrality == false && doprocessData_CentPbPb == false && doprocessData_CentPbPb_EP == false && doprocessMC == false && doprocessMC_noCentrality == false && doprocessMC_CentPbPb == false) { + if (doprocessData == false && doprocessData_noCentrality == false && doprocessData_CentPbPb == false && doprocessData_CentPbPb_EP == false && doprocessMC == false && doprocessMC_noCentrality == false && doprocessMC_CentPbPb == false && doprocessMC_CentPbPb_EP == false) { LOGF(fatal, "Neither processData nor processMC enabled. Please choose one."); } - if ((doprocessData == true && doprocessMC == true) || (doprocessData == true && doprocessMC_noCentrality == true) || (doprocessMC == true && doprocessMC_noCentrality == true) || (doprocessData_noCentrality == true && doprocessData == true) || (doprocessData_noCentrality == true && doprocessMC == true) || (doprocessData_noCentrality == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessData == true) || (doprocessData_CentPbPb == true && doprocessData_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessMC == true) || (doprocessData_CentPbPb == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessMC_CentPbPb == true) || (doprocessData_CentPbPb_EP == true && doprocessData == true) || (doprocessData_CentPbPb_EP == true && doprocessData_noCentrality == true) || (doprocessData_CentPbPb_EP == true && doprocessMC == true) || (doprocessData_CentPbPb_EP == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb_EP == true && doprocessMC_CentPbPb == true) || (doprocessData_CentPbPb_EP == true && doprocessData_CentPbPb == true)) { + if ((doprocessData == true && doprocessMC == true) || (doprocessData == true && doprocessMC_noCentrality == true) || (doprocessMC == true && doprocessMC_noCentrality == true) || (doprocessData_noCentrality == true && doprocessData == true) || (doprocessData_noCentrality == true && doprocessMC == true) || (doprocessData_noCentrality == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessData == true) || (doprocessData_CentPbPb == true && doprocessData_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessMC == true) || (doprocessData_CentPbPb == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb == true && doprocessMC_CentPbPb == true) || (doprocessData_CentPbPb_EP == true && doprocessData == true) || (doprocessData_CentPbPb_EP == true && doprocessData_noCentrality == true) || (doprocessData_CentPbPb_EP == true && doprocessMC == true) || (doprocessData_CentPbPb_EP == true && doprocessMC_noCentrality == true) || (doprocessData_CentPbPb_EP == true && doprocessMC_CentPbPb == true) || (doprocessData_CentPbPb_EP == true && doprocessData_CentPbPb == true) || (doprocessData_CentPbPb_EP == true && doprocessMC_CentPbPb_EP == true) || (doprocessMC_CentPbPb_EP == true && doprocessData == true) || (doprocessMC_CentPbPb_EP == true && doprocessData_noCentrality == true) || (doprocessMC_CentPbPb_EP == true && doprocessMC == true) || (doprocessMC_CentPbPb_EP == true && doprocessMC_noCentrality == true) || (doprocessMC_CentPbPb_EP == true && doprocessMC_CentPbPb == true) || (doprocessMC_CentPbPb_EP == true && doprocessData_CentPbPb == true)) { LOGF(fatal, "Cannot enable more than one process switch at the same time. " "Please choose one."); @@ -771,7 +775,7 @@ struct femtoDreamProducerTask { } if constexpr (doFlow) { - fillCollisionsFlow(col, tracks, mult, spher, epCal.ConfHarmonicOrder); + fillCollisionsFlow(col, tracks, mult, spher, epCal.ConfHarmonicOrder); } std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children @@ -1126,12 +1130,16 @@ struct femtoDreamProducerTask { } } - template + template void fillCollisionsFlow(CollisionType const& col, TrackType const& tracks, float mult, float spher, int EPHarmonic) { - float myqn = colCuts.computeqnVec(col); - float myEP = TMath::RadToDeg() * colCuts.computeEP(col, EPHarmonic); - // psi from rad(0-pi) to deg, in table psi would be in deg,from 0-180 + float myqn = 0.f; + float myEP = 0.f; + + if (!isMC || epCal.ConfMCQvec) { + myqn = colCuts.computeqnVec(col, epCal.ConfQvecDetector); + myEP = TMath::RadToDeg() * colCuts.computeEP(col, EPHarmonic, epCal.ConfEPDetector); // psi from rad(0-pi) to deg, in table psi would be in deg,from 0-180 + } if ((myqn >= 0 && myqn < 1e6) || (myEP >= 0 && myEP < 180)) { outputExtQnCollision(myqn, col.trackOccupancyInTimeRange()); @@ -1139,12 +1147,11 @@ struct femtoDreamProducerTask { } // Calculate flow via cumulant - - if (epCal.ConfQnSeparation) { + if (epCal.ConfQnSeparation && (!isMC || epCal.ConfMCQvec)) { colCuts.myqnBin(mult, epCal.ConfCentralityMax, epCal.ConfFillFlowQA, epCal.ConfQnBinSeparator, myqn, epCal.ConfNumQnBins, epCal.ConfCentBinWidth); } - if (epCal.ConfFillFlowQA) { - colCuts.fillEPQA(mult, spher, myqn, myEP); + if (epCal.ConfFillFlowQA && (!isMC || epCal.ConfMCQvec)) { + colCuts.fillEPQA(col, mult, spher, myqn, myEP, EPHarmonic); if (epCal.ConfDoCumlant) { colCuts.doCumulants(col, tracks, trackCuts, mult, epCal.ConfQnSeparation); } @@ -1277,6 +1284,21 @@ struct femtoDreamProducerTask { fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } PROCESS_SWITCH(femtoDreamProducerTask, processMC_CentPbPb, "Provide MC data with centrality information for PbPb collisions", false); + + void processMC_CentPbPb_EP(aod::FemtoFullCollisionMC_CentPbPb_qvec const& col, + aod::BCsWithTimestamps const&, + soa::Join const& tracks, + aod::FemtoFullMCgenCollisions const&, + aod::McParticles const&, + soa::Join const& fullV0s, /// \todo with FilteredFullV0s + soa::Join const& fullCascades) + { + // get magnetic field for run + initCCDB_Mag_Trig(col.bc_as()); + // fill the tables + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); + } + PROCESS_SWITCH(femtoDreamProducerTask, processMC_CentPbPb_EP, "Provide MC data with centrality and q-vector table for PbPb collisions", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx index f2100431efd..0d97ae5b676 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx @@ -95,6 +95,7 @@ struct femtoDreamPairTaskTrackTrack { Configurable storeEvtTrkInfo{"storeEvtTrkInfo", false, "Fill info of track1 and track2 while pariing in divided qn bins"}; Configurable doQnSeparation{"doQnSeparation", false, "Do qn separation"}; Configurable doEPReClibForMixing{"doEPReClibForMixing", false, "While mixing, using respective event plane for participating particles azimuthal angle caulculation"}; + Configurable mcQvec{"mcQvec", false, "Enable Q vector table for Monte Carlo"}; Configurable> qnBinSeparator{"qnBinSeparator", std::vector{-999.f, -999.f, -999.f}, "Qn bin separator"}; Configurable numQnBins{"numQnBins", 10, "Number of qn bins"}; Configurable qnBinMin{"qnBinMin", 0, "Number of qn bins"}; @@ -113,6 +114,8 @@ struct femtoDreamPairTaskTrackTrack { using FilteredMCCollision = FilteredMCCollisions::iterator; using FilteredQnCollisions = soa::Filtered>; using FilteredQnCollision = FilteredQnCollisions::iterator; + using FilteredMCQnCollisions = soa::Filtered>; + using FilteredMCQnCollision = FilteredMCQnCollisions::iterator; using FilteredMaskedCollisions = soa::Filtered>; using FilteredMaskedCollision = FilteredMaskedCollisions::iterator; @@ -322,9 +325,9 @@ struct femtoDreamPairTaskTrackTrack { if (EPCal.do3DFemto) { sameEventQnCont.init_3Dqn(&Registry, EPCal.DKout, EPCal.DKside, EPCal.DKlong, - Binning4D.mT, Binning4D.multPercentile, Option.IsMC, EPCal.qnBins, EPCal.pairPhiBins); + Binning4D.mT, Binning4D.multPercentile, Option.IsMC, EPCal.qnBins, EPCal.pairPhiBins, Option.SmearingByOrigin); mixedEventQnCont.init_3Dqn(&Registry, EPCal.DKout, EPCal.DKside, EPCal.DKlong, - Binning4D.mT, Binning4D.multPercentile, Option.IsMC, EPCal.qnBins, EPCal.pairPhiBins); + Binning4D.mT, Binning4D.multPercentile, Option.IsMC, EPCal.qnBins, EPCal.pairPhiBins, Option.SmearingByOrigin); sameEventQnCont.setPDGCodes(Track1.PDGCode, Track2.PDGCode); mixedEventQnCont.setPDGCodes(Track1.PDGCode, Track2.PDGCode); if (EPCal.fillFlowQA) { @@ -377,7 +380,10 @@ struct femtoDreamPairTaskTrackTrack { (doprocessMixedEvent && doprocessMixedEventEP) || (doprocessMixedEventMasked && doprocessMixedEventEP) || (doprocessSameEventMC && doprocessSameEventMCMasked) || - (doprocessMixedEventMC && doprocessMixedEventMCMasked)) { + (doprocessSameEventMC && doprocessSameEventEPMC) || + (doprocessMixedEventMC && doprocessMixedEventMCMasked) || + (doprocessMixedEventMC && doprocessMixedEventEPMC) || + (doprocessMixedEventMCMasked && doprocessMixedEventEPMC)) { LOG(fatal) << "Normal and masked processing cannot be activated simultaneously!"; } }; @@ -704,17 +710,20 @@ struct femtoDreamPairTaskTrackTrack { } } - auto myEP = TMath::DegToRad() * col.eventPlane(); + float myEP = -999.f; int myqnBin = -999; - if (EPCal.doQnSeparation || EPCal.do3DFemto) { - myqnBin = epCalculator.myqnBin(col.multV0M(), EPCal.centMax, EPCal.fillFlowQA, EPCal.qnBinSeparator, col.qnVal(), EPCal.numQnBins, EPCal.centBinWidth); - if (myqnBin < EPCal.qnBinMin || myqnBin > EPCal.numQnBins) { - myqnBin = -999; - } - } - if (EPCal.fillFlowQA) { - epCalculator.fillEPQA(col.multV0M(), col.sphericity(), col.qnVal(), col.eventPlane()); + if (!isMC || EPCal.mcQvec) { + myEP = TMath::DegToRad() * col.eventPlane(); + if (EPCal.doQnSeparation || EPCal.do3DFemto) { + myqnBin = epCalculator.myqnBin(col.multV0M(), EPCal.centMax, EPCal.fillFlowQA, EPCal.qnBinSeparator, col.qnVal(), EPCal.numQnBins, EPCal.centBinWidth); + if (myqnBin < EPCal.qnBinMin || myqnBin > EPCal.numQnBins) { + myqnBin = -999; + } + } + } else { + myEP = 0.f; + myqnBin = 0; } /// Now build the combinations @@ -738,14 +747,14 @@ struct femtoDreamPairTaskTrackTrack { sameEventQnCont.setPair_EP(p1, p2, col.multV0M(), EPCal.doQnSeparation, EPCal.doQnSeparation ? myqnBin + 0.f : myEP); } if (EPCal.do3DFemto) { - sameEventQnCont.setPair_3Dqn(p1, p2, col.multV0M(), Option.SameSpecies.value, myqnBin + 0.f, myEP); + sameEventQnCont.setPair_3Dqn(p1, p2, col.multV0M(), Option.SameSpecies.value, myqnBin + 0.f, myEP, Option.SmearingByOrigin); } } else { if (EPCal.do1DFemto) { sameEventQnCont.setPair_EP(p2, p1, col.multV0M(), EPCal.doQnSeparation, EPCal.doQnSeparation ? myqnBin + 0.f : myEP); } if (EPCal.do3DFemto) { - sameEventQnCont.setPair_3Dqn(p2, p1, col.multV0M(), Option.SameSpecies.value, myqnBin + 0.f, myEP); + sameEventQnCont.setPair_3Dqn(p2, p1, col.multV0M(), Option.SameSpecies.value, myqnBin + 0.f, myEP, Option.SmearingByOrigin); } } } @@ -764,7 +773,7 @@ struct femtoDreamPairTaskTrackTrack { sameEventQnCont.setPair_EP(p1, p2, col.multV0M(), EPCal.doQnSeparation, EPCal.doQnSeparation ? myqnBin + 0.f : myEP); } if (EPCal.do3DFemto) { - sameEventQnCont.setPair_3Dqn(p1, p2, col.multV0M(), Option.SameSpecies.value, myEP, myqnBin); + sameEventQnCont.setPair_3Dqn(p1, p2, col.multV0M(), Option.SameSpecies.value, myEP, myqnBin, Option.SmearingByOrigin); } } } @@ -789,6 +798,28 @@ struct femtoDreamPairTaskTrackTrack { } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventEP, "Enable processing same event wrt azimuthal angle and event-plane ", false); + /// process function for to call doSameEventEP with MC Data + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoDreamParticleTable + void processSameEventEPMC(FilteredMCQnCollision& col, + o2::aod::FDMCCollisions&, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + if (EPCal.storeEvtTrkInfo) { + fillCollision(col); + } + auto SliceTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceTrk1.size() == 0 && SliceTrk2.size() == 0) { + return; + } + if (EPCal.do1DFemto || EPCal.do3DFemto) { + doSameEventEP(SliceTrk1, SliceTrk2, parts, col); + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventEPMC, "Enable processing same event of 3D for Monte Carlo", false); + template void doMixedEvent_NotMaskedEP(CollisionType& cols, PartType& parts, PartitionType& part1, PartitionType& part2, BinningType policy) { @@ -799,8 +830,16 @@ struct femtoDreamPairTaskTrackTrack { continue; } - auto myEP_event1 = TMath::DegToRad() * collision1.eventPlane(); - auto myEP_event2 = TMath::DegToRad() * collision2.eventPlane(); + auto myEP_event1 = -999.f; + auto myEP_event2 = -999.f; + + if (!isMC || EPCal.mcQvec) { + myEP_event1 = TMath::DegToRad() * collision1.eventPlane(); + myEP_event2 = TMath::DegToRad() * collision2.eventPlane(); + } else { + myEP_event1 = 0.f; + myEP_event2 = 0.f; + } for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { if (Option.CPROn.value) { @@ -816,13 +855,13 @@ struct femtoDreamPairTaskTrackTrack { mixedEventQnCont.setPair_EP(p1, p2, collision1.multV0M(), EPCal.doQnSeparation, myEP_event1, myEP_event2); } if (EPCal.do3DFemto) { - mixedEventQnCont.setPair_3Dqn(p1, p2, collision1.multV0M(), Option.SameSpecies.value, 0.f, myEP_event1, myEP_event2); + mixedEventQnCont.setPair_3Dqn(p1, p2, collision1.multV0M(), Option.SameSpecies.value, 0.f, myEP_event1, myEP_event2, Option.SmearingByOrigin); } } else { if (EPCal.do1DFemto) mixedEventQnCont.setPair_EP(p1, p2, collision1.multV0M(), EPCal.doQnSeparation, EPCal.doQnSeparation ? 0.f : myEP_event1); if (EPCal.do3DFemto) { - mixedEventQnCont.setPair_3Dqn(p1, p2, collision1.multV0M(), Option.SameSpecies.value, 0.f, myEP_event1); + mixedEventQnCont.setPair_3Dqn(p1, p2, collision1.multV0M(), Option.SameSpecies.value, 0.f, myEP_event1, Option.SmearingByOrigin); } } } @@ -855,6 +894,33 @@ struct femtoDreamPairTaskTrackTrack { } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventEP, "Enable processing mixed events wrt azimuthal angle and event-plane", false); + + /// process function for to call doMixedEvent with Data + /// @param cols subscribe to the collisions table (Data) + /// @param parts subscribe to the femtoDreamParticleTable + void processMixedEventEPMC(FilteredMCQnCollisions& cols, o2::aod::FDMCCollisions&, soa::Join& parts, o2::aod::FDMCParticles&) + { + switch (Mixing.Policy.value) { + case femtodreamcollision::kMult: + doMixedEvent_NotMaskedEP(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_NotMaskedEP(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_NotMaskedEP(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultMultPercentile); + break; + case femtodreamcollision::kMultPercentileQn: + doMixedEvent_NotMaskedEP(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultPercentileqn); + break; + case femtodreamcollision::kMultPercentileEP: + doMixedEvent_NotMaskedEP(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultPercentileEP); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventEPMC, "Enable processing mixed events wrt azimuthal angle and event-plane for Monte Carlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) {