From 90ad8e7b917dcbdda4952bfb506d7478f83ab8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Fri, 13 Dec 2024 13:18:04 +0100 Subject: [PATCH 01/30] [Infrastructure] Bump MegaLinter to v8.3.0 (#8976) --- .github/workflows/mega-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 28bb7877865..90f11945ac0 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -38,7 +38,7 @@ jobs: id: ml # You can override MegaLinter flavor used to have faster performances # More info at https://megalinter.io/flavors/ - uses: oxsecurity/megalinter@v8.1.0 + uses: oxsecurity/megalinter@v8.3.0 env: # All available variables are described in documentation: # https://megalinter.io/configuration/ From 717995c123bc900031c05cb45a3d0fcd796932d1 Mon Sep 17 00:00:00 2001 From: Marvin Hemmer <53471402+mhemmer-cern@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:54:50 +0100 Subject: [PATCH 02/30] [PWGEM] [PWGEM-36] Cut on edge clusters for neutral meson flow (#8977) Co-authored-by: ALICE Action Bot --- PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx | 37 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx index e99f1dba904..e059ab8a74f 100644 --- a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx @@ -559,7 +559,7 @@ struct TaskPi0FlowEMC { auto [xQVec, yQVec] = getQvec(collision, qvecDetector); float cent = getCentrality(collision); int iCellIDPhoton1 = 0; - int iCellIDPhoton = 0; + int iCellIDPhoton2 = 0; ROOT::Math::AxisAngle rotationAxis(meson.Vect(), cfgRotAngle.value); ROOT::Math::Rotation3D rotationMatrix(rotationAxis); @@ -575,15 +575,15 @@ struct TaskPi0FlowEMC { iCellIDPhoton1 = -1; } try { - iCellIDPhoton = emcalGeom->GetAbsCellIdFromEtaPhi(photon2.Eta(), photon2.Phi()); - if (isTooCloseToEdge(iCellIDPhoton, cfgDistanceToEdge.value)) { - iCellIDPhoton = -1; + iCellIDPhoton2 = emcalGeom->GetAbsCellIdFromEtaPhi(photon2.Eta(), photon2.Phi()); + if (isTooCloseToEdge(iCellIDPhoton2, cfgDistanceToEdge.value)) { + iCellIDPhoton2 = -1; } } catch (o2::emcal::InvalidPositionException& e) { - iCellIDPhoton = -1; + iCellIDPhoton2 = -1; } - if (iCellIDPhoton1 == -1 && iCellIDPhoton == -1) { + if (iCellIDPhoton1 == -1 && iCellIDPhoton2 == -1) { return; } for (const auto& photon : photons_coll) { @@ -618,7 +618,7 @@ struct TaskPi0FlowEMC { } } } - if (iCellIDPhoton > 0) { + if (iCellIDPhoton2 > 0) { ROOT::Math::PtEtaPhiMVector mother2 = photon2 + photon3; float openingAngle2 = std::acos(photon2.Vect().Dot(photon3.Vect()) / (photon2.P() * photon3.P())); float cosNPhi2 = std::cos(harmonic * mother2.Phi()); @@ -738,6 +738,29 @@ struct TaskPi0FlowEMC { if (!(fEMCCut.IsSelected(g1)) || !(fEMCCut.IsSelected(g2))) { continue; } + + // Cut edge clusters away, similar to rotation method to ensure same acceptance is used + if (cfgDistanceToEdge.value) { + int iCellIDPhoton1 = -1; + int iCellIDPhoton2 = -1; + try { + iCellIDPhoton1 = emcalGeom->GetAbsCellIdFromEtaPhi(g1.eta(), g1.phi()); + if (isTooCloseToEdge(iCellIDPhoton1, cfgDistanceToEdge.value)) { + continue; + } + } catch (o2::emcal::InvalidPositionException& e) { + continue; + } + try { + iCellIDPhoton2 = emcalGeom->GetAbsCellIdFromEtaPhi(g2.eta(), g2.phi()); + if (isTooCloseToEdge(iCellIDPhoton2, cfgDistanceToEdge.value)) { + continue; + } + } catch (o2::emcal::InvalidPositionException& e) { + continue; + } + } + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2; From 600bd246cfaa8bc520a7e763d382063e3529c2f0 Mon Sep 17 00:00:00 2001 From: Sigurd Nese <32108009+sigurdnese@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:06:26 +0100 Subject: [PATCH 03/30] [PWGDQ] Add open charm MC analyses (#8894) Co-authored-by: ALICE Builder --- PWGDQ/Core/CutsLibrary.cxx | 36 + PWGDQ/Core/HistogramsLibrary.cxx | 2 + PWGDQ/Core/MCSignalLibrary.cxx | 120 +++ PWGDQ/Core/VarManager.cxx | 2 + PWGDQ/Core/VarManager.h | 35 +- PWGDQ/Tasks/dqEfficiency_withAssoc.cxx | 1106 +++++++++++++++++++++++- PWGDQ/Tasks/tableReader_withAssoc.cxx | 13 +- 7 files changed, 1267 insertions(+), 47 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 20ae5000bc8..2f6ad8a958e 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -3172,6 +3172,27 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("pairCosPointingPos")) { + cut->AddCut(GetAnalysisCut("pairCosPointingPos")); + return cut; + } + + if (!nameStr.compare("pairCosPointingNeg90")) { + cut->AddCut(GetAnalysisCut("pairCosPointingNeg90")); + return cut; + } + + if (!nameStr.compare("pairCosPointingNeg85")) { + cut->AddCut(GetAnalysisCut("pairCosPointingNeg85")); + return cut; + } + + if (!nameStr.compare("pairTauxyzProjectedCosPointing1")) { + cut->AddCut(GetAnalysisCut("pairCosPointingNeg")); + cut->AddCut(GetAnalysisCut("pairTauxyzProjected1")); + return cut; + } + // ------------------------------------------------------------------------------------------------- // // Below are a list of single electron single muon and in order or optimize the trigger @@ -5962,6 +5983,21 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("pairCosPointingPos")) { + cut->AddCut(VarManager::kCosPointingAngle, 0.9, 1000.); + return cut; + } + + if (!nameStr.compare("pairCosPointingNeg90")) { + cut->AddCut(VarManager::kCosPointingAngle, -1000., -0.9); + return cut; + } + + if (!nameStr.compare("pairCosPointingNeg85")) { + cut->AddCut(VarManager::kCosPointingAngle, -1000., -0.85); + return cut; + } + // ------------------------------------------------------------------------------------------------- // // Below are a list of single electron single muon and pair selection in order or optimize the trigger diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index c55f34bf1c9..c8eac97666b 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -941,6 +941,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "LxyProj_Pt", "", false, 10, 0.0, 20.0, VarManager::kPt, 1000, -1.0, 1.0, VarManager::kVertexingLxyProjected); hm->AddHistogram(histClass, "LxyProj_Mass_Pt", "", false, 50, 2.0, 4.0, VarManager::kMass, 10, 0.0, 20.0, VarManager::kPt, 1000, -1.0, 1.0, VarManager::kVertexingLxyProjected); hm->AddHistogram(histClass, "LzProj_Mass_Pt", "", false, 50, 2.0, 4.0, VarManager::kMass, 10, 0.0, 20.0, VarManager::kPt, 1000, -1.0, 1.0, VarManager::kVertexingLzProjected); + hm->AddHistogram(histClass, "CosPointingAngle", "", false, 200, -1.0, 1.0, VarManager::kCosPointingAngle); } if (subGroupStr.Contains("kalman-filter")) { @@ -1378,6 +1379,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MassD0region_Rapidity", "", false, 140, 1.5, 2.2, VarManager::kMass, 10, -0.8, 0.8, VarManager::kRap); hm->AddHistogram(histClass, "MassD0region_eta", "", false, 140, 1.5, 2.2, VarManager::kMass, 40, -2., 2., VarManager::kEta); hm->AddHistogram(histClass, "MassD0region_TauxyzProj", "", false, 140, 1.5, 2.2, VarManager::kMass, 200, -0.03, 0.03, VarManager::kVertexingTauxyzProjected); + hm->AddHistogram(histClass, "MassD0region_CosPointing", "", false, 140, 1.5, 2.2, VarManager::kMass, 200, -1.0, 1.0, VarManager::kCosPointingAngle); hm->AddHistogram(histClass, "MassD0region_VtxNContribReal", "", false, 140, 1.5, 2.2, VarManager::kMass, 50, 0, 50, VarManager::kVtxNcontribReal); hm->AddHistogram(histClass, "MassD0region_Rapidity_AveragePt", "", true, 140, 1.5, 2.2, VarManager::kMass, 10, -0.8, 0.8, VarManager::kRap, 150, 0.0, 30.0, VarManager::kPt); } diff --git a/PWGDQ/Core/MCSignalLibrary.cxx b/PWGDQ/Core/MCSignalLibrary.cxx index 22f445252f9..6cef5603b9a 100644 --- a/PWGDQ/Core/MCSignalLibrary.cxx +++ b/PWGDQ/Core/MCSignalLibrary.cxx @@ -1185,6 +1185,126 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } + //------------------------------------------------------------------------------------ + + if (!nameStr.compare("D0")) { + MCProng prong(1, {Pdg::kD0}, {true}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D0", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("KPiFromD0")) { + MCProng prongKaon(2, {321, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + MCProng prongPion(2, {211, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon and pion pair from D0", {prongKaon, prongPion}, {1, 1}); + return signal; + } + if (!nameStr.compare("Dcharged")) { + MCProng prong(1, {Pdg::kDPlus}, {true}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D+/-", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("Dplus")) { + MCProng prong(1, {Pdg::kDPlus}, {false}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D+", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("Dminus")) { + MCProng prong(1, {-Pdg::kDPlus}, {false}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D+", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("KPiPiFromDcharged")) { + MCProng prongKaon(2, {321, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + MCProng prongPion(2, {211, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon pion pion triplet from D+/-", {prongKaon, prongPion, prongPion}, {1, 1, 1}); + return signal; + } + if (!nameStr.compare("KPiPiFromDplus")) { + MCProng prongKaon(2, {-321, Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); + MCProng prongPion(2, {211, Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon pion pion triplet from D+", {prongKaon, prongPion, prongPion}, {1, 1, 1}); + return signal; + } + if (!nameStr.compare("KPiPiFromDminus")) { + MCProng prongKaon(2, {321, -Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); + MCProng prongPion(2, {-211, -Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon pion pion triplet from D-", {prongKaon, prongPion, prongPion}, {1, 1, 1}); + return signal; + } + if (!nameStr.compare("Dstar")) { + MCProng prong(1, {Pdg::kDStar}, {true}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D*", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("DstarPlus")) { + MCProng prong(1, {Pdg::kDStar}, {false}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D*+", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("DstarMinus")) { + MCProng prong(1, {-Pdg::kDStar}, {false}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "D*-", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("pionFromDstar")) { + MCProng prong(2, {211, Pdg::kDStar}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Pions from D* decays", {prong}, {1}); + return signal; + } + if (!nameStr.compare("D0FromDstar")) { + MCProng prong(2, {Pdg::kD0, Pdg::kDStar}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "D0 from D* decays", {prong}, {1}); + return signal; + } + if (!nameStr.compare("KFromD0FromDstar")) { + MCProng prong(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + signal = new MCSignal(name, "Kaons from D0 from D* decays", {prong}, {1}); + return signal; + } + if (!nameStr.compare("PiFromD0FromDstar")) { + MCProng prong(3, {211, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + signal = new MCSignal(name, "Pions from D0 from D* decays", {prong}, {1}); + return signal; + } + if (!nameStr.compare("KPiFromD0FromDstar")) { + MCProng prongKaon(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPion(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + signal = new MCSignal(name, "Kaon and pion pair from D0 from D* decay", {prongKaon, prongPion}, {1, 1}); + return signal; + } + if (!nameStr.compare("KPiPiFromD0FromDstar")) { + MCProng prongKaon(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPionSecondary(3, {211, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPion(2, {211, Pdg::kDStar}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon pion pion triplet from D*", {prongKaon, prongPionSecondary, prongPion}, {2, 2, 1}); + return signal; + } + if (!nameStr.compare("KPiPiFromD0FromDstarPlus")) { + MCProng prongKaon(3, {-321, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPionSecondary(3, {211, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPion(2, {211, Pdg::kDStar}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon pion pion triplet from D*+", {prongKaon, prongPionSecondary, prongPion}, {2, 2, 1}); + return signal; + } + if (!nameStr.compare("KPiPiFromD0FromDstarMinus")) { + MCProng prongKaon(3, {321, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPionSecondary(3, {-211, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); + MCProng prongPion(2, {-211, Pdg::kDStar}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon pion pion triplet from D*-", {prongKaon, prongPionSecondary, prongPion}, {2, 2, 1}); + return signal; + } + if (!nameStr.compare("KFromDplus")) { + MCProng prong(2, {321, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); + prong.SetSourceBit(0, MCProng::kPhysicalPrimary); + signal = new MCSignal(name, "Kaons from D+/- decays", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("LambdaC")) { + MCProng prong(1, {Pdg::kLambdaCPlus}, {true}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "Lambda_c", {prong}, {-1}); + return signal; + } + //-------------------------------------------------------------------------------- if (!nameStr.compare("JpsiFromChic0")) { diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 77de7838f8e..91315f7069c 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -642,6 +642,8 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kVertexingLzOverErr] = ""; fgVariableNames[kVertexingLxyzOverErr] = "Pair Lxyz/DLxyz"; fgVariableUnits[kVertexingLxyzOverErr] = ""; + fgVariableNames[kCosPointingAngle] = "Cos #theta_{pointing}"; + fgVariableUnits[kCosPointingAngle] = ""; fgVariableNames[kKFTrack0DCAxyz] = "Daughter0 DCAxyz"; fgVariableUnits[kKFTrack0DCAxyz] = "cm"; fgVariableNames[kKFTrack1DCAxyz] = "Daughter1 DCAxyz"; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index bf328b6fa0c..6a2443dc3bb 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -146,7 +146,6 @@ class VarManager : public TObject kDecayToKPi, // e.g. D0 -> K+ pi- or cc. kTripleCandidateToKPiPi, // e.g. D+ -> K- pi+ pi+ kTripleCandidateToPKPi, // e.g. Lambda_c -> p K- pi+ - kTripleCandidateToKKPi, // e.g. D_s -> K+ K- pi+ kNMaxCandidateTypes }; @@ -2885,21 +2884,6 @@ void VarManager::FillTriple(T1 const& t1, T2 const& t2, T3 const& t3, float* val values[kPhi] = v123.Phi(); values[kRap] = -v123.Rapidity(); } - - if (pairType == kTripleCandidateToKKPi) { - float m1 = o2::constants::physics::MassKaonCharged; - float m2 = o2::constants::physics::MassPionCharged; - - ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), m1); - ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), m1); - ROOT::Math::PtEtaPhiMVector v3(t3.pt(), t3.eta(), t3.phi(), m2); - ROOT::Math::PtEtaPhiMVector v123 = v1 + v2 + v3; - values[kMass] = v123.M(); - values[kPt] = v123.Pt(); - values[kEta] = v123.Eta(); - values[kPhi] = v123.Phi(); - values[kRap] = -v123.Rapidity(); - } } template @@ -3063,6 +3047,21 @@ void VarManager::FillTripleMC(T1 const& t1, T2 const& t2, T3 const& t3, float* v values[kPt1] = t1.pt(); values[kPt2] = t2.pt(); } + + if (pairType == kTripleCandidateToKPiPi) { + float m1 = o2::constants::physics::MassKaonCharged; + float m2 = o2::constants::physics::MassPionCharged; + + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), m1); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), m2); + ROOT::Math::PtEtaPhiMVector v3(t3.pt(), t3.eta(), t3.phi(), m2); + ROOT::Math::PtEtaPhiMVector v123 = v1 + v2 + v3; + values[kMass] = v123.M(); + values[kPt] = v123.Pt(); + values[kEta] = v123.Eta(); + values[kPhi] = v123.Phi(); + values[kRap] = -v123.Rapidity(); + } } template @@ -3574,6 +3573,10 @@ void VarManager::FillTripletVertexing(C const& collision, T const& t1, T const& values[kVertexingTauzErr] = values[kVertexingLzErr] * v123.M() / (TMath::Abs(v123.Pz()) * o2::constants::physics::LightSpeedCm2NS); values[kVertexingTauxyErr] = values[kVertexingLxyErr] * v123.M() / (v123.Pt() * o2::constants::physics::LightSpeedCm2NS); + values[kCosPointingAngle] = ((collision.posX() - secondaryVertex[0]) * v123.Px() + + (collision.posY() - secondaryVertex[1]) * v123.Py() + + (collision.posZ() - secondaryVertex[2]) * v123.Pz()) / + (v123.P() * values[VarManager::kVertexingLxyz]); // run 2 definitions: Decay length projected onto the momentum vector of the candidate values[kVertexingLzProjected] = (secondaryVertex[2] - collision.posZ()) * v123.Pz(); values[kVertexingLzProjected] = values[kVertexingLzProjected] / TMath::Sqrt(v123.Pz() * v123.Pz()); diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 62dfcd46652..7cdb426d55e 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -29,6 +29,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisHelpers.h" #include "PWGDQ/DataModel/ReducedInfoTables.h" #include "PWGDQ/Core/VarManager.h" #include "PWGDQ/Core/HistogramManager.h" @@ -106,6 +107,7 @@ using MyBarrelTracksWithCov = soa::Join; using MyBarrelTracksWithCovWithAmbiguitiesWithColl = soa::Join; using MyDielectronCandidates = soa::Join; +using MyDitrackCandidates = soa::Join; using MyDimuonCandidates = soa::Join; using MyMuonTracks = soa::Join; using MyMuonTracksWithCov = soa::Join; @@ -1878,6 +1880,922 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", false); }; +// Run pairing for resonance with legs fulfilling separate cuts (asymmetric decay channel) +struct AnalysisAsymmetricPairing { + + Produces ditrackList; + Produces ditrackExtraList; + + o2::base::MatLayerCylSet* fLUT = nullptr; + int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + + // Output objects + OutputObj fOutputList{"output"}; + + // Configurables + Configurable fConfigLegCuts{"cfgLegCuts", "", ":[:],[:[:],...]"}; + Configurable fConfigLegAFilterMask{"cfgLegAFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; + Configurable fConfigLegBFilterMask{"cfgLegBFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; + Configurable fConfigLegCFilterMask{"cfgLegCFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; + Configurable fConfigCommonTrackCuts{"cfgCommonTrackCuts", "", "Comma separated list of cuts to be applied to all legs"}; + Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable fConfigSkipAmbiguousIdCombinations{"cfgSkipAmbiguousIdCombinations", true, "Choose whether to skip pairs/triples which pass a stricter combination of cuts, e.g. KKPi triplets for D+ -> KPiPi"}; + + Configurable fConfigHistogramSubgroups{"cfgAsymmetricPairingHistogramsSubgroups", "barrel,vertexing", "Comma separated list of asymmetric-pairing histogram subgroups"}; + Configurable fConfigSameSignHistograms{"cfgSameSignHistograms", false, "Include same sign pair histograms for 2-prong decays"}; + // Configurable fConfigAmbiguousHistograms{"cfgAmbiguousHistograms", false, "Include separate histograms for pairs/triplets with ambiguous tracks"}; + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigGRPMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable fConfigUseRemoteField{"cfgUseRemoteField", false, "Choose whether to fetch the magnetic field from ccdb or set it manually"}; + Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; + + Configurable fConfigUseKFVertexing{"cfgUseKFVertexing", false, "Use KF Particle for secondary vertex reconstruction (DCAFitter is used by default)"}; + Configurable fConfigUseAbsDCA{"cfgUseAbsDCA", false, "Use absolute DCA minimization instead of chi^2 minimization in secondary vertexing"}; + Configurable fConfigPropToPCA{"cfgPropToPCA", false, "Propagate tracks to secondary vertex"}; + Configurable fConfigLutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + + Configurable fConfigRunMCGenPair{"cfgRunMCGenPair", false, "Do pairing of true MC particles"}; + Configurable fConfigMCGenSignals{"cfgBarrelMCGenSignals", "", "Comma separated list of MC signals (generated)"}; + Configurable fConfigMCRecSignals{"cfgBarrelMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; + + Service fCCDB; + + HistogramManager* fHistMan; + + std::map> fTrackHistNames; + std::map> fBarrelHistNamesMCmatched; + std::vector fPairCuts; + + std::vector fRecMCSignals; + std::vector fGenMCSignals; + + // Filter masks to find legs in BarrelTrackCuts table + uint32_t fLegAFilterMask; + uint32_t fLegBFilterMask; + uint32_t fLegCFilterMask; + // Map tracking which pair of leg cuts the track cuts participate in + std::map fTrackCutFilterMasks; + // Filter map for common track cuts + uint32_t fCommonTrackCutMask; + // Map tracking which common track cut the track cuts correspond to + std::map fCommonTrackCutFilterMasks; + + int fNLegCuts; + int fNPairCuts = 0; + int fNCommonTrackCuts; + + Preslice> trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; + + // Partitions for triplets and asymmetric pairs + Partition> legACandidateAssocs = (o2::aod::dqanalysisflags::isBarrelSelected & fConfigLegAFilterMask) > static_cast(0); + Partition> legBCandidateAssocs = (o2::aod::dqanalysisflags::isBarrelSelected & fConfigLegBFilterMask) > static_cast(0); + Partition> legCCandidateAssocs = (o2::aod::dqanalysisflags::isBarrelSelected & fConfigLegCFilterMask) > static_cast(0); + + void init(o2::framework::InitContext& context) + { + if (context.mOptions.get("processDummy")) { + return; + } + + TString histNames = ""; + std::vector names; + + // Get the leg cut filter maps + fLegAFilterMask = fConfigLegAFilterMask.value; + fLegBFilterMask = fConfigLegBFilterMask.value; + fLegCFilterMask = fConfigLegCFilterMask.value; + // Get the pair cuts + TString cutNamesStr = fConfigPairCuts.value; + if (!cutNamesStr.IsNull()) { + std::unique_ptr objArray(cutNamesStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + fPairCuts.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); + } + } + + // Setting the MC rec signal names + TString sigNamesStr = fConfigMCRecSignals.value; + std::unique_ptr objRecSigArray(sigNamesStr.Tokenize(",")); + + for (int isig = 0; isig < objRecSigArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objRecSigArray->At(isig)->GetName()); + if (sig) { + fRecMCSignals.push_back(*sig); + } + } + + // Get the barrel track selection cuts + string tempCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); + TString tempCutsStr = tempCuts; + std::unique_ptr objArray(tempCutsStr.Tokenize(",")); + // Get the common leg cuts + int commonCutIdx; + TString commonNamesStr = fConfigCommonTrackCuts.value; + if (!commonNamesStr.IsNull()) { // if common track cuts + std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); + fNCommonTrackCuts = objArrayCommon->GetEntries(); + for (int icut = 0; icut < fNCommonTrackCuts; ++icut) { + commonCutIdx = objArray->IndexOf(objArrayCommon->At(icut)); + if (commonCutIdx >= 0) { + fCommonTrackCutMask |= static_cast(1) << objArray->IndexOf(objArrayCommon->At(icut)); + fCommonTrackCutFilterMasks[icut] = static_cast(1) << objArray->IndexOf(objArrayCommon->At(icut)); + } else { + LOGF(fatal, "Common track cut %s was not calculated upstream. Check the config!", objArrayCommon->At(icut)->GetName()); + } + } + } + // Check that the leg cut masks make sense + if (static_cast(std::floor(TMath::Log2(fLegAFilterMask))) + 1 > objArray->GetEntries()) { + LOGF(fatal, "fConfigLegAFilterMask has highest bit at position %d, but track-selection only has %d cuts!", static_cast(std::floor(TMath::Log2(fLegAFilterMask))) + 1, objArray->GetEntries()); + } + if (static_cast(std::floor(TMath::Log2(fLegBFilterMask))) + 1 > objArray->GetEntries()) { + LOGF(fatal, "fConfigLegBFilterMask has highest bit at position %d, but track-selection only has %d cuts!", static_cast(std::floor(TMath::Log2(fLegBFilterMask))) + 1, objArray->GetEntries()); + } + if (static_cast(std::floor(TMath::Log2(fLegCFilterMask))) + 1 > objArray->GetEntries()) { + LOGF(fatal, "fConfigLegCFilterMask has highest bit at position %d, but track-selection only has %d cuts!", static_cast(std::floor(TMath::Log2(fLegCFilterMask))) + 1, objArray->GetEntries()); + } + + // Get the cuts defining the legs + uint32_t fConstructedLegAFilterMask = 0; + uint32_t fConstructedLegBFilterMask = 0; + uint32_t fConstructedLegCFilterMask = 0; + TString legCutsStr = fConfigLegCuts.value; + std::unique_ptr objArrayLegs(legCutsStr.Tokenize(",")); + if (objArrayLegs->GetEntries() == 0) { + LOG(fatal) << "No cuts defining legs. Check the config!"; + } + fNLegCuts = objArrayLegs->GetEntries(); + std::vector isThreeProng; + int legAIdx; + int legBIdx; + int legCIdx; + // Loop over leg defining cuts + for (int icut = 0; icut < fNLegCuts; ++icut) { + TString legsStr = objArrayLegs->At(icut)->GetName(); + std::unique_ptr legs(legsStr.Tokenize(":")); + if (legs->GetEntries() == 3) { + isThreeProng.push_back(true); + } else if (legs->GetEntries() == 2) { + isThreeProng.push_back(false); + } else { + LOGF(fatal, "Leg cuts %s has the wrong format and could not be parsed!", legsStr.Data()); + continue; + } + // Find leg cuts in the track selection cuts + legAIdx = objArray->IndexOf(legs->At(0)); + if (legAIdx >= 0) { + fConstructedLegAFilterMask |= static_cast(1) << legAIdx; + fTrackCutFilterMasks[icut] |= static_cast(1) << legAIdx; + } else { + LOGF(fatal, "Leg A cut %s was not calculated upstream. Check the config!", legs->At(0)->GetName()); + continue; + } + legBIdx = objArray->IndexOf(legs->At(1)); + if (legBIdx >= 0) { + fConstructedLegBFilterMask |= static_cast(1) << legBIdx; + fTrackCutFilterMasks[icut] |= static_cast(1) << legBIdx; + } else { + LOGF(fatal, "Leg B cut %s was not calculated upstream. Check the config!", legs->At(1)->GetName()); + continue; + } + if (isThreeProng[icut]) { + legCIdx = objArray->IndexOf(legs->At(2)); + if (legCIdx >= 0) { + fConstructedLegCFilterMask |= static_cast(1) << legCIdx; + fTrackCutFilterMasks[icut] |= static_cast(1) << legCIdx; + } else { + LOGF(fatal, "Leg C cut %s was not calculated upstream. Check the config!", legs->At(2)->GetName()); + continue; + } + } + if (isThreeProng[icut]) { + names = { + Form("TripletsBarrelSE_%s", legsStr.Data())}; + histNames += Form("%s;", names[0].Data()); + if (fConfigQA) { + names.push_back(Form("TripletsBarrelSE_ambiguous_%s", legsStr.Data())); + histNames += Form("%s;", names[1].Data()); + } + fTrackHistNames[icut] = names; + + std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + names.push_back(Form("TripletsBarrelSE_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName())); + histNames += Form("%s;", names[0].Data()); + fTrackHistNames[fNLegCuts + icut * fNCommonTrackCuts + iCommonCut] = names; + } + + TString cutNamesStr = fConfigPairCuts.value; + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + fNPairCuts = objArrayPair->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + names = {}; + names.push_back(Form("TripletsBarrelSE_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName())); + histNames += Form("%s;", names[0].Data()); + fTrackHistNames[fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = names; + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName())); + histNames += Form("%s;", names[0].Data()); + fTrackHistNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts + 1) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + + // TODO: assign hist directories for the MC matched triplets for each (leg cut combo,MCsignal) combination + if (!sigNamesStr.IsNull()) { + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + names = { + Form("TripletsBarrelSE_%s_%s", legsStr.Data(), sig.GetName())}; + histNames += Form("%s;", names[0].Data()); + fBarrelHistNamesMCmatched[offset + icut] = names; + + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig.GetName())); + histNames += Form("%s;", names[0].Data()); + fBarrelHistNamesMCmatched[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut] = names; + } + + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + names = {}; + names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + histNames += Form("%s;", names[0].Data()); + fBarrelHistNamesMCmatched[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = names; + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + names.push_back(Form("TripletsBarrelSE_%s_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + histNames += Form("%s;", names[0].Data()); + fBarrelHistNamesMCmatched[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + } // end loop over MC signals + } // end if (MC signals) + } else { + names = {}; + std::vector pairHistPrefixes = {"PairsBarrelSEPM"}; + if (fConfigSameSignHistograms.value) { + pairHistPrefixes.push_back("PairsBarrelSEPP"); + pairHistPrefixes.push_back("PairsBarrelSEMM"); + } + int fNPairHistPrefixes = pairHistPrefixes.size(); + + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data())); + histNames += Form("%s;", names[iPrefix].Data()); + } + if (fConfigQA) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_ambiguous_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data())); + histNames += Form("%s;", names[fNPairHistPrefixes + iPrefix].Data()); + } + } + fTrackHistNames[icut] = names; + + std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fTrackHistNames[fNLegCuts + icut * fNCommonTrackCuts + iCommonCut] = names; + } + + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + fNPairCuts = objArrayPair->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + names = {}; + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayPair->At(iPairCut)->GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fTrackHistNames[fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = names; + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fTrackHistNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + + // assign hist directories for the MC matched triplets for each (leg cut combo,MCsignal) combination + if (!sigNamesStr.IsNull()) { + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); + names = {}; + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig.GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fBarrelHistNamesMCmatched[offset + icut] = names; + + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig.GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fBarrelHistNamesMCmatched[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut] = names; + } + + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + names = {}; + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fBarrelHistNamesMCmatched[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = names; + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + names = {}; + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + names.push_back(Form("%s_%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + histNames += Form("%s;", names[iPrefix].Data()); + } + fBarrelHistNamesMCmatched[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + } // end loop over MC signals + } // end if (MC signals) + } + } + + // Add histogram classes for each specified MCsignal at the generator level + // TODO: create a std::vector of hist classes to be used at Fill time, to avoid using Form in the process function + TString sigGenNamesStr = fConfigMCGenSignals.value; + std::unique_ptr objGenSigArray(sigGenNamesStr.Tokenize(",")); + for (int isig = 0; isig < objGenSigArray->GetEntries(); isig++) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objGenSigArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() == 1) { // NOTE: 1-prong signals required + fGenMCSignals.push_back(*sig); + histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + } + } + } + + // Make sure the leg cuts are covered by the configured filter masks + if (fLegAFilterMask != fConstructedLegAFilterMask) { + LOGF(fatal, "cfgLegAFilterMask (%d) is not equal to the mask constructed by the cuts specified in cfgLegCuts (%d)!", fLegAFilterMask, fConstructedLegAFilterMask); + } + if (fLegBFilterMask != fConstructedLegBFilterMask) { + LOGF(fatal, "cfgLegBFilterMask (%d) is not equal to the mask constructed by the cuts specified in cfgLegCuts (%d)!", fLegBFilterMask, fConstructedLegBFilterMask); + } + if (fLegCFilterMask != fConstructedLegCFilterMask) { + LOGF(fatal, "cfgLegCFilterMask (%d) is not equal to the mask constructed by the cuts specified in cfgLegCuts (%d)!", fLegCFilterMask, fConstructedLegCFilterMask); + } + // Make sure only pairs or only triplets of leg cuts were given + int tripletCheckSum = std::count(isThreeProng.begin(), isThreeProng.end(), true); + if (tripletCheckSum != 0 && tripletCheckSum != fNLegCuts) { + LOGF(fatal, "A mix of pairs and triplets was given as leg cuts. Check your config!"); + } + + fCurrentRun = 0; + + fCCDB->setURL(fConfigCcdbUrl.value); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + + fLUT = o2::base::MatLayerCylSet::rectifyPtrFromFile(fCCDB->get(fConfigLutPath)); + VarManager::SetupMatLUTFwdDCAFitter(fLUT); + + VarManager::SetDefaultVarNames(); + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + DefineHistograms(fHistMan, histNames.Data(), fConfigHistogramSubgroups.value.data()); // define all histograms + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + + void initParamsFromCCDB(uint64_t timestamp, bool isTriplets) + { + if (fConfigUseRemoteField.value) { + o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigGRPMagPath, timestamp); + float magField = 0.0; + if (grpmag != nullptr) { + magField = grpmag->getNominalL3Field(); + } else { + LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", timestamp); + } + if (isTriplets) { + if (fConfigUseKFVertexing.value) { + VarManager::SetupThreeProngKFParticle(magField); + } else { + VarManager::SetupThreeProngDCAFitter(magField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigUseAbsDCA.value); + } + } else { + if (fConfigUseKFVertexing.value) { + VarManager::SetupTwoProngKFParticle(magField); + } else { + VarManager::SetupTwoProngDCAFitter(magField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigUseAbsDCA.value); // TODO: get these parameters from Configurables + } + } + } else { + if (isTriplets) { + if (fConfigUseKFVertexing.value) { + VarManager::SetupThreeProngKFParticle(fConfigMagField.value); + } else { + VarManager::SetupThreeProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigUseAbsDCA.value); + } + } else { + if (fConfigUseKFVertexing.value) { + VarManager::SetupTwoProngKFParticle(fConfigMagField.value); + } else { + VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigUseAbsDCA.value); // TODO: get these parameters from Configurables + } + } + } + } + + // Template function to run same event pairing with asymmetric pairs (e.g. kaon-pion) + template + void runAsymmetricPairing(TEvents const& events, Preslice& preslice, TTrackAssocs const& /*assocs*/, TTracks const& /*tracks*/, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& /*mcTracks*/) + { + if (events.size() > 0) { // Additional protection to avoid crashing of events.begin().runNumber() + if (fCurrentRun != events.begin().runNumber()) { + initParamsFromCCDB(events.begin().timestamp(), false); + fCurrentRun = events.begin().runNumber(); + } + } + + std::map> histNamesMC = fBarrelHistNamesMCmatched; + std::map> histNames = fTrackHistNames; + + int sign1 = 0; + int sign2 = 0; + uint32_t mcDecision = 0; + ditrackList.reserve(1); + ditrackExtraList.reserve(1); + + constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); + + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + + auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegAAssocs.size() == 0) { + continue; + } + auto groupedLegBAssocs = legBCandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegBAssocs.size() == 0) { + continue; + } + + for (auto& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { + + uint32_t twoTrackFilter = 0; + uint32_t twoTrackCommonFilter = 0; + uint32_t pairFilter = 0; + bool isPairIdWrong = false; + for (int icut = 0; icut < fNLegCuts; ++icut) { + // Find leg pair definitions both candidates participate in + if ((((a1.isBarrelSelected_raw() & fLegAFilterMask) | (a2.isBarrelSelected_raw() & fLegBFilterMask)) & fTrackCutFilterMasks[icut]) == fTrackCutFilterMasks[icut]) { + twoTrackFilter |= static_cast(1) << icut; + // If the supposed pion passes a kaon cut, this is a K+K-. Skip it. + if (TPairType == VarManager::kDecayToKPi && fConfigSkipAmbiguousIdCombinations.value) { + if (a2.isBarrelSelected_raw() & fLegAFilterMask) { + isPairIdWrong = true; + } + } + } + } + + if (!twoTrackFilter || isPairIdWrong) { + continue; + } + + // Find common track cuts both candidates pass + twoTrackCommonFilter |= a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & fCommonTrackCutMask; + + auto t1 = a1.template reducedtrack_as(); + auto t2 = a2.template reducedtrack_as(); + + // Avoid self-pairs + if (t1.globalIndex() == t2.globalIndex()) { + continue; + } + + sign1 = t1.sign(); + sign2 = t2.sign(); + // store the ambiguity number of the two dilepton legs in the last 4 digits of the two-track filter + if (t1.barrelAmbiguityInBunch() > 1 || t1.barrelAmbiguityOutOfBunch() > 1) { + twoTrackFilter |= static_cast(1) << 30; + } + if (t2.barrelAmbiguityInBunch() > 1 || t2.barrelAmbiguityOutOfBunch() > 1) { + twoTrackFilter |= static_cast(1) << 31; + } + + // run MC matching for this pair + int isig = 0; + mcDecision = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { + if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) { + mcDecision |= static_cast(1) << isig; + } + } + } // end loop over MC signals + + VarManager::FillPair(t1, t2); + if constexpr (TTwoProngFitter) { + VarManager::FillPairVertexing(event, t1, t2, fConfigPropToPCA); + } + + // Fill histograms + bool isAmbi = false; + for (int icut = 0; icut < fNLegCuts; icut++) { + if (twoTrackFilter & (static_cast(1) << icut)) { + isAmbi = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); + if (sign1 * sign2 < 0) { // +- pairs + fHistMan->FillHistClass(histNames[icut][0].Data(), VarManager::fgValues); // reconstructed, unmatched + if (isAmbi && fConfigQA) { + fHistMan->FillHistClass(histNames[icut][3].Data(), VarManager::fgValues); + } + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { // ++ pairs + fHistMan->FillHistClass(histNames[icut][1].Data(), VarManager::fgValues); + if (isAmbi && fConfigQA) { + fHistMan->FillHistClass(histNames[icut][4].Data(), VarManager::fgValues); + } + } else { // -- pairs + fHistMan->FillHistClass(histNames[icut][2].Data(), VarManager::fgValues); + if (isAmbi && fConfigQA) { + fHistMan->FillHistClass(histNames[icut][5].Data(), VarManager::fgValues); + } + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNamesMC[offset + icut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNamesMC[offset + icut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNamesMC[offset + icut][2].Data(), VarManager::fgValues); + } + } + } + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNames[fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNames[fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNames[fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][2].Data(), VarManager::fgValues); + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][2].Data(), VarManager::fgValues); + } + } + } + } + } + } // end loop (common cuts) + for (unsigned int iPairCut = 0; iPairCut < fPairCuts.size(); iPairCut++) { + AnalysisCompositeCut cut = fPairCuts.at(iPairCut); + if (!(cut.IsSelected(VarManager::fgValues))) // apply pair cuts + continue; + pairFilter |= (static_cast(1) << iPairCut); + // Histograms with pair cuts + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNames[fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNames[fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNames[fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][2].Data(), VarManager::fgValues); + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][2].Data(), VarManager::fgValues); + } + } + } + } + // Histograms with pair cuts and common track cuts + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][2].Data(), VarManager::fgValues); + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][0].Data(), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][2].Data(), VarManager::fgValues); + } + } + } + } + } + } + } // end loop (pair cuts) + } + } // end loop (cuts) + ditrackList(event.globalIndex(), VarManager::fgValues[VarManager::kMass], + VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], + t1.sign() + t2.sign(), twoTrackFilter, pairFilter, twoTrackCommonFilter); + if constexpr (trackHasCov && TTwoProngFitter) { + ditrackExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); + } + } // end inner assoc loop (leg A) + } // end event loop + } + + // Template function to run same event triplets (e.g. D+->K-pi+pi+) + template + void runThreeProng(TEvents const& events, Preslice& preslice, TTrackAssocs const& /*assocs*/, TTracks const& tracks, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& /*mcTracks*/, VarManager::PairCandidateType tripletType) + { + if (events.size() > 0) { // Additional protection to avoid crashing of events.begin().runNumber() + if (fCurrentRun != events.begin().runNumber()) { + initParamsFromCCDB(events.begin().timestamp(), true); + fCurrentRun = events.begin().runNumber(); + } + } + + std::map> histNames = fTrackHistNames; + std::map> histNamesMC = fBarrelHistNamesMCmatched; + + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + + auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegAAssocs.size() == 0) { + continue; + } + auto groupedLegBAssocs = legBCandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegBAssocs.size() == 0) { + continue; + } + auto groupedLegCAssocs = legCCandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegCAssocs.size() == 0) { + continue; + } + + // Based on triplet type, make suitable combinations of the partitions + if (tripletType == VarManager::kTripleCandidateToPKPi) { + for (auto& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { + readTriplet(a1, a2, a3, tracks, event, tripletType, histNames, histNamesMC); + } + } else if (tripletType == VarManager::kTripleCandidateToKPiPi) { + for (auto& a1 : groupedLegAAssocs) { + for (auto& [a2, a3] : combinations(groupedLegBAssocs, groupedLegCAssocs)) { + readTriplet(a1, a2, a3, tracks, event, tripletType, histNames, histNamesMC); + } + } + } else { + LOG(fatal) << "Given tripletType not recognized. Don't know how to make combinations!" << endl; + } + } // end event loop + } + + // Helper function to process triplet + template + void readTriplet(TTrackAssoc const& a1, TTrackAssoc const& a2, TTrackAssoc const& a3, TTracks const& /*tracks*/, TEvent const& event, VarManager::PairCandidateType tripletType, std::map> histNames, std::map> histNamesMC) + { + uint32_t mcDecision = 0; + + uint32_t threeTrackFilter = 0; + uint32_t threeTrackCommonFilter = 0; + for (int icut = 0; icut < fNLegCuts; ++icut) { + // Find out which leg cut combination the triplet passes + if ((((a1.isBarrelSelected_raw() & fLegAFilterMask) | (a2.isBarrelSelected_raw() & fLegBFilterMask) | (a3.isBarrelSelected_raw() & fLegCFilterMask)) & fTrackCutFilterMasks[icut]) == fTrackCutFilterMasks[icut]) { + threeTrackFilter |= (static_cast(1) << icut); + if (tripletType == VarManager::kTripleCandidateToPKPi && fConfigSkipAmbiguousIdCombinations.value) { + // Check if the supposed pion passes as a proton or kaon, if so, skip this triplet. It is pKp or pKK. + if ((a3.isBarrelSelected_raw() & fLegAFilterMask) || (a3.isBarrelSelected_raw() & fLegBFilterMask)) { + return; + } + // Check if the supposed kaon passes as a proton, if so, skip this triplet. It is ppPi. + if (a2.isBarrelSelected_raw() & fLegAFilterMask) { + return; + } + } + if (tripletType == VarManager::kTripleCandidateToKPiPi && fConfigSkipAmbiguousIdCombinations.value) { + // Check if one of the supposed pions pass as a kaon, if so, skip this triplet. It is KKPi. + if ((a2.isBarrelSelected_raw() & fLegAFilterMask) || (a3.isBarrelSelected_raw() & fLegAFilterMask)) { + return; + } + } + } + } + if (!threeTrackFilter) { + return; + } + + // Find common track cuts all candidates pass + threeTrackCommonFilter |= a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & a3.isBarrelSelected_raw() & fCommonTrackCutMask; + + auto t1 = a1.template reducedtrack_as(); + auto t2 = a2.template reducedtrack_as(); + auto t3 = a3.template reducedtrack_as(); + + // Avoid self-pairs + if (t1 == t2 || t1 == t3 || t2 == t3) { + return; + } + + // store the ambiguity of the three legs in the last 3 digits of the two-track filter + if (t1.barrelAmbiguityInBunch() > 1 || t1.barrelAmbiguityOutOfBunch() > 1) { + threeTrackFilter |= (static_cast(1) << 29); + } + if (t2.barrelAmbiguityInBunch() > 1 || t2.barrelAmbiguityOutOfBunch() > 1) { + threeTrackFilter |= (static_cast(1) << 30); + } + if (t3.barrelAmbiguityInBunch() > 1 || t3.barrelAmbiguityOutOfBunch() > 1) { + threeTrackFilter |= (static_cast(1) << 31); + } + + // run MC matching for this triplet + int isig = 0; + mcDecision = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack() && t3.has_reducedMCTrack()) { + if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack(), t3.reducedMCTrack())) { + mcDecision |= (static_cast(1) << isig); + } + } + } // end loop over MC signals + + VarManager::FillTriple(t1, t2, t3, VarManager::fgValues, tripletType); + if constexpr (TThreeProngFitter) { + VarManager::FillTripletVertexing(event, t1, t2, t3, tripletType); + } + + // Fill histograms + bool isAmbi = false; + for (int icut = 0; icut < fNLegCuts; icut++) { + isAmbi = (threeTrackFilter & (static_cast(1) << 29)) || (threeTrackFilter & (static_cast(1) << 30)) || (threeTrackFilter & (static_cast(1) << 31)); + if (threeTrackFilter & (static_cast(1) << icut)) { + fHistMan->FillHistClass(histNames[icut][0].Data(), VarManager::fgValues); + // TODO: loop over MC signals + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(histNamesMC[offset + icut][0].Data(), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + if (fConfigQA && isAmbi) { + fHistMan->FillHistClass(histNames[icut][1].Data(), VarManager::fgValues); + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + fHistMan->FillHistClass(histNames[fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][0].Data(), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut][0].Data(), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + } + } // end loop (common cuts) + for (unsigned int iPairCut = 0; iPairCut < fPairCuts.size(); iPairCut++) { + AnalysisCompositeCut cut = fPairCuts.at(iPairCut); + if (!(cut.IsSelected(VarManager::fgValues))) { // apply pair cuts + continue; + } + // Histograms with pair cuts + fHistMan->FillHistClass(histNames[fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][0].Data(), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(histNamesMC[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][0].Data(), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + // Histograms with pair cuts and common track cuts + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts + 1) + iCommonCut * (1 + fNPairCuts) + iPairCut][0].Data(), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][0].Data(), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + } + } + } // end loop (pair cuts) + } + } // end loop (cuts) + } + + PresliceUnsorted perReducedMcEvent = aod::reducedtrackMC::reducedMCeventId; + + void runMCGen(ReducedMCTracks const& mcTracks) + { + // loop over mc stack and fill histograms for pure MC truth signals + // group all the MC tracks which belong to the MC event corresponding to the current reconstructed event + for (auto& mctrack : mcTracks) { + VarManager::FillTrackMC(mcTracks, mctrack); + // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. + // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. + // TODO: Use the mcReducedFlags to select signals + for (auto& sig : fGenMCSignals) { + if (sig.GetNProngs() != 1) { // NOTE: 1-prong signals required here + continue; + } + bool checked = false; + checked = sig.CheckSignal(true, mctrack); + if (checked) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig.GetName()), VarManager::fgValues); + } + } + } + } // end runMCGen + + void processKaonPionSkimmed(MyEventsVtxCovSelected const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + { + runAsymmetricPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); + if (fConfigRunMCGenPair) + runMCGen(mcTracks); + } + + void processKaonPionPionSkimmed(MyEventsVtxCovSelected const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + { + runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks, VarManager::kTripleCandidateToKPiPi); + if (fConfigRunMCGenPair) + runMCGen(mcTracks); + } + + void processDummy(MyEvents&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionSkimmed, "Run kaon pion pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionPionSkimmed, "Run kaon pion pion triplets, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", true); +}; + // Combines dileptons with barrel or muon tracks for either resonance or correlation analyses // Dileptons produced with all the selection cuts specified in the same-event pairing task are combined with the // tracks passing the fConfigTrackCut cut. The dileptons cuts from the same-event pairing task are auto-detected @@ -1903,8 +2821,12 @@ struct AnalysisDileptonTrack { int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. int fNCuts; + int fNPairCuts; + int fNCommonTrackCuts; + std::map fCommonTrackCutMap; int fTrackCutBit; std::map fHistNamesDileptonTrack; + // std::map fHistNamesDileptonTrackMCmatched; std::map> fHistNamesDileptonTrackMCmatched; std::vector fHistNamesMCgen; std::map fHistNamesDileptons; @@ -1934,8 +2856,9 @@ struct AnalysisDileptonTrack { } bool isBarrel = context.mOptions.get("processBarrelSkimmed"); + bool isBarrelAsymmetric = context.mOptions.get("processDstarToD0Pi"); bool isMuon = context.mOptions.get("processMuonSkimmed"); - bool isAnyProcessEnabled = isBarrel || isMuon; + bool isAnyProcessEnabled = isBarrel || isMuon || isBarrelAsymmetric; bool isDummy = context.mOptions.get("processDummy"); if (isDummy) { if (isAnyProcessEnabled) { @@ -1972,10 +2895,10 @@ struct AnalysisDileptonTrack { // For each track/muon selection used to produce dileptons, create a separate histogram directory using the // name of the track/muon cut. // Also, create a map which will hold the name of the histogram directories so they can be accessed directly in the pairing loop - if (isBarrel || isMuon) { + if (isBarrel || isMuon || isBarrelAsymmetric) { // get the list of single track and muon cuts computed in the dedicated tasks upstream string tempCutsSingle; - if (isBarrel) { + if (isBarrel || isBarrelAsymmetric) { getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCutsSingle, false); } else { getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", tempCutsSingle, false); @@ -1988,6 +2911,7 @@ struct AnalysisDileptonTrack { if (objArraySingleCuts->FindObject(fConfigTrackCut.value.data()) == nullptr) { LOG(fatal) << " Track cut chosen for the correlation task was not computed in the single-track task! Check it out!"; } + // Loop over single-track/muon task cuts and find the cuts used for the track to be combined with dileptons for (int icut = 0; icut < objArraySingleCuts->GetEntries(); ++icut) { TString tempStr = objArraySingleCuts->At(icut)->GetName(); if (tempStr.CompareTo(fConfigTrackCut.value.data()) == 0) { @@ -1996,31 +2920,99 @@ struct AnalysisDileptonTrack { } // get the cuts employed for same-event pairing string tempCutsPair; + string tempCutsAsymPair; + string tempCutsAsymCommon; if (isBarrel) { getTaskOptionValue(context, "analysis-same-event-pairing", "cfgTrackCuts", tempCutsPair, false); - } else { + } else if (isMuon) { getTaskOptionValue(context, "analysis-same-event-pairing", "cfgMuonCuts", tempCutsPair, false); + } else if (isBarrelAsymmetric) { + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgLegCuts", tempCutsPair, false); + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgPairCuts", tempCutsAsymPair, false); + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgCommonTrackCuts", tempCutsAsymCommon, false); + } + + // If asymmetric pair is used, it may have common track cuts + TString tempCutsAsymCommonStr = tempCutsAsymCommon; + if (!tempCutsAsymCommonStr.IsNull()) { // if common track cuts + std::unique_ptr objArrayCommon(tempCutsAsymCommonStr.Tokenize(",")); + fNCommonTrackCuts = objArrayCommon->GetEntries(); + for (int icut = 0; icut < fNCommonTrackCuts; ++icut) { + for (int iicut = 0; iicut < objArraySingleCuts->GetEntries(); ++iicut) { + if (std::strcmp(objArrayCommon->At(icut)->GetName(), objArraySingleCuts->At(iicut)->GetName()) == 0) { + fCommonTrackCutMap[icut] = iicut; + } + } + } } + TString tempCutsPairStr = tempCutsPair; if (!tempCutsSingleStr.IsNull() && !tempCutsPairStr.IsNull()) { std::unique_ptr objArray(tempCutsPairStr.Tokenize(",")); fNCuts = objArray->GetEntries(); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + for (int icut = 0; icut < fNCuts; ++icut) { TString tempStr = objArray->At(icut)->GetName(); - if (objArray->FindObject(tempStr.Data()) != nullptr) { - fHistNamesDileptonTrack[icut] = Form("DileptonTrack_%s_%s", tempStr.Data(), fConfigTrackCut.value.data()); - fHistNamesDileptons[icut] = Form("DileptonsSelected_%s", tempStr.Data()); - DefineHistograms(fHistMan, fHistNamesDileptonTrack[icut], fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms - DefineHistograms(fHistMan, fHistNamesDileptons[icut], "barrel,vertexing"); // define dilepton histograms - std::vector mcHistNames; - - for (auto& sig : fRecMCSignals) { - mcHistNames.push_back(Form("DileptonTrackMCMatched_%s_%s_%s", tempStr.Data(), fConfigTrackCut.value.data(), sig.GetName())); - DefineHistograms(fHistMan, mcHistNames[mcHistNames.size() - 1], fConfigHistogramSubgroups.value.data()); + fHistNamesDileptonTrack[icut] = Form("DileptonTrack_%s_%s", tempStr.Data(), fConfigTrackCut.value.data()); + fHistNamesDileptons[icut] = Form("DileptonsSelected_%s", tempStr.Data()); + DefineHistograms(fHistMan, fHistNamesDileptonTrack[icut], fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + DefineHistograms(fHistMan, fHistNamesDileptons[icut], "barrel,vertexing"); // define dilepton histograms + if (!tempCutsAsymCommonStr.IsNull()) { + std::unique_ptr objArrayCommon(tempCutsAsymCommonStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + fHistNamesDileptonTrack[fNCuts + icut * fNCommonTrackCuts + iCommonCut] = Form("DileptonTrack_%s_%s_%s", tempStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), fConfigTrackCut.value.data()); + fHistNamesDileptons[fNCuts + icut * fNCommonTrackCuts + iCommonCut] = Form("DileptonsSelected_%s_%s", tempStr.Data(), objArrayCommon->At(iCommonCut)->GetName()); + DefineHistograms(fHistMan, fHistNamesDileptonTrack[fNCuts + icut * fNCommonTrackCuts + iCommonCut], fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + DefineHistograms(fHistMan, fHistNamesDileptons[fNCuts + icut * fNCommonTrackCuts + iCommonCut], "barrel,vertexing"); // define dilepton histograms } - fHistNamesDileptonTrackMCmatched[icut] = mcHistNames; } - } + TString tempCutsAsymPairStr = tempCutsAsymPair; + if (!tempCutsAsymPairStr.IsNull()) { + std::unique_ptr objArrayPairCuts(tempCutsAsymPairStr.Tokenize(",")); + fNPairCuts = objArrayPairCuts->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { + fHistNamesDileptonTrack[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = Form("DileptonTrack_%s_%s_%s", tempStr.Data(), objArrayPairCuts->At(iPairCut)->GetName(), fConfigTrackCut.value.data()); + fHistNamesDileptons[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = Form("DileptonsSelected_%s_%s", tempStr.Data(), objArrayPairCuts->At(iPairCut)->GetName()); + DefineHistograms(fHistMan, fHistNamesDileptonTrack[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut], fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + DefineHistograms(fHistMan, fHistNamesDileptons[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut], "barrel,vertexing"); // define dilepton histograms + if (!tempCutsAsymCommonStr.IsNull()) { + std::unique_ptr objArrayCommon(tempCutsAsymCommonStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + fHistNamesDileptonTrack[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut] = Form("DileptonTrack_%s_%s_%s_%s", tempStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPairCuts->At(iPairCut)->GetName(), fConfigTrackCut.value.data()); + fHistNamesDileptons[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut] = Form("DileptonsSelected_%s_%s_%s", tempStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPairCuts->At(iPairCut)->GetName()); + DefineHistograms(fHistMan, fHistNamesDileptonTrack[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut], fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + DefineHistograms(fHistMan, fHistNamesDileptons[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut], "barrel,vertexing"); // define dilepton histograms + } + } + } // end loop (pair cuts) + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); + fHistNamesDileptonTrackMCmatched[icut].push_back(Form("DileptonTrackMCMatched_%s_%s_%s", tempStr.Data(), fConfigTrackCut.value.data(), sig.GetName())); + DefineHistograms(fHistMan, fHistNamesDileptonTrackMCmatched[icut].back(), fConfigHistogramSubgroups.value.data()); + if (!tempCutsAsymCommonStr.IsNull()) { + std::unique_ptr objArrayCommon(tempCutsAsymCommonStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + fHistNamesDileptonTrackMCmatched[fNCuts + icut * fNCommonTrackCuts + iCommonCut].push_back(Form("DileptonTrackMCMatched_%s_%s_%s_%s", tempStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), fConfigTrackCut.value.data(), sig.GetName())); + DefineHistograms(fHistMan, fHistNamesDileptonTrackMCmatched[fNCuts + icut * fNCommonTrackCuts + iCommonCut].back(), fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + } + } + if (!tempCutsAsymPairStr.IsNull()) { + std::unique_ptr objArrayPairCuts(tempCutsAsymPairStr.Tokenize(",")); + fNPairCuts = objArrayPairCuts->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { + fHistNamesDileptonTrackMCmatched[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut].push_back(Form("DileptonTrackMCMatched_%s_%s_%s_%s", tempStr.Data(), objArrayPairCuts->At(iPairCut)->GetName(), fConfigTrackCut.value.data(), sig.GetName())); + DefineHistograms(fHistMan, fHistNamesDileptonTrackMCmatched[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut].back(), fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + if (!tempCutsAsymCommonStr.IsNull()) { + std::unique_ptr objArrayCommon(tempCutsAsymCommonStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + fHistNamesDileptonTrackMCmatched[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut].push_back(Form("DileptonTrackMCMatched_%s_%s_%s_%s_%s", tempStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPairCuts->At(iPairCut)->GetName(), fConfigTrackCut.value.data(), sig.GetName())); + DefineHistograms(fHistMan, fHistNamesDileptonTrackMCmatched[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut].back(), fConfigHistogramSubgroups.value.data()); // define dilepton-track histograms + } // end loop (common cuts) + } + } // end loop (pair cuts) + } + } // end loop (MC signals) + } // end loop (leg defining cuts) } // Add histogram classes for each specified MCsignal at the generator level // TODO: create a std::vector of hist classes to be used at Fill time, to avoid using Form in the process function @@ -2099,12 +3091,29 @@ struct AnalysisDileptonTrack { for (int icut = 0; icut < fNCuts; icut++) { if (dilepton.filterMap_bit(icut)) { fHistMan->FillHistClass(fHistNamesDileptons[icut].Data(), fValuesDilepton); + if constexpr (TCandidateType == VarManager::kDstarToD0KPiPi) { // Dielectrons and Dimuons don't have the PairFilterMap column + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (dilepton.commonFilterMap_bit(fCommonTrackCutMap[iCommonCut])) { + fHistMan->FillHistClass(fHistNamesDileptons[fNCuts + icut * fNCommonTrackCuts + iCommonCut].Data(), fValuesDilepton); + } + } + for (int iPairCut = 0; iPairCut < fNPairCuts; iPairCut++) { + if (dilepton.pairFilterMap_bit(iPairCut)) { + fHistMan->FillHistClass(fHistNamesDileptons[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut].Data(), fValuesDilepton); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (dilepton.commonFilterMap_bit(fCommonTrackCutMap[iCommonCut])) { + fHistMan->FillHistClass(fHistNamesDileptons[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut].Data(), fValuesDilepton); + } + } + } + } + } } } // loop over hadrons for (auto& assoc : assocs) { - if constexpr (TCandidateType == VarManager::kBtoJpsiEEK) { + if constexpr (TCandidateType == VarManager::kBtoJpsiEEK || TCandidateType == VarManager::kDstarToD0KPiPi) { if (!assoc.isBarrelSelected_bit(fTrackCutBit)) { continue; } @@ -2155,7 +3164,39 @@ struct AnalysisDileptonTrack { fHistMan->FillHistClass(fHistNamesDileptonTrackMCmatched[icut][isig], fValuesHadron); } } - } + if constexpr (TCandidateType == VarManager::kDstarToD0KPiPi) { // Dielectrons and Dimuons don't have the PairFilterMap column + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (dilepton.commonFilterMap_bit(fCommonTrackCutMap[iCommonCut])) { + fHistMan->FillHistClass(fHistNamesDileptonTrack[fNCuts + icut * fNCommonTrackCuts + iCommonCut].Data(), fValuesHadron); + for (isig = 0; isig < fRecMCSignals.size(); isig++) { + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(fHistNamesDileptonTrackMCmatched[fNCuts + icut * fNCommonTrackCuts + iCommonCut][isig], fValuesHadron); + } + } // end loop (MC signals) + } + } // end loop (common track cuts) + for (int iPairCut = 0; iPairCut < fNPairCuts; iPairCut++) { + if (dilepton.pairFilterMap_bit(iPairCut)) { + fHistMan->FillHistClass(fHistNamesDileptonTrack[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut].Data(), fValuesHadron); + for (isig = 0; isig < fRecMCSignals.size(); isig++) { + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(fHistNamesDileptonTrackMCmatched[fNCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut][isig], fValuesHadron); + } + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (dilepton.commonFilterMap_bit(fCommonTrackCutMap[iCommonCut])) { + fHistMan->FillHistClass(fHistNamesDileptonTrack[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut].Data(), fValuesHadron); + for (isig = 0; isig < fRecMCSignals.size(); isig++) { + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(fHistNamesDileptonTrackMCmatched[(fNCuts * (fNCommonTrackCuts + 1) + fNCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][isig], fValuesHadron); + } + } // end loop (MC signals) + } + } // end loop (common track cuts) + } + } // end loop (pair cuts) + } + } // end loop (cuts) } // table to be written out for ML analysis BmesonsTable(fValuesHadron[VarManager::kPairMass], fValuesHadron[VarManager::kPairPt], fValuesHadron[VarManager::kVertexingLxy], fValuesHadron[VarManager::kVertexingLxyz], fValuesHadron[VarManager::kVertexingLz], fValuesHadron[VarManager::kVertexingTauxy], fValuesHadron[VarManager::kVertexingTauz], fValuesHadron[VarManager::kKFDCAxyzBetweenProngs], fValuesHadron[VarManager::kCosPointingAngle], fValuesHadron[VarManager::kVertexingChi2PCA], mcDecision); @@ -2165,6 +3206,7 @@ struct AnalysisDileptonTrack { Preslice trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; Preslice dielectronsPerCollision = aod::reducedpair::reducedeventId; + Preslice ditracksPerCollision = aod::reducedpair::reducedeventId; void processBarrelSkimmed(soa::Filtered const& events, soa::Filtered> const& assocs, @@ -2189,6 +3231,26 @@ struct AnalysisDileptonTrack { } } + void processDstarToD0Pi(soa::Filtered const& events, + soa::Filtered> const& assocs, + MyBarrelTracksWithCov const& tracks, soa::Filtered const& ditracks, + ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + { + // set up KF or DCAfitter + if (events.size() == 0) { + return; + } + if (fCurrentRun != events.begin().runNumber()) { // start: runNumber + initParamsFromCCDB(events.begin().timestamp()); + fCurrentRun = events.begin().runNumber(); + } // end: runNumber + for (auto& event : events) { + auto groupedBarrelAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); + auto groupedDitracks = ditracks.sliceBy(ditracksPerCollision, event.globalIndex()); + runDileptonHadron(event, groupedBarrelAssocs, tracks, groupedDitracks, mcEvents, mcTracks); + } + } + Preslice muonAssocsPerCollision = aod::reducedtrack_association::reducedeventId; Preslice dimuonsPerCollision = aod::reducedpair::reducedeventId; @@ -2241,6 +3303,7 @@ struct AnalysisDileptonTrack { } PROCESS_SWITCH(AnalysisDileptonTrack, processBarrelSkimmed, "Run barrel dilepton-track pairing, using skimmed data", false); + PROCESS_SWITCH(AnalysisDileptonTrack, processDstarToD0Pi, "Run barrel pairing of D0 daughters with pion candidate, using skimmed data", false); PROCESS_SWITCH(AnalysisDileptonTrack, processMuonSkimmed, "Run muon dilepton-track pairing, using skimmed data", false); PROCESS_SWITCH(AnalysisDileptonTrack, processMCGen, "Loop over MC particle stack and fill generator level histograms", false); PROCESS_SWITCH(AnalysisDileptonTrack, processDummy, "Dummy function", false); @@ -2254,6 +3317,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; } @@ -2308,6 +3372,10 @@ void DefineHistograms(HistogramManager* histMan, TString histClasses, const char dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "pair", histName); } + if (classStr.Contains("Triplets")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "pair", histName); + } + if (classStr.Contains("MCTruthGenPair")) { dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth_pair"); } diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index 739a9ff1957..7d4c90fcefc 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -2232,8 +2232,6 @@ struct AnalysisAsymmetricPairing { continue; } - // TODO: Think about double counting - std::set> globIdxPairs; for (auto& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { uint32_t twoTrackFilter = static_cast(0); @@ -2395,9 +2393,8 @@ struct AnalysisAsymmetricPairing { continue; } - std::set> globIdxTriplets; // Based on triplet type, make suitable combinations of the partitions - if (tripletType == VarManager::kTripleCandidateToPKPi || tripletType == VarManager::kTripleCandidateToKKPi) { + if (tripletType == VarManager::kTripleCandidateToPKPi) { for (auto& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { readTriplet(a1, a2, a3, tracks, event, tripletType, histNames); } @@ -2517,13 +2514,6 @@ struct AnalysisAsymmetricPairing { runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, VarManager::kTripleCandidateToKPiPi); } - void processKaonKaonPionSkimmed(MyEventsVtxCovZdcSelected const& events, - soa::Join const& barrelAssocs, - MyBarrelTracksWithCovWithAmbiguities const& barrelTracks) - { - runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, VarManager::kTripleCandidateToKKPi); - } - void processProtonKaonPionSkimmed(MyEventsVtxCovZdcSelected const& events, soa::Join const& barrelAssocs, MyBarrelTracksWithCovWithAmbiguities const& barrelTracks) @@ -2538,7 +2528,6 @@ struct AnalysisAsymmetricPairing { PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionSkimmed, "Run kaon pion pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionPionSkimmed, "Run kaon pion pion triplets, with skimmed tracks", false); - PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonKaonPionSkimmed, "Run kaon kaon pion triplets, with skimmed tracks", false); PROCESS_SWITCH(AnalysisAsymmetricPairing, processProtonKaonPionSkimmed, "Run proton kaon pion triplets, with skimmed tracks", false); PROCESS_SWITCH(AnalysisAsymmetricPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", true); }; From 2699fa199394d02a5e43e16d793950449b935638 Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:29:20 +0100 Subject: [PATCH 04/30] [PWGCF] FemtoUniverse -- Adding inv mass for K+K+ and K-K- (#8928) Co-authored-by: Pritam Chakraborty <47203359+prchakra@users.noreply.github.com> --- .../Core/FemtoUniverseTrackSelection.h | 35 +- .../femtoUniverseProducerTask.cxx | 656 +++++++++--------- .../Tasks/femtoUniversePairTaskTrackPhi.cxx | 358 +++++----- 3 files changed, 514 insertions(+), 535 deletions(-) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h index 71086d55b8d..389273d0836 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h @@ -21,7 +21,6 @@ #include #include #include -#include #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -31,7 +30,7 @@ #include "ReconstructionDataFormats/PID.h" #include "Framework/HistogramRegistry.h" -using namespace o2::framework; +// using namespace o2::framework; namespace o2::analysis::femtoUniverse { @@ -110,7 +109,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection tmpPids = pids; /// necessary due to some features of the configurable for (o2::track::PID pid : tmpPids) { - mPIDspecies.push_back(pid); + kPIDspecies.push_back(pid); } } @@ -161,7 +160,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection(prefix); - outString += static_cast(mSelectionNames[iSel]); + outString += static_cast(kSelectionNames[iSel]); outString += suffix; return outString; } @@ -172,7 +171,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection(prefix) + static_cast(mSelectionNames[index]); + std::string comp = static_cast(prefix) + static_cast(kSelectionNames[index]); std::string_view cmp{comp}; if (obs.compare(cmp) == 0) return index; @@ -184,7 +183,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection(prefix); - outString += static_cast(mSelectionHelper[iSel]); + outString += static_cast(kSelectionHelper[iSel]); return outString; } @@ -242,9 +241,9 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection mPIDspecies; ///< All the particle species for which the n_sigma values need to be stored + std::vector kPIDspecies; ///< All the particle species for which the n_sigma values need to be stored static constexpr int kNtrackSelection = 14; - static constexpr std::string_view mSelectionNames[kNtrackSelection] = {"Sign", + static constexpr std::string_view kSelectionNames[kNtrackSelection] = {"Sign", "PtMin", "PtMax", "EtaMax", @@ -259,7 +258,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection void FemtoUniverseTrackSelection::init(HistogramRegistry* registry) @@ -305,7 +304,7 @@ void FemtoUniverseTrackSelection::init(HistogramRegistry* registry) mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, 2. * M_PI}}); + mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, o2::constants::math::TwoPI}}); mHistogramRegistry->add((folderName + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); mHistogramRegistry->add((folderName + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); mHistogramRegistry->add((folderName + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", kTH1F, {{100, 0.5, 1.5}}); @@ -397,7 +396,7 @@ bool FemtoUniverseTrackSelection::isSelectedMinimal(T const& track) const auto dca = track.dcaXY(); // Accordingly to FemtoUniverse in AliPhysics as well as LF analysis, // only dcaXY should be checked; NOT std::sqrt(pow(dcaXY, 2.) + pow(dcaZ, 2.)) std::vector pidTPC, pidTOF; - for (auto it : mPIDspecies) { + for (auto it : kPIDspecies) { pidTPC.push_back(getNsigmaTPC(track, it)); pidTOF.push_back(getNsigmaTOF(track, it)); } @@ -474,10 +473,10 @@ std::array FemtoUniverseTrackSelection::getCutContainer(T c const auto itsNClsIB = track.itsNClsInnerBarrel(); const auto dcaXY = track.dcaXY(); const auto dcaZ = track.dcaZ(); - const auto dca = std::sqrt(pow(dcaXY, 2.) + pow(dcaZ, 2.)); + const auto dca = std::sqrt(std::pow(dcaXY, 2.) + std::pow(dcaZ, 2.)); std::vector pidTPC, pidTOF; - for (auto it : mPIDspecies) { + for (auto it : kPIDspecies) { pidTPC.push_back(getNsigmaTPC(track, it)); pidTOF.push_back(getNsigmaTOF(track, it)); } @@ -487,7 +486,7 @@ std::array FemtoUniverseTrackSelection::getCutContainer(T c const auto selVariable = sel.getSelectionVariable(); if (selVariable == femtoUniverseTrackSelection::kPIDnSigmaMax) { /// PID needs to be handled a bit differently since we may need more than one species - for (size_t i = 0; i < mPIDspecies.size(); ++i) { + for (size_t i = 0; i < kPIDspecies.size(); ++i) { auto pidTPCVal = pidTPC.at(i) - nSigmaPIDOffsetTPC; auto pidTOFVal = pidTOF.at(i) - nSigmaPIDOffsetTOF; auto pidComb = std::sqrt(pidTPCVal * pidTPCVal + pidTOFVal * pidTOFVal); @@ -561,7 +560,7 @@ void FemtoUniverseTrackSelection::fillQA(T const& track) mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/hITSclustersIB"), track.itsNClsInnerBarrel()); mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/hDCAxy"), track.pt(), track.dcaXY()); mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/hDCAz"), track.pt(), track.dcaZ()); - mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/hDCA"), track.pt(), std::sqrt(pow(track.dcaXY(), 2.) + pow(track.dcaZ(), 2.))); + mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/hDCA"), track.pt(), std::sqrt(std::pow(track.dcaXY(), 2.) + std::pow(track.dcaZ(), 2.))); mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/hTPCdEdX"), track.p(), track.tpcSignal()); mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/nSigmaTPC_el"), track.p(), track.tpcNSigmaEl()); mHistogramRegistry->fill(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtouniverseparticle::TrackTypeName[tracktype]) + HIST("/nSigmaTPC_pi"), track.p(), track.tpcNSigmaPi()); diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index e1428e4a6ab..3d28e133237 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -103,7 +103,7 @@ int getRowDaughters(int daughID, T const& vecID) return rowInPrimaryTrackTableDaugh; } -struct femtoUniverseProducerTask { +struct FemtoUniverseProducerTask { Produces outputCollision; Produces outputCollExtra; Produces outputParts; @@ -113,70 +113,70 @@ struct femtoUniverseProducerTask { Produces outputDebugPartsMC; Produces outputCascParts; - Configurable ConfIsDebug{"ConfIsDebug", true, "Enable Debug tables"}; + Configurable confIsDebug{"confIsDebug", true, "Enable Debug tables"}; // Choose if filtering or skimming version is run - Configurable ConfIsTrigger{"ConfIsTrigger", false, "Store all collisions"}; + // Configurable confIsTrigger{"confIsTrigger", false, "Store all collisions"}; //Commented: not used configurable // Choose if running on converted data or Run3 / Pilot - Configurable ConfIsRun3{"ConfIsRun3", true, "Running on Run3 or pilot"}; - Configurable ConfIsMC{"ConfIsMC", false, "Running on MC; implemented only for Run3"}; + Configurable confIsRun3{"confIsRun3", true, "Running on Run3 or pilot"}; + // Configurable confIsMC{"confIsMC", false, "Running on MC; implemented only for Run3"}; //Commented: not used configurable - Configurable ConfIsForceGRP{"ConfIsForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; + Configurable confIsForceGRP{"confIsForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; - Configurable ConfDoSpher{"ConfDoSpher", false, "Calculate sphericity. If false sphericity will take value of 2."}; - Configurable ConfFillCollExt{"ConfFillCollExt", false, "Option to fill collision extended table"}; + Configurable confDoSpher{"confDoSpher", false, "Calculate sphericity. If false sphericity will take value of 2."}; + Configurable confFillCollExt{"confFillCollExt", false, "Option to fill collision extended table"}; /// Event cuts FemtoUniverseCollisionSelection colCuts; - Configurable ConfEvtUseTPCmult{"ConfEvtUseTPCmult", false, "Use multiplicity based on the number of tracks with TPC information"}; - Configurable ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; - Configurable ConfEvtTriggerCheck{"ConfEvtTriggerCheck", true, "Evt sel: check for trigger"}; - Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; - Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; - Configurable ConfIsActivateV0{"ConfIsActivateV0", false, "Activate filling of V0 into femtouniverse tables"}; - Configurable ConfActivateSecondaries{"ConfActivateSecondaries", false, "Fill secondary MC gen particles that were reconstructed"}; - Configurable ConfIsActivateCascade{"ConfIsActivateCascade", false, "Activate filling of Cascade into femtouniverse tables"}; - Configurable ConfIsSelectCascOmega{"ConfIsSelectCascOmega", false, "Select Omegas for cascade analysis"}; - Configurable ConfIsActivatePhi{"ConfIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; - Configurable ConfMCTruthAnalysisWithPID{"ConfMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; - Configurable> ConfMCTruthPDGCodes{"ConfMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; - Configurable ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; - Configurable ConfCentFT0Max{"ConfCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; - Configurable ConfEvIsGoodZvtxFT0vsPV{"ConfEvIsGoodZvtxFT0vsPV", true, "Require kIsGoodZvtxFT0vsPV selection on Events."}; - Configurable ConfEvNoSameBunchPileup{"ConfEvNoSameBunchPileup", true, "Require kNoSameBunchPileup selection on Events."}; - Configurable ConfIsUsePileUp{"ConfIsUsePileUp", true, "Required for choosing whether to run the pile-up cuts"}; - Configurable ConfEvIsVertexITSTPC{"ConfEvIsVertexITSTPC", true, "Require kIsVertexITSTPC selection on Events"}; - Configurable ConfTPCOccupancyMin{"ConfTPCOccupancyMin", 0, "Minimum value for TPC Occupancy selection"}; - Configurable ConfTPCOccupancyMax{"ConfTPCOccupancyMax", 500, "Maximum value for TPC Occupancy selection"}; - - Filter CustomCollCentFilter = (aod::cent::centFT0C > ConfCentFT0Min) && - (aod::cent::centFT0C < ConfCentFT0Max); + Configurable confEvtUseTPCmult{"confEvtUseTPCmult", false, "Use multiplicity based on the number of tracks with TPC information"}; + Configurable confEvtZvtx{"confEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable confEvtTriggerCheck{"confEvtTriggerCheck", true, "Evt sel: check for trigger"}; + Configurable confEvtTriggerSel{"confEvtTriggerSel", kINT7, "Evt sel: trigger"}; + Configurable confEvtOfflineCheck{"confEvtOfflineCheck", false, "Evt sel: check for offline selection"}; + Configurable confIsActivateV0{"confIsActivateV0", false, "Activate filling of V0 into femtouniverse tables"}; + Configurable confActivateSecondaries{"confActivateSecondaries", false, "Fill secondary MC gen particles that were reconstructed"}; + Configurable confIsActivateCascade{"confIsActivateCascade", false, "Activate filling of Cascade into femtouniverse tables"}; + Configurable confIsSelectCascOmega{"confIsSelectCascOmega", false, "Select Omegas for cascade analysis"}; + Configurable confIsActivatePhi{"confIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; + Configurable confMCTruthAnalysisWithPID{"confMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; + Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; + Configurable confCentFT0Min{"confCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; + Configurable confCentFT0Max{"confCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; + Configurable confEvIsGoodZvtxFT0vsPV{"confEvIsGoodZvtxFT0vsPV", true, "Require kIsGoodZvtxFT0vsPV selection on Events."}; + Configurable confEvNoSameBunchPileup{"confEvNoSameBunchPileup", true, "Require kNoSameBunchPileup selection on Events."}; + Configurable confIsUsePileUp{"confIsUsePileUp", true, "Required for choosing whether to run the pile-up cuts"}; + Configurable confEvIsVertexITSTPC{"confEvIsVertexITSTPC", true, "Require kIsVertexITSTPC selection on Events"}; + Configurable confTPCOccupancyMin{"confTPCOccupancyMin", 0, "Minimum value for TPC Occupancy selection"}; + Configurable confTPCOccupancyMax{"confTPCOccupancyMax", 500, "Maximum value for TPC Occupancy selection"}; + + Filter customCollCentFilter = (aod::cent::centFT0C > confCentFT0Min) && + (aod::cent::centFT0C < confCentFT0Max); // just sanity check to make sure in case there are problems in conversion or // MC production it does not affect results - Configurable ConfTrkRejectNotPropagated{"ConfTrkRejectNotPropagated", false, "True: reject not propagated tracks"}; + Configurable confTrkRejectNotPropagated{"confTrkRejectNotPropagated", false, "True: reject not propagated tracks"}; // Configurable ConfRejectITSHitandTOFMissing{ // "ConfRejectITSHitandTOFMissing", false, // "True: reject if neither ITS hit nor TOF timing satisfied"}; FemtoUniverseTrackSelection trackCuts; - Configurable> ConfTrkCharge{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kSign, "ConfTrk"), std::vector{-1, 1}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kSign, "Track selection: ")}; - Configurable> ConfTrkPtmin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kpTMin, "ConfTrk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kpTMin, "Track selection: ")}; - Configurable> ConfTrkPtmax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kpTMax, "ConfTrk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kpTMax, "Track selection: ")}; - Configurable> ConfTrkEta{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kEtaMax, "ConfTrk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> ConfTrkTPCnclsMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCnClsMin, "ConfTrk"), std::vector{70.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCnClsMin, "Track selection: ")}; - Configurable> ConfTrkTPCfCls{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCfClsMin, "ConfTrk"), std::vector{0.83f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCfClsMin, "Track selection: ")}; - Configurable> ConfTrkTPCcRowsMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCcRowsMin, "ConfTrk"), std::vector{70.f, 60.f, 80.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCcRowsMin, "Track selection: ")}; - Configurable> ConfTrkTPCsCls{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCsClsMax, "ConfTrk"), std::vector{0.1f, 160.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCsClsMax, "Track selection: ")}; - Configurable> ConfTrkITSnclsMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kITSnClsMin, "ConfTrk"), std::vector{-1.f, 2.f, 4.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kITSnClsMin, "Track selection: ")}; - Configurable> ConfTrkITSnclsIbMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kITSnClsIbMin, "ConfTrk"), std::vector{-1.f, 1.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kITSnClsIbMin, "Track selection: ")}; - Configurable> ConfTrkDCAxyMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kDCAxyMax, "ConfTrk"), std::vector{0.1f, 3.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kDCAxyMax, "Track selection: ")}; - Configurable> ConfTrkDCAzMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kDCAzMax, "ConfTrk"), std::vector{0.2f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kDCAzMax, "Track selection: ")}; /// \todo Reintegrate PID to the general selection container - Configurable> ConfTrkPIDnSigmaMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kPIDnSigmaMax, "ConfTrk"), std::vector{3.5f, 3.f, 2.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kPIDnSigmaMax, "Track selection: ")}; - Configurable ConfTrkPIDnSigmaOffsetTPC{"ConfTrkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; - Configurable ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID (Pion=2, Kaon=3, Proton=4, Deuteron=5)"}; + Configurable> confTrkCharge{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kSign, "ConfTrk"), std::vector{-1, 1}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kSign, "Track selection: ")}; + Configurable> confTrkPtmin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kpTMin, "ConfTrk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kpTMin, "Track selection: ")}; + Configurable> confTrkPtmax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kpTMax, "ConfTrk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kpTMax, "Track selection: ")}; + Configurable> confTrkEta{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kEtaMax, "ConfTrk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kEtaMax, "Track selection: ")}; + Configurable> confTrkTPCnclsMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCnClsMin, "ConfTrk"), std::vector{70.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCnClsMin, "Track selection: ")}; + Configurable> confTrkTPCfCls{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCfClsMin, "ConfTrk"), std::vector{0.83f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCfClsMin, "Track selection: ")}; + Configurable> confTrkTPCcRowsMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCcRowsMin, "ConfTrk"), std::vector{70.f, 60.f, 80.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCcRowsMin, "Track selection: ")}; + Configurable> confTrkTPCsCls{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kTPCsClsMax, "ConfTrk"), std::vector{0.1f, 160.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kTPCsClsMax, "Track selection: ")}; + Configurable> confTrkITSnclsMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kITSnClsMin, "ConfTrk"), std::vector{-1.f, 2.f, 4.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kITSnClsMin, "Track selection: ")}; + Configurable> confTrkITSnclsIbMin{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kITSnClsIbMin, "ConfTrk"), std::vector{-1.f, 1.f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kITSnClsIbMin, "Track selection: ")}; + Configurable> confTrkDCAxyMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kDCAxyMax, "ConfTrk"), std::vector{0.1f, 3.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kDCAxyMax, "Track selection: ")}; + Configurable> confTrkDCAzMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kDCAzMax, "ConfTrk"), std::vector{0.2f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kDCAzMax, "Track selection: ")}; /// \todo Reintegrate PID to the general selection container + Configurable> confTrkPIDnSigmaMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kPIDnSigmaMax, "ConfTrk"), std::vector{3.5f, 3.f, 2.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kPIDnSigmaMax, "Track selection: ")}; + Configurable confTrkPIDnSigmaOffsetTPC{"confTrkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; + Configurable confTrkPIDnSigmaOffsetTOF{"confTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; + Configurable> confTrkPIDspecies{"confTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID (Pion=2, Kaon=3, Proton=4, Deuteron=5)"}; // Numbers from ~/alice/O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h //static constexpr ID Pion = 2; static constexpr ID Kaon = 3; static constexpr ID Proton = 4; static constexpr ID Deuteron = 5; - Configurable ConfTOFpTmin{"ConfTOFpTmin", 500, "TOF pT min"}; + Configurable confTOFpTmin{"confTOFpTmin", 500, "TOF pT min"}; // TrackSelection *o2PhysicsTrackSelection; /// \todo Labeled array (see Track-Track task) @@ -184,120 +184,123 @@ struct femtoUniverseProducerTask { // V0 FemtoUniverseV0Selection v0Cuts; struct : o2::framework::ConfigurableGroup { - Configurable ConfIsFillV0s{"ConfIsFillV0s", false, "Choice to fill V0s"}; - Configurable> ConfV0Sign{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0Sign, "ConfV0"), std::vector{-1, 1}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0Sign, "V0 selection: ")}; - Configurable> ConfV0PtMin{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0pTMin, "ConfV0"), std::vector{0.3f, 0.4f, 0.5f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0pTMin, "V0 selection: ")}; - Configurable> ConfV0PtMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0pTMax, "ConfV0"), std::vector{3.3f, 3.4f, 3.5f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0pTMax, "V0 selection: ")}; - Configurable> ConfV0EtaMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0etaMax, "ConfV0"), std::vector{0.8f, 0.7f, 0.9f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0etaMax, "V0 selection: ")}; - Configurable> ConfV0DCADaughMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0DCADaughMax, "ConfV0"), std::vector{1.2f, 1.5f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0DCADaughMax, "V0 selection: ")}; - Configurable> ConfV0CPAMin{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0CPAMin, "ConfV0"), std::vector{0.99f, 0.995f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0CPAMin, "V0 selection: ")}; - Configurable> ConfV0TranRadMin{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0TranRadMin, "ConfV0"), std::vector{0.2f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0TranRadMin, "V0 selection: ")}; - Configurable> ConfV0TranRadMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0TranRadMax, "ConfV0"), std::vector{100.f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0TranRadMax, "V0 selection: ")}; - Configurable> ConfV0DecVtxMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0DecVtxMax, "ConfV0"), std::vector{100.f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0DecVtxMax, "V0 selection: ")}; - - Configurable> ConfChildCharge{"ConfChildSign", std::vector{-1, 1}, "V0 Child sel: Charge"}; - Configurable> ConfChildEtaMax{"ConfChildEtaMax", std::vector{0.8f}, "V0 Child sel: max eta"}; - Configurable> ConfChildTPCnClsMin{"ConfChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "V0 Child sel: Min. nCls TPC"}; - Configurable> ConfChildDCAMin{"ConfChildDCAMin", std::vector{0.05f, 0.06f}, "V0 Child sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{5.f, 4.f}, "V0 Child sel: Max. PID nSigma TPC"}; - Configurable> ConfChildPIDspecies{"ConfChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "V0 Child sel: Particles species for PID"}; - - Configurable ConfV0InvMassLowLimit{"ConfV0InvV0MassLowLimit", 1.05, "Lower limit of the V0 invariant mass"}; - Configurable ConfV0InvMassUpLimit{"ConfV0InvV0MassUpLimit", 1.30, "Upper limit of the V0 invariant mass"}; - - Configurable ConfV0RejectKaons{"ConfV0RejectKaons", false, "Switch to reject kaons"}; - Configurable ConfV0InvKaonMassLowLimit{"ConfV0InvKaonMassLowLimit", 0.48, "Lower limit of the V0 invariant mass for Kaon rejection"}; - Configurable ConfV0InvKaonMassUpLimit{"ConfV0InvKaonMassUpLimit", 0.515, "Upper limit of the V0 invariant mass for Kaon rejection"}; + // Configurable confIsFillV0s{"confIsFillV0s", false, "Choice to fill V0s"}; //Commented: not used configurable + Configurable> confV0Sign{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0Sign, "ConfV0"), std::vector{-1, 1}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0Sign, "V0 selection: ")}; + Configurable> confV0PtMin{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0pTMin, "ConfV0"), std::vector{0.3f, 0.4f, 0.5f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0pTMin, "V0 selection: ")}; + Configurable> confV0PtMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0pTMax, "ConfV0"), std::vector{3.3f, 3.4f, 3.5f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0pTMax, "V0 selection: ")}; + Configurable> confV0EtaMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0etaMax, "ConfV0"), std::vector{0.8f, 0.7f, 0.9f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0etaMax, "V0 selection: ")}; + Configurable> confV0DCADaughMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0DCADaughMax, "ConfV0"), std::vector{1.2f, 1.5f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0DCADaughMax, "V0 selection: ")}; + Configurable> confV0CPAMin{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0CPAMin, "ConfV0"), std::vector{0.99f, 0.995f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0CPAMin, "V0 selection: ")}; + Configurable> confV0TranRadMin{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0TranRadMin, "ConfV0"), std::vector{0.2f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0TranRadMin, "V0 selection: ")}; + Configurable> confV0TranRadMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0TranRadMax, "ConfV0"), std::vector{100.f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0TranRadMax, "V0 selection: ")}; + Configurable> confV0DecVtxMax{FemtoUniverseV0Selection::getSelectionName(femtoUniverseV0Selection::kV0DecVtxMax, "ConfV0"), std::vector{100.f}, FemtoUniverseV0Selection::getSelectionHelper(femtoUniverseV0Selection::kV0DecVtxMax, "V0 selection: ")}; + + Configurable> confChildCharge{"confChildCharge", std::vector{-1, 1}, "V0 Child sel: Charge"}; + Configurable> confChildEtaMax{"confChildEtaMax", std::vector{0.8f}, "V0 Child sel: max eta"}; + Configurable> confChildTPCnClsMin{"confChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "V0 Child sel: Min. nCls TPC"}; + Configurable> confChildDCAMin{"confChildDCAMin", std::vector{0.05f, 0.06f}, "V0 Child sel: Max. DCA Daugh to PV (cm)"}; + Configurable> confChildPIDnSigmaMax{"confChildPIDnSigmaMax", std::vector{5.f, 4.f}, "V0 Child sel: Max. PID nSigma TPC"}; + Configurable> confChildPIDspecies{"confChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "V0 Child sel: Particles species for PID"}; + + Configurable confV0InvMassLowLimit{"confV0InvMassLowLimit", 1.05, "Lower limit of the V0 invariant mass"}; + Configurable confV0InvMassUpLimit{"confV0InvMassUpLimit", 1.30, "Upper limit of the V0 invariant mass"}; + + Configurable confV0RejectKaons{"confV0RejectKaons", false, "Switch to reject kaons"}; + Configurable confV0InvKaonMassLowLimit{"confV0InvKaonMassLowLimit", 0.48, "Lower limit of the V0 invariant mass for Kaon rejection"}; + Configurable confV0InvKaonMassUpLimit{"confV0InvKaonMassUpLimit", 0.515, "Upper limit of the V0 invariant mass for Kaon rejection"}; } ConfV0Selection; struct : o2::framework::ConfigurableGroup { - Configurable ConfPtLowFilterCut{"ConfPtLowFilterCut", 0.14, "Lower limit for Pt for the global track"}; // pT low - Configurable ConfPtHighFilterCut{"ConfPtHighFilterCut", 5.0, "Higher limit for Pt for the global track"}; // pT high - Configurable ConfEtaFilterCut{"ConfEtaFilterCut", 0.8, "Eta cut for the global track"}; // eta - Configurable ConfDxaXYCustom0Cut{"ConfDxaXYCustom0Cut", false, "Enable Custom Dcaxy < [0] cut."}; - Configurable ConfDcaXYFilterCut{"ConfDcaXYFilterCut", 2.4, "Value for DCA_XY for the global track"}; // max dca to vertex XY - Configurable ConfDcaZFilterCut{"ConfDcaZFilterCut", 3.2, "Value for DCA_Z for the global track"}; // max dca to vertex Z - Configurable ConfDcaXYCustom1Cut{"ConfDcaXYCustom1Cut", true, "Enable Custom |DCAxy| < [1] + [2]/pt cut."}; - Configurable ConfDcaXYCustom11FilterCut{"ConfDcaXY1FilterCut", 0.004, "Value for [1] custom DCAxy cut -> |DCAxy| < [1] + [2]/pT"}; - Configurable ConfDcaXYCustom12FilterCut{"ConfDcaXY2FilterCut", 0.013, "Value for [2] custom DCAxy cut -> |DCAxy| < [1] + [2]/pT"}; + Configurable confPtLowFilterCut{"confPtLowFilterCut", 0.14, "Lower limit for Pt for the global track"}; // pT low + Configurable confPtHighFilterCut{"confPtHighFilterCut", 5.0, "Higher limit for Pt for the global track"}; // pT high + Configurable confEtaFilterCut{"confEtaFilterCut", 0.8, "Eta cut for the global track"}; // eta + Configurable confDxaXYCustom0Cut{"confDxaXYCustom0Cut", false, "Enable Custom Dcaxy < [0] cut."}; + Configurable confDcaXYFilterCut{"confDcaXYFilterCut", 2.4, "Value for DCA_XY for the global track"}; // max dca to vertex XY + Configurable confDcaZFilterCut{"confDcaZFilterCut", 3.2, "Value for DCA_Z for the global track"}; // max dca to vertex Z + Configurable confDcaXYCustom1Cut{"confDcaXYCustom1Cut", true, "Enable Custom |DCAxy| < [1] + [2]/pt cut."}; + Configurable confDcaXYCustom11FilterCut{"confDcaXYCustom11FilterCut", 0.004, "Value for [1] custom DCAxy cut -> |DCAxy| < [1] + [2]/pT"}; + Configurable confDcaXYCustom12FilterCut{"confDcaXYCustom12FilterCut", 0.013, "Value for [2] custom DCAxy cut -> |DCAxy| < [1] + [2]/pT"}; } ConfFilterCuts; - Filter GlobalCutFilter = requireGlobalTrackInFilter(); - Filter CustomTrackFilter = (aod::track::pt > ConfFilterCuts.ConfPtLowFilterCut) && - (aod::track::pt < ConfFilterCuts.ConfPtHighFilterCut) && - (nabs(aod::track::eta) < ConfFilterCuts.ConfEtaFilterCut) && - (!ConfFilterCuts.ConfDxaXYCustom0Cut || (aod::track::dcaXY < ConfFilterCuts.ConfDcaXYFilterCut)) && // true if configurable set to false or if configurable is true and it passes the selection - (aod::track::dcaZ < ConfFilterCuts.ConfDcaZFilterCut) && - (!ConfFilterCuts.ConfDcaXYCustom1Cut || (nabs(aod::track::dcaXY) < ConfFilterCuts.ConfDcaXYCustom11FilterCut + ConfFilterCuts.ConfDcaXYCustom12FilterCut / aod::track::pt)); // same logic here + Filter globalCutFilter = requireGlobalTrackInFilter(); + Filter customTrackFilter = (aod::track::pt > ConfFilterCuts.confPtLowFilterCut) && + (aod::track::pt < ConfFilterCuts.confPtHighFilterCut) && + (nabs(aod::track::eta) < ConfFilterCuts.confEtaFilterCut) && + (!ConfFilterCuts.confDxaXYCustom0Cut || (aod::track::dcaXY < ConfFilterCuts.confDcaXYFilterCut)) && // true if configurable set to false or if configurable is true and it passes the selection + (aod::track::dcaZ < ConfFilterCuts.confDcaZFilterCut) && + (!ConfFilterCuts.confDcaXYCustom1Cut || (nabs(aod::track::dcaXY) < ConfFilterCuts.confDcaXYCustom11FilterCut + ConfFilterCuts.confDcaXYCustom12FilterCut / aod::track::pt)); // same logic here // CASCADE FemtoUniverseCascadeSelection cascadeCuts; struct : o2::framework::ConfigurableGroup { - Configurable ConfIsFillCascades{"ConfIsFillCascades", false, "Choice to fill cascades"}; - Configurable> ConfCascSign{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeSign, "ConfCasc"), std::vector{-1, 1}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeSign, "Cascade selection: ")}; - Configurable> ConfCascPtMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadepTMin, "ConfCasc"), std::vector{0.3f, 0.4f, 0.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadepTMin, "Cascade selection: ")}; - Configurable> ConfCascPtMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadepTMax, "ConfCasc"), std::vector{3.3f, 3.4f, 3.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadepTMax, "Cascade selection: ")}; - Configurable> ConfCascEtaMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeetaMax, "ConfCasc"), std::vector{0.8f, 0.7f, 0.9f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeetaMax, "Cascade selection: ")}; - Configurable> ConfCascV0DCADaughMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0DCADaughMax, "ConfCasc"), std::vector{1.f, 1.2f, 1.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0DCADaughMax, "Cascade selection: ")}; - Configurable> ConfCascV0CPAMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0CPAMin, "ConfCasc"), std::vector{0.99f, 0.95f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0CPAMin, "Cascade selection: ")}; - Configurable> ConfCascV0TranRadMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0TranRadMin, "ConfCasc"), std::vector{0.2f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0TranRadMin, "Cascade selection: ")}; - Configurable> ConfCascV0TranRadMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0TranRadMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0TranRadMax, "Cascade selection: ")}; - Configurable> ConfCascV0DecVtxMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0DecVtxMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0DecVtxMax, "Cascade selection: ")}; - Configurable> ConfCascDCADaughMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCADaughMax, "ConfCasc"), std::vector{1.f, 1.2f, 1.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCADaughMax, "Cascade selection: ")}; - Configurable> ConfCascCPAMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeCPAMin, "ConfCasc"), std::vector{0.99f, 0.95f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeCPAMin, "Cascade selection: ")}; - Configurable> ConfCascTranRadMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeTranRadMin, "ConfCasc"), std::vector{0.2f, 0.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeTranRadMin, "Cascade selection: ")}; - Configurable> ConfCascTranRadMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeTranRadMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeTranRadMax, "Cascade selection: ")}; - Configurable> ConfCascDecVtxMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDecVtxMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDecVtxMax, "Cascade selection: ")}; - - Configurable> ConfCascDCAPosToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCAPosToPV, "ConfCasc"), std::vector{0.1f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCAPosToPV, "Cascade selection: ")}; - Configurable> ConfCascDCANegToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCANegToPV, "ConfCasc"), std::vector{0.1f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCANegToPV, "Cascade selection: ")}; - Configurable> ConfCascDCABachToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCABachToPV, "ConfCasc"), std::vector{0.1f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCABachToPV, "Cascade selection: ")}; - Configurable> ConfCascDCAV0ToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCAV0ToPV, "ConfCasc"), std::vector{0.01f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCAV0ToPV, "Cascade selection: ")}; - Configurable> ConfCascV0MassLowLimit{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0MassMin, "ConfCasc"), std::vector{1.05f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0MassMin, "Cascade selection: ")}; - Configurable> ConfCascV0MassUpLimit{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0MassMax, "ConfCasc"), std::vector{1.30f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0MassMax, "Cascade selection: ")}; - - Configurable> ConfCascChildCharge{"ConfCascChildSign", std::vector{-1, 1}, "Cascade Child sel: Charge"}; - Configurable> ConfCascChildEtaMax{"ConfCascChildEtaMax", std::vector{0.8f}, "Cascade Child sel: max eta"}; - Configurable> ConfCascChildTPCnClsMin{"ConfCascChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "Cascade Child sel: Min. nCls TPC"}; - // Configurable> ConfCascChildDCAMin{"ConfCascChildDCAMin", std::vector{0.05f, 0.06f}, "Cascade Child sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfCascChildPIDnSigmaMax{"ConfCascChildPIDnSigmaMax", std::vector{3.f, 4.f}, "Cascade Child sel: Max. PID nSigma TPC"}; - Configurable> ConfCascChildPIDspecies{"ConfCascChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "Cascade Child sel: particle species for PID"}; - - Configurable ConfCascInvMassLowLimit{"ConfCascInvMassLowLimit", 1.25, "Lower limit of the cascade invariant mass"}; - Configurable ConfCascInvMassUpLimit{"ConfCascInvMassUpLimit", 1.40, "Upper limit of the cascade invariant mass"}; - - Configurable ConfCascRejectCompetingMass{"ConfCascRejectCompetingMass", false, "Switch on to reject Omegas (for Xi) or Xis (for Omegas)"}; - Configurable ConfCascInvCompetingMassLowLimit{"ConfCascInvCompetingMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for competing mass rejection"}; - Configurable ConfCascInvCompetingMassUpLimit{"ConfCascInvCompetingMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for competing mass rejection"}; + // Configurable confIsFillCascades{"confIsFillCascades", false, "Choice to fill cascades"}; //Commented: not used configurable + Configurable> confCascSign{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeSign, "ConfCasc"), std::vector{-1, 1}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeSign, "Cascade selection: ")}; + Configurable> confCascPtMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadepTMin, "ConfCasc"), std::vector{0.3f, 0.4f, 0.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadepTMin, "Cascade selection: ")}; + Configurable> confCascPtMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadepTMax, "ConfCasc"), std::vector{3.3f, 3.4f, 3.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadepTMax, "Cascade selection: ")}; + Configurable> confCascEtaMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeetaMax, "ConfCasc"), std::vector{0.8f, 0.7f, 0.9f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeetaMax, "Cascade selection: ")}; + Configurable> confCascV0DCADaughMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0DCADaughMax, "ConfCasc"), std::vector{1.f, 1.2f, 1.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0DCADaughMax, "Cascade selection: ")}; + Configurable> confCascV0CPAMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0CPAMin, "ConfCasc"), std::vector{0.99f, 0.95f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0CPAMin, "Cascade selection: ")}; + Configurable> confCascV0TranRadMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0TranRadMin, "ConfCasc"), std::vector{0.2f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0TranRadMin, "Cascade selection: ")}; + Configurable> confCascV0TranRadMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0TranRadMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0TranRadMax, "Cascade selection: ")}; + Configurable> confCascV0DecVtxMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0DecVtxMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0DecVtxMax, "Cascade selection: ")}; + Configurable> confCascDCADaughMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCADaughMax, "ConfCasc"), std::vector{1.f, 1.2f, 1.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCADaughMax, "Cascade selection: ")}; + Configurable> confCascCPAMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeCPAMin, "ConfCasc"), std::vector{0.99f, 0.95f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeCPAMin, "Cascade selection: ")}; + Configurable> confCascTranRadMin{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeTranRadMin, "ConfCasc"), std::vector{0.2f, 0.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeTranRadMin, "Cascade selection: ")}; + Configurable> confCascTranRadMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeTranRadMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeTranRadMax, "Cascade selection: ")}; + Configurable> confCascDecVtxMax{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDecVtxMax, "ConfCasc"), std::vector{100.f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDecVtxMax, "Cascade selection: ")}; + + Configurable> confCascDCAPosToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCAPosToPV, "ConfCasc"), std::vector{0.1f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCAPosToPV, "Cascade selection: ")}; + Configurable> confCascDCANegToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCANegToPV, "ConfCasc"), std::vector{0.1f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCANegToPV, "Cascade selection: ")}; + Configurable> confCascDCABachToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCABachToPV, "ConfCasc"), std::vector{0.1f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCABachToPV, "Cascade selection: ")}; + Configurable> confCascDCAV0ToPV{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeDCAV0ToPV, "ConfCasc"), std::vector{0.01f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeDCAV0ToPV, "Cascade selection: ")}; + Configurable> confCascV0MassLowLimit{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0MassMin, "ConfCasc"), std::vector{1.05f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0MassMin, "Cascade selection: ")}; + Configurable> confCascV0MassUpLimit{FemtoUniverseCascadeSelection::getSelectionName(femtoUniverseCascadeSelection::kCascadeV0MassMax, "ConfCasc"), std::vector{1.30f}, FemtoUniverseCascadeSelection::getSelectionHelper(femtoUniverseCascadeSelection::kCascadeV0MassMax, "Cascade selection: ")}; + + Configurable> confCascChildCharge{"confCascChildCharge", std::vector{-1, 1}, "Cascade Child sel: Charge"}; + Configurable> confCascChildEtaMax{"confCascChildEtaMax", std::vector{0.8f}, "Cascade Child sel: max eta"}; + Configurable> confCascChildTPCnClsMin{"confCascChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "Cascade Child sel: Min. nCls TPC"}; + // Configurable> confCascChildDCAMin{"confCascChildDCAMin", std::vector{0.05f, 0.06f}, "Cascade Child sel: Max. DCA Daugh to PV (cm)"}; //Commented: not used variable + Configurable> confCascChildPIDnSigmaMax{"confCascChildPIDnSigmaMax", std::vector{3.f, 4.f}, "Cascade Child sel: Max. PID nSigma TPC"}; + Configurable> confCascChildPIDspecies{"confCascChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "Cascade Child sel: particle species for PID"}; + + Configurable confCascInvMassLowLimit{"confCascInvMassLowLimit", 1.25, "Lower limit of the cascade invariant mass"}; + Configurable confCascInvMassUpLimit{"confCascInvMassUpLimit", 1.40, "Upper limit of the cascade invariant mass"}; + + Configurable confCascRejectCompetingMass{"confCascRejectCompetingMass", false, "Switch on to reject Omegas (for Xi) or Xis (for Omegas)"}; + Configurable confCascInvCompetingMassLowLimit{"confCascInvCompetingMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for competing mass rejection"}; + Configurable confCascInvCompetingMassUpLimit{"confCascInvCompetingMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for competing mass rejection"}; } ConfCascadeSelection; // PHI FemtoUniversePhiSelection phiCuts; struct : o2::framework::ConfigurableGroup { - Configurable ConfLooseTPCNSigma{"ConfLooseTPCNSigma", false, "Use loose TPC N sigmas for Kaon PID."}; - Configurable ConfLooseTPCNSigmaValue{"ConfLooseTPCNSigmaValue", 10, "Value for the loose TPC N Sigma for Kaon PID."}; - Configurable ConfLooseTOFNSigma{"ConfLooseTOFNSigma", false, "Use loose TPC N sigmas for Kaon PID."}; - Configurable ConfLooseTOFNSigmaValue{"ConfLooseTOFNSigmaValue", 10, "Value for the loose TOF N Sigma for Kaon PID."}; - Configurable ConfInvMassLowLimitPhi{"ConfInvMassLowLimitPhi", 1.011, "Lower limit of the Phi invariant mass"}; // change that to do invariant mass cut - Configurable ConfInvMassUpLimitPhi{"ConfInvMassUpLimitPhi", 1.027, "Upper limit of the Phi invariant mass"}; - Configurable ConfPtLowLimitPhi{"ConfPtLowLimitPhi", 0.8, "Lower limit of the Phi pT."}; - Configurable ConfPtHighLimitPhi{"ConfPtHighLimitPhi", 4.0, "Higher limit of the Phi pT."}; - Configurable ConfNsigmaRejectPion{"ConfNsigmaRejectPion", 3.0, "Reject if particle could be a Pion combined nsigma value."}; - Configurable ConfNsigmaRejectProton{"ConfNsigmaRejectProton", 3.0, "Reject if particle could be a Proton combined nsigma value."}; + /// Phi meson + Configurable confInvMassLowLimitPhi{"confInvMassLowLimitPhi", 1.011, "Lower limit of the Phi invariant mass"}; // change that to do invariant mass cut + Configurable confInvMassUpLimitPhi{"confInvMassUpLimitPhi", 1.027, "Upper limit of the Phi invariant mass"}; + Configurable confPtLowLimitPhi{"confPtLowLimitPhi", 0.8, "Lower limit of the Phi pT."}; + Configurable confPtHighLimitPhi{"confPtHighLimitPhi", 4.0, "Higher limit of the Phi pT."}; + // Phi meson daughters + Configurable confLooseTPCNSigma{"confLooseTPCNSigma", false, "Use loose TPC N sigmas for Kaon PID."}; + Configurable confLooseTPCNSigmaValue{"confLooseTPCNSigmaValue", 10, "Value for the loose TPC N Sigma for Kaon PID."}; + Configurable confLooseTOFNSigma{"confLooseTOFNSigma", false, "Use loose TPC N sigmas for Kaon PID."}; + Configurable confNsigmaRejectPion{"confNsigmaRejectPion", 3.0, "Reject if particle could be a Pion combined nsigma value."}; + Configurable confNsigmaRejectProton{"confNsigmaRejectProton", 3.0, "Reject if particle could be a Proton combined nsigma value."}; + Configurable confLooseTOFNSigmaValue{"confLooseTOFNSigmaValue", 10, "Value for the loose TOF N Sigma for Kaon PID."}; } ConfPhiSelection; - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 321, "Particle 1 - PDG code"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 321, "Particle 2 - PDG code"}; + // PDG codes for fillMCParticle function + Configurable confPDGCodePartOne{"confPDGCodePartOne", 321, "Particle 1 - PDG code"}; + Configurable confPDGCodePartTwo{"confPDGCodePartTwo", 321, "Particle 2 - PDG code"}; // D0/D0bar mesons struct : o2::framework::ConfigurableGroup { - Configurable ConfD0D0barCandMaxY{"ConfD0D0barCandMaxY", -1., "max. cand. rapidity"}; - Configurable ConfD0D0barCandEtaCut{"ConfD0D0barCandEtaCut", 0.8, "max. cand. pseudorapidity"}; + Configurable confD0D0barCandMaxY{"confD0D0barCandMaxY", -1., "max. cand. rapidity"}; + Configurable confD0D0barCandEtaCut{"confD0D0barCandEtaCut", 0.8, "max. cand. pseudorapidity"}; } ConfD0Selection; HfHelper hfHelper; - bool IsKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) + bool isKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) { if (mom < 0.3) { // 0.0-0.3 @@ -337,35 +340,35 @@ struct femtoUniverseProducerTask { } } - bool IsKaonNSigmaTPCLoose(float mom, float nsigmaTPCK, float nsigmaTOFK) + bool isKaonNSigmaTPCLoose(float mom, float nsigmaTPCK, float nsigmaTOFK) { if (mom < 0.3) { // 0.0-0.3 - if (std::abs(nsigmaTPCK) < ConfPhiSelection.ConfLooseTPCNSigmaValue.value) { + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confLooseTPCNSigmaValue.value) { return true; } else { return false; } } else if (mom < 0.45) { // 0.30 - 0.45 - if (std::abs(nsigmaTPCK) < ConfPhiSelection.ConfLooseTPCNSigmaValue.value) { + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confLooseTPCNSigmaValue.value) { return true; } else { return false; } } else if (mom < 0.55) { // 0.45-0.55 - if (std::abs(nsigmaTPCK) < ConfPhiSelection.ConfLooseTPCNSigmaValue.value) { + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confLooseTPCNSigmaValue.value) { return true; } else { return false; } } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) - if ((std::abs(nsigmaTOFK) < 3.0) && (std::abs(nsigmaTPCK) < ConfPhiSelection.ConfLooseTPCNSigmaValue.value)) { + if ((std::abs(nsigmaTOFK) < 3.0) && (std::abs(nsigmaTPCK) < ConfPhiSelection.confLooseTPCNSigmaValue.value)) { return true; } else { return false; } } else if (mom > 1.5) { // 1.5 - - if ((std::abs(nsigmaTOFK) < 2.0) && (std::abs(nsigmaTPCK) < ConfPhiSelection.ConfLooseTPCNSigmaValue.value)) { + if ((std::abs(nsigmaTOFK) < 2.0) && (std::abs(nsigmaTPCK) < ConfPhiSelection.confLooseTPCNSigmaValue.value)) { return true; } else { return false; @@ -375,7 +378,7 @@ struct femtoUniverseProducerTask { } } - bool IsKaonNSigmaTOFLoose(float mom, float nsigmaTPCK, float nsigmaTOFK) + bool isKaonNSigmaTOFLoose(float mom, float nsigmaTPCK, float nsigmaTOFK) { if (mom < 0.3) { // 0.0-0.3 if (std::abs(nsigmaTPCK) < 3.0) { @@ -396,7 +399,7 @@ struct femtoUniverseProducerTask { return false; } } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) - if ((std::abs(nsigmaTOFK) < ConfPhiSelection.ConfLooseTOFNSigmaValue.value) && (std::abs(nsigmaTPCK) < 3.0)) { + if ((std::abs(nsigmaTOFK) < ConfPhiSelection.confLooseTOFNSigmaValue.value) && (std::abs(nsigmaTPCK) < 3.0)) { { return true; } @@ -404,7 +407,7 @@ struct femtoUniverseProducerTask { return false; } } else if (mom > 1.5) { // 1.5 - - if ((std::abs(nsigmaTOFK) < ConfPhiSelection.ConfLooseTOFNSigmaValue.value) && (std::abs(nsigmaTPCK) < 3.0)) { + if ((std::abs(nsigmaTOFK) < ConfPhiSelection.confLooseTOFNSigmaValue.value) && (std::abs(nsigmaTPCK) < 3.0)) { return true; } else { return false; @@ -414,19 +417,19 @@ struct femtoUniverseProducerTask { } } - bool IsKaonRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi) + bool isKaonRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi) { if (mom < 0.5) { - if (std::abs(nsigmaTPCPi) < ConfPhiSelection.ConfNsigmaRejectPion.value) { + if (std::abs(nsigmaTPCPi) < ConfPhiSelection.confNsigmaRejectPion.value) { return true; - } else if (std::abs(nsigmaTPCPr) < ConfPhiSelection.ConfNsigmaRejectProton.value) { + } else if (std::abs(nsigmaTPCPr) < ConfPhiSelection.confNsigmaRejectProton.value) { return true; } } if (mom > 0.5) { - if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfPhiSelection.ConfNsigmaRejectPion.value) { + if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfPhiSelection.confNsigmaRejectPion.value) { return true; - } else if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfPhiSelection.ConfNsigmaRejectProton.value) { + } else if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfPhiSelection.confNsigmaRejectProton.value) { return true; } else { return false; @@ -462,65 +465,65 @@ struct femtoUniverseProducerTask { "Please choose one."); } - colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3, ConfCentFT0Min, ConfCentFT0Max); + colCuts.setCuts(confEvtZvtx, confEvtTriggerCheck, confEvtTriggerSel, confEvtOfflineCheck, confIsRun3, confCentFT0Min, confCentFT0Max); colCuts.init(&qaRegistry); - trackCuts.setSelection(ConfTrkCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); - trackCuts.setSelection(ConfTrkPtmin, femtoUniverseTrackSelection::kpTMin, femtoUniverseSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkPtmax, femtoUniverseTrackSelection::kpTMax, femtoUniverseSelection::kUpperLimit); - trackCuts.setSelection(ConfTrkEta, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); - trackCuts.setSelection(ConfTrkTPCnclsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkTPCfCls, femtoUniverseTrackSelection::kTPCfClsMin, femtoUniverseSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkTPCcRowsMin, femtoUniverseTrackSelection::kTPCcRowsMin, femtoUniverseSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkTPCsCls, femtoUniverseTrackSelection::kTPCsClsMax, femtoUniverseSelection::kUpperLimit); - trackCuts.setSelection(ConfTrkITSnclsMin, femtoUniverseTrackSelection::kITSnClsMin, femtoUniverseSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkITSnclsIbMin, femtoUniverseTrackSelection::kITSnClsIbMin, femtoUniverseSelection::kLowerLimit); - trackCuts.setSelection(ConfTrkDCAxyMax, femtoUniverseTrackSelection::kDCAxyMax, femtoUniverseSelection::kAbsUpperLimit); - trackCuts.setSelection(ConfTrkDCAzMax, femtoUniverseTrackSelection::kDCAzMax, femtoUniverseSelection::kAbsUpperLimit); - trackCuts.setSelection(ConfTrkPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); - trackCuts.setPIDSpecies(ConfTrkPIDspecies); - trackCuts.setnSigmaPIDOffset(ConfTrkPIDnSigmaOffsetTPC, ConfTrkPIDnSigmaOffsetTOF); + trackCuts.setSelection(confTrkCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); + trackCuts.setSelection(confTrkPtmin, femtoUniverseTrackSelection::kpTMin, femtoUniverseSelection::kLowerLimit); + trackCuts.setSelection(confTrkPtmax, femtoUniverseTrackSelection::kpTMax, femtoUniverseSelection::kUpperLimit); + trackCuts.setSelection(confTrkEta, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); + trackCuts.setSelection(confTrkTPCnclsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); + trackCuts.setSelection(confTrkTPCfCls, femtoUniverseTrackSelection::kTPCfClsMin, femtoUniverseSelection::kLowerLimit); + trackCuts.setSelection(confTrkTPCcRowsMin, femtoUniverseTrackSelection::kTPCcRowsMin, femtoUniverseSelection::kLowerLimit); + trackCuts.setSelection(confTrkTPCsCls, femtoUniverseTrackSelection::kTPCsClsMax, femtoUniverseSelection::kUpperLimit); + trackCuts.setSelection(confTrkITSnclsMin, femtoUniverseTrackSelection::kITSnClsMin, femtoUniverseSelection::kLowerLimit); + trackCuts.setSelection(confTrkITSnclsIbMin, femtoUniverseTrackSelection::kITSnClsIbMin, femtoUniverseSelection::kLowerLimit); + trackCuts.setSelection(confTrkDCAxyMax, femtoUniverseTrackSelection::kDCAxyMax, femtoUniverseSelection::kAbsUpperLimit); + trackCuts.setSelection(confTrkDCAzMax, femtoUniverseTrackSelection::kDCAzMax, femtoUniverseSelection::kAbsUpperLimit); + trackCuts.setSelection(confTrkPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); + trackCuts.setPIDSpecies(confTrkPIDspecies); + trackCuts.setnSigmaPIDOffset(confTrkPIDnSigmaOffsetTPC, confTrkPIDnSigmaOffsetTOF); trackCuts.init(&qaRegistry); /// \todo fix how to pass array to setSelection, getRow() passing a /// different type! // v0Cuts.setSelection(ConfV0Selection->getRow(0), // femtoUniverseV0Selection::kDecVtxMax, femtoUniverseSelection::kAbsUpperLimit); - if (ConfIsActivateV0) { + if (confIsActivateV0) { // initializing for V0 - v0Cuts.setSelection(ConfV0Selection.ConfV0Sign, femtoUniverseV0Selection::kV0Sign, femtoUniverseSelection::kEqual); - v0Cuts.setSelection(ConfV0Selection.ConfV0PtMin, femtoUniverseV0Selection::kV0pTMin, femtoUniverseSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0PtMax, femtoUniverseV0Selection::kV0pTMax, femtoUniverseSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0EtaMax, femtoUniverseV0Selection::kV0etaMax, femtoUniverseSelection::kAbsUpperLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0DCADaughMax, femtoUniverseV0Selection::kV0DCADaughMax, femtoUniverseSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0CPAMin, femtoUniverseV0Selection::kV0CPAMin, femtoUniverseSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0TranRadMin, femtoUniverseV0Selection::kV0TranRadMin, femtoUniverseSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0TranRadMax, femtoUniverseV0Selection::kV0TranRadMax, femtoUniverseSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0Selection.ConfV0DecVtxMax, femtoUniverseV0Selection::kV0DecVtxMax, femtoUniverseSelection::kUpperLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.ConfChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.ConfChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.ConfChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.ConfChildDCAMin, femtoUniverseTrackSelection::kDCAMin, femtoUniverseSelection::kAbsLowerLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.ConfChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.ConfChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.ConfChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.ConfChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.ConfChildDCAMin, femtoUniverseTrackSelection::kDCAMin, femtoUniverseSelection::kAbsLowerLimit); - v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.ConfChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); - v0Cuts.setChildPIDSpecies(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.ConfChildPIDspecies); - v0Cuts.setChildPIDSpecies(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.ConfChildPIDspecies); + v0Cuts.setSelection(ConfV0Selection.confV0Sign, femtoUniverseV0Selection::kV0Sign, femtoUniverseSelection::kEqual); + v0Cuts.setSelection(ConfV0Selection.confV0PtMin, femtoUniverseV0Selection::kV0pTMin, femtoUniverseSelection::kLowerLimit); + v0Cuts.setSelection(ConfV0Selection.confV0PtMax, femtoUniverseV0Selection::kV0pTMax, femtoUniverseSelection::kUpperLimit); + v0Cuts.setSelection(ConfV0Selection.confV0EtaMax, femtoUniverseV0Selection::kV0etaMax, femtoUniverseSelection::kAbsUpperLimit); + v0Cuts.setSelection(ConfV0Selection.confV0DCADaughMax, femtoUniverseV0Selection::kV0DCADaughMax, femtoUniverseSelection::kUpperLimit); + v0Cuts.setSelection(ConfV0Selection.confV0CPAMin, femtoUniverseV0Selection::kV0CPAMin, femtoUniverseSelection::kLowerLimit); + v0Cuts.setSelection(ConfV0Selection.confV0TranRadMin, femtoUniverseV0Selection::kV0TranRadMin, femtoUniverseSelection::kLowerLimit); + v0Cuts.setSelection(ConfV0Selection.confV0TranRadMax, femtoUniverseV0Selection::kV0TranRadMax, femtoUniverseSelection::kUpperLimit); + v0Cuts.setSelection(ConfV0Selection.confV0DecVtxMax, femtoUniverseV0Selection::kV0DecVtxMax, femtoUniverseSelection::kUpperLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.confChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.confChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.confChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.confChildDCAMin, femtoUniverseTrackSelection::kDCAMin, femtoUniverseSelection::kAbsLowerLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.confChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.confChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.confChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.confChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.confChildDCAMin, femtoUniverseTrackSelection::kDCAMin, femtoUniverseSelection::kAbsLowerLimit); + v0Cuts.setChildCuts(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.confChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); + v0Cuts.setChildPIDSpecies(femtoUniverseV0Selection::kPosTrack, ConfV0Selection.confChildPIDspecies); + v0Cuts.setChildPIDSpecies(femtoUniverseV0Selection::kNegTrack, ConfV0Selection.confChildPIDspecies); v0Cuts.init(&qaRegistry); - v0Cuts.setInvMassLimits(ConfV0Selection.ConfV0InvMassLowLimit, ConfV0Selection.ConfV0InvMassUpLimit); + v0Cuts.setInvMassLimits(ConfV0Selection.confV0InvMassLowLimit, ConfV0Selection.confV0InvMassUpLimit); - v0Cuts.setChildRejectNotPropagatedTracks(femtoUniverseV0Selection::kPosTrack, ConfTrkRejectNotPropagated); - v0Cuts.setChildRejectNotPropagatedTracks(femtoUniverseV0Selection::kNegTrack, ConfTrkRejectNotPropagated); + v0Cuts.setChildRejectNotPropagatedTracks(femtoUniverseV0Selection::kPosTrack, confTrkRejectNotPropagated); + v0Cuts.setChildRejectNotPropagatedTracks(femtoUniverseV0Selection::kNegTrack, confTrkRejectNotPropagated); - v0Cuts.setnSigmaPIDOffsetTPC(ConfTrkPIDnSigmaOffsetTPC); - v0Cuts.setChildnSigmaPIDOffset(femtoUniverseV0Selection::kPosTrack, ConfTrkPIDnSigmaOffsetTPC, ConfTrkPIDnSigmaOffsetTOF); - v0Cuts.setChildnSigmaPIDOffset(femtoUniverseV0Selection::kNegTrack, ConfTrkPIDnSigmaOffsetTPC, ConfTrkPIDnSigmaOffsetTOF); + v0Cuts.setnSigmaPIDOffsetTPC(confTrkPIDnSigmaOffsetTPC); + v0Cuts.setChildnSigmaPIDOffset(femtoUniverseV0Selection::kPosTrack, confTrkPIDnSigmaOffsetTPC, confTrkPIDnSigmaOffsetTOF); + v0Cuts.setChildnSigmaPIDOffset(femtoUniverseV0Selection::kNegTrack, confTrkPIDnSigmaOffsetTPC, confTrkPIDnSigmaOffsetTOF); - if (ConfV0Selection.ConfV0RejectKaons) { - v0Cuts.setKaonInvMassLimits(ConfV0Selection.ConfV0InvKaonMassLowLimit, ConfV0Selection.ConfV0InvKaonMassUpLimit); + if (ConfV0Selection.confV0RejectKaons) { + v0Cuts.setKaonInvMassLimits(ConfV0Selection.confV0InvKaonMassLowLimit, ConfV0Selection.confV0InvKaonMassUpLimit); } // if (ConfRejectITSHitandTOFMissing) { // o2PhysicsTrackSelection = new @@ -529,60 +532,60 @@ struct femtoUniverseProducerTask { // } } - if (ConfIsActivateCascade) { + if (confIsActivateCascade) { // initializing for cascades - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascSign, femtoUniverseCascadeSelection::kCascadeSign, femtoUniverseSelection::kEqual); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascPtMin, femtoUniverseCascadeSelection::kCascadepTMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascPtMax, femtoUniverseCascadeSelection::kCascadepTMax, femtoUniverseSelection::kUpperLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascEtaMax, femtoUniverseCascadeSelection::kCascadeetaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascSign, femtoUniverseCascadeSelection::kCascadeSign, femtoUniverseSelection::kEqual); + cascadeCuts.setSelection(ConfCascadeSelection.confCascPtMin, femtoUniverseCascadeSelection::kCascadepTMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascPtMax, femtoUniverseCascadeSelection::kCascadepTMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascEtaMax, femtoUniverseCascadeSelection::kCascadeetaMax, femtoUniverseSelection::kAbsUpperLimit); // v0 child cuts - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0DCADaughMax, femtoUniverseCascadeSelection::kCascadeV0DCADaughMax, femtoUniverseSelection::kUpperLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0CPAMin, femtoUniverseCascadeSelection::kCascadeV0CPAMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0TranRadMin, femtoUniverseCascadeSelection::kCascadeV0TranRadMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0TranRadMax, femtoUniverseCascadeSelection::kCascadeV0TranRadMax, femtoUniverseSelection::kUpperLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0DecVtxMax, femtoUniverseCascadeSelection::kCascadeV0DecVtxMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0DCADaughMax, femtoUniverseCascadeSelection::kCascadeV0DCADaughMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0CPAMin, femtoUniverseCascadeSelection::kCascadeV0CPAMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0TranRadMin, femtoUniverseCascadeSelection::kCascadeV0TranRadMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0TranRadMax, femtoUniverseCascadeSelection::kCascadeV0TranRadMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0DecVtxMax, femtoUniverseCascadeSelection::kCascadeV0DecVtxMax, femtoUniverseSelection::kUpperLimit); // cascade cuts - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascDCADaughMax, femtoUniverseCascadeSelection::kCascadeDCADaughMax, femtoUniverseSelection::kUpperLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascCPAMin, femtoUniverseCascadeSelection::kCascadeCPAMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascTranRadMin, femtoUniverseCascadeSelection::kCascadeTranRadMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascTranRadMax, femtoUniverseCascadeSelection::kCascadeTranRadMax, femtoUniverseSelection::kUpperLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascDecVtxMax, femtoUniverseCascadeSelection::kCascadeDecVtxMax, femtoUniverseSelection::kUpperLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascDCAPosToPV, femtoUniverseCascadeSelection::kCascadeDCAPosToPV, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascDCANegToPV, femtoUniverseCascadeSelection::kCascadeDCANegToPV, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascDCABachToPV, femtoUniverseCascadeSelection::kCascadeDCABachToPV, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascDCAV0ToPV, femtoUniverseCascadeSelection::kCascadeDCAV0ToPV, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0MassLowLimit, femtoUniverseCascadeSelection::kCascadeV0MassMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setSelection(ConfCascadeSelection.ConfCascV0MassUpLimit, femtoUniverseCascadeSelection::kCascadeV0MassMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascDCADaughMax, femtoUniverseCascadeSelection::kCascadeDCADaughMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascCPAMin, femtoUniverseCascadeSelection::kCascadeCPAMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascTranRadMin, femtoUniverseCascadeSelection::kCascadeTranRadMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascTranRadMax, femtoUniverseCascadeSelection::kCascadeTranRadMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascDecVtxMax, femtoUniverseCascadeSelection::kCascadeDecVtxMax, femtoUniverseSelection::kUpperLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascDCAPosToPV, femtoUniverseCascadeSelection::kCascadeDCAPosToPV, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascDCANegToPV, femtoUniverseCascadeSelection::kCascadeDCANegToPV, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascDCABachToPV, femtoUniverseCascadeSelection::kCascadeDCABachToPV, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascDCAV0ToPV, femtoUniverseCascadeSelection::kCascadeDCAV0ToPV, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0MassLowLimit, femtoUniverseCascadeSelection::kCascadeV0MassMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setSelection(ConfCascadeSelection.confCascV0MassUpLimit, femtoUniverseCascadeSelection::kCascadeV0MassMax, femtoUniverseSelection::kUpperLimit); // children cuts - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.ConfCascChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.ConfCascChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.ConfCascChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.ConfCascChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.ConfCascChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.ConfCascChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.ConfCascChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.ConfCascChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.ConfCascChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.ConfCascChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.ConfCascChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); - cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.ConfCascChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.confCascChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.confCascChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.confCascChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kPosTrack, ConfCascadeSelection.confCascChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.confCascChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.confCascChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.confCascChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kNegTrack, ConfCascadeSelection.confCascChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.confCascChildCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.confCascChildEtaMax, femtoUniverseTrackSelection::kEtaMax, femtoUniverseSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.confCascChildTPCnClsMin, femtoUniverseTrackSelection::kTPCnClsMin, femtoUniverseSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.confCascChildPIDnSigmaMax, femtoUniverseTrackSelection::kPIDnSigmaMax, femtoUniverseSelection::kAbsUpperLimit); // TODO - cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kPosTrack, ConfV0Selection.ConfChildPIDspecies); - cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kNegTrack, ConfV0Selection.ConfChildPIDspecies); - cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.ConfCascChildPIDspecies); + cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kPosTrack, ConfV0Selection.confChildPIDspecies); + cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kNegTrack, ConfV0Selection.confChildPIDspecies); + cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.confCascChildPIDspecies); // check if works correctly for bachelor track - cascadeCuts.init(&cascadeQaRegistry, ConfIsSelectCascOmega); + cascadeCuts.init(&cascadeQaRegistry, confIsSelectCascOmega); // invmass cuts - cascadeCuts.setInvMassLimits(ConfCascadeSelection.ConfCascInvMassLowLimit, ConfCascadeSelection.ConfCascInvMassUpLimit); + cascadeCuts.setInvMassLimits(ConfCascadeSelection.confCascInvMassLowLimit, ConfCascadeSelection.confCascInvMassUpLimit); - if (ConfCascadeSelection.ConfCascRejectCompetingMass) { - cascadeCuts.setCompetingInvMassLimits(ConfCascadeSelection.ConfCascInvCompetingMassLowLimit, ConfCascadeSelection.ConfCascInvCompetingMassUpLimit); + if (ConfCascadeSelection.confCascRejectCompetingMass) { + cascadeCuts.setCompetingInvMassLimits(ConfCascadeSelection.confCascInvCompetingMassLowLimit, ConfCascadeSelection.confCascInvCompetingMassUpLimit); } } - if (ConfIsActivatePhi) { + if (confIsActivatePhi) { // initializing for Phi meson phiCuts.init(&qaRegistry); } @@ -608,7 +611,7 @@ struct femtoUniverseProducerTask { auto timestamp = bc.timestamp(); float output = -999; - if (ConfIsRun3 && !ConfIsForceGRP) { + if (confIsRun3 && !confIsForceGRP) { static o2::parameters::GRPMagField* grpo = nullptr; grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); if (grpo == nullptr) { @@ -616,12 +619,11 @@ struct femtoUniverseProducerTask { return; } LOGF(info, "Retrieved GRP for timestamp %llu with L3 ", timestamp, grpo->getL3Current()); - // taken from GRP onject definition of getNominalL3Field; update later to something smarter (mNominalL3Field = std::lround(5.f * mL3Current / 30000.f);) - auto NominalL3Field = std::lround(5.f * grpo->getL3Current() / 30000.f); - output = 0.1 * (NominalL3Field); + // taken from GRP onject definition of getnominalL3Field; update later to something smarter (mnominalL3Field = std::lround(5.f * mL3Current / 30000.f);) + auto nominalL3Field = std::lround(5.f * grpo->getL3Current() / 30000.f); + output = 0.1 * (nominalL3Field); } else { - static o2::parameters::GRPObject* grpo = nullptr; grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); if (grpo == nullptr) { @@ -686,7 +688,7 @@ struct femtoUniverseProducerTask { int particleOrigin = 99; auto motherparticlesMC = particleMC.template mothers_as(); - if (std::abs(pdgCode) == std::abs(ConfPDGCodePartOne.value) || std::abs(pdgCode) == std::abs(ConfPDGCodePartTwo.value)) { + if (std::abs(pdgCode) == std::abs(confPDGCodePartOne.value) || std::abs(pdgCode) == std::abs(confPDGCodePartTwo.value)) { if (particleMC.isPhysicalPrimary()) { particleOrigin = aod::femtouniverseMCparticle::ParticleOriginMCTruth::kPrimary; } else if (!motherparticlesMC.empty()) { @@ -768,7 +770,7 @@ struct femtoUniverseProducerTask { const auto vtxZ = col.posZ(); float mult = 0; int multNtr = 0; - if (ConfIsRun3) { + if (confIsRun3) { mult = col.multFV0M(); multNtr = col.multNTracksPV(); } else { @@ -776,7 +778,7 @@ struct femtoUniverseProducerTask { /// FemtoUniverseRun2 is defined V0M/2 multNtr = col.multTracklets(); } - if (ConfEvtUseTPCmult) { + if (confEvtUseTPCmult) { multNtr = col.multTPC(); } @@ -788,14 +790,14 @@ struct femtoUniverseProducerTask { if (!colCuts.isSelected(col)) { return false; } else { - if (!ConfIsUsePileUp) { - if (ConfDoSpher) { + if (!confIsUsePileUp) { + if (confDoSpher) { outputCollision(vtxZ, mult, multNtr, colCuts.computeSphericity(col, tracks), mMagField); } else { outputCollision(vtxZ, mult, multNtr, 2, mMagField); } } else { - if (ConfDoSpher && (!ConfEvNoSameBunchPileup || col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (!ConfEvIsGoodZvtxFT0vsPV || col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) && (!ConfEvIsVertexITSTPC || col.selection_bit(aod::evsel::kIsVertexITSTPC))) { + if (confDoSpher && (!confEvNoSameBunchPileup || col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (!confEvIsGoodZvtxFT0vsPV || col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) && (!confEvIsVertexITSTPC || col.selection_bit(aod::evsel::kIsVertexITSTPC))) { outputCollision(vtxZ, mult, multNtr, colCuts.computeSphericity(col, tracks), mMagField); } else { outputCollision(vtxZ, mult, multNtr, 2, mMagField); @@ -814,11 +816,11 @@ struct femtoUniverseProducerTask { float mult = 0; int multNtr = 0; - if (std::abs(vtxZ) > ConfEvtZvtx) { + if (std::abs(vtxZ) > confEvtZvtx) { continue; } - if (ConfDoSpher) { + if (confDoSpher) { outputCollision(vtxZ, mult, multNtr, colCuts.computeSphericity(col, tracks), mMagField); } else { outputCollision(vtxZ, mult, multNtr, 2, mMagField); @@ -859,7 +861,8 @@ struct femtoUniverseProducerTask { // in case of skimming run - don't store such collisions // in case of trigger run - store such collisions but don't store any // particle candidates for such collisions - if (!colCuts.isSelectedRun3(col) || (occupancy < ConfTPCOccupancyMin || occupancy > ConfTPCOccupancyMax)) { + + if (!colCuts.isSelectedRun3(col) || (occupancy < confTPCOccupancyMin || occupancy > confTPCOccupancyMax)) { return false; } else { if ((col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { @@ -891,7 +894,7 @@ struct femtoUniverseProducerTask { continue; } - if (track.pt() > ConfTOFpTmin) { + if (track.pt() > confTOFpTmin) { if (!track.hasTOF()) { continue; } @@ -903,14 +906,15 @@ struct femtoUniverseProducerTask { auto cutContainer = trackCuts.getCutContainer(track); // now the table is filled - if (!ConfIsActivateCascade) { + if (!confIsActivateCascade) { outputParts(outputCollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::femtouniverseparticle::ParticleType::kTrack, cutContainer.at( femtoUniverseTrackSelection::TrackContainerPosition::kCuts), cutContainer.at( femtoUniverseTrackSelection::TrackContainerPosition::kPID), - track.dcaXY(), childIDs, 0, 0); + track.dcaXY(), childIDs, 0, + track.sign()); // sign getter is mAntiLambda() } else { outputCascParts(outputCollision.lastIndex(), track.pt(), track.eta(), track.phi(), aod::femtouniverseparticle::ParticleType::kTrack, @@ -921,7 +925,7 @@ struct femtoUniverseProducerTask { track.dcaXY(), childIDs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } tmpIDtrack.push_back(track.globalIndex()); - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(track); } @@ -1011,7 +1015,7 @@ struct femtoUniverseProducerTask { indexChildID, v0.mLambda(), v0.mAntiLambda()); - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(postrack); // QA for positive daughter fillDebugParticle(negtrack); // QA for negative daughter fillDebugParticle(v0); // QA for v0 @@ -1142,8 +1146,8 @@ struct femtoUniverseProducerTask { 0, 0, indexCascChildID, - ConfIsSelectCascOmega ? casc.mOmega() : casc.mXi(), - ConfIsSelectCascOmega ? casc.mOmega() : casc.mXi(), + confIsSelectCascOmega ? casc.mOmega() : casc.mXi(), + confIsSelectCascOmega ? casc.mOmega() : casc.mXi(), casc.dcaV0daughters(), casc.v0cosPA(col.posX(), col.posY(), col.posZ()), casc.v0radius(), @@ -1154,7 +1158,7 @@ struct femtoUniverseProducerTask { casc.dcanegtopv(), casc.dcabachtopv(), casc.dcav0topv(col.posX(), col.posY(), col.posZ())); - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(posTrackCasc); // QA for positive daughter fillDebugParticle(negTrackCasc); // QA for negative daughter fillDebugParticle(bachTrackCasc); // QA for negative daughter @@ -1179,11 +1183,11 @@ struct femtoUniverseProducerTask { continue; } - if (ConfD0Selection.ConfD0D0barCandMaxY >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.ConfD0D0barCandMaxY) { + if (ConfD0Selection.confD0D0barCandMaxY >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.confD0D0barCandMaxY) { continue; } - if (std::abs(hfCand.eta()) > ConfD0Selection.ConfD0D0barCandEtaCut) { + if (std::abs(hfCand.eta()) > ConfD0Selection.confD0D0barCandEtaCut) { continue; } @@ -1269,7 +1273,7 @@ struct femtoUniverseProducerTask { invMassD0, // D0 mass (mLambda) invMassD0bar); // D0bar mass (mAntiLambda) - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(postrack); // QA for positive daughter fillDebugParticle(negtrack); // QA for negative daughter fillDebugParticle(hfCand); // QA for D0/D0bar @@ -1292,33 +1296,33 @@ struct femtoUniverseProducerTask { continue; } // implementing PID cuts for phi children - if (ConfPhiSelection.ConfLooseTPCNSigma.value) { - if (!(IsKaonNSigmaTPCLoose(p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon)))) { + if (ConfPhiSelection.confLooseTPCNSigma.value) { + if (!(isKaonNSigmaTPCLoose(p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon)))) { continue; } - if (!(IsKaonNSigmaTPCLoose(p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon)))) { + if (!(isKaonNSigmaTPCLoose(p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon)))) { continue; } } - if (ConfPhiSelection.ConfLooseTOFNSigma.value) { - if (!(IsKaonNSigmaTOFLoose(p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon)))) { + if (ConfPhiSelection.confLooseTOFNSigma.value) { + if (!(isKaonNSigmaTOFLoose(p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon)))) { continue; } - if (!(IsKaonNSigmaTOFLoose(p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon)))) { + if (!(isKaonNSigmaTOFLoose(p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon)))) { continue; } } else { - if (!(IsKaonNSigma(p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon)))) { + if (!(isKaonNSigma(p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon)))) { continue; } - if (!(IsKaonNSigma(p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon)))) { + if (!(isKaonNSigma(p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon)))) { continue; } } - if (IsKaonRejected(p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion))) { + if (isKaonRejected(p1.p(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion))) { continue; } - if (IsKaonRejected(p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion))) { + if (isKaonRejected(p2.p(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion))) { continue; } @@ -1344,20 +1348,14 @@ struct femtoUniverseProducerTask { } float phiPt = sumVec.Pt(); - if ((phiPt < ConfPhiSelection.ConfPtLowLimitPhi.value) || (phiPt > ConfPhiSelection.ConfPtHighLimitPhi.value)) { + if ((phiPt < ConfPhiSelection.confPtLowLimitPhi.value) || (phiPt > ConfPhiSelection.confPtHighLimitPhi.value)) { continue; } - /*float phiPhi = sumVec.Phi(); - if (sumVec.Phi() < 0) { - phiPhi = sumVec.Phi() + o2::constants::math::TwoPI; - } else if (sumVec.Phi() >= 0) { - phiPhi = sumVec.Phi(); - }*/ float phiPhi = RecoDecay::constrainAngle(sumVec.Phi(), 0); float phiM = sumVec.M(); - if (((phiM < ConfPhiSelection.ConfInvMassLowLimitPhi.value) || (phiM > ConfPhiSelection.ConfInvMassUpLimitPhi.value))) { + if (((phiM < ConfPhiSelection.confInvMassLowLimitPhi.value) || (phiM > ConfPhiSelection.confInvMassUpLimitPhi.value))) { continue; } @@ -1372,12 +1370,12 @@ struct femtoUniverseProducerTask { outputParts(outputCollision.lastIndex(), p1.pt(), p1.eta(), p1.phi(), aod::femtouniverseparticle::ParticleType::kPhiChild, - -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kPosCuts), - -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kPosPID), - p1.dcaXY(), + -999, // cutContainer + -999, // cutContainer + p1.dcaXY(), // tempFitVar childIDs, 0, - 1); // sign, workaround for now + p1.sign()); const int rowOfPosTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(p1, o2::aod::femtouniverseparticle::ParticleType::kPhiChild); @@ -1392,12 +1390,12 @@ struct femtoUniverseProducerTask { p2.eta(), p2.phi(), aod::femtouniverseparticle::ParticleType::kPhiChild, - -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kNegCuts), - -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kNegPID), - p2.dcaXY(), + -999, // cutContainer + -999, // cutContainer + p2.dcaXY(), // tempFitVar childIDs, 0, - -1); // sign, workaround for now + p2.sign()); // sign, workaround for now const int rowOfNegTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(p2, o2::aod::femtouniverseparticle::ParticleType::kPhiChild); @@ -1409,14 +1407,14 @@ struct femtoUniverseProducerTask { phiEta, phiPhi, aod::femtouniverseparticle::ParticleType::kPhi, - -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kV0), + -999, // cutContainer 0, - phiM, // v0.v0cosPA(), + phiM, // tempFitVar indexChildID, - phiM, // phi.mLambda(), //for now it will have a mLambda getter, maybe we will change it in the future so it's more logical - -999); // v0.mAntiLambda() + phiM, // phi.mLambda(), //for now it will have a mLambda getter, maybe we will change it in the future so it's more logical + 0); // phi.mAntiLambda() <- sign - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(p1); // QA for positive daughter fillDebugParticle(p2); // QA for negative daughter fillDebugParticle(p1); // QA for phi @@ -1437,22 +1435,22 @@ struct femtoUniverseProducerTask { /// if the most open selection criteria are not fulfilled there is no /// point looking further at the track - if (particle.eta() < -ConfFilterCuts.ConfEtaFilterCut || particle.eta() > ConfFilterCuts.ConfEtaFilterCut) + if (particle.eta() < -ConfFilterCuts.confEtaFilterCut || particle.eta() > ConfFilterCuts.confEtaFilterCut) continue; - if (particle.pt() < ConfFilterCuts.ConfPtLowFilterCut || particle.pt() > ConfFilterCuts.ConfPtHighFilterCut) + if (particle.pt() < ConfFilterCuts.confPtLowFilterCut || particle.pt() > ConfFilterCuts.confPtHighFilterCut) continue; uint32_t pdgCode = static_cast(particle.pdgCode()); - if (ConfMCTruthAnalysisWithPID) { + if (confMCTruthAnalysisWithPID) { bool pass = false; - std::vector tmpPDGCodes = ConfMCTruthPDGCodes; // necessary due to some features of the Configurable - for (uint32_t pdg : tmpPDGCodes) { + std::vector tmpPDGCodes = confMCTruthPDGCodes; // necessary due to some features of the Configurable + for (auto const& pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { if (pdgCode == 333) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles pass = true; } else { - if (particle.isPhysicalPrimary() || (ConfActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) + if (particle.isPhysicalPrimary() || (confActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) pass = true; } } @@ -1488,7 +1486,7 @@ struct femtoUniverseProducerTask { childIDs, 0, 0); - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(particle); } @@ -1523,7 +1521,7 @@ struct femtoUniverseProducerTask { childIDs, 0, 0); - if (ConfIsDebug) { + if (confIsDebug) { fillDebugParticle(particle); } @@ -1543,14 +1541,14 @@ struct femtoUniverseProducerTask { const auto colcheck = fillCollisions(col, tracks); if (colcheck) { fillTracks(tracks); - if (ConfIsActivateV0) { + if (confIsActivateV0) { fillV0(col, fullV0s, tracks); } - if (ConfIsActivatePhi) { + if (confIsActivatePhi) { fillPhi(col, tracks); } } - // if (ConfIsActivateCascade) { + // if (confIsActivateCascade) { // fillCascade(col, fullCascades, tracks); // } } @@ -1565,7 +1563,7 @@ struct femtoUniverseProducerTask { // fill the tables fillCollisionsAndTracksAndV0AndPhi(col, tracks, fullV0s); } - PROCESS_SWITCH(femtoUniverseProducerTask, processFullData, "Provide experimental data", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processFullData, "Provide experimental data", false); void processTrackV0(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, @@ -1577,7 +1575,7 @@ struct femtoUniverseProducerTask { // fill the tables fillCollisionsAndTracksAndV0AndPhi(col, tracks, fullV0s); } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackV0, "Provide experimental data for track v0", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackV0, "Provide experimental data for track v0", false); void processTrackCascadeData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, @@ -1593,7 +1591,7 @@ struct femtoUniverseProducerTask { fillCascade(col, fullCascades, tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCascadeData, "Provide experimental data for track cascades", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackCascadeData, "Provide experimental data for track cascades", false); /*void processTrackV0CentRun3(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, @@ -1607,7 +1605,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); fillV0(col, fullV0s, tracks); } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackV0CentRun3, "Provide experimental data for track v0", false);*/ + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackV0CentRun3, "Provide experimental data for track v0", false);*/ void processFullMC(aod::FemtoFullCollisionMC const& col, aod::BCsWithTimestamps const&, @@ -1621,7 +1619,7 @@ struct femtoUniverseProducerTask { // fill the tables fillCollisionsAndTracksAndV0AndPhi(col, tracks, fullV0s); } - PROCESS_SWITCH(femtoUniverseProducerTask, processFullMC, "Provide MC data (tracks, V0, Phi)", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processFullMC, "Provide MC data (tracks, V0, Phi)", false); void processTrackMC(aod::FemtoFullCollisionMC const& col, aod::BCsWithTimestamps const&, @@ -1637,7 +1635,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackMC, "Provide MC data for track analysis", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackMC, "Provide MC data for track analysis", false); void processTrackPhiMC(aod::FemtoFullCollisionMC const& col, aod::BCsWithTimestamps const&, @@ -1654,7 +1652,7 @@ struct femtoUniverseProducerTask { fillPhi(col, tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackPhiMC, "Provide MC data for track Phi analysis", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackPhiMC, "Provide MC data for track Phi analysis", false); void processTrackD0MC(aod::FemtoFullCollisionMC const& col, aod::BCsWithTimestamps const&, @@ -1671,7 +1669,7 @@ struct femtoUniverseProducerTask { // fillD0mesons(col, tracks, candidates); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackD0MC, "Provide MC data for track D0 analysis", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackD0MC, "Provide MC data for track D0 analysis", false); void processTrackData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, @@ -1683,13 +1681,13 @@ struct femtoUniverseProducerTask { // fill the tables const auto colcheck = fillCollisions(col, tracks); if (colcheck) { - if (ConfFillCollExt) { + if (confFillCollExt) { fillCollisionsCentRun3ColExtra(col, ir); } fillTracks(tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackData, + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackData, "Provide experimental data for track track", true); // using FilteredFemtoFullTracks = soa::Filtered; @@ -1706,7 +1704,7 @@ struct femtoUniverseProducerTask { fillPhi(col, tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackPhiData, + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackPhiData, "Provide experimental data for track phi", false); void processTrackD0mesonData(aod::FemtoFullCollision const& col, @@ -1723,7 +1721,7 @@ struct femtoUniverseProducerTask { fillD0mesons(col, tracks, candidates); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackD0mesonData, + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackD0mesonData, "Provide experimental data for track D0 meson", false); void processTrackMCTruth(aod::McCollision const&, @@ -1736,7 +1734,7 @@ struct femtoUniverseProducerTask { fillMCTruthCollisions(collisions, mcParticles); fillParticles(mcParticles); } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackMCTruth, "Provide MC data for MC truth track analysis", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackMCTruth, "Provide MC data for MC truth track analysis", false); void processTrackMCGen(aod::McCollision const& col, aod::McParticles const& mcParticles) @@ -1744,7 +1742,7 @@ struct femtoUniverseProducerTask { outputCollision(col.posZ(), 0, 0, 2, 0); fillParticles(mcParticles); } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackMCGen, "Provide MC Generated for model comparisons", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackMCGen, "Provide MC Generated for model comparisons", false); Preslice perMCCollision = aod::mcparticle::mcCollisionId; PresliceUnsorted> recoCollsPerMCColl = aod::mcparticle::mcCollisionId; @@ -1779,7 +1777,7 @@ struct femtoUniverseProducerTask { fillParticles(groupedMCParticles, recoMcIds); // fills mc particles } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTruthAndFullMC, "Provide both MC truth and reco for tracks and V0s", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTruthAndFullMC, "Provide both MC truth and reco for tracks and V0s", false); void processFullMCCent(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, @@ -1799,7 +1797,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processFullMCCent, "Provide MC data with centrality bins", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processFullMCCent, "Provide MC data with centrality bins", false); void processTrackCentRun2Data(aod::FemtoFullCollisionCentRun2 const& col, aod::BCsWithTimestamps const&, @@ -1817,7 +1815,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCentRun2Data, "Provide experimental data for Run 2 with centrality for track track", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackCentRun2Data, "Provide experimental data for Run 2 with centrality for track track", false); void processTrackCentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, @@ -1835,7 +1833,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackCentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); void processV0CentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, @@ -1855,7 +1853,7 @@ struct femtoUniverseProducerTask { fillV0(col, fullV0s, tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processV0CentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processV0CentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); void processCascadeCentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, @@ -1875,11 +1873,11 @@ struct femtoUniverseProducerTask { fillCascade(col, fullCascades, tracks); } } - PROCESS_SWITCH(femtoUniverseProducerTask, processCascadeCentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); + PROCESS_SWITCH(FemtoUniverseProducerTask, processCascadeCentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; return workflow; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index 15aea7eee19..c9044e71374 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file femtoUniversePairTaskTrackPhi.cxx -/// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks +/// \brief Tasks that reads the track tables used for the pairing and builds pairs for h-Phi angular correlation analysis /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de /// \author Anton Riedel, TU München, anton.riedel@tum.de @@ -25,7 +25,6 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "TDatabasePDG.h" #include "ReconstructionDataFormats/PID.h" #include "Common/DataModel/PIDResponse.h" @@ -49,16 +48,16 @@ using namespace o2::soa; namespace { -static constexpr int nPart = 2; -static constexpr int nCuts = 5; +static constexpr int NPart = 2; +static constexpr int NCuts = 5; static const std::vector partNames{"PhiCandidate", "Track"}; static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; -static const float cutsTable[nPart][nCuts]{ +static const float cutsTable[NPart][NCuts]{ {4.05f, 1.f, 3.f, 3.f, 100.f}, {4.05f, 1.f, 3.f, 3.f, 100.f}}; } // namespace -struct femtoUniversePairTaskTrackPhi { +struct FemtoUniversePairTaskTrackPhi { Service pdgMC; @@ -71,64 +70,58 @@ struct femtoUniversePairTaskTrackPhi { // Efficiency struct : o2::framework::ConfigurableGroup { - Configurable ConfEfficiencyTrackPath{"ConfEfficiencyTrackPath", "", "Local path to proton efficiency TH2F file"}; - Configurable ConfEfficiencyPhiPath{"ConfEfficiencyPhiPath", "", "Local path to Phi efficiency TH2F file"}; - Configurable ConfEfficiencyTrackTimestamp{"ConfEfficiencyTrackTimestamp", 0, "(int64_t) Timestamp for hadron"}; - Configurable ConfEfficiencyPhiTimestamp{"ConfEfficiencyPhiTimestamp", 0, "(int64_t) Timestamp for phi"}; + Configurable confEfficiencyTrackPath{"confEfficiencyTrackPath", "", "Local path to proton efficiency TH2F file"}; + Configurable confEfficiencyPhiPath{"confEfficiencyPhiPath", "", "Local path to Phi efficiency TH2F file"}; + Configurable confEfficiencyTrackTimestamp{"confEfficiencyTrackTimestamp", 0, "(int64_t) Timestamp for hadron"}; + Configurable confEfficiencyPhiTimestamp{"confEfficiencyPhiTimestamp", 0, "(int64_t) Timestamp for phi"}; } ConfEff; struct : o2::framework::ConfigurableGroup { - Configurable ConfCPRIsEnabled{"ConfCPRIsEnabled", true, "Close Pair Rejection"}; - Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; - Configurable ConfCPRdeltaPhiCutMax{"ConfCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; - Configurable ConfCPRdeltaPhiCutMin{"ConfCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaCutMax{"ConfCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaCutMin{"ConfCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; - Configurable ConfCPRInvMassCutMin{"ConfCPRInvMassCutMin", 1.014, "Invariant mass (low) cut for Close Pair Rejection"}; - Configurable ConfCPRInvMassCutMax{"ConfCPRInvMassCutMax", 1.026, "Invariant mass (high) cut for Close Pair Rejection"}; - Configurable ConfCPRChosenRadii{"ConfCPRChosenRadii", 0.80, "Delta Eta cut for Close Pair Rejection"}; + Configurable confCPRIsEnabled{"confCPRIsEnabled", false, "Close Pair Rejection"}; + Configurable confCPRPlotPerRadii{"confCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable confCPRdeltaPhiCutMax{"confCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; + Configurable confCPRdeltaPhiCutMin{"confCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; + Configurable confCPRdeltaEtaCutMax{"confCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; + Configurable confCPRdeltaEtaCutMin{"confCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; + Configurable confCPRInvMassCutMin{"confCPRInvMassCutMin", 1.014, "Invariant mass (low) cut for Close Pair Rejection"}; + Configurable confCPRInvMassCutMax{"confCPRInvMassCutMax", 1.026, "Invariant mass (high) cut for Close Pair Rejection"}; + Configurable confCPRChosenRadii{"confCPRChosenRadii", 0.80, "Delta Eta cut for Close Pair Rejection"}; } ConfCPR; /// Table for both particles struct : o2::framework::ConfigurableGroup { - Configurable ConfPIDProtonNsigmaCombined{"ConfPIDProtonNsigmaCombined", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > 0.5"}; - Configurable ConfPIDProtonNsigmaTPC{"ConfPIDProtonNsigmaTPC", 3.0, "TPC Proton Sigma for momentum < 0.5"}; - Configurable ConfPIDKaonNsigmaReject{"ConfPIDKaonNsigmaReject", 3.0, "Reject if particle could be a Kaon combined nsigma value."}; - Configurable ConfPIDPionNsigmaReject{"ConfPIDPionNsigmaReject", 3.0, "Reject if particle could be a Pion combined nsigma value."}; - Configurable ConfPIDProtonNsigmaReject{"ConfPIDProtonNsigmaReject", 3.0, "Reject if particle could be a Proton combined nsigma value."}; - Configurable ConfPIDPionNsigmaCombined{"ConfPIDPionNsigmaCombined", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > 0.5"}; - Configurable ConfPIDPionNsigmaTPC{"ConfPIDPionNsigmaTPC", 3.0, "TPC Pion Sigma for momentum < 0.5"}; - - Configurable> ConfCutTable{"ConfCutTable", {cutsTable[0], nPart, nCuts, partNames, cutNames}, "Particle selections"}; - Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; - Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histograms in the case of a MonteCarlo Run"}; - Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; - Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; - Configurable ConfBinsPhi{"ConfBinsPhi", 29, "Number of phi bins in deta dphi"}; - Configurable ConfBinsEta{"ConfBinsEta", 29, "Number of eta bins in deta dphi"}; + Configurable confPIDProtonNsigmaCombined{"confPIDProtonNsigmaCombined", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > 0.5"}; + Configurable confPIDProtonNsigmaTPC{"confPIDProtonNsigmaTPC", 3.0, "TPC Proton Sigma for momentum < 0.5"}; + Configurable confPIDKaonNsigmaReject{"confPIDKaonNsigmaReject", 3.0, "Reject if particle could be a Kaon combined nsigma value."}; + Configurable confPIDPionNsigmaReject{"confPIDPionNsigmaReject", 3.0, "Reject if particle could be a Pion combined nsigma value."}; + Configurable confPIDProtonNsigmaReject{"confPIDProtonNsigmaReject", 3.0, "Reject if particle could be a Proton combined nsigma value."}; + Configurable confPIDPionNsigmaCombined{"confPIDPionNsigmaCombined", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > 0.5"}; + Configurable confPIDPionNsigmaTPC{"confPIDPionNsigmaTPC", 3.0, "TPC Pion Sigma for momentum < 0.5"}; + + // Configurable> confCutTable{"confCutTable", {cutsTable[0], NPart, NCuts, partNames, cutNames}, "Particle selections"}; //unused + // Configurable confNspecies{"confNspecies", 2, "Number of particle spieces with PID info"}; //unused + Configurable confIsMC{"confIsMC", false, "Enable additional Histograms in the case of a MonteCarlo Run"}; + Configurable> confTrkPIDnSigmaMax{"confTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; + Configurable confUse3D{"confUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + Configurable confBinsPhi{"confBinsPhi", 29, "Number of phi bins in deta dphi"}; + Configurable confBinsEta{"confBinsEta", 29, "Number of eta bins in deta dphi"}; } ConfBothTracks; /// Particle 1 --- IDENTIFIED TRACK struct : o2::framework::ConfigurableGroup { - Configurable ConfTrackIsSame{"ConfTrackIsSame", false, "Pairs of the same particle"}; - Configurable ConfTrackPDGCode{"ConfTrackPDGCode", 2212, "Particle 2 - PDG code"}; - Configurable ConfTrackPID{"ConfTrackPID", 2, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> - Configurable ConfTrackSign{"ConfTrackSign", 1, "Track sign"}; - Configurable ConfTrackIsIdentified{"ConfTrackIsIdentified", true, "Enable PID for the track"}; - Configurable ConfTrackIsRejected{"ConfTrackIsRejected", true, "Enable PID rejection for the track other species than the identified one."}; - Configurable ConfTrackPtLowLimit{"ConfTrackPtLowLimit", 0.5, "Lower limit of the Phi pT."}; - Configurable ConfTrackPtHighLimit{"ConfTrackPtHighLimit", 2.5, "Higher limit of the Phi pT."}; + Configurable confTrackIsSame{"confTrackIsSame", false, "Pairs of the same particle"}; + Configurable confTrackPDGCode{"confTrackPDGCode", 2212, "Particle 2 - PDG code"}; + Configurable confTrackPID{"confTrackPID", 2, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> + Configurable confTrackSign{"confTrackSign", 1, "Track sign"}; + Configurable confTrackIsIdentified{"confTrackIsIdentified", true, "Enable PID for the track"}; + Configurable confTrackIsRejected{"confTrackIsRejected", true, "Enable PID rejection for the track other species than the identified one."}; + Configurable confTrackPtLowLimit{"confTrackPtLowLimit", 0.5, "Lower limit of the Phi pT."}; + Configurable confTrackPtHighLimit{"confTrackPtHighLimit", 2.5, "Higher limit of the Phi pT."}; } ConfTrack; - /// Particle 2 --- PHI - struct : o2::framework::ConfigurableGroup { - Configurable ConfPhiPDGCode{"ConfPhiPDGCode", 333, "Phi meson - PDG code"}; - Configurable ConfPhiPID{"ConfPhiPID", 2, "Phi meson - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector>int>> - } ConfPhi; - /// Partitions for particle 1 - Partition partsTrack = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == ConfTrack.ConfTrackSign.value) && (aod::femtouniverseparticle::pt > ConfTrack.ConfTrackPtLowLimit.value) && (aod::femtouniverseparticle::pt < ConfTrack.ConfTrackPtHighLimit.value); - Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == ConfTrack.ConfTrackSign.value) && (aod::femtouniverseparticle::pt > ConfTrack.ConfTrackPtLowLimit.value) && (aod::femtouniverseparticle::pt < ConfTrack.ConfTrackPtHighLimit.value); + Partition partsTrack = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == ConfTrack.confTrackSign.value) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackPtLowLimit.value) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackPtHighLimit.value); + Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == ConfTrack.confTrackSign.value) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackPtLowLimit.value) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackPtHighLimit.value); /// Partitions for particle 2 Partition partsPhi = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kPhi)); @@ -151,26 +144,22 @@ struct femtoUniversePairTaskTrackPhi { /// Histogramming for Event FemtoUniverseEventHisto eventHisto; - /// The configurables need to be passed to an std::vector - int vPIDPhiCandidate, vPIDTrack; - std::vector kNsigma; - /// particle part - ConfigurableAxis ConfBinsTempFitVar{"ConfDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfBinsTempFitVarInvMass{"ConfDTempFitVarInvMassBins", {6000, 0.9, 4.0}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfBinsTempFitVarpT{"ConfBinsTempFitVarpT", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + ConfigurableAxis confBinsTempFitVar{"confBinsTempFitVar", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confBinsTempFitVarInvMass{"confBinsTempFitVarInvMass", {6000, 0.9, 4.0}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confBinsTempFitVarpT{"confBinsTempFitVarpT", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; /// Correlation part - ConfigurableAxis ConfBinsMult{"ConfBinsMult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task - ConfigurableAxis ConfBinsVtx{"ConfBinsVtx", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis ConfBins3DmT{"ConfBins3DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ConfigurableAxis ConfBins3Dmult{"ConfBins3Dmult", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis confBinsMult{"confBinsMult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task + ConfigurableAxis confBinsVtx{"confBinsVtx", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + ConfigurableAxis confBins3DmT{"confBins3DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis confBins3Dmult{"confBins3Dmult", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ColumnBinningPolicy colBinning{{ConfBinsVtx, ConfBinsMult}, true}; + ColumnBinningPolicy colBinning{{confBinsVtx, confBinsMult}, true}; - ConfigurableAxis ConfBinskstar{"ConfBinskstar", {1500, 0., 6.}, "binning kstar"}; - ConfigurableAxis ConfBinskT{"ConfBinskT", {150, 0., 9.}, "binning kT"}; - ConfigurableAxis ConfBinsmT{"ConfBinsmT", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis confBinskstar{"confBinskstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis confBinskT{"confBinskT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis confBinsmT{"confBinsmT", {225, 0., 7.5}, "binning mT"}; FemtoUniverseAngularContainer sameEventAngularCont; FemtoUniverseAngularContainer mixedEventAngularCont; @@ -179,11 +168,11 @@ struct femtoUniversePairTaskTrackPhi { FemtoUniverseTrackSelection trackCuts; /// Histogram output - HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry qaRegistry{"qaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry registryMCtruth{"MCtruthHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; - HistogramRegistry registryMCreco{"MCrecoHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry mixQaRegistry{"mixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry registryMCtruth{"registryMCtruth", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry registryMCreco{"registryMCreco", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry registryPhiMinvBackground{"registryPhiMinvBackground", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; Service ccdb; @@ -191,16 +180,16 @@ struct femtoUniversePairTaskTrackPhi { TH2F* phieff; // PID for protons - bool IsProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx + bool isProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx { if (mom < 0.5) { - if (TMath::Abs(nsigmaTPCPr) < ConfBothTracks.ConfPIDProtonNsigmaTPC.value) { + if (std::abs(nsigmaTPCPr) < ConfBothTracks.confPIDProtonNsigmaTPC.value) { return true; } else { return false; } } else if (mom > 0.4) { - if (TMath::Hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.ConfPIDProtonNsigmaCombined.value) { + if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.confPIDProtonNsigmaCombined.value) { return true; } else { return false; @@ -209,15 +198,15 @@ struct femtoUniversePairTaskTrackPhi { return false; } - bool IsProtonRejected(float mom, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) + bool isProtonRejected(float mom, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) { if (mom < 0.5) { return true; } if (mom > 0.5) { - if (TMath::Hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.ConfPIDPionNsigmaReject.value) { + if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.confPIDPionNsigmaReject.value) { return true; - } else if (TMath::Hypot(nsigmaTOFK, nsigmaTPCK) < ConfBothTracks.ConfPIDKaonNsigmaReject.value) { + } else if (std::hypot(nsigmaTOFK, nsigmaTPCK) < ConfBothTracks.confPIDKaonNsigmaReject.value) { return true; } else { return false; @@ -227,28 +216,28 @@ struct femtoUniversePairTaskTrackPhi { } } - bool IsKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) + bool isKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) { if (mom < 0.3) { // 0.0-0.3 - if (TMath::Abs(nsigmaTPCK) < 3.0) { + if (std::abs(nsigmaTPCK) < 3.0) { return true; } else { return false; } } else if (mom < 0.45) { // 0.30 - 0.45 - if (TMath::Abs(nsigmaTPCK) < 2.0) { + if (std::abs(nsigmaTPCK) < 2.0) { return true; } else { return false; } } else if (mom < 0.55) { // 0.45-0.55 - if (TMath::Abs(nsigmaTPCK) < 1.0) { + if (std::abs(nsigmaTPCK) < 1.0) { return true; } else { return false; } } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) - if ((TMath::Abs(nsigmaTOFK) < 3.0) && (TMath::Abs(nsigmaTPCK) < 3.0)) { + if ((std::abs(nsigmaTOFK) < 3.0) && (std::abs(nsigmaTPCK) < 3.0)) { { return true; } @@ -256,7 +245,7 @@ struct femtoUniversePairTaskTrackPhi { return false; } } else if (mom > 1.5) { // 1.5 - - if ((TMath::Abs(nsigmaTOFK) < 2.0) && (TMath::Abs(nsigmaTPCK) < 3.0)) { + if ((std::abs(nsigmaTOFK) < 2.0) && (std::abs(nsigmaTPCK) < 3.0)) { return true; } else { return false; @@ -266,19 +255,19 @@ struct femtoUniversePairTaskTrackPhi { } } - bool IsKaonRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi) + bool isKaonRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi) { if (mom < 0.5) { - if (TMath::Abs(nsigmaTPCPi) < ConfBothTracks.ConfPIDPionNsigmaReject.value) { + if (std::abs(nsigmaTPCPi) < ConfBothTracks.confPIDPionNsigmaReject.value) { return true; - } else if (TMath::Abs(nsigmaTPCPr) < ConfBothTracks.ConfPIDProtonNsigmaReject.value) { + } else if (std::abs(nsigmaTPCPr) < ConfBothTracks.confPIDProtonNsigmaReject.value) { return true; } } if (mom > 0.5) { - if (TMath::Hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.ConfPIDPionNsigmaReject.value) { + if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.confPIDPionNsigmaReject.value) { return true; - } else if (TMath::Hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.ConfPIDProtonNsigmaReject.value) { + } else if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.confPIDProtonNsigmaReject.value) { return true; } else { return false; @@ -288,17 +277,17 @@ struct femtoUniversePairTaskTrackPhi { } } - bool IsPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) + bool isPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) { if (true) { if (mom < 0.5) { - if (TMath::Abs(nsigmaTPCPi) < ConfBothTracks.ConfPIDPionNsigmaTPC.value) { + if (std::abs(nsigmaTPCPi) < ConfBothTracks.confPIDPionNsigmaTPC.value) { return true; } else { return false; } } else if (mom > 0.5) { - if (TMath::Hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.ConfPIDPionNsigmaCombined.value) { + if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.confPIDPionNsigmaCombined.value) { return true; } else { return false; @@ -308,19 +297,19 @@ struct femtoUniversePairTaskTrackPhi { return false; } - bool IsPionRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCK, float nsigmaTOFK) + bool isPionRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCK, float nsigmaTOFK) { if (mom < 0.5) { - if (TMath::Abs(nsigmaTPCK) < ConfBothTracks.ConfPIDKaonNsigmaReject.value) { + if (std::abs(nsigmaTPCK) < ConfBothTracks.confPIDKaonNsigmaReject.value) { return true; - } else if (TMath::Abs(nsigmaTPCPr) < ConfBothTracks.ConfPIDProtonNsigmaReject.value) { + } else if (std::abs(nsigmaTPCPr) < ConfBothTracks.confPIDProtonNsigmaReject.value) { return true; } } if (mom > 0.5) { - if (TMath::Hypot(nsigmaTOFK, nsigmaTPCK) < ConfBothTracks.ConfPIDKaonNsigmaReject.value) { + if (std::hypot(nsigmaTOFK, nsigmaTPCK) < ConfBothTracks.confPIDKaonNsigmaReject.value) { return true; - } else if (TMath::Hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.ConfPIDProtonNsigmaReject.value) { + } else if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.confPIDProtonNsigmaReject.value) { return true; } else { return false; @@ -330,40 +319,40 @@ struct femtoUniversePairTaskTrackPhi { } } - bool IsParticleNSigmaAccepted(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) + bool isParticleNSigmaAccepted(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) { - switch (ConfTrack.ConfTrackPDGCode) { + switch (ConfTrack.confTrackPDGCode) { case 2212: // Proton case -2212: // anty Proton - return IsProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); + return isProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); break; case 211: // Pion case -211: // Pion- - return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + return isPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); break; case 321: // Kaon+ case -321: // Kaon- - return IsKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + return isKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); break; default: return false; } } - bool IsParticleNSigmaRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) + bool isParticleNSigmaRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) { - switch (ConfTrack.ConfTrackPDGCode) { + switch (ConfTrack.confTrackPDGCode) { case 2212: // Proton case -2212: // anty Proton - return IsProtonRejected(mom, nsigmaTPCPi, nsigmaTOFPi, nsigmaTPCK, nsigmaTOFK); + return isProtonRejected(mom, nsigmaTPCPi, nsigmaTOFPi, nsigmaTPCK, nsigmaTOFK); break; case 211: // Pion case -211: // Pion- - return IsPionRejected(mom, nsigmaTPCPr, nsigmaTOFPr, nsigmaTPCK, nsigmaTOFK); + return isPionRejected(mom, nsigmaTPCPr, nsigmaTOFPr, nsigmaTPCK, nsigmaTOFK); break; case 321: // Kaon+ case -321: // Kaon- - return IsKaonRejected(mom, nsigmaTPCPr, nsigmaTOFPr, nsigmaTPCPi, nsigmaTOFPi); + return isKaonRejected(mom, nsigmaTPCPr, nsigmaTOFPr, nsigmaTPCPi, nsigmaTOFPi); break; default: return false; @@ -377,14 +366,14 @@ struct femtoUniversePairTaskTrackPhi { qaRegistry.add("PhiDaugh_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("PhiDaugh_pos/pt", "; #it{p_T} (GeV/#it{c}); Counts", kTH1F, {{100, 0, 10}}); qaRegistry.add("PhiDaugh_pos/eta", "; #it{eta}; Counts", kTH1F, {{200, -1.5, 1.5}}); - qaRegistry.add("PhiDaugh_pos/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, 2. * M_PI}}); + qaRegistry.add("PhiDaugh_pos/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, o2::constants::math::TwoPI}}); qaRegistry.add("PhiDaugh_pos/hDCAxy", "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); qaRegistry.add("PhiDaugh_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("PhiDaugh_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("PhiDaugh_neg/pt", "; #it{p_T} (GeV/#it{c}); Counts", kTH1F, {{100, 0, 10}}); qaRegistry.add("PhiDaugh_neg/eta", "; #it{eta}; Counts", kTH1F, {{200, -1.5, 1.5}}); - qaRegistry.add("PhiDaugh_neg/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, 2. * M_PI}}); + qaRegistry.add("PhiDaugh_neg/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, o2::constants::math::TwoPI}}); qaRegistry.add("PhiDaugh_neg/hDCAxy", "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); registryPhiMinvBackground.add("InvariantMassKpKp", "; invariant mass K+K+; Counts", kTH1F, {{6000, 0.9, 4.0}}); @@ -415,23 +404,23 @@ struct femtoUniversePairTaskTrackPhi { registryMCreco.add("MCrecoPpos", "MC reco proton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCreco.add("MCrecoPneg", "MC reco antiproton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - trackHistoPartPhi.init(&qaRegistry, ConfBinsTempFitVarpT, ConfBinsTempFitVarInvMass, ConfBothTracks.ConfIsMC, ConfPhi.ConfPhiPDGCode); - if (!ConfTrack.ConfTrackIsSame) { - trackHistoPartTrack.init(&qaRegistry, ConfBinsTempFitVarpT, ConfBinsTempFitVar, ConfBothTracks.ConfIsMC, ConfTrack.ConfTrackPDGCode); + trackHistoPartPhi.init(&qaRegistry, confBinsTempFitVarpT, confBinsTempFitVarInvMass, ConfBothTracks.confIsMC, 333); + if (!ConfTrack.confTrackIsSame) { + trackHistoPartTrack.init(&qaRegistry, confBinsTempFitVarpT, confBinsTempFitVar, ConfBothTracks.confIsMC, ConfTrack.confTrackPDGCode); } - MixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); - MixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + mixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + mixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); - sameEventAngularCont.init(&resultRegistry, ConfBinskstar, ConfBinsMult, ConfBinskT, ConfBinsmT, ConfBins3Dmult, ConfBins3DmT, ConfBothTracks.ConfBinsEta, ConfBothTracks.ConfBinsPhi, ConfBothTracks.ConfIsMC, ConfBothTracks.ConfUse3D); - mixedEventAngularCont.init(&resultRegistry, ConfBinskstar, ConfBinsMult, ConfBinskT, ConfBinsmT, ConfBins3Dmult, ConfBins3DmT, ConfBothTracks.ConfBinsEta, ConfBothTracks.ConfBinsPhi, ConfBothTracks.ConfIsMC, ConfBothTracks.ConfUse3D); + sameEventAngularCont.init(&resultRegistry, confBinskstar, confBinsMult, confBinskT, confBinsmT, confBins3Dmult, confBins3DmT, ConfBothTracks.confBinsEta, ConfBothTracks.confBinsPhi, ConfBothTracks.confIsMC, ConfBothTracks.confUse3D); + mixedEventAngularCont.init(&resultRegistry, confBinskstar, confBinsMult, confBinskT, confBinsmT, confBins3Dmult, confBins3DmT, ConfBothTracks.confBinsEta, ConfBothTracks.confBinsPhi, ConfBothTracks.confIsMC, ConfBothTracks.confUse3D); - sameEventAngularCont.setPDGCodes(ConfPhi.ConfPhiPDGCode, ConfTrack.ConfTrackPDGCode); - mixedEventAngularCont.setPDGCodes(ConfPhi.ConfPhiPDGCode, ConfTrack.ConfTrackPDGCode); + sameEventAngularCont.setPDGCodes(333, ConfTrack.confTrackPDGCode); + mixedEventAngularCont.setPDGCodes(333, ConfTrack.confTrackPDGCode); pairCleaner.init(&qaRegistry); - if (ConfCPR.ConfCPRIsEnabled.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPR.ConfCPRdeltaPhiCutMin.value, ConfCPR.ConfCPRdeltaPhiCutMax.value, ConfCPR.ConfCPRdeltaEtaCutMin.value, ConfCPR.ConfCPRdeltaEtaCutMax.value, ConfCPR.ConfCPRChosenRadii.value, ConfCPR.ConfCPRPlotPerRadii.value, ConfCPR.ConfCPRInvMassCutMin.value, ConfCPR.ConfCPRInvMassCutMax.value); + if (ConfCPR.confCPRIsEnabled.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPR.confCPRdeltaPhiCutMin.value, ConfCPR.confCPRdeltaPhiCutMax.value, ConfCPR.confCPRdeltaEtaCutMin.value, ConfCPR.confCPRdeltaEtaCutMax.value, ConfCPR.confCPRChosenRadii.value, ConfCPR.confCPRPlotPerRadii.value, ConfCPR.confCPRInvMassCutMin.value, ConfCPR.confCPRInvMassCutMax.value); } /// Initializing CCDB @@ -442,28 +431,24 @@ struct femtoUniversePairTaskTrackPhi { int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); - if (!ConfEff.ConfEfficiencyTrackPath.value.empty()) { - protoneff = ccdb->getForTimeStamp(ConfEff.ConfEfficiencyTrackPath.value.c_str(), ConfEff.ConfEfficiencyTrackTimestamp.value); + if (!ConfEff.confEfficiencyTrackPath.value.empty()) { + protoneff = ccdb->getForTimeStamp(ConfEff.confEfficiencyTrackPath.value.c_str(), ConfEff.confEfficiencyTrackTimestamp.value); if (!protoneff || protoneff->IsZombie()) { - LOGF(fatal, "Could not load efficiency protoneff histogram from %s", ConfEff.ConfEfficiencyTrackPath.value.c_str()); + LOGF(fatal, "Could not load efficiency protoneff histogram from %s", ConfEff.confEfficiencyTrackPath.value.c_str()); } } - if (!ConfEff.ConfEfficiencyPhiPath.value.empty()) { - phieff = ccdb->getForTimeStamp(ConfEff.ConfEfficiencyPhiPath.value.c_str(), ConfEff.ConfEfficiencyPhiTimestamp.value); + if (!ConfEff.confEfficiencyPhiPath.value.empty()) { + phieff = ccdb->getForTimeStamp(ConfEff.confEfficiencyPhiPath.value.c_str(), ConfEff.confEfficiencyPhiTimestamp.value); if (!phieff || phieff->IsZombie()) { - LOGF(fatal, "Could not load efficiency phieff histogram from %s", ConfEff.ConfEfficiencyPhiPath.value.c_str()); + LOGF(fatal, "Could not load efficiency phieff histogram from %s", ConfEff.confEfficiencyPhiPath.value.c_str()); } } - - vPIDPhiCandidate = ConfPhi.ConfPhiPID.value; - vPIDTrack = ConfTrack.ConfTrackPID.value; - kNsigma = ConfBothTracks.ConfTrkPIDnSigmaMax.value; } template void fillCollision(CollisionType col) { - MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); + mixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); eventHisto.fillQA(col); } @@ -482,13 +467,13 @@ struct femtoUniversePairTaskTrackPhi { { /// Histogramming same event - for (auto& phicandidate : groupPartsPhi) { + for (auto const& phicandidate : groupPartsPhi) { trackHistoPartPhi.fillQA(phicandidate); } float tpcNSigma; float tofNSigma; - for (auto& phidaugh : groupPartsPhiDaugh) { + for (auto const& phidaugh : groupPartsPhiDaugh) { if (phidaugh.mAntiLambda() == 1) { // workaround tpcNSigma = trackCuts.getNsigmaTPC(phidaugh, o2::track::PID::Kaon); tofNSigma = trackCuts.getNsigmaTOF(phidaugh, o2::track::PID::Kaon); @@ -512,8 +497,8 @@ struct femtoUniversePairTaskTrackPhi { } } float tpcNSigmaPr, tofNSigmaPr, tpcNSigmaPi, tofNSigmaPi, tpcNSigmaKa, tofNSigmaKa; - if (!ConfTrack.ConfTrackIsSame) { - for (auto& track : groupPartsTrack) { + if (!ConfTrack.confTrackIsSame) { + for (auto const& track : groupPartsTrack) { tpcNSigmaPi = trackCuts.getNsigmaTPC(track, o2::track::PID::Pion); tofNSigmaPi = trackCuts.getNsigmaTOF(track, o2::track::PID::Pion); tpcNSigmaKa = trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon); @@ -521,14 +506,14 @@ struct femtoUniversePairTaskTrackPhi { tpcNSigmaPr = trackCuts.getNsigmaTPC(track, o2::track::PID::Proton); tofNSigmaPr = trackCuts.getNsigmaTOF(track, o2::track::PID::Proton); - if (ConfTrack.ConfTrackIsIdentified) { - if (!IsParticleNSigmaAccepted(track.p(), tpcNSigmaPr, tofNSigmaPr, tpcNSigmaPi, tofNSigmaPi, tpcNSigmaKa, tofNSigmaKa)) { + if (ConfTrack.confTrackIsIdentified) { + if (!isParticleNSigmaAccepted(track.p(), tpcNSigmaPr, tofNSigmaPr, tpcNSigmaPi, tofNSigmaPi, tpcNSigmaKa, tofNSigmaKa)) { continue; } } - if (ConfTrack.ConfTrackIsRejected) { - if (IsParticleNSigmaRejected(track.p(), tpcNSigmaPr, tofNSigmaPr, tpcNSigmaPi, tofNSigmaPi, tpcNSigmaKa, tofNSigmaKa)) { + if (ConfTrack.confTrackIsRejected) { + if (isParticleNSigmaRejected(track.p(), tpcNSigmaPr, tofNSigmaPr, tpcNSigmaPi, tofNSigmaPi, tpcNSigmaKa, tofNSigmaKa)) { continue; } } @@ -544,21 +529,21 @@ struct femtoUniversePairTaskTrackPhi { } } /// Now build the combinations - for (auto& [track, phicandidate] : combinations(CombinationsFullIndexPolicy(groupPartsTrack, groupPartsPhi))) { - if (ConfTrack.ConfTrackIsIdentified) { - if (!IsParticleNSigmaAccepted(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + for (auto const& [track, phicandidate] : combinations(CombinationsFullIndexPolicy(groupPartsTrack, groupPartsPhi))) { + if (ConfTrack.confTrackIsIdentified) { + if (!isParticleNSigmaAccepted(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { continue; } } - if (ConfTrack.ConfTrackIsRejected) { - if (IsParticleNSigmaRejected(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + if (ConfTrack.confTrackIsRejected) { + if (isParticleNSigmaRejected(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { continue; } } - // // Close Pair Rejection - if (ConfCPR.ConfCPRIsEnabled.value) { + // Close Pair Rejection + if (ConfCPR.confCPRIsEnabled.value) { if (pairCloseRejection.isClosePair(track, phicandidate, parts, magFieldTesla, femtoUniverseContainer::EventType::same)) { continue; } @@ -572,24 +557,21 @@ struct femtoUniversePairTaskTrackPhi { float weight = 1.0f; if (phieff) { weight = protoneff->GetBinContent(protoneff->FindBin(track.pt(), track.eta())) * phieff->GetBinContent(phieff->FindBin(phicandidate.pt(), phicandidate.eta())); - sameEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); + sameEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.confUse3D, weight); } else { - sameEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); + sameEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.confUse3D, weight); } } + // Used for better fitting of invariant mass background. + TLorentzVector part1Vec; TLorentzVector part2Vec; - float mMassOne = TDatabasePDG::Instance()->GetParticle(321)->Mass(); // FIXME: Get from the PDG service of the common header - float mMassTwo = TDatabasePDG::Instance()->GetParticle(-321)->Mass(); // FIXME: Get from the PDG service of the common header + float mMassOne = o2::constants::physics::MassKPlus; + float mMassTwo = o2::constants::physics::MassKMinus; - for (auto& [kaon1, kaon2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsKaons, groupPartsKaons))) { - // empty if statements commented out on 20241114 to get rid of MegaLinter errors - // if (!IsKaonNSigma(kaon1.p(), trackCuts.getNsigmaTPC(kaon1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(kaon1, o2::track::PID::Kaon))) { - // } - // if (!IsKaonNSigma(kaon2.p(), trackCuts.getNsigmaTPC(kaon2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(kaon2, o2::track::PID::Kaon))) { - // } + for (auto const& [kaon1, kaon2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsKaons, groupPartsKaons))) { if ((kaon1.mAntiLambda() == 1) && (kaon2.mAntiLambda() == 1)) { part1Vec.SetPtEtaPhiM(kaon1.pt(), kaon1.eta(), kaon1.phi(), mMassOne); part2Vec.SetPtEtaPhiM(kaon2.pt(), kaon2.eta(), kaon2.phi(), mMassOne); @@ -611,8 +593,8 @@ struct femtoUniversePairTaskTrackPhi { /// process function for to call doSameEvent with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoUniverseParticleTable - void processSameEvent(o2::aod::FDCollision& col, - FemtoFullParticles& parts) + void processSameEvent(o2::aod::FDCollision const& col, + FemtoFullParticles const& parts) { fillCollision(col); @@ -623,15 +605,15 @@ struct femtoUniversePairTaskTrackPhi { doSameEvent(thegroupPartsTrack, thegroupPartsPhi, thegroupPartsPhiDaugh, thegroupPartsKaons, parts, col.magField(), col.multNtr()); } - PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processSameEvent, "Enable processing same event", true); + PROCESS_SWITCH(FemtoUniversePairTaskTrackPhi, processSameEvent, "Enable processing same event", true); /// process function for to call doSameEvent with Monte Carlo /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) /// \param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth /// \param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table - void processSameEventMC(o2::aod::FDCollision& col, - soa::Join& parts, - o2::aod::FDMCParticles&) + void processSameEventMC(o2::aod::FDCollision const& col, + soa::Join const& parts, + o2::aod::FDMCParticles const&) { fillCollision(col); @@ -642,7 +624,7 @@ struct femtoUniversePairTaskTrackPhi { doSameEvent(thegroupPartsTrack, thegroupPartsPhi, thegroupPartsPhiDaugh, thegroupPartsKaons, parts, col.magField(), col.multNtr()); } - PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processSameEventMC, "Enable processing same event for Monte Carlo", false); + PROCESS_SWITCH(FemtoUniversePairTaskTrackPhi, processSameEventMC, "Enable processing same event for Monte Carlo", false); /// This function processes the mixed event /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... @@ -658,20 +640,20 @@ struct femtoUniversePairTaskTrackPhi { void doMixedEvent(PartitionType groupPartsTrack, PartitionType groupPartsPhi, PartType parts, float magFieldTesla, int multCol) { - for (auto& [track, phicandidate] : combinations(CombinationsFullIndexPolicy(groupPartsTrack, groupPartsPhi))) { - if (ConfTrack.ConfTrackIsIdentified) { - if (!IsParticleNSigmaAccepted(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + for (auto const& [track, phicandidate] : combinations(CombinationsFullIndexPolicy(groupPartsTrack, groupPartsPhi))) { + if (ConfTrack.confTrackIsIdentified) { + if (!isParticleNSigmaAccepted(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { continue; } } - if (ConfTrack.ConfTrackIsRejected) { - if (IsParticleNSigmaRejected(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + if (ConfTrack.confTrackIsRejected) { + if (isParticleNSigmaRejected(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { continue; } } - if (ConfCPR.ConfCPRIsEnabled.value) { + if (ConfCPR.confCPRIsEnabled.value) { if (pairCloseRejection.isClosePair(track, phicandidate, parts, magFieldTesla, femtoUniverseContainer::EventType::mixed)) { continue; } @@ -680,9 +662,9 @@ struct femtoUniversePairTaskTrackPhi { float weight = 1.0f; if (protoneff) { weight = protoneff->GetBinContent(protoneff->FindBin(track.pt(), track.eta())) * phieff->GetBinContent(phieff->FindBin(phicandidate.pt(), phicandidate.eta())); - mixedEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); + mixedEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.confUse3D, weight); } else { - mixedEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.ConfUse3D, weight); + mixedEventAngularCont.setPair(track, phicandidate, multCol, ConfBothTracks.confUse3D, weight); } } } @@ -690,13 +672,13 @@ struct femtoUniversePairTaskTrackPhi { /// process function for to call doMixedEvent with Data /// @param cols subscribe to the collisions table (Data) /// @param parts subscribe to the femtoUniverseParticleTable - void processMixedEvent(o2::aod::FDCollisions& cols, - FemtoFullParticles& parts) + void processMixedEvent(o2::aod::FDCollisions const& cols, + FemtoFullParticles const& parts) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); auto groupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); auto groupPartsPhi = partsPhi->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); @@ -708,25 +690,25 @@ struct femtoUniversePairTaskTrackPhi { continue; } /// \todo before mixing we should check whether both collisions contain a pair of particles! - // if (partsPhi.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTrack.size() == 0 ) continue; + // if (partsPhi.size() == 0 || NPart2Evt1 == 0 || NPart1Evt2 == 0 || partsTrack.size() == 0 ) continue; doMixedEvent(groupPartsTrack, groupPartsPhi, parts, magFieldTesla1, multiplicityCol); } } - PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processMixedEvent, "Enable processing mixed events", true); + PROCESS_SWITCH(FemtoUniversePairTaskTrackPhi, processMixedEvent, "Enable processing mixed events", true); /// brief process function for to call doMixedEvent with Monte Carlo /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) /// @param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth /// @param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table - void processMixedEventMC(o2::aod::FDCollisions& cols, - soa::Join& parts, - o2::aod::FDMCParticles&) + void processMixedEventMC(o2::aod::FDCollisions const& cols, + soa::Join const& parts, + o2::aod::FDMCParticles const&) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); auto groupPartsTrack = partsTrackMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); auto groupPartsPhi = partsPhiMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); @@ -738,19 +720,19 @@ struct femtoUniversePairTaskTrackPhi { continue; } /// \todo before mixing we should check whether both collisions contain a pair of particles! - // if (partsPhi.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTrack.size() == 0 ) continue; + // if (partsPhi.size() == 0 || NPart2Evt1 == 0 || NPart1Evt2 == 0 || partsTrack.size() == 0 ) continue; doMixedEvent(groupPartsTrack, groupPartsPhi, parts, magFieldTesla1, multiplicityCol); } } - PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processMixedEventMC, "Enable processing mixed events MC", false); + PROCESS_SWITCH(FemtoUniversePairTaskTrackPhi, processMixedEventMC, "Enable processing mixed events MC", false); ///--------------------------------------------MC-------------------------------------------------/// /// This function fills MC truth particles from derived MC table void processMCTruth(aod::FDParticles const& parts) { - for (auto& part : parts) { + for (auto const& part : parts) { if (part.partType() != uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) continue; @@ -787,11 +769,11 @@ struct femtoUniversePairTaskTrackPhi { } } } - PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processMCTruth, "Process MC truth data", false); + PROCESS_SWITCH(FemtoUniversePairTaskTrackPhi, processMCTruth, "Process MC truth data", false); void processMCReco(FemtoRecoParticles const& parts, aod::FDMCParticles const& mcparts) { - for (auto& part : parts) { + for (auto const& part : parts) { auto mcPartId = part.fdMCParticleId(); if (mcPartId == -1) continue; // no MC particle @@ -803,14 +785,14 @@ struct femtoUniversePairTaskTrackPhi { } else if (part.partType() == aod::femtouniverseparticle::ParticleType::kTrack) { if (part.sign() > 0) { registryMCreco.fill(HIST("MCrecoAllPositivePt"), mcpart.pt()); - if (mcpart.pdgMCTruth() == 2212 && IsParticleNSigmaAccepted(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + if (mcpart.pdgMCTruth() == 2212 && isParticleNSigmaAccepted(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { registryMCreco.fill(HIST("MCrecoPpos"), mcpart.pt(), mcpart.eta()); } } if (part.sign() < 0) { registryMCreco.fill(HIST("MCrecoAllNegativePt"), mcpart.pt()); - if (mcpart.pdgMCTruth() == -2212 && IsParticleNSigmaAccepted(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + if (mcpart.pdgMCTruth() == -2212 && isParticleNSigmaAccepted(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { registryMCreco.fill(HIST("MCrecoPneg"), mcpart.pt(), mcpart.eta()); } } @@ -818,13 +800,13 @@ struct femtoUniversePairTaskTrackPhi { } } - PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processMCReco, "Process MC reco data", false); + PROCESS_SWITCH(FemtoUniversePairTaskTrackPhi, processMCReco, "Process MC reco data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } From ea4a78380c41fd06350b807cfc5e4e6841613e8e Mon Sep 17 00:00:00 2001 From: Sasha Bylinkin <37345380+abylinkin@users.noreply.github.com> Date: Fri, 13 Dec 2024 17:23:40 +0100 Subject: [PATCH 05/30] [PWGUD] Removing obsolete pids from personal task (#8979) Co-authored-by: ALICE Action Bot --- PWGUD/DataModel/SGTables.h | 8 +------- PWGUD/Tasks/sgPIDAnalyzer.cxx | 24 ------------------------ PWGUD/Tasks/sgPIDSpectraTable.cxx | 17 +++++++++-------- 3 files changed, 10 insertions(+), 39 deletions(-) diff --git a/PWGUD/DataModel/SGTables.h b/PWGUD/DataModel/SGTables.h index e0896459fea..a9bcd664063 100644 --- a/PWGUD/DataModel/SGTables.h +++ b/PWGUD/DataModel/SGTables.h @@ -54,17 +54,11 @@ DECLARE_SOA_COLUMN(TOFel, tofel, float); DECLARE_SOA_COLUMN(TPCmu, tpcmu, float); DECLARE_SOA_COLUMN(TOFmu, tofmu, float); DECLARE_SOA_COLUMN(TPCde, tpcde, float); -DECLARE_SOA_COLUMN(TPCtr, tpctr, float); -DECLARE_SOA_COLUMN(TPChe, tpche, float); -DECLARE_SOA_COLUMN(TPCal, tpcal, float); DECLARE_SOA_COLUMN(TOFde, tofde, float); -DECLARE_SOA_COLUMN(TOFtr, toftr, float); -DECLARE_SOA_COLUMN(TOFhe, tofhe, float); -DECLARE_SOA_COLUMN(TOFal, tofal, float); } // namespace sgtrack DECLARE_SOA_TABLE(SGTracks, "AOD", "SGTRACK", o2::soa::Index<>, sgtrack::SGEventId, - sgtrack::Pt, sgtrack::Eta, sgtrack::Phi, sgtrack::Sign, sgtrack::TPCpi, sgtrack::TPCka, sgtrack::TPCpr, sgtrack::TPCel, sgtrack::TOFpi, sgtrack::TOFka, sgtrack::TOFpr, sgtrack::TOFel, sgtrack::TPCmu, sgtrack::TOFmu, sgtrack::TPCde, sgtrack::TPCtr, sgtrack::TPChe, sgtrack::TPCal, sgtrack::TOFde, sgtrack::TOFtr, sgtrack::TOFhe, sgtrack::TOFal); + sgtrack::Pt, sgtrack::Eta, sgtrack::Phi, sgtrack::Sign, sgtrack::TPCpi, sgtrack::TPCka, sgtrack::TPCpr, sgtrack::TPCel, sgtrack::TOFpi, sgtrack::TOFka, sgtrack::TOFpr, sgtrack::TOFel, sgtrack::TPCmu, sgtrack::TOFmu, sgtrack::TPCde, sgtrack::TOFde); using SGTrack = SGTracks::iterator; } // namespace o2::aod diff --git a/PWGUD/Tasks/sgPIDAnalyzer.cxx b/PWGUD/Tasks/sgPIDAnalyzer.cxx index 9a69891ee0a..e4015417971 100644 --- a/PWGUD/Tasks/sgPIDAnalyzer.cxx +++ b/PWGUD/Tasks/sgPIDAnalyzer.cxx @@ -61,12 +61,6 @@ struct sgPIDAnalyzer { histos.add("TPC/nTPC_El", "Negative TPC El Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); histos.add("TPC/pTPC_De", "Positive TPC De Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); histos.add("TPC/nTPC_De", "Negative TPC De Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); - histos.add("TPC/pTPC_Tr", "Positive TPC Tr Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); - histos.add("TPC/nTPC_Tr", "Negative TPC Tr Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); - histos.add("TPC/pTPC_He", "Positive TPC He Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); - histos.add("TPC/nTPC_He", "Negative TPC He Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); - histos.add("TPC/pTPC_Al", "Positive TPC Al Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); - histos.add("TPC/nTPC_Al", "Negative TPC Al Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); histos.add("TPC/pTPC_Mu", "Positive TPC Mu Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); histos.add("TPC/nTPC_Mu", "Negative TPC Mu Tracks", {HistType::kTH2F, {ptBins, nSigmaBins}}); @@ -164,12 +158,6 @@ struct sgPIDAnalyzer { histos.add("TOF/nEl", "Negative TPC El vs TOF El vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); histos.add("TOF/pDe", "Positive TPC De vs TOF Pi vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); histos.add("TOF/nDe", "Negative TPC De vs TOF Pi vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); - histos.add("TOF/pTr", "Positive TPC Tr vs TOF Ka vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); - histos.add("TOF/nTr", "Negative TPC Tr vs TOF Ka vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); - histos.add("TOF/pHe", "Positive TPC He vs TOF Pr vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); - histos.add("TOF/nHe", "Negative TPC He vs TOF Pr vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); - histos.add("TOF/pAl", "Positive TPC Al vs TOF El vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); - histos.add("TOF/nAl", "Negative TPC Al vs TOF El vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); histos.add("TOF/pMu", "Positive TPC Mu vs TOF El vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); histos.add("TOF/nMu", "Negative TPC Mu vs TOF El vs pt", {HistType::kTH3F, {ptBins, ntofBins, ntofBins}}); } @@ -189,9 +177,6 @@ struct sgPIDAnalyzer { histos.fill(HIST("TPC/pTPC_Pr"), track.pt(), track.tpcpr()); histos.fill(HIST("TPC/pTPC_El"), track.pt(), track.tpcel()); histos.fill(HIST("TPC/pTPC_De"), track.pt(), track.tpcde()); - histos.fill(HIST("TPC/pTPC_Tr"), track.pt(), track.tpctr()); - histos.fill(HIST("TPC/pTPC_He"), track.pt(), track.tpche()); - histos.fill(HIST("TPC/pTPC_Al"), track.pt(), track.tpcal()); histos.fill(HIST("TPC/pTPC_Mu"), track.pt(), track.tpcmu()); if (std::abs(track.tpcpi()) < 1) { histos.fill(HIST("TPC/pTPC_Ka_Pi"), track.pt(), track.tpcka()); @@ -229,9 +214,6 @@ struct sgPIDAnalyzer { histos.fill(HIST("TPC/nTPC_Pr"), track.pt(), track.tpcpr()); histos.fill(HIST("TPC/nTPC_El"), track.pt(), track.tpcel()); histos.fill(HIST("TPC/nTPC_De"), track.pt(), track.tpcde()); - histos.fill(HIST("TPC/nTPC_Tr"), track.pt(), track.tpctr()); - histos.fill(HIST("TPC/nTPC_He"), track.pt(), track.tpche()); - histos.fill(HIST("TPC/nTPC_Al"), track.pt(), track.tpcal()); histos.fill(HIST("TPC/nTPC_Mu"), track.pt(), track.tpcmu()); if (std::abs(track.tpcpi()) < 1) { histos.fill(HIST("TPC/nTPC_Ka_Pi"), track.pt(), track.tpcka()); @@ -271,9 +253,6 @@ struct sgPIDAnalyzer { histos.fill(HIST("TOF/pPr"), track.pt(), track.tpcpr(), track.tofpr()); histos.fill(HIST("TOF/pEl"), track.pt(), track.tpcel(), track.tofel()); histos.fill(HIST("TOF/pDe"), track.pt(), track.tpcpi(), track.tofde()); - histos.fill(HIST("TOF/pTr"), track.pt(), track.tpcka(), track.toftr()); - histos.fill(HIST("TOF/pHe"), track.pt(), track.tpcpr(), track.tofhe()); - histos.fill(HIST("TOF/pAl"), track.pt(), track.tpcel(), track.tofal()); histos.fill(HIST("TOF/pMu"), track.pt(), track.tpcel(), track.tofmu()); if (std::abs(track.tofpi()) < 1) { histos.fill(HIST("TOF/pTOF_Ka_Pi"), track.pt(), track.tofka()); @@ -311,9 +290,6 @@ struct sgPIDAnalyzer { histos.fill(HIST("TOF/nPr"), track.pt(), track.tpcpr(), track.tofpr()); histos.fill(HIST("TOF/nEl"), track.pt(), track.tpcel(), track.tofel()); histos.fill(HIST("TOF/nDe"), track.pt(), track.tpcpi(), track.tofde()); - histos.fill(HIST("TOF/nTr"), track.pt(), track.tpcka(), track.toftr()); - histos.fill(HIST("TOF/nHe"), track.pt(), track.tpcpr(), track.tofhe()); - histos.fill(HIST("TOF/nAl"), track.pt(), track.tpcel(), track.tofal()); histos.fill(HIST("TOF/nMu"), track.pt(), track.tpcel(), track.tofmu()); if (std::abs(track.tofpi()) < 1) { histos.fill(HIST("TOF/nTOF_Ka_Pi"), track.pt(), track.tofka()); diff --git a/PWGUD/Tasks/sgPIDSpectraTable.cxx b/PWGUD/Tasks/sgPIDSpectraTable.cxx index e5ad7187a34..f8e6e69373c 100644 --- a/PWGUD/Tasks/sgPIDSpectraTable.cxx +++ b/PWGUD/Tasks/sgPIDSpectraTable.cxx @@ -81,7 +81,7 @@ struct SGPIDSpectraTable { std::vector parameters = {PV_cut, dcaZ_cut, dcaXY_cut, tpcChi2_cut, tpcNClsFindable_cut, itsChi2_cut, eta_cut, pt_cut}; // check rho0 signals float tpcpi, tpcka, tpcel, tpcpr, tofpi, tofka, tofpr, tofel; - float tpcde, tpctr, tpche, tpcal, tofde, toftr, tofhe, tofal, tpcmu, tofmu; + float tpcde, tofde, tpcmu, tofmu; TVector3 a; int goodtracks = 0; for (auto t : tracks) { @@ -107,14 +107,15 @@ struct SGPIDSpectraTable { tofpr = t.hasTOF() ? t.tofNSigmaPr() : -999; tofel = t.hasTOF() ? t.tofNSigmaEl() : -999; tpcde = t.hasTPC() ? t.tpcNSigmaDe() : -999; - tpctr = t.hasTPC() ? t.tpcNSigmaTr() : -999; - tpche = t.hasTPC() ? t.tpcNSigmaHe() : -999; - tpcal = t.hasTPC() ? t.tpcNSigmaAl() : -999; + // tpctr = t.hasTPC() ? t.tpcNSigmaTr() : -999; + // tpche = t.hasTPC() ? t.tpcNSigmaHe() : -999; + // tpcal = t.hasTPC() ? t.tpcNSigmaAl() : -999; tofde = t.hasTOF() ? t.tofNSigmaDe() : -999; - toftr = t.hasTOF() ? t.tofNSigmaTr() : -999; - tofhe = t.hasTOF() ? t.tofNSigmaHe() : -999; - tofal = t.hasTOF() ? t.tofNSigmaAl() : -999; - SGtracks(SGevents.lastIndex(), a.Pt(), a.Eta(), a.Phi(), t.sign(), tpcpi, tpcka, tpcpr, tpcel, tofpi, tofka, tofpr, tofel, tpcmu, tofmu, tpcde, tpctr, tpche, tpcal, tofde, toftr, tofhe, tofal); + // toftr = t.hasTOF() ? t.tofNSigmaTr() : -999; + // tofhe = t.hasTOF() ? t.tofNSigmaHe() : -999; + // tofal = t.hasTOF() ? t.tofNSigmaAl() : -999; + // SGtracks(SGevents.lastIndex(),a.Pt(),a.Eta(),a.Phi(),t.sign(),tpcpi, tpcka, tpcpr, tpcel, tofpi, tofka, tofpr, tofel, tpcmu, tofmu, tpcde, tpctr, tpche, tpcal, tofde, toftr, tofhe, tofal); + SGtracks(SGevents.lastIndex(), a.Pt(), a.Eta(), a.Phi(), t.sign(), tpcpi, tpcka, tpcpr, tpcel, tofpi, tofka, tofpr, tofel, tpcmu, tofmu, tpcde, tofde); } } } From 00033943f96a8384a69ea12319272ff17c04b05d Mon Sep 17 00:00:00 2001 From: Yash Patley <52608802+yashpatley@users.noreply.github.com> Date: Sat, 14 Dec 2024 00:22:12 +0530 Subject: [PATCH 06/30] [PWGCF] Update lambdaR2Correlation.cxx (#8973) --- .../Tasks/lambdaR2Correlation.cxx | 134 +++++++++++------- 1 file changed, 79 insertions(+), 55 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index fa0d783fe52..ed063e4812a 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -165,14 +165,14 @@ struct LambdaCorrTableProducer { Configurable cTrackMinDcaXY{"cTrackMinDcaXY", 0.05, "Minimum DcaXY of Daughter Tracks"}; // V0s - Configurable cMinV0DcaDaughters{"cMinV0DcaDaughters", 1.0, "min DCA between V0 daughters"}; + Configurable cMinV0DcaDaughters{"cMinV0DcaDaughters", 1.4, "min DCA between V0 daughters"}; Configurable cMinDcaPosToPV{"cMinDcaPosToPV", 0.1, "Minimum V0 Positive Track DCAr cut to PV"}; Configurable cMinDcaNegToPV{"cMinDcaNegToPV", 0.1, "Minimum V0 Negative Track DCAr cut to PV"}; - Configurable cMinDcaV0ToPV{"cMinDcaV0ToPV", 0.6, "Minimum DCA V0 to PV"}; - Configurable cMinV0TransRadius{"cMinV0TransRadius", 0.0, "Minimum V0 radius from PV"}; - Configurable cMaxV0TransRadius{"cMaxV0TransRadius", 50.0, "Maximum V0 radius from PV"}; + Configurable cMinDcaV0ToPV{"cMinDcaV0ToPV", 3.0, "Minimum DCA V0 to PV"}; + Configurable cMinV0TransRadius{"cMinV0TransRadius", 0.2, "Minimum V0 radius from PV"}; + Configurable cMaxV0TransRadius{"cMaxV0TransRadius", 200.0, "Maximum V0 radius from PV"}; Configurable cMinV0CTau{"cMinV0CTau", 0.0, "Minimum ctau"}; - Configurable cMaxV0CTau{"cMaxV0CTau", 50.0, "Maximum ctau"}; + Configurable cMaxV0CTau{"cMaxV0CTau", 30.0, "Maximum ctau"}; Configurable cMinV0CosPA{"cMinV0CosPA", 0.998, "Minimum V0 CosPA to PV"}; Configurable cLambdaMassWindow{"cLambdaMassWindow", 0.007, "Mass Window to select Lambda"}; Configurable cKshortRejMassWindow{"cKshortRejMassWindow", 0.005, "Reject K0Short Candidates"}; @@ -183,13 +183,14 @@ struct LambdaCorrTableProducer { // V0s kinmatic acceptance Configurable cMinV0Pt{"cMinV0Pt", 0.8, "Minimum V0 pT"}; Configurable cMaxV0Pt{"cMaxV0Pt", 3.2, "Minimum V0 pT"}; - Configurable cMaxV0Rap{"cMaxV0Rap", 0.6, "|rap| cut"}; + Configurable cMaxV0Rap{"cMaxV0Rap", 0.8, "|rap| cut"}; // V0s MC Configurable cHasMcFlag{"cHasMcFlag", true, "Has Mc Tag"}; - Configurable cSelectTrueLambda{"cSelectTrueLambda", true, "Select True Lambda"}; - Configurable cRecPrimaryLambda{"cRecPrimaryLambda", true, "Primary Lambda"}; - Configurable cGenPrimaryLambda{"cGenPrimaryLambda", true, "Primary Lambda"}; + Configurable cSelectTrueLambda{"cSelectTrueLambda", false, "Select True Lambda"}; + Configurable cRecPrimaryLambda{"cRecPrimaryLambda", false, "Primary Reconstructed Lambda"}; + Configurable cRecSecondaryLambda{"cRecSecondaryLambda", false, "Secondary Reconstructed Lambda"}; + Configurable cGenPrimaryLambda{"cGenPrimaryLambda", true, "Primary Generated Lambda"}; // Efficiency Correction Configurable cCorrectionFlag{"cCorrectionFlag", true, "Efficiency Correction Flag"}; @@ -206,9 +207,9 @@ struct LambdaCorrTableProducer { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // initialize corr_factor objects - std::vector> vCorrFactStrings = {{"h1f_LaP_cf", "h1f_LaM_cf"}, - {"h2f_LaP_cf", "h2f_LaM_cf"}, - {"h3f_LaP_cf", "h3f_LaM_cf"}}; + std::vector> vCorrFactStrings = {{"hEffVsPtLambda", "hEffVsPtAntiLambda"}, + {"hEffVsPtYLambda", "hEffVsPtYAntiLambda"}, + {"hEffVsPtYVzLambda", "hEffVsPtYVzAntiLambda"}}; void init(InitContext const&) { @@ -294,6 +295,7 @@ struct LambdaCorrTableProducer { histos.add("Tracks/h2f_tracks_pid_after_sel", "PIDs", kTH2F, {axisPID, axisV0Pt}); histos.add("Tracks/h2f_lambda_from_sigma", "PIDs", kTH2F, {axisPID, axisV0Pt}); histos.add("Tracks/h2f_lambda_from_cascade", "PIDs", kTH2F, {axisPID, axisV0Pt}); + histos.add("Tracks/h2f_lambda_from_omega", "PIDs", kTH2F, {axisPID, axisV0Pt}); // McGen Histos histos.add("McGen/h1f_collisions_info", "# of collisions", kTH1F, {axisCol}); @@ -420,16 +422,6 @@ struct LambdaCorrTableProducer { histos.fill(HIST("Tracks/h1f_tracks_info"), 4.5); - // Armentros-Podolanski Selection - if (cArmPodCutFlag && (std::abs(v0.alpha()) < v0.qtarm() / cArmPodCutValue)) { - return false; - } - - // Kshort mass rejection hypothesis - if (cKshortRejFlag && (std::abs(v0.mK0Short() - MassK0Short) <= cKshortRejMassWindow)) { - return false; - } - return true; } @@ -483,14 +475,30 @@ struct LambdaCorrTableProducer { } if (!lambdaFlag && !antiLambdaFlag) { // neither Lambda nor Anti-Lambda - histos.fill(HIST("Tracks/h1f_tracks_info"), 18.5); + histos.fill(HIST("Tracks/h1f_tracks_info"), 17.5); return false; } else if (lambdaFlag && antiLambdaFlag) { // check if the track is identified as lambda and anti-lambda both (DISCARD THIS TRACK) - histos.fill(HIST("Tracks/h1f_tracks_info"), 19.5); + histos.fill(HIST("Tracks/h1f_tracks_info"), 18.5); return false; } - return true; + // Armentros-Podolanski Selection + if (cArmPodCutFlag && (std::abs(v0.alpha()) < v0.qtarm() / cArmPodCutValue)) { + return false; + } + + // Kshort mass rejection hypothesis + if (cKshortRejFlag && (std::abs(v0.mK0Short() - MassK0Short) <= cKshortRejMassWindow)) { + return false; + } + + if (lambdaFlag || antiLambdaFlag) { + return true; + } + + histos.fill(HIST("Tracks/h1f_tracks_info"), 19.5); + + return false; } template @@ -498,19 +506,17 @@ struct LambdaCorrTableProducer { { auto mcpart = v0.template mcParticle_as(); - // check for lambda/anti-lambda if (std::abs(mcpart.pdgCode()) != kLambda0) { - histos.fill(HIST("Tracks/h1f_tracks_info"), 10.5); return false; } // check for primary/secondary lambda if (cRecPrimaryLambda && !mcpart.isPhysicalPrimary()) { - histos.fill(HIST("Tracks/h1f_tracks_info"), 11.5); - return false; - } else if (!cRecPrimaryLambda && mcpart.isPhysicalPrimary()) { histos.fill(HIST("Tracks/h1f_tracks_info"), 12.5); return false; + } else if (cRecSecondaryLambda && mcpart.isPhysicalPrimary()) { + histos.fill(HIST("Tracks/h1f_tracks_info"), 13.5); + return false; } auto postrack = v0.template posTrack_as(); @@ -518,16 +524,35 @@ struct LambdaCorrTableProducer { // check if the daughters have corresponding mcparticle if (!postrack.has_mcParticle() || !negtrack.has_mcParticle()) { - histos.fill(HIST("Tracks/h1f_tracks_info"), 13.5); + histos.fill(HIST("Tracks/h1f_tracks_info"), 14.5); return false; } auto mcpostrack = postrack.template mcParticle_as(); auto mcnegtrack = negtrack.template mcParticle_as(); - if (std::abs(mcpostrack.pdgCode()) != kProton || std::abs(mcnegtrack.pdgCode()) != kPiPlus) { // incorrect decay channel -> return false - histos.fill(HIST("Tracks/h1f_tracks_info"), 14.5); - return false; + if (mcpart.pdgCode() == kLambda0) { + if (mcpostrack.pdgCode() != kProton || mcnegtrack.pdgCode() != kPiMinus) { + histos.fill(HIST("Tracks/h1f_tracks_info"), 15.5); + return false; + } + } else if (mcpart.pdgCode() == kLambda0Bar) { + if (mcpostrack.pdgCode() != kPiPlus || mcnegtrack.pdgCode() != kProtonBar) { + histos.fill(HIST("Tracks/h1f_tracks_info"), 16.5); + return false; + } + } + + // get information about secondary lambdas + if (cRecSecondaryLambda) { + auto lambdaMothers = mcpart.template mothers_as(); + if (std::abs(lambdaMothers[0].pdgCode()) == 3112 || std::abs(lambdaMothers[0].pdgCode()) == 3212 || std::abs(lambdaMothers[0].pdgCode()) == 3222) { + histos.fill(HIST("Tracks/h2f_lambda_from_sigma"), mcpart.pdgCode(), mcpart.pt()); + } else if (std::abs(lambdaMothers[0].pdgCode()) == 3312 || std::abs(lambdaMothers[0].pdgCode()) == 3322) { + histos.fill(HIST("Tracks/h2f_lambda_from_cascade"), mcpart.pdgCode(), mcpart.pt()); + } else if (std::abs(lambdaMothers[0].pdgCode()) == 3334) { + histos.fill(HIST("Tracks/h2f_lambda_from_omega"), mcpart.pdgCode(), mcpart.pt()); + } } return true; @@ -552,25 +577,22 @@ struct LambdaCorrTableProducer { // get ccdb object TObject* obj = reinterpret_cast(ccdbObj->FindObject(Form("%s", vCorrFactStrings[cCorrFactHistType][part].c_str()))); - - if (obj->InheritsFrom("TH1F")) { - TH1F* hist = reinterpret_cast(obj->Clone()); - int ptBin = hist->GetXaxis()->FindBin(v0.pt()); - return hist->GetBinContent(ptBin); - } else if (obj->InheritsFrom("TH2F")) { - TH2F* hist = reinterpret_cast(obj->Clone()); - int ptBin = hist->GetXaxis()->FindBin(v0.pt()); - int rapBin = hist->GetYaxis()->FindBin(v0.yLambda()); - return hist->GetBinContent(ptBin, rapBin); - } else if (obj->InheritsFrom("TH3F")) { - TH3F* hist = reinterpret_cast(obj->Clone()); - int ptBin = hist->GetXaxis()->FindBin(v0.pt()); - int rapBin = hist->GetYaxis()->FindBin(v0.yLambda()); - int vzBin = hist->GetZaxis()->FindBin(col.posZ()); - return hist->GetBinContent(ptBin, rapBin, vzBin); + TH1F* hist = reinterpret_cast(obj->Clone()); + float retVal = 0.; + + if (std::string(obj->ClassName()) == "TH1F") { + retVal = hist->GetBinContent(hist->FindBin(v0.pt())); + } else if (std::string(obj->ClassName()) == "TH2F") { + retVal = hist->GetBinContent(hist->FindBin(v0.pt(), v0.yLambda())); + } else if (std::string(obj->ClassName()) == "TH3F") { + retVal = hist->GetBinContent(hist->FindBin(v0.pt(), v0.yLambda(), col.posZ())); } else { - return 1.; + LOGF(warning, "CCDB OBJECT IS NOT A HISTOGRAM !!!"); + retVal = 1.; } + + delete hist; + return retVal; } template @@ -674,7 +696,6 @@ struct LambdaCorrTableProducer { } histos.fill(HIST("Tracks/h1f_tracks_info"), 6.5); - histos.fill(HIST("Tracks/h2f_armpod_after_sel"), v0.alpha(), v0.qtarm()); // we have v0 as lambda // do MC analysis @@ -687,6 +708,8 @@ struct LambdaCorrTableProducer { histos.fill(HIST("Tracks/h2f_tracks_pid_after_sel"), v0.mcParticle().pdgCode(), v0.pt()); } + histos.fill(HIST("Tracks/h2f_armpod_after_sel"), v0.alpha(), v0.qtarm()); + // get correction factors and mass corr_fact = (v0type == kLambda) ? getCorrectionFactors(collision, v0) : getCorrectionFactors(collision, v0); mass = (v0type == kLambda) ? v0.mLambda() : v0.mAntiLambda(); @@ -831,7 +854,7 @@ struct LambdaR2Correlation { const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); const AxisSpec axisMult(10, 0, 10, "N_{#Lambda}"); const AxisSpec axisMass(100, 1.06, 1.16, "Inv Mass (GeV/#it{c}^{2})"); - const AxisSpec axisPt(64, 0.2, 3.5, "p_{T} (GeV/#it{c})"); + const AxisSpec axisPt(64, 0.2, 3.4, "p_{T} (GeV/#it{c})"); const AxisSpec axisEta(24, -1.2, 1.2, "#eta"); const AxisSpec axisCPA(100, 0.99, 1.0, "cos(#theta_{PA})"); const AxisSpec axisDcaDau(75, 0., 1.5, "Daug DCA (#sigma)"); @@ -864,6 +887,8 @@ struct LambdaR2Correlation { histos.addClone("Reco/QA_Lambda/", "Reco/QA_AntiLambda/"); // Efficiency Histograms + histos.add("Reco/Efficiency/h1f_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH1F, {axisEfPt}); + histos.add("Reco/Efficiency/h1f_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1F, {axisEfPt}); histos.add("Reco/Efficiency/h2f_n1_pteta_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisEfPt, axisEfEta}); histos.add("Reco/Efficiency/h2f_n1_pteta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisEfPt, axisEfEta}); histos.add("Reco/Efficiency/h2f_n1_ptrap_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisEfPt, axisEfRap}); @@ -1022,6 +1047,7 @@ struct LambdaR2Correlation { histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h1d_n1_rap_") + HIST(SubDirHist[part]), track.rap(), track.corrFact()); // Efficiency Calculation Plots + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h1f_n1_pt_") + HIST(SubDirHist[part]), track.pt()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h2f_n1_pteta_") + HIST(SubDirHist[part]), track.pt(), track.eta()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h2f_n1_ptrap_") + HIST(SubDirHist[part]), track.pt(), track.rap()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h3f_n1_ptetaposz_") + HIST(SubDirHist[part]), track.pt(), track.eta(), col.posZ()); @@ -1082,7 +1108,6 @@ struct LambdaR2Correlation { using LambdaTracks = aod::LambdaTracks; SliceCache cache; - Partition partLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kLambda); Partition partAntiLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kAntiLambda); @@ -1112,7 +1137,6 @@ struct LambdaR2Correlation { void processMCGen(LambdaMcGenCollisions::iterator const& mcgencol, LambdaMcGenTracks const&) { - histos.fill(HIST("Event/McGen/h1f_collision_posz"), mcgencol.posZ()); auto lambdaMcGenTracks = partLambdaMcGenTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); From 7727b0fd654c18f7772b8835473bd3c0f8314d06 Mon Sep 17 00:00:00 2001 From: Fabrizio Chinu <91954233+fchinu@users.noreply.github.com> Date: Fri, 13 Dec 2024 20:11:01 +0100 Subject: [PATCH 07/30] [PWGHF] Add selection on radius and fix pid variables filling (#8981) --- PWGHF/Tasks/taskPidStudies.cxx | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/PWGHF/Tasks/taskPidStudies.cxx b/PWGHF/Tasks/taskPidStudies.cxx index 8516963bafc..8b905524fb0 100644 --- a/PWGHF/Tasks/taskPidStudies.cxx +++ b/PWGHF/Tasks/taskPidStudies.cxx @@ -119,6 +119,7 @@ DECLARE_SOA_TABLE(PidCascades, "AOD", "PIDCASCADES", //! Table with PID informat pid_studies::Pt, pid_studies::BachPt, pid_studies::TpcInnerParBach, + pid_studies::Radius, pid_studies::MLambda, pid_studies::V0cosPA, pid_studies::MassXi, @@ -144,6 +145,7 @@ struct HfTaskPidStudies { Configurable massLambdaMax{"massLambdaMax", 1.3, "Maximum mass for lambda"}; Configurable massOmegaMin{"massOmegaMin", 1.5, "Minimum mass for omega"}; Configurable massOmegaMax{"massOmegaMax", 1.8, "Maximum mass for omega"}; + Configurable radiusMax{"radiusMax", 2.3, "Maximum decay radius (cm)"}; Configurable qtArmenterosMinForK0{"qtArmenterosMinForK0", 0.12, "Minimum Armenteros' qt for K0"}; Configurable qtArmenterosMaxForLambda{"qtArmenterosMaxForLambda", 0.12, "Minimum Armenteros' qt for (anti)Lambda"}; Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of candidates to keep"}; @@ -188,14 +190,14 @@ struct HfTaskPidStudies { candidate.v0cosPA(), candidate.dcaV0daughters(), candidate.dcav0topv(), - posTrack.tofNSigmaPi(), - negTrack.tofNSigmaPi(), - posTrack.tofNSigmaPr(), - negTrack.tofNSigmaPr(), posTrack.tpcNSigmaPi(), negTrack.tpcNSigmaPi(), posTrack.tpcNSigmaPr(), negTrack.tpcNSigmaPr(), + posTrack.tofNSigmaPi(), + negTrack.tofNSigmaPi(), + posTrack.tofNSigmaPr(), + negTrack.tofNSigmaPr(), candidate.alpha(), candidate.qtarm(), coll.ft0cOccupancyInTimeRange(), @@ -210,6 +212,7 @@ struct HfTaskPidStudies { candidate.pt(), candidate.bachelorpt(), bachTrack.tpcInnerParam(), + candidate.cascradius(), candidate.mLambda(), candidate.v0cosPA(coll.posX(), coll.posY(), coll.posZ()), candidate.mXi(), @@ -276,6 +279,9 @@ struct HfTaskPidStudies { if (v0.qtarm() < qtArmenterosMinForK0) { return false; } + if (v0.v0radius() > radiusMax) { + return false; + } return true; } @@ -289,6 +295,9 @@ struct HfTaskPidStudies { if (v0.qtarm() > qtArmenterosMaxForLambda) { return false; } + if (v0.v0radius() > radiusMax) { + return false; + } return true; } @@ -301,6 +310,9 @@ struct HfTaskPidStudies { if (casc.mLambda() < massLambdaMin || casc.mLambda() > massLambdaMax) { return false; } + if (casc.cascradius() > radiusMax) { + return false; + } return true; } From ea2fd767ce7c6223b10845b1dbbc61b967661587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BiaoZhang=20=28=E5=BC=A0=E5=BD=AA=29?= <52267892+zhangbiao-phy@users.noreply.github.com> Date: Fri, 13 Dec 2024 20:43:59 +0100 Subject: [PATCH 08/30] [PWGHF] Add D0 D0bar reflection infos tagged from data in D0 task (#8891) --- PWGHF/D2H/Tasks/taskD0.cxx | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskD0.cxx b/PWGHF/D2H/Tasks/taskD0.cxx index f76d9d7bfb8..c4870213625 100644 --- a/PWGHF/D2H/Tasks/taskD0.cxx +++ b/PWGHF/D2H/Tasks/taskD0.cxx @@ -35,10 +35,12 @@ using namespace o2::framework::expressions; namespace { enum CandTypeSel { - SigD0 = 0, // Signal D0 - SigD0bar, // Signal D0bar - ReflectedD0, // Reflected D0 - ReflectedD0bar // Reflected D0bar + SigD0 = 0, // Signal D0 + SigD0bar, // Signal D0bar + ReflectedD0, // Reflected D0 + ReflectedD0bar, // Reflected D0bar + PureSigD0, // Signal D0 exclude Reflected D0bar + PureSigD0bar // Signal D0bar exclude Reflected D0 }; } // namespace struct HfTaskD0 { @@ -63,7 +65,7 @@ struct HfTaskD0 { ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {500, 0, 50}, "Cand. pT bins"}; ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {20, -1, 1}, "Cand. rapidity bins"}; ConfigurableAxis thnConfigAxisOrigin{"thnConfigAxisOrigin", {3, -0.5, 2.5}, "Cand. origin type"}; - ConfigurableAxis thnConfigAxisCandType{"thnConfigAxisCandType", {4, -0.5, 3.5}, "D0 type"}; + ConfigurableAxis thnConfigAxisCandType{"thnConfigAxisCandType", {6, -0.5, 5.5}, "D0 type"}; ConfigurableAxis thnConfigAxisGenPtD{"thnConfigAxisGenPtD", {500, 0, 50}, "Gen Pt D"}; ConfigurableAxis thnConfigAxisGenPtB{"thnConfigAxisGenPtB", {1000, 0, 100}, "Gen Pt B"}; ConfigurableAxis thnConfigAxisNumPvContr{"thnConfigAxisNumPvContr", {200, -0.5, 199.5}, "Number of PV contributors"}; @@ -318,16 +320,36 @@ struct HfTaskD0 { if constexpr (applyMl) { if (candidate.isSelD0() >= selectionFlagD0) { registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], candidate.mlProbD0()[2], massD0, ptCandidate, hfHelper.yD0(candidate), SigD0); + if (candidate.isSelD0bar()) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], candidate.mlProbD0()[2], massD0, ptCandidate, hfHelper.yD0(candidate), ReflectedD0); + } else if (!candidate.isSelD0bar()) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], candidate.mlProbD0()[2], massD0, ptCandidate, hfHelper.yD0(candidate), PureSigD0); + } } if (candidate.isSelD0bar() >= selectionFlagD0bar) { registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsD0Type"), candidate.mlProbD0bar()[0], candidate.mlProbD0bar()[1], candidate.mlProbD0bar()[2], massD0bar, ptCandidate, hfHelper.yD0(candidate), SigD0bar); + if (candidate.isSelD0()) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], candidate.mlProbD0()[2], massD0bar, ptCandidate, hfHelper.yD0(candidate), ReflectedD0bar); + } else if (!candidate.isSelD0()) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsPtBVsYVsOriginVsD0Type"), candidate.mlProbD0bar()[0], candidate.mlProbD0bar()[1], candidate.mlProbD0bar()[2], massD0bar, ptCandidate, hfHelper.yD0(candidate), PureSigD0bar); + } } } else { if (candidate.isSelD0() >= selectionFlagD0) { registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsD0Type"), massD0, ptCandidate, hfHelper.yD0(candidate), SigD0); + if (candidate.isSelD0bar()) { + registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsD0Type"), massD0, ptCandidate, hfHelper.yD0(candidate), ReflectedD0); + } else if (!candidate.isSelD0bar()) { + registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsD0Type"), massD0, ptCandidate, hfHelper.yD0(candidate), PureSigD0); + } } if (candidate.isSelD0bar() >= selectionFlagD0bar) { registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsD0Type"), massD0bar, ptCandidate, hfHelper.yD0(candidate), SigD0bar); + if (candidate.isSelD0()) { + registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsD0Type"), massD0bar, ptCandidate, hfHelper.yD0(candidate), ReflectedD0bar); + } else if (!candidate.isSelD0()) { + registry.fill(HIST("hMassVsPtVsPtBVsYVsOriginVsD0Type"), massD0bar, ptCandidate, hfHelper.yD0(candidate), PureSigD0bar); + } } } } From f60e2b94078b7f5c93733da171c64bb7145f570c Mon Sep 17 00:00:00 2001 From: prottayCMT <61418725+prottayCMT@users.noreply.github.com> Date: Fri, 13 Dec 2024 21:24:15 +0100 Subject: [PATCH 09/30] [PWGLF] removed TOF tables due to memory consumption in Hyperloop (#8985) Co-authored-by: Prottay Das --- PWGLF/Tasks/Strangeness/lambdapolsp.cxx | 33 ++++++------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx index bc0993bb77a..fb1d114efe5 100644 --- a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx +++ b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx @@ -100,7 +100,6 @@ struct lambdapolsp { Configurable cfgTPCcluster{"cfgTPCcluster", 70, "Number of TPC cluster"}; Configurable isPVContributor{"isPVContributor", true, "is PV contributor"}; Configurable checkwithpub{"checkwithpub", true, "checking results with published"}; - Configurable useTPCTOF{"useTPCTOF", true, "flag to use TPC and TOF"}; // Configs for V0 Configurable ConfV0PtMin{"ConfV0PtMin", 0.f, "Minimum transverse momentum of V0"}; @@ -120,8 +119,6 @@ struct lambdapolsp { Configurable ConfDaughTPCnclsMin{"ConfDaughTPCnclsMin", 50.f, "V0 Daugh sel: Min. nCls TPC"}; Configurable ConfDaughDCAMin{"ConfDaughDCAMin", 0.08f, "V0 Daugh sel: Max. DCA Daugh to PV (cm)"}; Configurable ConfDaughPIDCuts{"ConfDaughPIDCuts", 3, "PID selections for Lambda daughters"}; - Configurable ConfDaughPIDTPCCuts{"ConfDaughPIDTPCCuts", 3, "PID selections for Lambda daughters in TPC"}; - Configurable ConfDaughPIDTOFCuts{"ConfDaughPIDTOFCuts", 3, "PID selections for Lambda daughters in TOF"}; Configurable CentNbins{"CentNbins", 16, "Number of bins in cent histograms"}; Configurable lbinCent{"lbinCent", 0.0, "lower bin value in cent histograms"}; @@ -413,28 +410,11 @@ struct lambdapolsp { return false; }*/ - if (useTPCTOF) { - if (track.pt() < 0.5 && pid == 0 && TMath::Abs(track.tpcNSigmaPr()) > ConfDaughPIDCuts) { - return false; - } - if (track.pt() < 0.5 && pid == 1 && TMath::Abs(track.tpcNSigmaPi()) > ConfDaughPIDCuts) { - return false; - } - if (track.hasTOF()) { - if (track.pt() > 0.5 && pid == 0 && TMath::Abs(track.tpcNSigmaPr()) > ConfDaughPIDTPCCuts && TMath::Abs(track.tofNSigmaPr()) > ConfDaughPIDTOFCuts) { - return false; - } - if (track.pt() > 0.5 && pid == 1 && TMath::Abs(track.tpcNSigmaPi()) > ConfDaughPIDTPCCuts && TMath::Abs(track.tofNSigmaPi()) > ConfDaughPIDTOFCuts) { - return false; - } - } - } else { - if (pid == 0 && TMath::Abs(track.tpcNSigmaPr()) > ConfDaughPIDCuts) { - return false; - } - if (pid == 1 && TMath::Abs(track.tpcNSigmaPi()) > ConfDaughPIDCuts) { - return false; - } + if (pid == 0 && TMath::Abs(track.tpcNSigmaPr()) > ConfDaughPIDCuts) { + return false; + } + if (pid == 1 && TMath::Abs(track.tpcNSigmaPi()) > ConfDaughPIDCuts) { + return false; } if (pid == 0 && pt < cfgDaughPrPt) { @@ -477,7 +457,8 @@ struct lambdapolsp { using EventCandidates = soa::Filtered>; // using AllTrackCandidates = soa::Join; - using AllTrackCandidates = soa::Filtered>; + // using AllTrackCandidates = soa::Filtered>; + using AllTrackCandidates = soa::Filtered>; using ResoV0s = aod::V0Datas; // void processData(EventCandidates::iterator const& collision, AllTrackCandidates const&, ResoV0s const& V0s, aod::BCs const&) From 7826dc67318a7a801f22f7f360f624ea624ad865 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Fri, 13 Dec 2024 22:36:06 +0100 Subject: [PATCH 10/30] [Common] add extra MFT counters to mult table (#8980) Co-authored-by: ALICE Builder --- Common/DataModel/Multiplicity.h | 5 +- Common/TableProducer/multiplicityTable.cxx | 62 +++++++++++++--------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/Common/DataModel/Multiplicity.h b/Common/DataModel/Multiplicity.h index 40175ded7a4..2547f888691 100644 --- a/Common/DataModel/Multiplicity.h +++ b/Common/DataModel/Multiplicity.h @@ -47,7 +47,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(IsInelGt1, isInelGt1, //! is INEL > 1 [](int multPveta1) -> bool { return multPveta1 > 1; }); // forward track counters -DECLARE_SOA_COLUMN(MFTNtracks, mftNtracks, int); //! +DECLARE_SOA_COLUMN(MFTNalltracks, mftNalltracks, int); //! overall counter, uses AO2D coll assoc +DECLARE_SOA_COLUMN(MFTNtracks, mftNtracks, int); //! reassigned, uses mult group software // MC DECLARE_SOA_COLUMN(MultMCFT0A, multMCFT0A, int); //! @@ -113,7 +114,7 @@ DECLARE_SOA_TABLE(PVMults, "AOD", "PVMULT", //! Multiplicity from the PV contrib mult::IsInelGt0, mult::IsInelGt1); DECLARE_SOA_TABLE(MFTMults, "AOD", "MFTMULT", //! Multiplicity with MFT - mult::MFTNtracks); + mult::MFTNalltracks, mult::MFTNtracks); using BarrelMults = soa::Join; using Mults = soa::Join; using FT0Mult = FT0Mults::iterator; diff --git a/Common/TableProducer/multiplicityTable.cxx b/Common/TableProducer/multiplicityTable.cxx index 2f9040b569c..908a44e92fb 100644 --- a/Common/TableProducer/multiplicityTable.cxx +++ b/Common/TableProducer/multiplicityTable.cxx @@ -28,6 +28,7 @@ #include "TableHelper.h" #include "MetadataHelper.h" #include "TList.h" +#include "PWGMM/Mult/DataModel/bestCollisionTable.h" using namespace o2; using namespace o2::framework; @@ -49,8 +50,7 @@ static constexpr int kFT0MultZeqs = 10; static constexpr int kFDDMultZeqs = 11; static constexpr int kPVMultZeqs = 12; static constexpr int kMultMCExtras = 13; -static constexpr int kMFTMults = 14; -static constexpr int nTables = 15; +static constexpr int nTables = 14; // Checking that the Zeq tables are after the normal ones static_assert(kFV0Mults < kFV0MultZeqs); @@ -72,10 +72,9 @@ static const std::vector tableNames{"FV0Mults", // 0 "FT0MultZeqs", // 10 "FDDMultZeqs", // 11 "PVMultZeqs", // 12 - "MultMCExtras", // 13 - "MFTMults"}; // 14 + "MultMCExtras"}; // 13 static const std::vector parameterNames{"Enable"}; -static const int defaultParameters[nTables][nParameters]{{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}}; +static const int defaultParameters[nTables][nParameters]{{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}}; struct MultiplicityTable { SliceCache cache; @@ -94,7 +93,7 @@ struct MultiplicityTable { Produces tablePVZeqs; // 12 Produces tableExtraMc; // 13 Produces tableExtraMult2MCExtras; - Produces mftMults; // 14 + Produces mftMults; // Not accounted for, produced using custom process function to avoid dependencies Produces multsGlobal; // Not accounted for, produced based on process function processGlobalTrackingCounters // For vertex-Z corrections in calibration @@ -301,8 +300,7 @@ struct MultiplicityTable { aod::Zdcs const&, aod::FV0As const&, aod::FT0s const&, - aod::FDDs const&, - aod::MFTTracks const& mftTracks) + aod::FDDs const&) { // reserve memory for (auto i : mEnabledTables) { @@ -348,9 +346,6 @@ struct MultiplicityTable { break; case kMultMCExtras: // MC extra information (nothing to do in the data) break; - case kMFTMults: // Equalized multiplicity for PV - mftMults.reserve(collisions.size()); - break; default: LOG(fatal) << "Unknown table requested: " << i; break; @@ -629,19 +624,6 @@ struct MultiplicityTable { case kMultMCExtras: // MC only (nothing to do) { } break; - case kMFTMults: { - // for centrality estimation with the MFT if desired - // step 1: produce proper grouping - const uint64_t collIdx = collision.globalIndex(); - auto mftTracksGrouped = mftTracks.sliceBy(perCollisionMFT, collIdx); - int nTracks = 0; - for (auto& track : mftTracksGrouped) { - if (track.nClusters() >= 5) { // hardcoded on purpose to avoid trouble - nTracks++; - } - } - mftMults(nTracks); - } break; default: // Default { LOG(fatal) << "Unknown table requested: " << i; @@ -754,12 +736,44 @@ struct MultiplicityTable { multsGlobal(nGlobalTracks, multNContribsEta08_kGlobalTrackWoDCA, multNContribsEta10_kGlobalTrackWoDCA, multNContribsEta05_kGlobalTrackWoDCA); } + void processRun3MFT(soa::Join::iterator const&, + o2::aod::MFTTracks const& mftTracks, + soa::SmallGroups const& retracks) + { + int nAllTracks = 0; + int nTracks = 0; + + for (auto& track : mftTracks) { + if (track.nClusters() >= 5) { // hardcoded for now + nAllTracks++; + } + } + + if (retracks.size() > 0) { + for (auto& retrack : retracks) { + auto track = retrack.mfttrack(); + if (track.nClusters() < 5) { + continue; // min cluster requirement + } + if ((track.eta() > -2.0f) && (track.eta() < -3.9f)) { + continue; // too far to be of true interest + } + if (std::abs(retrack.bestDCAXY()) > 2.0f) { + continue; // does not point to PV properly + } + nTracks++; + } + } + mftMults(nAllTracks, nTracks); + } + // Process switches PROCESS_SWITCH(MultiplicityTable, processRun2, "Produce Run 2 multiplicity tables", false); PROCESS_SWITCH(MultiplicityTable, processRun3, "Produce Run 3 multiplicity tables", true); PROCESS_SWITCH(MultiplicityTable, processGlobalTrackingCounters, "Produce Run 3 global counters", false); PROCESS_SWITCH(MultiplicityTable, processMC, "Produce MC multiplicity tables", false); PROCESS_SWITCH(MultiplicityTable, processMC2Mults, "Produce MC -> Mult map", false); + PROCESS_SWITCH(MultiplicityTable, processRun3MFT, "Produce MFT mult tables", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 271ebea347b903ed03190075db990595582a39df Mon Sep 17 00:00:00 2001 From: sashingo Date: Sat, 14 Dec 2024 06:39:43 +0900 Subject: [PATCH 11/30] [PWGHF] added a function to isolation e (#8786) --- PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx | 66 +++++++++++++++++++---- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index e86fe36813f..55f586dcbe7 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -39,9 +39,9 @@ struct HfTaskElectronWeakBoson { // configurable parameters Configurable nBinsPt{"nBinsPt", 100, "N bins in pt registry"}; - Configurable BinPtmax{"BinPtmax", 100.0, "maximum pt registry"}; + Configurable binPtmax{"binPtmax", 100.0, "maximum pt registry"}; Configurable nBinsE{"nBinsE", 100, "N bins in E registry"}; - Configurable BinEmax{"BinEmax", 100.0, "maximum E registry"}; + Configurable binEmax{"binEmax", 100.0, "maximum E registry"}; Configurable vtxZ{"vtxZ", 10.f, ""}; @@ -64,7 +64,10 @@ struct HfTaskElectronWeakBoson { Configurable timeEmcMax{"timeEmcMax", +20., "Maximum EMCcluster timing"}; Configurable m02Min{"m02Min", 0.1, "Minimum M02"}; Configurable m02Max{"m02Max", 0.9, "Maximum M02"}; - Configurable rMatchMax{"rMatchMax", 0.1, "cluster - track matching cut"}; + Configurable rMatchMax{"rMatchMax", 0.05, "cluster - track matching cut"}; + + Configurable rIsolation{"rIsolation", 0.3, "cone radius for isolation cut"}; + Configurable energyIsolationMax{"energyIsolationMax", 0.1, "isolation cut on energy"}; using SelectedClusters = o2::aod::EMCALClusters; // PbPb @@ -79,7 +82,7 @@ struct HfTaskElectronWeakBoson { Filter etafilter = (aod::track::eta < etaTrUp) && (aod::track::eta > etaTrLow); Filter dcaxyfilter = (nabs(aod::track::dcaXY) < dcaxyMax); - Filter filter_globalTr = requireGlobalTrackInFilter(); + Filter filterGlobalTr = requireGlobalTrackInFilter(); Filter clusterDefinitionSelection = (o2::aod::emcalcluster::definition == clusterDefinition) && (o2::aod::emcalcluster::time >= timeEmcMin) && (o2::aod::emcalcluster::time <= timeEmcMax) && (o2::aod::emcalcluster::m02 > m02Min) && (o2::aod::emcalcluster::m02 < m02Max); @@ -98,9 +101,9 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisZvtx{400, -20, 20, "Zvtx"}; const AxisSpec axisCounter{1, 0, 1, "events"}; const AxisSpec axisEta{200, -1.0, 1.0, "#eta"}; - const AxisSpec axisPt{nBinsPt, 0, BinPtmax, "p_{T}"}; + const AxisSpec axisPt{nBinsPt, 0, binPtmax, "p_{T}"}; const AxisSpec axisNsigma{100, -5, 5, "N#sigma"}; - const AxisSpec axisE{nBinsE, 0, BinEmax, "Energy"}; + const AxisSpec axisE{nBinsE, 0, binEmax, "Energy"}; const AxisSpec axisM02{100, 0, 1, "M02"}; const AxisSpec axisdPhi{200, -1, 1, "dPhi"}; const AxisSpec axisdEta{200, -1, 1, "dEta"}; @@ -110,6 +113,7 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisCluster{100, 0.0, 200.0, "counts"}; const AxisSpec axisITSNCls{20, 0.0, 20, "counts"}; const AxisSpec axisEMCtime{200, -100.0, 100, "EMC time"}; + const AxisSpec axisIsoEnergy{100, 0, 1, "Isolation energy(GeV/C)"}; // create registrygrams registry.add("hZvtx", "Z vertex", kTH1F, {axisZvtx}); @@ -130,12 +134,47 @@ struct HfTaskElectronWeakBoson { registry.add("hMatchPhi", "Match in Phi", kTH2F, {{axisPhi}, {axisPhi}}); registry.add("hMatchEta", "Match in Eta", kTH2F, {{axisEta}, {axisEta}}); registry.add("hEop", "energy momentum match", kTH2F, {{axisPt}, {axisEop}}); + registry.add("hEopIsolation", "energy momentum match after isolation", kTH2F, {{axisPt}, {axisEop}}); registry.add("hEopNsigTPC", "Eop vs. Nsigma", kTH2F, {{axisNsigma}, {axisEop}}); registry.add("hEMCtime", "EMC timing", kTH1F, {axisEMCtime}); + registry.add("hIsolationEnergy", "Isolation Energy", kTH2F, {{axisE}, {axisIsoEnergy}}); + } + bool isIsolatedCluster(const o2::aod::EMCALCluster& cluster, + const SelectedClusters& clusters) + { + float energySum = 0.0; + float isoEnergy = 10.0; + float etaAssCluster = cluster.eta(); + float phiAssCluster = cluster.phi(); + + for (const auto& associateCluster : clusters) { + // Calculate angular distances + double dEta = associateCluster.eta() - etaAssCluster; + double dPhi = associateCluster.phi() - phiAssCluster; + + // Normalize φ difference + dPhi = RecoDecay::constrainAngle(dPhi, -o2::constants::math::PI); + + // Calculate ΔR + double deltaR = std::sqrt(dEta * dEta + dPhi * dPhi); + + // Sum energy within isolation cone + if (deltaR < rIsolation) { + energySum += associateCluster.energy(); + } + } + + if (energySum > 0) { + isoEnergy = energySum / cluster.energy() - 1.0; + } + + registry.fill(HIST("hIsolationEnergy"), cluster.energy(), isoEnergy); + + return (isoEnergy < energyIsolationMax); } void process(soa::Filtered::iterator const& collision, - SelectedClusters const&, + SelectedClusters const& emcClusters, TrackEle const& tracks, o2::aod::EMCALMatchedTracks const& matchedtracks) { @@ -210,8 +249,8 @@ struct HfTaskElectronWeakBoson { double dPhi = match.track_as().trackPhiEmcal() - phiEmc; dPhi = RecoDecay::constrainAngle(dPhi, -o2::constants::math::PI); - registry.fill(HIST("hMatchPhi"), phiEmc, match.track_as().phi()); - registry.fill(HIST("hMatchEta"), etaEmc, match.track_as().eta()); + registry.fill(HIST("hMatchPhi"), phiEmc, match.track_as().trackPhiEmcal()); + registry.fill(HIST("hMatchEta"), etaEmc, match.track_as().trackEtaEmcal()); double r = RecoDecay::sqrtSumOfSquares(dPhi, dEta); if (r < rMin) { @@ -223,9 +262,12 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hEMCtime"), timeEmc); registry.fill(HIST("hEnergy"), energyEmc); - if (r < rMatchMax) + if (r > rMatchMax) continue; + const auto& cluster = match.emcalcluster_as(); + bool isIsolated = isIsolatedCluster(cluster, emcClusters); + double eop = energyEmc / match.track_as().p(); // LOG(info) << "E/p" << eop; registry.fill(HIST("hEopNsigTPC"), match.track_as().tpcNSigmaEl(), eop); @@ -233,6 +275,10 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hM20"), match.track_as().tpcNSigmaEl(), m20Emc); if (match.track_as().tpcNSigmaEl() > nsigTpcMin && match.track_as().tpcNSigmaEl() < nsigTpcMax) { registry.fill(HIST("hEop"), match.track_as().pt(), eop); + + if (isIsolated) { + registry.fill(HIST("hEopIsolation"), match.track_as().pt(), eop); + } } } From ec478c6a42cdc5a05b284b19b16b600ec3c2c9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sat, 14 Dec 2024 00:16:09 +0100 Subject: [PATCH 12/30] [PWGHF,Tutorial] Fix parent level options and improve argument processing (#8988) --- Tutorials/PWGHF/dpl-config_task.json | 4 +--- Tutorials/PWGHF/run_skim.sh | 21 +++++++++++------ Tutorials/PWGHF/run_task.sh | 34 +++++++++++++++++----------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/Tutorials/PWGHF/dpl-config_task.json b/Tutorials/PWGHF/dpl-config_task.json index 6418d9b7fc0..4e07d936675 100644 --- a/Tutorials/PWGHF/dpl-config_task.json +++ b/Tutorials/PWGHF/dpl-config_task.json @@ -8,9 +8,7 @@ "orbit-multiplier-enumeration": "0", "start-value-enumeration": "0", "end-value-enumeration": "-1", - "step-value-enumeration": "1", - "aod-parent-access-level": "1", - "aod-parent-base-path-replacement": "old-path-to-parent;new-path-to-parent" + "step-value-enumeration": "1" }, "internal-dpl-aod-spawner": "", "bc-converter": "", diff --git a/Tutorials/PWGHF/run_skim.sh b/Tutorials/PWGHF/run_skim.sh index fbd33e2b443..6adefe69b01 100644 --- a/Tutorials/PWGHF/run_skim.sh +++ b/Tutorials/PWGHF/run_skim.sh @@ -28,16 +28,23 @@ DIR_THIS="$(dirname "$(realpath "$0")")" JSON="$DIR_THIS/dpl-config_skim.json" # command line options of O2 workflows -OPTIONS="-b --configuration json://$JSON --aod-memory-rate-limit 2000000000 --shm-segment-size 16000000000 --resources-monitoring 2 --aod-writer-keep AOD/HFT2PRONG/0" +OPTIONS=( + -b + --configuration json://"$JSON" + --aod-memory-rate-limit 2000000000 + --shm-segment-size 16000000000 + --resources-monitoring 2 + --aod-writer-keep "AOD/HFT2PRONG/0" +) # execute the mini task workflow and its dependencies # shellcheck disable=SC2086 # Ignore unquoted options. -o2-analysistutorial-hf-skim-creator-mini $OPTIONS | \ -o2-analysis-timestamp $OPTIONS | \ -o2-analysis-trackselection $OPTIONS | \ -o2-analysis-track-propagation $OPTIONS | \ -o2-analysis-bc-converter $OPTIONS | \ -o2-analysis-tracks-extra-converter $OPTIONS \ +o2-analysistutorial-hf-skim-creator-mini "${OPTIONS[@]}" | \ +o2-analysis-timestamp "${OPTIONS[@]}" | \ +o2-analysis-trackselection "${OPTIONS[@]}" | \ +o2-analysis-track-propagation "${OPTIONS[@]}" | \ +o2-analysis-bc-converter "${OPTIONS[@]}" | \ +o2-analysis-tracks-extra-converter "${OPTIONS[@]}" \ > "$LOGFILE" 2>&1 # report status diff --git a/Tutorials/PWGHF/run_task.sh b/Tutorials/PWGHF/run_task.sh index 73c1c014930..de4096c2b85 100644 --- a/Tutorials/PWGHF/run_task.sh +++ b/Tutorials/PWGHF/run_task.sh @@ -28,22 +28,30 @@ DIR_THIS="$(dirname "$(realpath "$0")")" JSON="$DIR_THIS/dpl-config_task.json" # command line options of O2 workflows -OPTIONS="-b --configuration json://$JSON --aod-memory-rate-limit 2000000000 --shm-segment-size 16000000000 --resources-monitoring 2" +OPTIONS=( + -b + --configuration json://"$JSON" + --aod-memory-rate-limit 2000000000 + --shm-segment-size 16000000000 + --resources-monitoring 2 + --aod-parent-base-path-replacement "old-path-to-parent;new-path-to-parent" + --aod-parent-access-level 1 +) # execute the mini task workflow and its dependencies # shellcheck disable=SC2086 # Ignore unquoted options. -o2-analysistutorial-hf-task-mini $OPTIONS | \ -o2-analysis-timestamp $OPTIONS | \ -o2-analysis-track-propagation $OPTIONS | \ -o2-analysis-event-selection $OPTIONS | \ -o2-analysis-pid-tpc-base $OPTIONS | \ -o2-analysis-pid-tpc $OPTIONS | \ -o2-analysis-pid-tof-base $OPTIONS | \ -o2-analysis-pid-tof-full $OPTIONS | \ -o2-analysis-ft0-corrected-table $OPTIONS | \ -o2-analysis-bc-converter $OPTIONS | \ -o2-analysis-tracks-extra-converter $OPTIONS | \ -o2-analysis-zdc-converter $OPTIONS \ +o2-analysistutorial-hf-task-mini "${OPTIONS[@]}" | \ +o2-analysis-timestamp "${OPTIONS[@]}" | \ +o2-analysis-track-propagation "${OPTIONS[@]}" | \ +o2-analysis-event-selection "${OPTIONS[@]}" | \ +o2-analysis-pid-tpc-base "${OPTIONS[@]}" | \ +o2-analysis-pid-tpc "${OPTIONS[@]}" | \ +o2-analysis-pid-tof-base "${OPTIONS[@]}" | \ +o2-analysis-pid-tof-full "${OPTIONS[@]}" | \ +o2-analysis-ft0-corrected-table "${OPTIONS[@]}" | \ +o2-analysis-bc-converter "${OPTIONS[@]}" | \ +o2-analysis-tracks-extra-converter "${OPTIONS[@]}" | \ +o2-analysis-zdc-converter "${OPTIONS[@]}" \ > "$LOGFILE" 2>&1 # report status From 11f25f933e9c57a4b387f9c9bf88118448afb266 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Sat, 14 Dec 2024 05:29:22 +0100 Subject: [PATCH 13/30] [PWGLF,Tutorial] Add LambdaMass to Resonance Table and New Table Combination Tutorial (#8986) --- PWGLF/DataModel/LFResonanceTables.h | 1 + .../Resonances/resonanceInitializer.cxx | 1 + .../Resonances/resonanceModuleInitializer.cxx | 1 + Tutorials/PWGLF/Resonance/CMakeLists.txt | 5 + .../PWGLF/Resonance/resonancesCombine.cxx | 193 ++++++++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 Tutorials/PWGLF/Resonance/resonancesCombine.cxx diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index a446b97abc0..c2a13c35270 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -370,6 +370,7 @@ DECLARE_SOA_TABLE(ResoCascades, "AOD", "RESOCASCADES", cascdata::DCAXYCascToPV, cascdata::DCAZCascToPV, cascdata::Sign, + resodaughter::MLambda, resodaughter::MXi, resodaughter::TransRadius, resodaughter::CascTransRadius, diff --git a/PWGLF/TableProducer/Resonances/resonanceInitializer.cxx b/PWGLF/TableProducer/Resonances/resonanceInitializer.cxx index e518efc3986..202432fe061 100644 --- a/PWGLF/TableProducer/Resonances/resonanceInitializer.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceInitializer.cxx @@ -593,6 +593,7 @@ struct ResonanceInitializer { casc.dcaXYCascToPV(), casc.dcaZCascToPV(), casc.sign(), + casc.mLambda(), casc.mXi(), casc.v0radius(), casc.cascradius(), casc.x(), casc.y(), casc.z()); if constexpr (isMC) { diff --git a/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx b/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx index 327585d6295..8b2315d219a 100644 --- a/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx @@ -1055,6 +1055,7 @@ struct ResonanceDaughterInitializer { casc.dcaXYCascToPV(), casc.dcaZCascToPV(), casc.sign(), + casc.mLambda(), casc.mXi(), casc.v0radius(), casc.cascradius(), casc.x(), casc.y(), casc.z()); if constexpr (isMC) { diff --git a/Tutorials/PWGLF/Resonance/CMakeLists.txt b/Tutorials/PWGLF/Resonance/CMakeLists.txt index 6adf9fb3247..09f58af5cd0 100644 --- a/Tutorials/PWGLF/Resonance/CMakeLists.txt +++ b/Tutorials/PWGLF/Resonance/CMakeLists.txt @@ -44,3 +44,8 @@ o2physics_add_dpl_workflow(resonances-step6 SOURCES resonances_step6.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(resonances-combine + SOURCES resonancesCombine.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) diff --git a/Tutorials/PWGLF/Resonance/resonancesCombine.cxx b/Tutorials/PWGLF/Resonance/resonancesCombine.cxx new file mode 100644 index 00000000000..0168c140c23 --- /dev/null +++ b/Tutorials/PWGLF/Resonance/resonancesCombine.cxx @@ -0,0 +1,193 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \file resonancesCombine.cxx +/// \brief Resonance combination tutorial +/// \author Bong-Hwi Lim +/// \since 13/12/2024 + +#include +#include + +#include "CommonConstants/PhysicsConstants.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// Extract STEP +// Combine Resonance tables into other O2 tables +struct ResonanceCombine { + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Configurable for number of bins + Configurable nBins{"nBins", 100, "N bins in all histos"}; + // Configurable for min pT cut + Configurable cMinPtcut{"cMinPtcut", 0.15, "Track minium pt cut"}; + // Configurable for event plane + Configurable cfgEvtPl{"cfgEvtPl", 40500, "Configuration of three subsystems for the event plane and its resolution, 10000*RefA + 100*RefB + S, where FT0C:0, FT0A:1, FT0M:2, FV0A:3, BPos:5, BNeg:6"}; + + // Track selection + // primary track condition + Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; + Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; + Configurable cfgPVContributor{"cfgPVContributor", true, "PV contributor track selection"}; + // DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + // PID selection + Configurable nSigmaCutTPC{"nSigmaCutTPC", 3.0, "Value of the TPC Nsigma cut"}; + Configurable nSigmaCutTOF{"nSigmaCutTOF", 3.0, "Value of the TOF Nsigma cut"}; + + double massKa = o2::constants::physics::MassKPlus; + + EventPlaneHelper helperEP; + int evtPlRefAId = static_cast(cfgEvtPl / 10000); + int evtPlRefBId = static_cast((cfgEvtPl - evtPlRefAId * 10000) / 100); + int evtPlDetId = cfgEvtPl - evtPlRefAId * 10000 - evtPlRefBId * 100; + + void init(o2::framework::InitContext&) + { + histos.add("hVertexZ", "hVertexZ", HistType::kTH1F, {{nBins, -15., 15.}}); + histos.add("hMultiplicityPercent", "Multiplicity Percentile", kTH1F, {{120, 0.0f, 120.0f}}); + histos.add("hEvtPl", "Event Plane", kTH1F, {{100, -1.0f, 1.0f}}); + histos.add("hEta", "Eta distribution", kTH1F, {{200, -1.0f, 1.0f}}); + histos.add("hDcaxy", "Dcaxy distribution", kTH1F, {{200, -1.0f, 1.0f}}); + histos.add("hDcaz", "Dcaz distribution", kTH1F, {{200, -1.0f, 1.0f}}); + histos.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH1F, {{100, -10.0f, 10.0f}}); + histos.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH1F, {{100, -10.0f, 10.0f}}); + histos.add("hTiemResolutionTOF", "TOF time resolution", kTH1F, {{100, -10.0f, 10.0f}}); + histos.add("h1PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH1F, {{300, 0.9, 1.2}}); + histos.add("h1PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH1F, {{300, 0.9, 1.2}}); + histos.add("h1PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH1F, {{300, 0.9, 1.2}}); + histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{120, 0.0f, 120.0f}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); + histos.add("h3PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH3F, {{120, 0.0f, 120.0f}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); + histos.add("h3PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH3F, {{120, 0.0f, 120.0f}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); + + LOG(info) << "Size of the histograms in resonance tutorial with table combination:"; + histos.print(); + } + + template + bool trackCut(const TrackType track) + { + if (std::abs(track.pt()) < cMinPtcut) + return false; + if (std::abs(track.dcaXY()) > cMaxDCArToPVcut) + return false; + if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut) + return false; + if (cfgPrimaryTrack && !track.isPrimaryTrack()) + return false; + if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + return false; + if (cfgPVContributor && !track.isPVContributor()) + return false; + return true; + } + + template + bool selectionPID(const T& candidate) + { + bool tpcPass = std::abs(candidate.tpcNSigmaKa()) < nSigmaCutTPC; + bool tofPass = (candidate.hasTOF()) ? std::abs(candidate.tofNSigmaKa()) < nSigmaCutTOF : true; + if (tpcPass && tofPass) { + return true; + } + return false; + } + + double rapidity, mass, pT, paircharge; + TLorentzVector daughter1, daughter2, mother; + template + void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2) + { + auto multiplicity = collision.template collision_as().cent(); + for (auto const& track1 : dTracks1) { + auto track1Reso = track1.template track_as(); + auto track1FullPidExt = track1.template track_as(); + if (!trackCut(track1Reso) || !selectionPID(track1Reso)) { + continue; + } + histos.fill(HIST("hEta"), track1Reso.eta()); + histos.fill(HIST("hDcaxy"), track1Reso.dcaXY()); + histos.fill(HIST("hDcaz"), track1Reso.dcaZ()); + histos.fill(HIST("hNsigmaKaonTPC"), track1Reso.tpcNSigmaKa()); + if (track1Reso.hasTOF()) { + histos.fill(HIST("hNsigmaKaonTOF"), track1Reso.tofNSigmaKa()); + histos.fill(HIST("hTiemResolutionTOF"), track1FullPidExt.trackTimeRes()); // TOF time resolution is not in the ResoTracks table (Important) + } + for (auto const& track2 : dTracks2) { + auto track2Reso = track2.template track_as(); + // auto track2FullPidExt = track2.template track_as(); + + if (!trackCut(track2Reso) || !selectionPID(track2Reso)) { + continue; + } + if (track2Reso.index() <= track1Reso.index()) { + continue; + } + daughter1.SetXYZM(track1Reso.px(), track1Reso.py(), track1Reso.pz(), massKa); + daughter2.SetXYZM(track2Reso.px(), track2Reso.py(), track2Reso.pz(), massKa); + mother = daughter1 + daughter2; + mass = mother.M(); + pT = mother.Pt(); + rapidity = mother.Rapidity(); + paircharge = track1Reso.sign() * track2Reso.sign(); + + if (std::abs(rapidity) > 0.5) + continue; + + if (paircharge < 0) { + histos.fill(HIST("h3PhiInvMassUnlikeSign"), multiplicity, pT, mass); + histos.fill(HIST("h1PhiInvMassUnlikeSign"), mass); + } else { + if (track1Reso.sign() > 0 && track2Reso.sign() > 0) { + histos.fill(HIST("h3PhiInvMassLikeSignPP"), multiplicity, pT, mass); + histos.fill(HIST("h1PhiInvMassLikeSignPP"), mass); + } else { + histos.fill(HIST("h3PhiInvMassLikeSignMM"), multiplicity, pT, mass); + histos.fill(HIST("h1PhiInvMassLikeSignMM"), mass); + } + } + } + } + } + + void process(soa::Join::iterator const& collision, soa::Join const& resotracks) + { + histos.fill(HIST("hVertexZ"), collision.posZ()); + // Both resoCollisions and Qvectors have the same cent column, so we have to use "_as" to access it + // Similarly, we can use "_as" to access the Qvectors table or other tables + histos.fill(HIST("hMultiplicityPercent"), collision.collision_as().cent()); + // Event plane + auto collisionQvec = collision.template collision_as(); // Qvectors table is not in the ResoCollisions table (Important) + auto evtPl = -999.0; + if (collisionQvec.qvecAmp()[evtPlDetId] > 1e-8) + evtPl = helperEP.GetEventPlane(collisionQvec.qvecRe()[evtPlDetId * 4 + 3], collisionQvec.qvecIm()[evtPlDetId * 4 + 3], 2); + if (evtPl > -999.0) + histos.fill(HIST("hEvtPl"), evtPl); + + fillHistograms(collision, resotracks, resotracks); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } From 129ca6483ec61eeac1b89d3d52651fe154431bcb Mon Sep 17 00:00:00 2001 From: Gyula Bencedi Date: Sat, 14 Dec 2024 08:55:48 +0100 Subject: [PATCH 14/30] [PWGLF] Removed filters for collisions (#8913) Co-authored-by: ALICE Action Bot --- PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx | 98 +++++++++++----------------- 1 file changed, 38 insertions(+), 60 deletions(-) diff --git a/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx b/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx index f1366069de8..a220811d105 100644 --- a/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx +++ b/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx @@ -259,7 +259,7 @@ struct PseudorapidityDensityMFT { {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); QAregistry.add({"Events/Centrality/hcentFT0C", " ; cent FT0C", - {HistType::kTH1F, {{1000, 0, 100}}}, + {HistType::kTH1F, {CentAxis}}, true}); QAregistry.add( {"Tracks/Centrality/Chi2Eta", @@ -505,11 +505,6 @@ struct PseudorapidityDensityMFT { } } - /// Filters - collision - Filter filterCollCent = nabs(aod::cent::centFT0C) < cfgCutCent; - Filter filterCollZvtx = nabs(aod::collision::posZ) < cfgCutZvtx; - Filter filterMcCollZvtx = nabs(aod::mccollision::posZ) < cfgCutZvtx; - /// Filters - tracks Filter filtTrkEta = (aod::fwdtrack::eta < trkcuts.cfg_eta_max) && (aod::fwdtrack::eta > trkcuts.cfg_eta_min); @@ -536,28 +531,9 @@ struct PseudorapidityDensityMFT { using MFTTracksLabeled = soa::Join; /// Filtered tables - using filtColls = soa::Filtered>; - using filtColl = - soa::Filtered>::iterator; - using filtCollsCent = - soa::Filtered>; - using filtCollCent = soa::Filtered< - soa::Join>::iterator; - using CollsGenCentSmallG = - o2::soa::SmallGroups>; - using filtCollsGenCentSmallG = - soa::SmallGroups>; - using filtCollsGenCent = - soa::Filtered>; - using filtMcGenColls = soa::Filtered; - using filtMcGenColl = soa::Filtered::iterator; using filtMftTracks = soa::Filtered; using filtMcMftTracks = soa::Filtered; using filtBestTracks = soa::Filtered; - using filtBestTracksJ = - soa::Filtered>; using filtParticles = soa::Filtered; template @@ -921,20 +897,20 @@ struct PseudorapidityDensityMFT { } /// @brief process fnc. to run on DATA and REC MC w/o centrality selection - void processDataInclusive(filtColls::iterator const& collision, + void processDataInclusive(Colls::iterator const& collision, filtMftTracks const& tracks) { - processData(collision, tracks); + processData(collision, tracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processDataInclusive, "Count tracks", false); /// @brief process fnc. to run on DATA and REC MC w/ FT0C centrality selection - void processDataCent(filtCollsCent::iterator const& collision, + void processDataCent(CollsCent::iterator const& collision, filtMftTracks const& tracks) { - processData(collision, tracks); + processData(collision, tracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processDataCent, @@ -943,10 +919,10 @@ struct PseudorapidityDensityMFT { /// @brief process fnc. to run on DATA and REC MC based on BestCollisionsFwd /// table w/o centrality selection void processDatawBestTracksInclusive( - filtColls::iterator const& collision, filtMftTracks const& tracks, + Colls::iterator const& collision, filtMftTracks const& tracks, soa::SmallGroups const& besttracks) { - processDatawBestTracks(collision, tracks, besttracks); + processDatawBestTracks(collision, tracks, besttracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processDatawBestTracksInclusive, @@ -955,10 +931,10 @@ struct PseudorapidityDensityMFT { /// @brief process fnc. to run on DATA and REC MC based on BestCollisionsFwd /// table w/ FT0C centrality selection void processDatawBestTracksCent( - filtCollsCent::iterator const& collision, filtMftTracks const& tracks, + CollsCent::iterator const& collision, filtMftTracks const& tracks, soa::SmallGroups const& besttracks) { - processDatawBestTracks(collision, tracks, besttracks); + processDatawBestTracks(collision, tracks, besttracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processDatawBestTracksCent, @@ -1077,12 +1053,12 @@ struct PseudorapidityDensityMFT { /// @brief process fnc. to run on MC w/o centrality selection void processMCInclusive( - filtMcGenColls::iterator const& mccollision, - soa::SmallGroups> const& collisions, + aod::McCollisions::iterator const& mccollision, + soa::SmallGroups> const& collisions, filtParticles const& particles, filtMcMftTracks const& tracks) { - processMC(mccollision, collisions, particles, - tracks); + processMC(mccollision, collisions, particles, + tracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processMCInclusive, @@ -1090,12 +1066,12 @@ struct PseudorapidityDensityMFT { /// @brief process fnc. to run on MC w FT0C centrality selection void processMCCent( - filtMcGenColls::iterator const& mccollision, - soa::SmallGroups> const& collisions, + aod::McCollisions::iterator const& mccollision, + soa::SmallGroups> const& collisions, filtParticles const& particles, filtMcMftTracks const& tracks) { - processMC(mccollision, collisions, particles, - tracks); + processMC(mccollision, collisions, particles, + tracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processMCCent, @@ -1189,14 +1165,14 @@ struct PseudorapidityDensityMFT { /// @brief process fnc. to run on MC (inclusive, using aod::BestCollisionsFwd /// tracks) void processMCwBestTracksInclusive( - filtMcGenColls::iterator const& mccollision, - soa::SmallGroups> const& collisions, + aod::McCollisions::iterator const& mccollision, + soa::SmallGroups> const& collisions, filtParticles const& particles, filtMcMftTracks const& tracks, // aod::BestCollisionsFwd const // &besttracks filtBestTracks const& besttracks) { - processMCwBestTracks( + processMCwBestTracks( mccollision, collisions, particles, tracks, besttracks); } @@ -1206,12 +1182,12 @@ struct PseudorapidityDensityMFT { /// @brief process fnc. to run on MC (FT0C centrality, using /// aod::BestCollisionsFwd tracks) void processMCwBestTracksCent( - filtMcGenColls::iterator const& mccollision, - soa::SmallGroups> const& collisions, + aod::McCollisions::iterator const& mccollision, + soa::SmallGroups> const& collisions, filtParticles const& particles, filtMcMftTracks const& tracks, filtBestTracks const& besttracks) { - processMCwBestTracks( + processMCwBestTracks( mccollision, collisions, particles, tracks, besttracks); } @@ -1463,18 +1439,21 @@ struct PseudorapidityDensityMFT { template void processMcQA( typename soa::SmallGroups> const& collisions, - filtMcGenColls const& mcCollisions, filtParticles const& /*particles*/, - MFTTracksLabeled const& tracks, aod::AmbiguousMFTTracks const& atracks) + aod::McCollisions const& mcCollisions, + filtParticles const& /*particles*/, MFTTracksLabeled const& tracks, + aod::AmbiguousMFTTracks const& atracks) { for (const auto& collision : collisions) { float c_rec = -1; if constexpr (C::template contains()) { c_rec = collision.centFT0C(); - QAregistry.fill(HIST("Events/Centrality/hRecPerGenColls"), - static_cast(collisions.size()) / mcCollisions.size(), c_rec); + QAregistry.fill( + HIST("Events/Centrality/hRecPerGenColls"), + static_cast(collisions.size()) / mcCollisions.size(), c_rec); } else { QAregistry.fill(HIST("Events/hRecPerGenColls"), - static_cast(collisions.size()) / mcCollisions.size()); + static_cast(collisions.size()) / + mcCollisions.size()); } if (!isGoodEvent(collision)) { @@ -1506,12 +1485,11 @@ struct PseudorapidityDensityMFT { /// @brief process function for QA checks (inclusive) void processMcQAInclusive( - soa::SmallGroups> const& collisions, - filtMcGenColls const& mcCollisions, filtParticles const& particles, + soa::SmallGroups> const& collisions, + aod::McCollisions const& mcCollisions, filtParticles const& particles, MFTTracksLabeled const& tracks, aod::AmbiguousMFTTracks const& atracks) { - processMcQA(collisions, mcCollisions, particles, tracks, - atracks); + processMcQA(collisions, mcCollisions, particles, tracks, atracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processMcQAInclusive, @@ -1519,12 +1497,12 @@ struct PseudorapidityDensityMFT { /// @brief process function for QA checks (in FT0 bins) void processMcQACent( - soa::SmallGroups> const& collisions, - filtMcGenColls const& mcCollisions, filtParticles const& particles, + soa::SmallGroups> const& collisions, + aod::McCollisions const& mcCollisions, filtParticles const& particles, MFTTracksLabeled const& tracks, aod::AmbiguousMFTTracks const& atracks) { - processMcQA(collisions, mcCollisions, particles, tracks, - atracks); + processMcQA(collisions, mcCollisions, particles, tracks, + atracks); } PROCESS_SWITCH(PseudorapidityDensityMFT, processMcQACent, From 8847e38abe377d72eebd3a5fa49a7a3aa8a01624 Mon Sep 17 00:00:00 2001 From: victorvalenciatorres <118812999+victorvalenciatorres@users.noreply.github.com> Date: Sat, 14 Dec 2024 11:15:45 +0100 Subject: [PATCH 15/30] [PWGDQ] Adding correct Flow checks (#8989) --- PWGDQ/Core/VarManager.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 6a2443dc3bb..50755cd301c 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -4350,14 +4350,14 @@ void VarManager::FillPairVn(T1 const& t1, T2 const& t2, float* values) values[kM0111POI] = values[kMultDimuons] * (values[kS31A] - 3. * values[kS11A] * values[kS12A] + 2. * values[kS13A]); values[kCORR2POI] = (P2 * conj(Q21)).real() / values[kM01POI]; values[kCORR4POI] = (P2 * Q21 * conj(Q21) * conj(Q21) - P2 * Q21 * conj(Q42) - 2. * values[kS12A] * P2 * conj(Q21) + 2. * P2 * conj(Q23)).real() / values[kM0111POI]; - values[kM01POIoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM01POI]) || std::isinf(values[kM01POI])) ? values[kM01POI] / values[kMultDimuons] : 0; - values[kM0111POIoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM0111POI]) || std::isinf(values[kM0111POI])) ? values[kM0111POI] / values[kMultDimuons] : 0; - values[kM11REFoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM11REF]) || std::isinf(values[kM11REF])) ? values[kM11REF] / values[kMultDimuons] : 0; - values[kM1111REFoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM1111REF]) || std::isinf(values[kM1111REF])) ? values[kM1111REF] / values[kMultDimuons] : 0; - values[kCORR2POIMp] = std::isnan(values[kCORR2POI]) || std::isinf(values[kCORR2POI]) ? 0 : values[kCORR2POI] * values[kMultDimuons]; - values[kCORR4POIMp] = std::isnan(values[kCORR4POI]) || std::isinf(values[kCORR4POI]) ? 0 : values[kCORR4POI] * values[kMultDimuons]; - values[kCORR2REF] = std::isnan(values[kCORR2REF]) || std::isinf(values[kCORR2REF]) ? 0 : values[kCORR2REF]; - values[kCORR4REF] = std::isnan(values[kCORR4REF]) || std::isinf(values[kCORR4REF]) ? 0 : values[kCORR4REF]; + values[kM01POIoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM01POI]) || std::isinf(values[kM01POI]) || std::isnan(values[kCORR2POI]) || std::isinf(values[kCORR2POI])) ? values[kM01POI] / values[kMultDimuons] : 0; + values[kM0111POIoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM0111POI]) || std::isinf(values[kM0111POI]) || std::isnan(values[kCORR4POI]) || std::isinf(values[kCORR4POI])) ? values[kM0111POI] / values[kMultDimuons] : 0; + values[kM11REFoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM11REF]) || std::isinf(values[kM11REF]) || std::isnan(values[kCORR2REF]) || std::isinf(values[kCORR2REF])) ? values[kM11REF] / values[kMultDimuons] : 0; + values[kM1111REFoverMp] = values[kMultDimuons] > 0 && !(std::isnan(values[kM1111REF]) || std::isinf(values[kM1111REF]) || std::isnan(values[kCORR4REF]) || std::isinf(values[kCORR4REF])) ? values[kM1111REF] / values[kMultDimuons] : 0; + values[kCORR2POIMp] = std::isnan(values[kCORR2POI]) || std::isinf(values[kCORR2POI]) || std::isnan(values[kM01POI]) || std::isinf(values[kM01POI]) ? 0 : values[kCORR2POI] * values[kMultDimuons]; + values[kCORR4POIMp] = std::isnan(values[kCORR4POI]) || std::isinf(values[kCORR4POI]) || std::isnan(values[kM0111POI]) || std::isinf(values[kM0111POI]) ? 0 : values[kCORR4POI] * values[kMultDimuons]; + values[kCORR2REF] = std::isnan(values[kM11REFoverMp]) || std::isinf(values[kM11REFoverMp]) || std::isnan(values[kCORR2REF]) || std::isinf(values[kCORR2REF]) ? 0 : values[kCORR2REF]; + values[kCORR4REF] = std::isnan(values[kM1111REFoverMp]) || std::isinf(values[kM1111REFoverMp]) || std::isnan(values[kCORR4REF]) || std::isinf(values[kCORR4REF]) ? 0 : values[kCORR4REF]; } ROOT::Math::PtEtaPhiMVector v1_vp(v1.Pt(), v1.Eta(), v1.Phi() - Psi2B, v1.M()); From e118140f65e6869a4a36494b4562bffbc6db878b Mon Sep 17 00:00:00 2001 From: Anantha Padmanabhan M Nair <82643666+ananthapadmanabhan18@users.noreply.github.com> Date: Sat, 14 Dec 2024 15:46:47 +0530 Subject: [PATCH 16/30] [PWGUD] Resonance analysis of rho' and 4-pi pair angular distributions. (#8994) --- PWGUD/Tasks/CMakeLists.txt | 5 + PWGUD/Tasks/exclusiveRhoTo4Pi.cxx | 351 ++++++++++++++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 PWGUD/Tasks/exclusiveRhoTo4Pi.cxx diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index a0f1eb17747..51eacc89534 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -212,3 +212,8 @@ o2physics_add_dpl_workflow(event-by-event SOURCES eventByevent.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGPIDSelector COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(exclusive-rho-to-four-pi + SOURCES exclusiveRhoTo4Pi.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGPIDSelector + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx new file mode 100644 index 00000000000..9d4cc4ca728 --- /dev/null +++ b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx @@ -0,0 +1,351 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// \Single Gap Event Analyzer +// \author Anantha Padmanabhan M Nair, anantha.manoj.nair@cern.ch +// \since May 2024 + +#include +#include +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "PWGUD/DataModel/UDTables.h" +#include "PWGUD/Core/SGSelector.h" +#include "PWGUD/Core/SGTrackSelector.h" +#include "Common/DataModel/PIDResponse.h" +#include +#include "TLorentzVector.h" +#include +#include "Math/Vector4D.h" +#include "Math/Vector3D.h" +#include "Math/GenVector/Boost.h" + +using namespace std; +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +struct UPCAnalysis { + SGSelector sgSelector; + HistogramRegistry histos{"HistoReg", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Configurable FV0_cut{"FV0", 50., "FV0A threshold"}; + Configurable FT0A_cut{"FT0A", 150., "FT0A threshold"}; + Configurable FT0C_cut{"FT0C", 50., "FT0C threshold"}; + Configurable FDDA_cut{"FDDA", 10000., "FDDA threshold"}; + Configurable FDDC_cut{"FDDC", 10000., "FDDC threshold"}; + Configurable ZDC_cut{"ZDC", 10., "ZDC threshold"}; + + Configurable PV_cut{"PV_cut", 1.0, "Use Only PV tracks"}; + Configurable dcaZ_cut{"dcaZ_cut", 3.2, "dcaZ cut"}; + Configurable dcaXY_cut{"dcaXY_cut", 2.4, "dcaXY cut (0 for Pt-function)"}; + Configurable tpcChi2_cut{"tpcChi2_cut", 4, "Max tpcChi2NCl"}; + Configurable tpcNClsFindable_cut{"tpcNClsFindable_cut", 80, "Min tpcNClsFindable"}; + Configurable itsChi2_cut{"itsChi2_cut", 36, "Max itsChi2NCl"}; + Configurable eta_cut{"eta_cut", 0.9, "Track Pseudorapidity"}; + Configurable pt_cut{"pt_cut", 0, "Track Pt"}; + + Configurable nSigmaTPC_cut{"nsigmatpccut", 3, "TPC cut"}; + Configurable nSigmaTOF_cut{"nsigmatofcut", 3, "TOF cut"}; + Configurable StrictEventSelection{"StrictEventSelection", true, "Event Selection"}; + //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + // Begin of Init Function----------------------------------------------------------------------------------------------------------------------------------------------------- + void init(InitContext const&) + { + + histos.add("GapSide", "Gap Side; Events", kTH1F, {{4, -1.5, 2.5}}); + histos.add("TrueGapSide", "Gap Side; Events", kTH1F, {{4, -1.5, 2.5}}); + histos.add("EventCounts", "Total Events; Events", kTH1F, {{10, 0, 10}}); // 2=#Events, 3= #Selected Events, 5=#Selected Events with Zero Net charge, 6=Selected Events with Non-Zero Net charge + + // TPC nSigma + histos.add("tpcNSigmaPi_WOTS", "TPC nSigma Pion without track selection; Events", kTH1F, {{100, -15, 15}}); + histos.add("tpcNSigmaPi_WTS", "TPC nSigma Pion with track selection; Events", kTH1F, {{100, -15, 15}}); + histos.add("tpcNSigmaPi_WTS_PID_Pi", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH1F, {{100, -15, 15}}); + + // TOF nSigma + histos.add("tofNSigmaPi_WTS", "TOF nSigma Pion with track selection; Events", kTH1F, {{100, -15, 15}}); + histos.add("tofNSigmaPi_WOTS", "TOF nSigma Pion without track selection; Events", kTH1F, {{100, -15, 15}}); + histos.add("tofNSigmaPi_WTS_PID_Pi", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH1F, {{100, -15, 15}}); + + // Track Transverse Momentum + histos.add("pT_track_WOTS", "pT without track selection; pT [GeV/c]; Events", kTH1F, {{100, 0, 2}}); + histos.add("pT_track_WTS", "pT with track selection; pT [GeV/c]; Events", kTH1F, {{100, 0, 2}}); + histos.add("pT_track_WTS_PID_Pi", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{100, 0, 2}}); + + // Zero charge Event Transverse Momentum + histos.add("pT_event_0charge_WTS_PID_Pi", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Counts", kTH1F, {{100, 0, 2}}); + + // Non Zero charge Event Transverse Momentum + histos.add("pT_event_non0charge_WTS_PID_Pi", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Counts", kTH1F, {{100, 0, 2}}); + + // Rapidity of 0 charge Events + histos.add("rapidity_event_0charge_WTS_PID_Pi", "Rapidity of Events With Track Selection and PID Selection of Pi; y; Counts", kTH1F, {{100, -2.5, 2.5}}); + + // Rapidity of non 0 charge Events + histos.add("rapidity_event_non0charge_WTS_PID_Pi", "Rapidity of Events With Track Selection and PID Selection of Pi; y; Counts", kTH1F, {{100, -2.5, 2.5}}); + + // Invariant Mass of 0 charge events + histos.add("invMass_event_0charge_WTS_PID_Pi", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{1000, 0.8, 2.5}}); + + // Invariant mass of non 0 charge events + histos.add("invMass_event_non0charge_WTS_PID_Pi", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi; m(#pi^{+}#Pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{1000, 0.8, 2.5}}); + + // tpc signal + histos.add("tpcSignal", "TPC dEdx vs p; p [GeV/c]; dEdx [a.u.]", kTH2F, {{500, 0, 10}, {5000, 0.0, 5000.0}}); + histos.add("tpcSignal_Pi", "TPC dEdx vs p for pions; p [GeV/c]; dEdx [a.u.]", kTH2F, {{500, 0, 10}, {5000, 0.0, 5000.0}}); + + // tof beta + histos.add("tofBeta", "TOF beta vs p; p [GeV/c]; #beta", kTH2F, {{500, 0, 10}, {500, 0.0, 1.0}}); + histos.add("tofBeta_Pi", "TOF beta vs p for pions; p [GeV/c]; #beta", kTH2F, {{500, 0, 10}, {500, 0.0, 1.0}}); + + // Other signals + histos.add("FT0A", "T0A amplitude", kTH1F, {{200, 0.0, 500.0}}); + histos.add("FT0C", "T0C amplitude", kTH1F, {{200, 0.0, 500.0}}); + histos.add("ZDC_A", "ZDC amplitude", kTH1F, {{1000, 0.0, 15}}); + histos.add("ZDC_C", "ZDC amplitude", kTH1F, {{1000, 0.0, 15}}); + histos.add("V0A", "V0A amplitude", kTH1F, {{1000, 0.0, 100}}); + + // Collin Soper Theta and Phi + histos.add("CS_phi", "#phi Distribution; #phi; Entries", kTH1F, {{200, -3.2, 3.2}}); + histos.add("CS_costheta", "#theta Distribution;cos(#theta); Entries", kTH1F, {{200, -1, 1}}); + + } // End of init function + //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + using udtracks = soa::Join; + using udtracksfull = soa::Join; + using UDCollisionsFull = soa::Join; // + using UDCollisionFull = UDCollisionsFull::iterator; + //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + // Calculate the Collins-Soper Frame---------------------------------------------------------------------------------------------------------------------------- + Double_t CosThetaCollinsSoperFrame(ROOT::Math::PtEtaPhiMVector pair1, ROOT::Math::PtEtaPhiMVector pair2, ROOT::Math::PtEtaPhiMVector fourpion) + { + Double_t HalfSqrtSnn = 2680.; + Double_t MassOfLead208 = 193.6823; + Double_t MomentumBeam = TMath::Sqrt(HalfSqrtSnn * HalfSqrtSnn * 208 * 208 - MassOfLead208 * MassOfLead208); + + TLorentzVector pProjCM(0., 0., -MomentumBeam, HalfSqrtSnn * 208); // projectile + TLorentzVector pTargCM(0., 0., MomentumBeam, HalfSqrtSnn * 208); // target + + // TVector3 beta = (-1. / fourpion.E()) * fourpion.Vect(); + ROOT::Math::PtEtaPhiMVector v1 = pair1; + ROOT::Math::PtEtaPhiMVector v2 = pair2; + ROOT::Math::PtEtaPhiMVector v12 = fourpion; + + // Boost to center of mass frame + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; + ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam1_CM{(boostv12(pProjCM).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam2_CM{(boostv12(pTargCM).Vect()).Unit()}; + + // Axes + ROOT::Math::XYZVectorF zaxis_CS{((Beam1_CM.Unit() - Beam2_CM.Unit()).Unit())}; + + Double_t CosThetaCS = zaxis_CS.Dot((v1_CM)); + return CosThetaCS; + } // End of CosThetaCollinsSoperFrame function------------------------------------------------------------------------------------------------------------------------ + + // Calculate Phi in Collins-Soper Frame------------------------------------------------------------------------------------------------------------------------ + Double_t PhiCollinsSoperFrame(ROOT::Math::PtEtaPhiMVector pair1, ROOT::Math::PtEtaPhiMVector pair2, ROOT::Math::PtEtaPhiMVector fourpion) + { + // Half of the energy per pair of the colliding nucleons. + Double_t HalfSqrtSnn = 2680.; + Double_t MassOfLead208 = 193.6823; + Double_t MomentumBeam = TMath::Sqrt(HalfSqrtSnn * HalfSqrtSnn * 208 * 208 - MassOfLead208 * MassOfLead208); + + TLorentzVector pProjCM(0., 0., -MomentumBeam, HalfSqrtSnn * 208); // projectile + TLorentzVector pTargCM(0., 0., MomentumBeam, HalfSqrtSnn * 208); // target + ROOT::Math::PtEtaPhiMVector v1 = pair1; + ROOT::Math::PtEtaPhiMVector v2 = pair2; + ROOT::Math::PtEtaPhiMVector v12 = fourpion; + // Boost to center of mass frame + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; + ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam1_CM{(boostv12(pProjCM).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam2_CM{(boostv12(pTargCM).Vect()).Unit()}; + // Axes + ROOT::Math::XYZVectorF zaxis_CS{((Beam1_CM.Unit() - Beam2_CM.Unit()).Unit())}; + ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; + + Double_t phi = TMath::ATan2(yaxis_CS.Dot(v1_CM), xaxis_CS.Dot(v1_CM)); + return phi; + } // End of PhiCollinsSoperFrame function------------------------------------------------------------------------------------------------------------------------ + + // Begin of Process function-------------------------------------------------------------------------------------------------------------------------------------------------- + void process(UDCollisionFull const& collision, udtracksfull const& tracks) + { + + int gapSide = collision.gapSide(); + float FIT_cut[5] = {FV0_cut, FT0A_cut, FT0C_cut, FDDA_cut, FDDC_cut}; + std::vector parameters = {PV_cut, dcaZ_cut, dcaXY_cut, tpcChi2_cut, tpcNClsFindable_cut, itsChi2_cut, eta_cut, pt_cut}; + int truegapSide = sgSelector.trueGap(collision, FIT_cut[0], FIT_cut[1], FIT_cut[2], ZDC_cut); + histos.fill(HIST("GapSide"), gapSide); + histos.fill(HIST("TrueGapSide"), truegapSide); + histos.fill(HIST("EventCounts"), 1); + gapSide = truegapSide; + + if ((gapSide != 2)) { + return; + } + + histos.fill(HIST("V0A"), collision.totalFV0AmplitudeA()); + histos.fill(HIST("FT0A"), collision.totalFT0AmplitudeA()); + histos.fill(HIST("FT0C"), collision.totalFT0AmplitudeC()); + histos.fill(HIST("ZDC_A"), collision.energyCommonZNA()); + histos.fill(HIST("ZDC_C"), collision.energyCommonZNC()); + + if (StrictEventSelection) { + if (collision.numContrib() != 4) { + return; + } + } else { + if (collision.numContrib() >= 10) { + return; + } + } + + std::vector WOTS_tracks; + std::vector WTS_tracks; + std::vector WTS_PID_Pi_tracks; + std::vector Pi_plus_tracks; + std::vector Pi_minus_tracks; + + for (auto& t0 : tracks) { + + WOTS_tracks.push_back(t0); + + if (trackselector(t0, parameters)) { + WTS_tracks.push_back(t0); + + if (selectionPIDPion(t0, true, nSigmaTPC_cut, nSigmaTOF_cut)) { + WTS_PID_Pi_tracks.push_back(t0); + if (t0.sign() == 1) { + Pi_plus_tracks.push_back(t0); + } + if (t0.sign() == -1) { + Pi_minus_tracks.push_back(t0); + } + } // End of Selection PID Pion + + } // End of track selections + + } // End of loop over tracks + + int len_WOTS = static_cast(WOTS_tracks.size()); + int len_WTS = static_cast(WTS_tracks.size()); + int len_WTS_PID_Pi = static_cast(WTS_PID_Pi_tracks.size()); + int len_Pi_plus = static_cast(Pi_plus_tracks.size()); + int len_Pi_minus = static_cast(Pi_minus_tracks.size()); + + for (int i = 0; i < len_WOTS; i++) { + histos.fill(HIST("tpcNSigmaPi_WOTS"), WOTS_tracks[i].tpcNSigmaPi()); + histos.fill(HIST("tofNSigmaPi_WOTS"), WOTS_tracks[i].tofNSigmaPi()); + histos.fill(HIST("pT_track_WOTS"), TMath::Sqrt(WOTS_tracks[i].px() * WOTS_tracks[i].px() + WOTS_tracks[i].py() * WOTS_tracks[i].py())); + } // End of loop over tracks without selection + + for (int i = 0; i < len_WTS; i++) { + + histos.fill(HIST("tpcSignal"), TMath::Sqrt(WTS_tracks[i].px() * WTS_tracks[i].px() + WTS_tracks[i].py() * WTS_tracks[i].py() + WTS_tracks[i].pz() * WTS_tracks[i].pz()), WTS_tracks[i].tpcSignal()); + histos.fill(HIST("tofBeta"), TMath::Sqrt(WTS_tracks[i].px() * WTS_tracks[i].px() + WTS_tracks[i].py() * WTS_tracks[i].py() + WTS_tracks[i].pz() * WTS_tracks[i].pz()), WTS_tracks[i].beta()); + histos.fill(HIST("tpcNSigmaPi_WTS"), WTS_tracks[i].tpcNSigmaPi()); + histos.fill(HIST("tofNSigmaPi_WTS"), WTS_tracks[i].tofNSigmaPi()); + histos.fill(HIST("pT_track_WTS"), TMath::Sqrt(WTS_tracks[i].px() * WTS_tracks[i].px() + WTS_tracks[i].py() * WTS_tracks[i].py())); + } // End of loop over tracks with selection only + + for (int i = 0; i < len_WTS_PID_Pi; i++) { + + histos.fill(HIST("tpcSignal_Pi"), TMath::Sqrt(WTS_PID_Pi_tracks[i].px() * WTS_PID_Pi_tracks[i].px() + WTS_PID_Pi_tracks[i].py() * WTS_PID_Pi_tracks[i].py() + WTS_PID_Pi_tracks[i].pz() * WTS_PID_Pi_tracks[i].pz()), WTS_PID_Pi_tracks[i].tpcSignal()); + histos.fill(HIST("tofBeta_Pi"), TMath::Sqrt(WTS_PID_Pi_tracks[i].px() * WTS_PID_Pi_tracks[i].px() + WTS_PID_Pi_tracks[i].py() * WTS_PID_Pi_tracks[i].py() + WTS_PID_Pi_tracks[i].pz() * WTS_PID_Pi_tracks[i].pz()), WTS_PID_Pi_tracks[i].beta()); + histos.fill(HIST("tpcNSigmaPi_WTS_PID_Pi"), WTS_PID_Pi_tracks[i].tpcNSigmaPi()); + histos.fill(HIST("tofNSigmaPi_WTS_PID_Pi"), WTS_PID_Pi_tracks[i].tofNSigmaPi()); + histos.fill(HIST("pT_track_WTS_PID_Pi"), TMath::Sqrt(WTS_PID_Pi_tracks[i].px() * WTS_PID_Pi_tracks[i].px() + WTS_PID_Pi_tracks[i].py() * WTS_PID_Pi_tracks[i].py())); + } // End of loop over tracks with selection and PID selection of Pions + + if (len_WTS_PID_Pi != 4) { + return; + } + + if (len_Pi_minus == 2 && len_Pi_plus == 2) { + + TLorentzVector p1, p2, p3, p4, p1234; + ROOT::Math::PtEtaPhiMVector k1, k2, k3, k4, k1234, k13, k14, k23, k24; + + p1.SetXYZM(Pi_plus_tracks[0].px(), Pi_plus_tracks[0].py(), Pi_plus_tracks[0].pz(), o2::constants::physics::MassPionCharged); + p2.SetXYZM(Pi_plus_tracks[1].px(), Pi_plus_tracks[1].py(), Pi_plus_tracks[1].pz(), o2::constants::physics::MassPionCharged); + p3.SetXYZM(Pi_minus_tracks[0].px(), Pi_minus_tracks[0].py(), Pi_minus_tracks[0].pz(), o2::constants::physics::MassPionCharged); + p4.SetXYZM(Pi_minus_tracks[1].px(), Pi_minus_tracks[1].py(), Pi_minus_tracks[1].pz(), o2::constants::physics::MassPionCharged); + + k1.SetCoordinates(p1.Pt(), p1.Eta(), p1.Phi(), o2::constants::physics::MassPionCharged); + k2.SetCoordinates(p2.Pt(), p2.Eta(), p2.Phi(), o2::constants::physics::MassPionCharged); + k3.SetCoordinates(p3.Pt(), p3.Eta(), p3.Phi(), o2::constants::physics::MassPionCharged); + k4.SetCoordinates(p4.Pt(), p4.Eta(), p4.Phi(), o2::constants::physics::MassPionCharged); + + p1234 = p1 + p2 + p3 + p4; + k1234 = k1 + k2 + k3 + k4; + + k13 = k1 + k3; + k14 = k1 + k4; + k23 = k2 + k3; + k24 = k2 + k4; + + auto phi_pair_1 = PhiCollinsSoperFrame(k13, k24, k1234); + auto phi_pair_2 = PhiCollinsSoperFrame(k14, k23, k1234); + auto cos_theta_1 = CosThetaCollinsSoperFrame(k13, k24, k1234); + auto cos_theta_2 = CosThetaCollinsSoperFrame(k14, k23, k1234); + + histos.fill(HIST("pT_event_0charge_WTS_PID_Pi"), p1234.Pt()); + histos.fill(HIST("rapidity_event_0charge_WTS_PID_Pi"), p1234.Rapidity()); + histos.fill(HIST("invMass_event_0charge_WTS_PID_Pi"), p1234.M()); + histos.fill(HIST("CS_phi"), phi_pair_1); + histos.fill(HIST("CS_phi"), phi_pair_2); + histos.fill(HIST("CS_costheta"), cos_theta_1); + histos.fill(HIST("CS_costheta"), cos_theta_2); + + } // End of Analysis for 0 charge events + + if (len_Pi_minus != 2 && len_Pi_plus != 2) { + + TLorentzVector p1, p2, p3, p4, p1234; + p1.SetXYZM(WTS_PID_Pi_tracks[0].px(), WTS_PID_Pi_tracks[0].py(), WTS_PID_Pi_tracks[0].pz(), o2::constants::physics::MassPionCharged); + p2.SetXYZM(WTS_PID_Pi_tracks[1].px(), WTS_PID_Pi_tracks[1].py(), WTS_PID_Pi_tracks[1].pz(), o2::constants::physics::MassPionCharged); + p3.SetXYZM(WTS_PID_Pi_tracks[2].px(), WTS_PID_Pi_tracks[2].py(), WTS_PID_Pi_tracks[2].pz(), o2::constants::physics::MassPionCharged); + p4.SetXYZM(WTS_PID_Pi_tracks[3].px(), WTS_PID_Pi_tracks[3].py(), WTS_PID_Pi_tracks[3].pz(), o2::constants::physics::MassPionCharged); + + p1234 = p1 + p2 + p3 + p4; + + histos.fill(HIST("pT_event_non0charge_WTS_PID_Pi"), p1234.Pt()); + histos.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi"), p1234.Rapidity()); + histos.fill(HIST("invMass_event_non0charge_WTS_PID_Pi"), p1234.M()); + + } // End of Analysis for non 0 charge events + + } // End of process function + //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +}; // End of Struct UPCAnalysis +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} From 29241f8928abc817cd015c6de7dffcdbad0be993 Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:53:39 +0100 Subject: [PATCH 17/30] [PWGCF] FemtoUniverse -- Adding the correction requested by Vit (#8996) Co-authored-by: Zuzanna Chochulska Co-authored-by: Zuzanna Chochulska <01150674@pw.edu.pl> --- .../Tasks/femtoUniversePairTaskTrackPhi.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index c9044e71374..eedf16489c9 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -48,13 +48,13 @@ using namespace o2::soa; namespace { -static constexpr int NPart = 2; -static constexpr int NCuts = 5; +// static constexpr int NPart = 2; +// static constexpr int NCuts = 5; static const std::vector partNames{"PhiCandidate", "Track"}; static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; -static const float cutsTable[NPart][NCuts]{ - {4.05f, 1.f, 3.f, 3.f, 100.f}, - {4.05f, 1.f, 3.f, 3.f, 100.f}}; +// static const float cutsTable[NPart][NCuts]{ //unused variable +// {4.05f, 1.f, 3.f, 3.f, 100.f}, +// {4.05f, 1.f, 3.f, 3.f, 100.f}}; } // namespace struct FemtoUniversePairTaskTrackPhi { From 6c25c338e5d92c2507f7a5170e744b4921a4ccf3 Mon Sep 17 00:00:00 2001 From: FDUEnrich <23210190047@m.fudan.edu.cn> Date: Sun, 15 Dec 2024 22:52:31 +0800 Subject: [PATCH 18/30] [PWGHF] Omegac0/Xi pT cut (#8962) Co-authored-by: ALICE Action Bot --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index fe77bb275d9..5548863ac6c 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -19,6 +19,7 @@ /// \author Jinjoo Seo , Inha University /// \author Fabrizio Grosa , CERN /// \author Federica Zanone , Heidelberg University +/// \author Ruiqi Yin , Fudan University #include // std::find #include // std::distance @@ -277,10 +278,10 @@ struct HfTrackIndexSkimCreatorTagSelTracks { Preslice trackIndicesPerCollision = aod::track_association::collisionId; - Partition pvContributors = ((aod::track::flags & (uint32_t)aod::track::PVContributor) == (uint32_t)aod::track::PVContributor); - Partition pvContributorsWithPidTpc = ((aod::track::flags & (uint32_t)aod::track::PVContributor) == (uint32_t)aod::track::PVContributor); - Partition pvContributorsWithPidTof = ((aod::track::flags & (uint32_t)aod::track::PVContributor) == (uint32_t)aod::track::PVContributor); - Partition pvContributorsWithPidTpcTof = ((aod::track::flags & (uint32_t)aod::track::PVContributor) == (uint32_t)aod::track::PVContributor); + Partition pvContributors = ((aod::track::flags & static_cast(aod::track::PVContributor)) == static_cast(aod::track::PVContributor)); + Partition pvContributorsWithPidTpc = ((aod::track::flags & static_cast(aod::track::PVContributor)) == static_cast(aod::track::PVContributor)); + Partition pvContributorsWithPidTof = ((aod::track::flags & static_cast(aod::track::PVContributor)) == static_cast(aod::track::PVContributor)); + Partition pvContributorsWithPidTpcTof = ((aod::track::flags & static_cast(aod::track::PVContributor)) == static_cast(aod::track::PVContributor)); // QA of PV refit ConfigurableAxis axisPvRefitDeltaX{"axisPvRefitDeltaX", {1000, -0.5f, 0.5f}, "DeltaX binning PV refit"}; @@ -2048,7 +2049,7 @@ struct HfTrackIndexSkimCreator { } if (config.debugPvRefit) { LOG(info) << "===> nTrk: " << nTrk << ", nContrib: " << nContrib << ", nNonContrib: " << nNonContrib; - if ((uint16_t)vecPvContributorTrackParCov.size() != collision.numContrib() || (uint16_t)nContrib != collision.numContrib()) { + if (static_cast(vecPvContributorTrackParCov.size()) != collision.numContrib() || static_cast(nContrib != collision.numContrib())) { LOG(info) << "!!! Some problem here !!! vecPvContributorTrackParCov.size()= " << vecPvContributorTrackParCov.size() << ", nContrib=" << nContrib << ", collision.numContrib()" << collision.numContrib(); } } @@ -3234,7 +3235,11 @@ struct HfTrackIndexSkimCreatorLfCascades { // Selection criteria // selections have been set to run2 lambda dedicated cuts // selections for cascade have been set to the loosest value between xi and omega - // a tolerance has been added to be more conservative + // a tolerance has been added to be more conservative ptMinOmegaczeroToOmegaKaLfCasc ptMinXicZeroOmegacZeroToXiPiLfCasc + Configurable ptMinOmegacZeroToOmegaPiLfCasc{"ptMinOmegacZeroToOmegaPiLfCasc", 0.f, "min. pT for Omegaczero in Omega + Pi decays"}; + Configurable ptMinOmegaczeroToOmegaKaLfCasc{"ptMinOmegaczeroToOmegaKaLfCasc", 0.f, "min. pT for Omegaczero in Omega + Ka decays"}; + Configurable ptMinXicZeroOmegacZeroToXiPiLfCasc{"ptMinXicZeroOmegacZeroToXiPiLfCasc", 0.f, "min. pT for XicZeroOmegacZero in Xi + Pi decays"}; + Configurable ptMinXicplusLfCasc{"ptMinXicplusLfCasc", 0.f, "min. pT for Xicplus in Xi + Pi + Pi decays"}; Configurable v0TransvRadius{"v0TransvRadius", 1.0, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2 Configurable cascTransvRadius{"cascTransvRadius", 0.4, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2 Configurable dcaBachToPv{"dcaBachToPv", 0.03, "DCA Bach To PV"}; // 0.04 in run2 @@ -3358,6 +3363,16 @@ struct HfTrackIndexSkimCreatorLfCascades { registry.add("hDCACascDau", "hDCACascDau", {HistType::kTH1D, {{500, 0.0f, 5.0f, "cm^{2}"}}}); registry.add("hLambdaMass", "hLambdaMass", {HistType::kTH1D, {{400, 0.916f, 1.316f, "Inv. Mass (GeV/c^{2})"}}}); + // pT rej + registry.add("hPtCutsXicZeroOmegacZeroToXiPi", "Omegac/Xic to Xi Pi tracks selected by pT;#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{500, 0., 50.}}}); + registry.add("hPtCutsOmegacZeroToOmegaPi", "Omegac to Omega Pi tracks selected by pT;#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{500, 0., 50.}}}); + registry.add("hPtCutsOmegacZeroToOmegaKa", "Omegac to Omega Ka tracks selected by pT;#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{500, 0., 50.}}}); + registry.add("hPtCutsXicPlusToXiPiPi", "Xicplus to Xi Pi Pi tracks selected by pT;#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{500, 0., 50.}}}); + registry.add("hRejpTStatusXicZeroOmegacZeroToXiPi", "XicZeroOmegacZeroToXiPi rejected by pT status;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // pass dcafitter --> 0, pT>pTmin --> 1 + registry.add("hRejpTStatusOmegacZeroToOmegaPi", "OmegacZeroToOmegaPi rejected by pT status;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); + registry.add("hRejpTStatusOmegacZeroToOmegaKa", "OmegacZeroToOmegaKa rejected by pT status;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); + registry.add("hRejpTStatusXicPlusToXiPiPi", "XicPlusToXiPiPi rejected by pT status;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); + // mass spectra registry.add("hMassXicZeroOmegacZeroToXiPi", "2-prong candidates;inv. mass (#Xi #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2., 3.}}}); registry.add("hMassOmegacZeroToOmegaPi", "2-prong candidates;inv. mass (#Omega #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2., 3.}}}); @@ -3555,17 +3570,23 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array pVecPion1XiHyp = {0.}; df2.getTrack(0).getPxPyPzGlo(pVecXi); df2.getTrack(1).getPxPyPzGlo(pVecPion1XiHyp); + float ptXic = RecoDecay::pt(pVecXi, pVecPion1XiHyp); std::array, 2> arrMomToXi = {pVecXi, pVecPion1XiHyp}; auto mass2ProngXiHyp = RecoDecay::m(arrMomToXi, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi]); if ((std::abs(casc.mXi() - massXi) < config.cascadeMassWindow) && (mass2ProngXiHyp >= config.massXiPiMin) && (mass2ProngXiHyp <= config.massXiPiMax)) { - SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi); + registry.fill(HIST("hRejpTStatusXicZeroOmegacZeroToXiPi"), 0); + if (ptXic >= config.ptMinXicZeroOmegacZeroToXiPiLfCasc) { + SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi); + registry.fill(HIST("hRejpTStatusXicZeroOmegacZeroToXiPi"), 1); + } } // fill histograms if (config.fillHistograms && (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi))) { registry.fill(HIST("hMassXicZeroOmegacZeroToXiPi"), mass2ProngXiHyp); + registry.fill(HIST("hPtCutsXicZeroOmegacZeroToXiPi"), ptXic); } } else if (df2.isPropagationFailure()) { LOGF(info, "Exception caught: failed to propagate tracks (2prong - xi) to charm baryon decay vtx"); @@ -3596,6 +3617,7 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array pVecCharmBachelor1OmegaHyp = {0.}; df2.getTrack(0).getPxPyPzGlo(pVecOmega); df2.getTrack(1).getPxPyPzGlo(pVecCharmBachelor1OmegaHyp); + float ptOmegac = RecoDecay::pt(pVecOmega, pVecCharmBachelor1OmegaHyp); std::array, 2> arrMomToOmega = {pVecOmega, pVecCharmBachelor1OmegaHyp}; auto mass2ProngOmegaPiHyp = RecoDecay::m(arrMomToOmega, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi]); @@ -3603,10 +3625,18 @@ struct HfTrackIndexSkimCreatorLfCascades { if (std::abs(casc.mOmega() - massOmega) < config.cascadeMassWindow) { if ((mass2ProngOmegaPiHyp >= config.massOmegaCharmBachelorMin) && (mass2ProngOmegaPiHyp <= config.massOmegaCharmBachelorMax)) { - SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi); + registry.fill(HIST("hRejpTStatusOmegacZeroToOmegaPi"), 0); + if (ptOmegac >= config.ptMinOmegacZeroToOmegaPiLfCasc) { + SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi); + registry.fill(HIST("hRejpTStatusOmegacZeroToOmegaPi"), 1); + } } if ((mass2ProngOmegaKHyp >= config.massOmegaCharmBachelorMin) && (mass2ProngOmegaKHyp <= config.massOmegaCharmBachelorMax)) { - SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK); + registry.fill(HIST("hRejpTStatusOmegacZeroToOmegaKa"), 0); + if (ptOmegac >= config.ptMinOmegaczeroToOmegaKaLfCasc) { + SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK); + registry.fill(HIST("hRejpTStatusOmegacZeroToOmegaKa"), 1); + } } } @@ -3614,9 +3644,11 @@ struct HfTrackIndexSkimCreatorLfCascades { if (config.fillHistograms) { if (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi)) { registry.fill(HIST("hMassOmegacZeroToOmegaPi"), mass2ProngOmegaPiHyp); + registry.fill(HIST("hPtCutsOmegacZeroToOmegaPi"), ptOmegac); } if (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK)) { registry.fill(HIST("hMassOmegacZeroToOmegaK"), mass2ProngOmegaKHyp); + registry.fill(HIST("hPtCutsOmegacZeroToOmegaKa"), ptOmegac); } } } else if (df2.isPropagationFailure()) { @@ -3689,17 +3721,23 @@ struct HfTrackIndexSkimCreatorLfCascades { df3.getTrack(0).getPxPyPzGlo(pVec1); // take the momentum at the Xic vertex df3.getTrack(1).getPxPyPzGlo(pVec2); df3.getTrack(2).getPxPyPzGlo(pVec3); + float ptXic3Prong = RecoDecay::pt(pVec1, pVec2, pVec3); std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); if ((std::abs(casc.mXi() - massXi) < config.cascadeMassWindow) && (mass3Prong >= config.massXiPiPiMin) && (mass3Prong <= config.massXiPiPiMax)) { - SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi); + registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); + if (ptXic3Prong >= config.ptMinXicplusLfCasc) { + SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi); + registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1); + } } // fill histograms if (config.fillHistograms && (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi))) { registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong); + registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptXic3Prong); } } else if (df3.isPropagationFailure()) { LOGF(info, "Exception caught: failed to propagate tracks (3prong) to charm baryon decay vtx"); From c44f119fbcb19569fcbe15d3d5c07510d3f63b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BiaoZhang=20=28=E5=BC=A0=E5=BD=AA=29?= <52267892+zhangbiao-phy@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:53:18 +0100 Subject: [PATCH 19/30] [PWGHF] Add pt and inv.mass cuts also in mixed event (#8991) --- PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx index f421bd35ff3..9faaa37360a 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx @@ -396,6 +396,14 @@ struct HfTaskCharmHadronsFemtoDream { invMass = p2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); } + if (invMass < charmHadMinInvMass || invMass > charmHadMaxInvMass) { + continue; + } + + if (p2.pt() < charmHadMinPt || p2.pt() > charmHadMaxPt) { + continue; + } + int charmHadMc = 0; int originType = 0; if constexpr (isMc) { From 427e25c658534590d3a5426d00496b3ef05e758d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BiaoZhang=20=28=E5=BC=A0=E5=BD=AA=29?= <52267892+zhangbiao-phy@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:53:49 +0100 Subject: [PATCH 20/30] [PWGHF,Trigger] Add de-Lc femto trigger channel into the HFFilter task (#8937) Co-authored-by: ALICE Action Bot Co-authored-by: Fabrizio --- EventFiltering/PWGHF/HFFilter.cxx | 53 +++++-- EventFiltering/PWGHF/HFFilterHelpers.h | 201 +++++++++++++++++-------- 2 files changed, 182 insertions(+), 72 deletions(-) diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 9342beee317..1b7ec0ee02d 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -72,9 +72,9 @@ struct HfFilter { // Main struct for HF triggers // parameters for all triggers // nsigma PID (except for V0 and cascades) - Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 3, 6, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for TPC/TOF PID (except for V0 and cascades)"}; + Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 3, 7, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for TPC/TOF PID (except for V0 and cascades)"}; // min and max pts for tracks and bachelors (except for V0 and cascades) - Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 6, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; + Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 7, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; // parameters for high-pT triggers Configurable> ptThresholds{"ptThresholds", {cutsHighPtThresholds[0], 1, 2, labelsEmpty, labelsColumnsHighPtThresholds}, "pT treshold for high pT charm hadron candidates for kHighPt triggers in GeV/c"}; @@ -91,10 +91,11 @@ struct HfFilter { // Main struct for HF triggers // parameters for femto triggers Configurable femtoMaxRelativeMomentum{"femtoMaxRelativeMomentum", 2., "Maximal allowed value for relative momentum between charm-proton pairs in GeV/c"}; - Configurable> enableFemtoChannels{"enableFemtoChannels", {activeFemtoChannels[0], 1, 5, labelsEmpty, labelsColumnsFemtoChannels}, "Flags to enable/disable femto channels"}; + Configurable> enableFemtoChannels{"enableFemtoChannels", {activeFemtoChannels[0], 2, 5, labelsRowsFemtoChannels, labelsColumnsFemtoChannels}, "Flags to enable/disable femto channels"}; Configurable requireCharmMassForFemto{"requireCharmMassForFemto", false, "Flags to enable/disable cut on charm-hadron invariant-mass window for femto"}; - Configurable ptThresholdForFemtoPid{"ptThresholdForFemtoPid", 8., "pT threshold for changing strategy of proton PID in femto triggers"}; - Configurable forceTofPidForFemto{"forceTofPidForFemto", true, "force TOF PID for proton in femto triggers"}; + Configurable> ptThresholdsForFemto{"ptThresholdsForFemto", {cutsPtThresholdsForFemto[0], 1, 2, labelsEmpty, labelsColumnsPtThresholdsForFemto}, "pT treshold for proton or deuteron for kFemto triggers in GeV/c"}; + Configurable forceTofProtonForFemto{"forceTofProtonForFemto", true, "flag to force TOF PID for protons"}; + Configurable forceTofDeuteronForFemto{"forceTofDeuteronForFemto", false, "flag to force TOF PID for deuterons"}; // double charm Configurable> enableDoubleCharmChannels{"enableDoubleCharmChannels", {activeDoubleCharmChannels[0], 1, 3, labelsEmpty, labelsColumnsDoubleCharmChannels}, "Flags to enable/disable double charm channels"}; @@ -157,9 +158,11 @@ struct HfFilter { // Main struct for HF triggers std::shared_ptr hN2ProngCharmCand, hN3ProngCharmCand; std::array, kNCharmParticles> hCharmHighPt{}; std::array, kNCharmParticles> hCharmProtonKstarDistr{}; + std::array, kNCharmParticles> hCharmDeuteronKstarDistr{}; std::array, kNBeautyParticles> hMassVsPtB{}; std::array, kNCharmParticles + 17> hMassVsPtC{}; // +9 for resonances (D*+, D*0, Ds*+, Ds1+, Ds2*+, Xic+* right sign, Xic+* wrong sign, Xic0* right sign, Xic0* wrong sign) +2 for SigmaC (SigmaC++, SigmaC0) +2 for SigmaCK pairs (SigmaC++K-, SigmaC0K0s) +2 for charm baryons (Xi+Pi, Xi+Ka) std::shared_ptr hProtonTPCPID, hProtonTOFPID; + std::shared_ptr hDeuteronTPCPID, hDeuteronTOFPID; std::array, kNCharmParticles> hBDTScoreBkg{}; std::array, kNCharmParticles> hBDTScorePrompt{}; std::array, kNCharmParticles> hBDTScoreNonPrompt{}; @@ -181,20 +184,23 @@ struct HfFilter { // Main struct for HF triggers void init(InitContext&) { helper.setHighPtTriggerThresholds(ptThresholds->get(0u, 0u), ptThresholds->get(0u, 1u)); + helper.setPtTriggerThresholdsForFemto(ptThresholdsForFemto->get(0u, 0u), ptThresholdsForFemto->get(0u, 1u)); helper.setPtBinsSingleTracks(pTBinsTrack); helper.setPtBinsBeautyHadrons(pTBinsBHadron); helper.setPtLimitsBeautyBachelor(ptCuts->get(0u, 0u), ptCuts->get(1u, 0u)); helper.setPtLimitsDstarSoftPion(ptCuts->get(0u, 1u), ptCuts->get(1u, 1u)); helper.setPtLimitsProtonForFemto(ptCuts->get(0u, 2u), ptCuts->get(1u, 2u)); + helper.setPtLimitsDeuteronForFemto(ptCuts->get(0u, 6u), ptCuts->get(1u, 6u)); helper.setPtLimitsCharmBaryonBachelor(ptCuts->get(0u, 3u), ptCuts->get(1u, 3u)); helper.setCutsSingleTrackBeauty(cutsTrackBeauty3Prong, cutsTrackBeauty4Prong); helper.setCutsSingleTrackCharmBaryonBachelor(cutsTrackCharmBaryonBachelor); helper.setCutsBplus(cutsBplus); - helper.setPtThresholdPidStrategyForFemto(ptThresholdForFemtoPid); helper.setNsigmaProtonCutsForFemto(std::array{nSigmaPidCuts->get(0u, 3u), nSigmaPidCuts->get(1u, 3u), nSigmaPidCuts->get(2u, 3u)}); + helper.setNsigmaDeuteronCutsForFemto(std::array{nSigmaPidCuts->get(0u, 6u), nSigmaPidCuts->get(1u, 6u), nSigmaPidCuts->get(2u, 6u)}); helper.setNsigmaProtonCutsForCharmBaryons(nSigmaPidCuts->get(0u, 0u), nSigmaPidCuts->get(1u, 0u)); helper.setNsigmaPionKaonCutsForDzero(nSigmaPidCuts->get(0u, 1u), nSigmaPidCuts->get(1u, 1u)); helper.setNsigmaKaonCutsFor3Prongs(nSigmaPidCuts->get(0u, 2u), nSigmaPidCuts->get(1u, 2u)); + helper.setForceTofForFemto(forceTofProtonForFemto, forceTofDeuteronForFemto); helper.setV0Selections(cutsGammaK0sLambda->get(0u, 0u), cutsGammaK0sLambda->get(0u, 1u), cutsGammaK0sLambda->get(0u, 2u), cutsGammaK0sLambda->get(0u, 3u), cutsGammaK0sLambda->get(0u, 4u), cutsGammaK0sLambda->get(0u, 5u)); helper.setXiSelections(cutsXiCascades->get(0u, 0u), cutsXiCascades->get(0u, 1u), cutsXiCascades->get(0u, 2u), cutsXiCascades->get(0u, 3u), cutsXiCascades->get(0u, 4u), cutsXiCascades->get(0u, 5u), cutsXiCascades->get(0u, 6u), cutsXiCascades->get(0u, 7u)); helper.setNsigmaPiCutsForCharmBaryonBachelor(nSigmaPidCuts->get(0u, 4u), nSigmaPidCuts->get(1u, 4u)); @@ -222,6 +228,7 @@ struct HfFilter { // Main struct for HF triggers for (int iCharmPart{0}; iCharmPart < kNCharmParticles; ++iCharmPart) { hCharmHighPt[iCharmPart] = registry.add(Form("f%sHighPt", charmParticleNames[iCharmPart].data()), Form("#it{p}_{T} distribution of triggered high-#it{p}_{T} %s candidates;#it{p}_{T} (GeV/#it{c});counts", charmParticleNames[iCharmPart].data()), HistType::kTH1F, {ptAxis}); hCharmProtonKstarDistr[iCharmPart] = registry.add(Form("f%sProtonKstarDistr", charmParticleNames[iCharmPart].data()), Form("#it{k}* distribution of triggered p#minus%s pairs;#it{k}* (GeV/#it{c});counts", charmParticleNames[iCharmPart].data()), HistType::kTH1F, {kstarAxis}); + hCharmDeuteronKstarDistr[iCharmPart] = registry.add(Form("f%sDeuteronKstarDistr", charmParticleNames[iCharmPart].data()), Form("#it{k}* distribution of triggered de%s pairs;#it{k}* (GeV/#it{c});counts", charmParticleNames[iCharmPart].data()), HistType::kTH1F, {kstarAxis}); hMassVsPtC[iCharmPart] = registry.add(Form("fMassVsPt%s", charmParticleNames[iCharmPart].data()), Form("#it{M} vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", charmParticleNames[iCharmPart].data()), HistType::kTH2F, {ptAxis, massAxisC[iCharmPart]}); if (activateQA > 1) { hBDTScoreBkg[iCharmPart] = registry.add(Form("f%sBDTScoreBkgDistr", charmParticleNames[iCharmPart].data()), Form("BDT background score distribution for %s;BDT background score;counts", charmParticleNames[iCharmPart].data()), HistType::kTH1F, {bdtAxis}); @@ -276,6 +283,9 @@ struct HfFilter { // Main struct for HF triggers if (activateQA > 1) { hProtonTPCPID = registry.add("fProtonTPCPID", "#it{N}_{#sigma}^{TPC} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TPC}", HistType::kTH2F, {pAxis, nSigmaAxis}); hProtonTOFPID = registry.add("fProtonTOFPID", "#it{N}_{#sigma}^{TOF} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}", HistType::kTH2F, {pAxis, nSigmaAxis}); + hDeuteronTPCPID = registry.add("hDeuteronTPCPID", "#it{N}_{#sigma}^{TPC} vs. #it{p} for selected deuterons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TPC}", HistType::kTH2F, {pAxis, nSigmaAxis}); + hDeuteronTOFPID = registry.add("hDeuteronTOFPID", "#it{N}_{#sigma}^{TOF} vs. #it{p} for selected deuterons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}", HistType::kTH2F, {pAxis, nSigmaAxis}); + hV0Selected = registry.add("fV0Selected", "Selections for V0s;;counts", HistType::kTH2F, {{9, -0.5, 8.5}, {kNV0, -0.5, +kNV0 - 0.5}}); for (int iV0{kPhoton}; iV0 < kNV0; ++iV0) { @@ -303,8 +313,8 @@ struct HfFilter { // Main struct for HF triggers thresholdBDTScores = {thresholdBDTScoreD0ToKPi, thresholdBDTScoreDPlusToPiKPi, thresholdBDTScoreDSToPiKK, thresholdBDTScoreLcToPiKP, thresholdBDTScoreXicToPiKP}; } - using BigTracksMCPID = soa::Join; - using BigTracksPID = soa::Join; + using BigTracksMCPID = soa::Join; + using BigTracksPID = soa::Join; using CollsWithEvSel = soa::Join; using Hf2ProngsWithMl = soa::Join; @@ -355,7 +365,7 @@ struct HfFilter { // Main struct for HF triggers if (setTPCCalib == 1) { helper.setTpcRecalibMaps(ccdb, bc, ccdbPathTPC); } else if (setTPCCalib > 1) { - helper.setValuesBB(ccdbApi, bc, std::array{ccdbBBPion.value, ccdbBBAntiPion.value, ccdbBBKaon.value, ccdbBBAntiKaon.value, ccdbBBProton.value, ccdbBBAntiProton.value}); + helper.setValuesBB(ccdbApi, bc, std::array{ccdbBBPion.value, ccdbBBAntiPion.value, ccdbBBKaon.value, ccdbBBAntiKaon.value, ccdbBBProton.value, ccdbBBAntiProton.value, ccdbBBProton.value, ccdbBBAntiProton.value}); // dummy for deuteron } currentRun = bc.runNumber(); @@ -570,11 +580,11 @@ struct HfFilter { // Main struct for HF triggers // 2-prong femto if (!keepEvent[kFemto2P] && enableFemtoChannels->get(0u, 0u) && isCharmTagged && track.collisionId() == thisCollId && (TESTBIT(selD0, 0) || TESTBIT(selD0, 1) || !requireCharmMassForFemto)) { - bool isProton = helper.isSelectedProton4Femto(track, trackParThird, activateQA, hProtonTPCPID, hProtonTOFPID, forceTofPidForFemto); + bool isProton = helper.isSelectedTrack4Femto(track, trackParThird, activateQA, hProtonTPCPID, hProtonTOFPID, kProtonForFemto); if (isProton) { float relativeMomentum = helper.computeRelativeMomentum(pVecThird, pVec2Prong, massD0); if (applyOptimisation) { - optimisationTreeFemto(thisCollId, o2::constants::physics::Pdg::kD0, pt2Prong, scores[0], scores[1], scores[2], relativeMomentum, track.tpcNSigmaPr(), track.tofNSigmaPr()); + optimisationTreeFemto(thisCollId, o2::constants::physics::Pdg::kD0, pt2Prong, scores[0], scores[1], scores[2], relativeMomentum, track.tpcNSigmaPr(), track.tofNSigmaPr(), track.tpcNSigmaDe(), track.tofNSigmaDe()); } if (relativeMomentum < femtoMaxRelativeMomentum) { keepEvent[kFemto2P] = true; @@ -948,13 +958,15 @@ struct HfFilter { // Main struct for HF triggers } // end beauty selection // 3-prong femto - bool isProton = helper.isSelectedProton4Femto(track, trackParFourth, activateQA, hProtonTPCPID, hProtonTOFPID, forceTofPidForFemto); + bool isProton = helper.isSelectedTrack4Femto(track, trackParFourth, activateQA, hProtonTPCPID, hProtonTOFPID, kProtonForFemto); + bool isDeuteron = helper.isSelectedTrack4Femto(track, trackParFourth, activateQA, hDeuteronTPCPID, hDeuteronTOFPID, kDeuteronForFemto); + if (isProton && track.collisionId() == thisCollId) { for (int iHypo{0}; iHypo < kNCharmParticles - 1 && !keepEvent[kFemto3P]; ++iHypo) { if (isCharmTagged[iHypo] && enableFemtoChannels->get(0u, iHypo + 1) && (TESTBIT(is3ProngInMass[iHypo], 0) || TESTBIT(is3ProngInMass[iHypo], 1) || !requireCharmMassForFemto)) { float relativeMomentum = helper.computeRelativeMomentum(pVecFourth, pVec3Prong, massCharmHypos[iHypo]); if (applyOptimisation) { - optimisationTreeFemto(thisCollId, charmParticleID[iHypo], pt3Prong, scores[iHypo][0], scores[iHypo][1], scores[iHypo][2], relativeMomentum, track.tpcNSigmaPr(), track.tofNSigmaPr()); + optimisationTreeFemto(thisCollId, charmParticleID[iHypo], pt3Prong, scores[iHypo][0], scores[iHypo][1], scores[iHypo][2], relativeMomentum, track.tpcNSigmaPr(), track.tofNSigmaPr(), track.tpcNSigmaDe(), track.tofNSigmaDe()); } if (relativeMomentum < femtoMaxRelativeMomentum) { keepEvent[kFemto3P] = true; @@ -964,6 +976,21 @@ struct HfFilter { // Main struct for HF triggers } } } + } else if (isDeuteron && track.collisionId() == thisCollId) { + for (int iHypo{0}; iHypo < kNCharmParticles - 1 && !keepEvent[kFemto3P]; ++iHypo) { + if (isCharmTagged[iHypo] && enableFemtoChannels->get(1u, iHypo + 1) && (TESTBIT(is3ProngInMass[iHypo], 0) || TESTBIT(is3ProngInMass[iHypo], 1) || !requireCharmMassForFemto)) { + float relativeMomentum = helper.computeRelativeMomentum(pVecFourth, pVec3Prong, massCharmHypos[iHypo]); + if (applyOptimisation) { + optimisationTreeFemto(thisCollId, charmParticleID[iHypo], pt3Prong, scores[iHypo][0], scores[iHypo][1], scores[iHypo][2], relativeMomentum, track.tpcNSigmaPr(), track.tofNSigmaPr(), track.tpcNSigmaDe(), track.tofNSigmaDe()); + } + if (relativeMomentum < femtoMaxRelativeMomentum) { + keepEvent[kFemto3P] = true; + if (activateQA) { + hCharmDeuteronKstarDistr[iHypo + 1]->Fill(relativeMomentum); + } + } + } + } } // end femto selection // SigmaC++ K- trigger diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index f38ed71f5eb..6accb5e755c 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -118,7 +118,14 @@ enum PIDSpecies { kKa, kAntiKa, kPr, - kAntiPr + kAntiPr, + kDe, + kAntiDe +}; + +enum trackSpecies { + kProtonForFemto, + kDeuteronForFemto }; enum V0Species { @@ -155,6 +162,7 @@ static const std::tuple pdgCharmDaughters{ constexpr float massPi = o2::constants::physics::MassPiPlus; constexpr float massKa = o2::constants::physics::MassKPlus; constexpr float massProton = o2::constants::physics::MassProton; +constexpr float massDeuteron = o2::constants::physics::MassDeuteron; constexpr float massGamma = o2::constants::physics::MassGamma; constexpr float massK0S = o2::constants::physics::MassK0Short; constexpr float massLambda = o2::constants::physics::MassLambda0; @@ -188,20 +196,24 @@ static const std::array massAxisB = // default values for configurables // channels to trigger on for femto -constexpr int activeFemtoChannels[1][5] = {{1, 1, 1, 1, 0}}; // pD0, pD+, pDs, pLc, pXic +constexpr int activeFemtoChannels[2][5] = {{1, 1, 1, 1, 0}, // pD0, pD+, pDs, pLc, pXic + {0, 0, 0, 1, 0}}; // only for deLc static const std::vector labelsColumnsFemtoChannels = {"protonDZero", "protonDPlus", "protonDs", "protonLc", "protonXic"}; +static const std::vector labelsRowsFemtoChannels = {"protonCharmFemto", "deuteronCharmFemto"}; +constexpr float cutsPtThresholdsForFemto[1][2] = {{8., 1.4}}; // proton, deuteron +static const std::vector labelsColumnsPtThresholdsForFemto = {"Proton", "Deuteron"}; // min and max pT for all tracks combined (except for V0 and cascades) -constexpr float cutsPt[2][6] = {{1., 0.1, 0.8, 0.5, 0.1, 0.2}, - {100000., 100000., 5., 100000., 100000., 100000.}}; // beauty, D*, femto, SigmaC, Xic*+ -> SigmaC++K- -static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlus", "Femto", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC"}; +constexpr float cutsPt[2][7] = {{1., 0.1, 0.8, 0.5, 0.1, 0.2, 0.4}, + {100000., 100000., 5., 100000., 100000., 100000., 100000.}}; // beauty, D*, femto, SigmaC, Xic*+ -> SigmaC++K- +static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlus", "FemtoProton", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC", "FemtoDeuteron"}; static const std::vector labelsRowsCutsPt = {"Minimum", "Maximum"}; // PID cuts -constexpr float cutsNsigma[3][6] = {{3., 3., 3., 5., 3., 3.}, // TPC proton from Lc, pi/K from D0, K from 3-prong, femto, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon - {3., 3., 3., 2.5, 3., 3.}, // TOF proton from Lc, pi/K from D0, K from 3-prong, femto, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon - {999., 999., 999., 2.5, 999., 999.}}; // Sum in quadrature of TPC and TOF (used only for femto for pT < 4 GeV/c) -static const std::vector labelsColumnsNsigma = {"PrFromLc", "PiKaFromDZero", "KaFrom3Prong", "Femto", "PiKaFromCharmBaryon", "SoftKaonFromXicResoToSigmaC"}; +constexpr float cutsNsigma[3][7] = {{3., 3., 3., 5., 3., 3., 5.}, // TPC proton from Lc, pi/K from D0, K from 3-prong, femto selected proton, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon, femto selected deuteron + {3., 3., 3., 2.5, 3., 3., 5.}, // TOF proton from Lc, pi/K from D0, K from 3-prong, femto selected proton, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon, femto selected deuteron + {999., 999., 999., 2.5, 999., 999., 5.}}; // Sum in quadrature of TPC and TOF (used only for femto selected proton and deuteron for pT < 4 GeV/c) +static const std::vector labelsColumnsNsigma = {"PrFromLc", "PiKaFromDZero", "KaFrom3Prong", "FemtoProton", "PiKaFromCharmBaryon", "SoftKaonFromXicResoToSigmaC", "FemtoDeuteron"}; static const std::vector labelsRowsNsigma = {"TPC", "TOF", "Comb"}; // high pt @@ -277,6 +289,16 @@ class HfFilterHelper mPtThresholdHighPt2Prongs = threshold2Prongs; mPtThresholdHighPt3Prongs = threshold3Prongs; } + void setPtTriggerThresholdsForFemto(float thresholdProtons, float thresholdDeuterons) + { + mPtThresholdProtonForFemto = thresholdProtons; + mPtThresholdDeuteronForFemto = thresholdDeuterons; + } + void setForceTofForFemto(bool forceTofProtons, bool forceTofDeuterons) + { + mForceTofProtonForFemto = forceTofProtons; + mForceTofDeuteronForFemto = forceTofDeuterons; + } void setPtBinsSingleTracks(std::vector ptBins) { mPtBinsTracks = ptBins; } void setPtBinsBeautyHadrons(std::vector ptBins) { mPtBinsBeautyHadrons = ptBins; } void setCutsSingleTrackBeauty(o2::framework::LabeledArray cutsSingleTrack3P, o2::framework::LabeledArray cutsSingleTrack4P) @@ -293,6 +315,11 @@ class HfFilterHelper mPtMinProtonForFemto = minPt; mPtMaxProtonForFemto = maxPt; } + void setPtLimitsDeuteronForFemto(float minPt, float maxPt) + { + mPtMinDeuteronForFemto = minPt; + mPtMaxDeuteronForFemto = maxPt; + } void setPtLimitsBeautyBachelor(float minPt, float maxPt) { mPtMinBeautyBachelor = minPt; @@ -334,8 +361,8 @@ class HfFilterHelper mPtMaxCharmBaryonBachelor = maxPt; } - void setPtThresholdPidStrategyForFemto(float ptThreshold) { mPtThresholdPidStrategyForFemto = ptThreshold; } void setNsigmaProtonCutsForFemto(std::array nSigmaCuts) { mNSigmaPrCutsForFemto = nSigmaCuts; } + void setNsigmaDeuteronCutsForFemto(std::array nSigmaCuts) { mNSigmaDeCutsForFemto = nSigmaCuts; } void setNsigmaProtonCutsForCharmBaryons(float nSigmaTpc, float nSigmaTof) { mNSigmaTpcPrCutForCharmBaryons = nSigmaTpc; @@ -411,7 +438,7 @@ class HfFilterHelper template int8_t isSelectedTrackForSoftPionOrBeauty(const T& track, const T1& trackPar, const T2& dca, const int& whichTrigger); template - bool isSelectedProton4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hProtonTPCPID, H2 hProtonTOFPID, bool forceTof); + bool isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies); template int8_t isDzeroPreselected(const T& trackPos, const T& trackNeg); template @@ -460,7 +487,7 @@ class HfFilterHelper inline int setVtxConfiguration(T1 vertexer, bool useAbsDCA); // PID - void setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::array& ccdbPaths); + void setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::array& ccdbPaths); void setTpcRecalibMaps(o2::framework::Service const& ccdb, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string& ccdbPath); private: @@ -492,17 +519,21 @@ class HfFilterHelper float mPtMaxSoftKaonForXicResoToSigmaC{10000.f}; // maximum pt for the soft kaon of Xic* to SigmaC-Kaon float mPtMinBeautyBachelor{0.5}; // minimum pt for the b-hadron pion daughter float mPtMinProtonForFemto{0.8}; // minimum pt for the proton for femto + float mPtMinDeuteronForFemto{0.8}; // minimum pt for the deuteron for femto float mPtMinCharmBaryonBachelor{0.5}; // minimum pt for the bachelor pion from Xic/Omegac decays float mPtMaxSoftPionForDstar{2.}; // maximum pt for the D*+ soft pion float mPtMaxBeautyBachelor{100000.}; // maximum pt for the b-hadron pion daughter float mPtMaxProtonForFemto{5.0}; // maximum pt for the proton for femto + float mPtMaxDeuteronForFemto{5.0}; // maximum pt for the deuteron for femto float mPtMaxCharmBaryonBachelor{100000.}; // maximum pt for the bachelor pion from Xic/Omegac decays - float mPtThresholdPidStrategyForFemto{8.}; // pt threshold to change strategy for proton PID for femto + float mPtThresholdProtonForFemto{8.}; // pt threshold to change strategy for proton PID for femto + float mPtThresholdDeuteronForFemto{1.4}; // pt threshold to change strategy for deuteron PID for femto float mPtMinSigmaCZero{0.f}; // pt min SigmaC0 candidate float mPtMinSigmaC2520Zero{0.f}; // pt min SigmaC(2520)0 candidate float mPtMinSigmaCPlusPlus{0.f}; // pt min SigmaC++ candidate float mPtMinSigmaC2520PlusPlus{0.f}; // pt min SigmaC(2520)++ candidate std::array mNSigmaPrCutsForFemto{3., 3., 3.}; // cut values for Nsigma TPC, TOF, combined for femto protons + std::array mNSigmaDeCutsForFemto{3., 3., 3.}; // cut values for Nsigma TPC, TOF, combined for femto deuterons float mNSigmaTpcPrCutForCharmBaryons{3.}; // maximum Nsigma TPC for protons in Lc and Xic decays float mNSigmaTofPrCutForCharmBaryons{3.}; // maximum Nsigma TOF for protons in Lc and Xic decays float mNSigmaTpcKaCutFor3Prongs{3.}; // maximum Nsigma TPC for kaons in 3-prong decays @@ -543,12 +574,14 @@ class HfFilterHelper float mPtThresholdHighPt3Prongs{8.}; // threshold for high pT triggers for 3-prongs float mNSigmaTpcKaonFromXicResoToSigmaC{3.}; // maximum Nsigma TPC for kaons in Xic*->SigmaC-Kaon float mNSigmaTofKaonFromXicResoToSigmaC{3.}; // maximum Nsigma TOF for kaons in Xic*->SigmaC-Kaon + bool mForceTofProtonForFemto = true; // flag to force TOF PID for protons + bool mForceTofDeuteronForFemto = false; // flag to force TOF PID for deuterons o2::framework::LabeledArray mCutsBplus{}; // selections for B+ candidates (DeltaMass, CPA, DecayLength, ImpactParameterProduct) // PID recalibrations - int mTpcPidCalibrationOption{0}; // Option for TPC PID calibration (0 -> AO2D, 1 -> postcalibrations, 2 -> alternative bethe bloch parametrisation) - std::array mHistMapPiPrKa{}; // Map for TPC PID postcalibrations for pions, kaon and protons - std::array, 6> mBetheBlochPiKaPr{}; // Bethe-Bloch parametrisations for pions, antipions, kaons, antikaons, protons, antiprotons in TPC + int mTpcPidCalibrationOption{0}; // Option for TPC PID calibration (0 -> AO2D, 1 -> postcalibrations, 2 -> alternative bethe bloch parametrisation) + std::array mHistMapPiPrKaDe{}; // Map for TPC PID postcalibrations for pions, kaon, protons and deuterons + std::array, 8> mBetheBlochPiKaPrDe{}; // Bethe-Bloch parametrisations for pions, antipions, kaons, antikaons, protons, antiprotons, deuterons, antideuterons in TPC }; /// Selection of high-pt 2-prong candidates @@ -652,19 +685,44 @@ inline int8_t HfFilterHelper::isSelectedTrackForSoftPionOrBeauty(const T& track, return retValue; } -/// Basic selection of proton candidates +/// Basic selection of proton or deuteron candidates /// \param track is a track /// \param trackPar is a track parameter /// \param activateQA flag to activate the filling of QA histos /// \param hProtonTPCPID histo with NsigmaTPC vs. p /// \param hProtonTOFPID histo with NsigmaTOF vs. p -/// \param forceTof flag to force TOF PID +/// \param trackSpecies flag to choose proton or deuteron /// \return true if track passes all cuts template -inline bool HfFilterHelper::isSelectedProton4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hProtonTPCPID, H2 hProtonTOFPID, bool forceTof) +inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies) { float pt = trackPar.getPt(); - if (pt < mPtMinProtonForFemto || pt > mPtMaxProtonForFemto) { + float ptMin, ptMax, ptThresholdPidStrategy; + std::array nSigmaCuts; + bool forceTof = false; // flag to force TOF PID + + // Assign particle-specific parameters + switch (trackSpecies) { + case kProtonForFemto: + ptMin = mPtMinProtonForFemto; + ptMax = mPtMaxProtonForFemto; + nSigmaCuts = mNSigmaPrCutsForFemto; + forceTof = mForceTofProtonForFemto; + ptThresholdPidStrategy = mPtThresholdProtonForFemto; + break; + case kDeuteronForFemto: + ptMin = mPtMinDeuteronForFemto; + ptMax = mPtMaxDeuteronForFemto; + nSigmaCuts = mNSigmaDeCutsForFemto; + forceTof = mForceTofDeuteronForFemto; + ptThresholdPidStrategy = mPtThresholdDeuteronForFemto; + break; + default: + return false; // Unknown particle type + } + + // Common selection criteria + if (pt < ptMin || pt > ptMax) { return false; } @@ -675,39 +733,58 @@ inline bool HfFilterHelper::isSelectedProton4Femto(const T1& track, const T2& tr if (!track.isGlobalTrack()) { return false; // use only global tracks } - - float NSigmaTPC = track.tpcNSigmaPr(); - float NSigmaTOF = track.tofNSigmaPr(); + // PID evaluation + float NSigmaTPC = (trackSpecies == kProtonForFemto) ? track.tpcNSigmaPr() : track.tpcNSigmaDe(); + float NSigmaTOF = (trackSpecies == kProtonForFemto) ? track.tofNSigmaPr() : track.tofNSigmaDe(); if (!forceTof && !track.hasTOF()) { NSigmaTOF = 0.; // always accepted } + // Apply TPC PID post-calibration(only available for proton, dummy for deuteron) if (mTpcPidCalibrationOption == 1) { - NSigmaTPC = getTPCPostCalib(track, kPr); + NSigmaTPC = getTPCPostCalib(track, trackSpecies == kProtonForFemto ? kPr : kDe); } else if (mTpcPidCalibrationOption == 2) { if (track.sign() > 0) { - NSigmaTPC = getTPCSplineCalib(track, kPr); + NSigmaTPC = getTPCSplineCalib(track, trackSpecies == kProtonForFemto ? kPr : kDe); } else { - NSigmaTPC = getTPCSplineCalib(track, kAntiPr); + NSigmaTPC = getTPCSplineCalib(track, trackSpecies == kProtonForFemto ? kAntiPr : kAntiDe); } } float NSigma = std::sqrt(NSigmaTPC * NSigmaTPC + NSigmaTOF * NSigmaTOF); - if (trackPar.getPt() <= mPtThresholdPidStrategyForFemto) { - if (NSigma > mNSigmaPrCutsForFemto[2]) { - return false; + if (trackSpecies == kProtonForFemto) { + if (pt <= ptThresholdPidStrategy) { + if (NSigma > nSigmaCuts[2]) { + return false; + } + } else { + if (std::fabs(NSigmaTPC) > nSigmaCuts[0] || std::fabs(NSigmaTOF) > nSigmaCuts[1]) { + return false; + } } - } else { - if (std::fabs(NSigmaTPC) > mNSigmaPrCutsForFemto[0] || std::fabs(NSigmaTOF) > mNSigmaPrCutsForFemto[1]) { - return false; + } + // For deuterons: Determine whether to apply TOF based on pt threshold + if (trackSpecies == kDeuteronForFemto) { + // Apply different PID strategy in different pt range + if (pt <= ptThresholdPidStrategy) { + if (std::fabs(NSigmaTPC) > nSigmaCuts[0]) { // Use only TPC below the threshold + return false; + } + } else { + if (NSigma > nSigmaCuts[2]) { // Use combined TPC and TOF above the threshold + return false; + } } } if (activateQA > 1) { - hProtonTPCPID->Fill(track.p(), NSigmaTPC); - if (forceTof || track.hasTOF()) { - hProtonTOFPID->Fill(track.p(), NSigmaTOF); + hTPCPID->Fill(track.p(), NSigmaTPC); + if ((forceTof || track.hasTOF())) { + if (trackSpecies == kProtonForFemto) + hTOFPID->Fill(track.p(), NSigmaTOF); + else if (trackSpecies == kDeuteronForFemto && pt > ptThresholdPidStrategy) + hTOFPID->Fill(track.p(), NSigmaTOF); } } @@ -1531,9 +1608,9 @@ inline int HfFilterHelper::computeNumberOfCandidates(std::vector> /// \param ccdbApi is Api for CCDB /// \param bunchCrossing is the timestamp of bunchcrossing for the run number /// \param ccdbPaths are the paths on CCDB for pions, antipions, kaons, antikaons, protons, antiprotons -inline void HfFilterHelper::setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::array& ccdbPaths) +inline void HfFilterHelper::setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::array& ccdbPaths) { - for (int iSpecie{0u}; iSpecie < 6; ++iSpecie) { + for (int iSpecie{0u}; iSpecie < 8; ++iSpecie) { std::map metadata; auto hSpline = ccdbApi.retrieveFromTFileAny(ccdbPaths[iSpecie], metadata, bunchCrossing.timestamp()); @@ -1542,12 +1619,12 @@ inline void HfFilterHelper::setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWith } TAxis* axis = hSpline->GetXaxis(); - mBetheBlochPiKaPr[iSpecie] = {static_cast(hSpline->GetBinContent(axis->FindBin("bb1"))), - static_cast(hSpline->GetBinContent(axis->FindBin("bb2"))), - static_cast(hSpline->GetBinContent(axis->FindBin("bb3"))), - static_cast(hSpline->GetBinContent(axis->FindBin("bb4"))), - static_cast(hSpline->GetBinContent(axis->FindBin("bb5"))), - static_cast(hSpline->GetBinContent(axis->FindBin("Resolution")))}; + mBetheBlochPiKaPrDe[iSpecie] = {static_cast(hSpline->GetBinContent(axis->FindBin("bb1"))), + static_cast(hSpline->GetBinContent(axis->FindBin("bb2"))), + static_cast(hSpline->GetBinContent(axis->FindBin("bb3"))), + static_cast(hSpline->GetBinContent(axis->FindBin("bb4"))), + static_cast(hSpline->GetBinContent(axis->FindBin("bb5"))), + static_cast(hSpline->GetBinContent(axis->FindBin("Resolution")))}; } } @@ -1561,16 +1638,16 @@ inline void HfFilterHelper::setTpcRecalibMaps(o2::framework::Service mapNames = {"mean_map_pion", "sigma_map_pion", "mean_map_kaon", "sigma_map_kaon", "mean_map_proton", "sigma_map_proton"}; + std::array mapNames = {"mean_map_pion", "sigma_map_pion", "mean_map_kaon", "sigma_map_kaon", "mean_map_proton", "sigma_map_proton", "mean_map_deuteron", "sigma_map_deuteron"}; for (size_t iMap = 0; iMap < mapNames.size(); iMap++) { - mHistMapPiPrKa[iMap] = nullptr; + mHistMapPiPrKaDe[iMap] = nullptr; } for (size_t iMap = 0; iMap < mapNames.size(); iMap++) { - mHistMapPiPrKa[iMap] = reinterpret_cast(calibList->FindObject(mapNames[iMap].data())); - if (!mHistMapPiPrKa[iMap]) { + mHistMapPiPrKaDe[iMap] = reinterpret_cast(calibList->FindObject(mapNames[iMap].data())); + if (!mHistMapPiPrKaDe[iMap]) { LOG(fatal) << "Cannot find histogram: " << mapNames[iMap].data(); return; } @@ -1745,14 +1822,16 @@ inline double HfFilterHelper::getTPCSplineCalib(const T& track, const int& pidSp mMassPar = massKa; } else if (pidSpecies == kPr || pidSpecies == kAntiPr) { mMassPar = massProton; + } else if (pidSpecies == kDe || pidSpecies == kAntiDe) { + mMassPar = massDeuteron; } else { LOGP(fatal, "TPC recalibrated Nsigma requested for unknown particle species, return 999"); return 999.; } auto bgScaling = 1 / mMassPar; - double expBethe = tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() * bgScaling), mBetheBlochPiKaPr[pidSpecies][0], mBetheBlochPiKaPr[pidSpecies][1], mBetheBlochPiKaPr[pidSpecies][2], mBetheBlochPiKaPr[pidSpecies][3], mBetheBlochPiKaPr[pidSpecies][4]); - double expSigma = expBethe * mBetheBlochPiKaPr[pidSpecies][5]; + double expBethe = tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() * bgScaling), mBetheBlochPiKaPrDe[pidSpecies][0], mBetheBlochPiKaPrDe[pidSpecies][1], mBetheBlochPiKaPrDe[pidSpecies][2], mBetheBlochPiKaPrDe[pidSpecies][3], mBetheBlochPiKaPrDe[pidSpecies][4]); + double expSigma = expBethe * mBetheBlochPiKaPrDe[pidSpecies][5]; return static_cast((track.tpcSignal() - expBethe) / expSigma); } @@ -1783,22 +1862,22 @@ inline float HfFilterHelper::getTPCPostCalib(const T& track, const int& pidSpeci } else { LOG(fatal) << "Wrong PID Species be selected, please check!"; } - if (!mHistMapPiPrKa[iHist] || !mHistMapPiPrKa[iHist + 1]) { + if (!mHistMapPiPrKaDe[iHist] || !mHistMapPiPrKaDe[iHist + 1]) { LOGP(warn, "Postcalibration TPC PID histograms not set. Use default Nsigma values."); } - auto binTPCNCls = mHistMapPiPrKa[iHist]->GetXaxis()->FindBin(tpcNCls); + auto binTPCNCls = mHistMapPiPrKaDe[iHist]->GetXaxis()->FindBin(tpcNCls); binTPCNCls = (binTPCNCls == 0 ? 1 : binTPCNCls); - binTPCNCls = std::min(mHistMapPiPrKa[iHist]->GetXaxis()->GetNbins(), binTPCNCls); - auto binPin = mHistMapPiPrKa[iHist]->GetYaxis()->FindBin(tpcPin); + binTPCNCls = std::min(mHistMapPiPrKaDe[iHist]->GetXaxis()->GetNbins(), binTPCNCls); + auto binPin = mHistMapPiPrKaDe[iHist]->GetYaxis()->FindBin(tpcPin); binPin = (binPin == 0 ? 1 : binPin); - binPin = std::min(mHistMapPiPrKa[iHist]->GetYaxis()->GetNbins(), binPin); - auto binEta = mHistMapPiPrKa[iHist]->GetZaxis()->FindBin(eta); + binPin = std::min(mHistMapPiPrKaDe[iHist]->GetYaxis()->GetNbins(), binPin); + auto binEta = mHistMapPiPrKaDe[iHist]->GetZaxis()->FindBin(eta); binEta = (binEta == 0 ? 1 : binEta); - binEta = std::min(mHistMapPiPrKa[iHist]->GetZaxis()->GetNbins(), binEta); + binEta = std::min(mHistMapPiPrKaDe[iHist]->GetZaxis()->GetNbins(), binEta); - auto mean = mHistMapPiPrKa[iHist]->GetBinContent(binTPCNCls, binPin, binEta); - auto width = mHistMapPiPrKa[iHist + 1]->GetBinContent(binTPCNCls, binPin, binEta); + auto mean = mHistMapPiPrKaDe[iHist]->GetBinContent(binTPCNCls, binPin, binEta); + auto width = mHistMapPiPrKaDe[iHist + 1]->GetBinContent(binTPCNCls, binPin, binEta); return (tpcNSigma - mean) / width; } @@ -1962,6 +2041,8 @@ DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); //! DECLARE_SOA_COLUMN(KStar, kStar, float); //! DECLARE_SOA_COLUMN(NsigmaPrTPC, nsigmaPrTPC, float); //! DECLARE_SOA_COLUMN(NsigmaPrTOF, nsigmaPrTOF, float); //! +DECLARE_SOA_COLUMN(NsigmaDeTPC, nsigmaDeTPC, float); //! +DECLARE_SOA_COLUMN(NsigmaDeTOF, nsigmaDeTOF, float); //! } // namespace hfoptimisationTree DECLARE_SOA_TABLE(HFOptimisationTreeBeauty, "AOD", "HFOPTIMTREEB", //! @@ -1988,7 +2069,9 @@ DECLARE_SOA_TABLE(HFOptimisationTreeFemto, "AOD", "HFOPTIMTREEF", //! hfoptimisationTree::NonpromptBDT, hfoptimisationTree::KStar, hfoptimisationTree::NsigmaPrTPC, - hfoptimisationTree::NsigmaPrTOF); + hfoptimisationTree::NsigmaPrTOF, + hfoptimisationTree::NsigmaDeTPC, + hfoptimisationTree::NsigmaDeTOF); DECLARE_SOA_TABLE(HFOptimisationTreeCollisions, "AOD", "HFOPTIMTREECOLL", //! hfoptimisationTree::CollisionIndex) } // namespace o2::aod From a0ff0bae89eb802eb6ce792146f15ab53f7b9c48 Mon Sep 17 00:00:00 2001 From: Victor Gonzalez Date: Mon, 16 Dec 2024 01:34:30 +0100 Subject: [PATCH 21/30] [PWGCF] DptDpt - Tracking the TPC sector borders (#9000) Co-authored-by: Victor --- .../Tasks/dptDptEfficiencyAndQc.cxx | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx index 1fcb74db545..927464b65ca 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include "ReconstructionDataFormats/PID.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TableHelper.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" #include "Framework/ASoAHelpers.h" @@ -79,6 +81,10 @@ enum BeforeAfter { kAfter ///< filling after track selection }; +/* the structures for checking the TPC sector borders impact */ +constexpr int kNoOfTpcSectors = 18; +constexpr float kTpcPhiSectorWidth = (constants::math::TwoPI) / kNoOfTpcSectors; + /* the configuration of the nsigma axis */ float minNSigma = -4.05f; float maxNSigma = 4.05f; @@ -98,7 +104,7 @@ static const std::vector allmainsptitles{"e^{#plus}", "e^{#minus}", static const std::vector mainspecies{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton}; static const std::vector mainspnames{"PionP", "PionM", "KaonP", "KaonM", "ProtonP", "ProtonM"}; static const std::vector mainsptitles{"#pi^{#plus}", "#pi^{#minus}", "K^{#plus}", "K^{#minus}", "p", "#bar{p}"}; -static const std::vector pdgcodes = {11, 13, 211, 321, 2212}; +static const std::vector pdgcodes = {kElectron, kMuonPlus, kPiPlus, kKPlus, kProton}; } // namespace efficiencyandqatask /* the QA data collecting engine */ @@ -120,9 +126,17 @@ struct QADataCollectingEngine { std::vector> fhPtB{2, nullptr}; std::vector> fhPtVsEtaB{2, nullptr}; std::vector> fhPtVsZvtxB{2, nullptr}; + std::shared_ptr fhPhiVsPtPosB{nullptr}; + std::shared_ptr fhPhiVsInnerWallMomPosB{nullptr}; + std::shared_ptr fhPhiVsPtNegB{nullptr}; + std::shared_ptr fhPhiVsInnerWallMomNegB{nullptr}; std::vector>> fhPtA{2, {nsp, nullptr}}; std::vector>> fhPtVsEtaA{2, {nsp, nullptr}}; std::vector>> fhPtVsZvtxA{2, {nsp, nullptr}}; + std::vector> fhPhiVsPtA{nsp, nullptr}; + std::vector> fhPhiVsInnerWallMomA{nsp, nullptr}; + std::vector> fhPhiShiftedVsPtA{nsp, nullptr}; + std::vector> fhPhiShiftedVsInnerWallMomA{nsp, nullptr}; std::shared_ptr fhPtVsEtaItsAcc{nullptr}; std::shared_ptr fhPtVsEtaTpcAcc{nullptr}; std::shared_ptr fhPtVsEtaItsTpcAcc{nullptr}; @@ -182,11 +196,15 @@ struct QADataCollectingEngine { using namespace efficiencyandqatask; using namespace analysis::dptdptfilter; + AxisSpec pidPtAxis{150, 0.1, 5.0, "#it{p}_{T} (GeV/#it{c})"}; AxisSpec pidPAxis{150, 0.1, 5.0, "#it{p} (GeV/#it{c})"}; + pidPtAxis.makeLogarithmic(); pidPAxis.makeLogarithmic(); const AxisSpec ptAxis{ptbins, ptlow, ptup, "#it{p}_{T} (GeV/c)"}; const AxisSpec etaAxis{etabins, etalow, etaup, "#eta"}; - const AxisSpec phiAxis{360, 0.0f, constants::math::TwoPI, "#varphi"}; + const AxisSpec phiAxis{360, 0.0f, constants::math::TwoPI, "#varphi (rad)"}; + const AxisSpec phiSectorAxis{144, 0.0f, 0.36, "#varphi (mod(2#pi/18) (rad))"}; + const AxisSpec phiShiftedSectorAxis{220, -55.0f, 55.0f, "% of the sector"}; const AxisSpec zvtxAxis{zvtxbins, zvtxlow, zvtxup, "#it{z}_{vtx}"}; const AxisSpec itsNClsAxis{8, -0.5, 7.5, "ITS n clusters"}; const AxisSpec itsCh2Axis{100, 0, 40, "#Chi^{2}/Cls ITS"}; @@ -209,6 +227,10 @@ struct QADataCollectingEngine { if constexpr (kindOfData == kReco) { /* only the reconstructed level histograms*/ + fhPhiVsPtPosB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "PhiVsPtPos", "#varphi (mod(2#pi/18))", kTH2F, {pidPtAxis, phiSectorAxis}); + fhPhiVsInnerWallMomPosB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "PhiVsIwMomPos", "#varphi (mod(2#pi/18)) TPC_{iw} #it{p}", kTH2F, {pidPAxis, phiSectorAxis}); + fhPhiVsPtNegB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "PhiVsPtNeg", "#varphi (mod(2#pi/18))", kTH2F, {pidPtAxis, phiSectorAxis}); + fhPhiVsInnerWallMomNegB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "PhiVsIwMomNeg", "#varphi (mod(2#pi/18)) TPC_{iw} #it{p}", kTH2F, {pidPAxis, phiSectorAxis}); fhItsNClsVsPtB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "ITSNCls", "ITS clusters", kTH2F, {ptAxis, itsNClsAxis}); fhItsChi2NClsVsPtB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "ITSChi2NCls", "ITS #Chi^{2}", kTH2F, {ptAxis, itsCh2Axis}); fhTpcFindableNClsVsPtB = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "Before"), "TPCFindableNCls", "TPC findable clusters", kTH2F, {ptAxis, tpcNClsAxis}); @@ -227,6 +249,10 @@ struct QADataCollectingEngine { fhPtVsEtaTpcTofAcc = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Efficiency", "Reco"), "ptTpcTofAcc", "TPC&TOF tracks within the acceptance", kTH2F, {etaAxis, ptAxis}); fhPtVsEtaItsTpcTofAcc = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Efficiency", "Reco"), "ptItsTpcTofAcc", "ITS&TPC&TOF tracks within the acceptance", kTH2F, {etaAxis, ptAxis}); for (uint isp = 0; isp < nsp; ++isp) { + fhPhiVsPtA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("PhiVsPt_%s", tnames[isp].c_str()), HTITLESTRING("#varphi %s (mod(2#pi/18))", tnames[isp].c_str()), kTH2F, {pidPtAxis, phiSectorAxis}); + fhPhiVsInnerWallMomA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("PhiVsIwMom_%s", tnames[isp].c_str()), HTITLESTRING("#varphi %s (mod(2#pi/18)) TPC_{iw} #it{p}", tnames[isp].c_str()), kTH2F, {pidPAxis, phiSectorAxis}); + fhPhiShiftedVsPtA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("PhiShiftedVsPt_%s", tnames[isp].c_str()), HTITLESTRING("%s TPC sector %%", tnames[isp].c_str()), kTH2F, {pidPtAxis, phiShiftedSectorAxis}); + fhPhiShiftedVsInnerWallMomA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("PhiShiftedVsIwMom_%s", tnames[isp].c_str()), HTITLESTRING("%s TPC sector %% TPC_{iw} #it{p}", tnames[isp].c_str()), kTH2F, {pidPAxis, phiShiftedSectorAxis}); fhItsNClsVsPtA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("ITSNCls_%s", tnames[isp].c_str()), HTITLESTRING("ITS clusters %s", tnames[isp].c_str()), kTH2F, {ptAxis, itsNClsAxis}); fhItsChi2NClsVsPtA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("ITSChi2NCls_%s", tnames[isp].c_str()), HTITLESTRING("ITS #Chi^{2} %s", tnames[isp].c_str()), kTH2F, {ptAxis, itsCh2Axis}); fhTpcFindableNClsVsPtA[isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "Reco", "After"), HNAMESTRING("TPCFindableNCls_%s", tnames[isp].c_str()), HTITLESTRING("TPC findable clusters %s", tnames[isp].c_str()), kTH2F, {ptAxis, tpcNClsAxis}); @@ -338,6 +364,16 @@ struct QADataCollectingEngine { bool hastpc = track.hasTPC() && TrackSelectionFlags::checkFlag(track.trackCutFlag(), TrackSelectionTPC); bool hastof = track.hasTOF(); + float phiInTpcSector = std::fmod(track.phi(), kTpcPhiSectorWidth); + float phiShiftedPercentInTpcSector = phiInTpcSector * 100 / kTpcPhiSectorWidth; + phiShiftedPercentInTpcSector = (phiShiftedPercentInTpcSector > 50.0f) ? (phiShiftedPercentInTpcSector - 100.0f) : phiShiftedPercentInTpcSector; + if (track.sign() > 0) { + fhPhiVsPtPosB->Fill(track.pt(), phiInTpcSector); + fhPhiVsInnerWallMomPosB->Fill(track.tpcInnerParam(), phiInTpcSector); + } else { + fhPhiVsPtNegB->Fill(track.pt(), phiInTpcSector); + fhPhiVsInnerWallMomNegB->Fill(track.tpcInnerParam(), phiInTpcSector); + } fhItsNClsVsPtB->Fill(track.pt(), track.itsNCls()); fhItsChi2NClsVsPtB->Fill(track.pt(), track.itsChi2NCl()); fhTpcFindableNClsVsPtB->Fill(track.pt(), track.tpcNClsFindable()); @@ -357,6 +393,10 @@ struct QADataCollectingEngine { fillhisto(fhPtVsEtaItsTpcTofAcc, hasits && hastpc && hastof); } if (!(track.trackacceptedid() < 0)) { + fhPhiVsPtA[track.trackacceptedid()]->Fill(track.pt(), phiInTpcSector); + fhPhiVsInnerWallMomA[track.trackacceptedid()]->Fill(track.tpcInnerParam(), phiInTpcSector); + fhPhiShiftedVsPtA[track.trackacceptedid()]->Fill(track.pt(), phiShiftedPercentInTpcSector); + fhPhiShiftedVsInnerWallMomA[track.trackacceptedid()]->Fill(track.tpcInnerParam(), phiShiftedPercentInTpcSector); fhItsNClsVsPtA[track.trackacceptedid()]->Fill(track.pt(), track.itsNCls()); fhItsChi2NClsVsPtA[track.trackacceptedid()]->Fill(track.pt(), track.itsChi2NCl()); fhTpcFindableNClsVsPtA[track.trackacceptedid()]->Fill(track.pt(), track.tpcNClsFindable()); From 6a1d6825b12a27c1ce4d541fc3b12d2e88f56ebb Mon Sep 17 00:00:00 2001 From: Sasha Bylinkin <37345380+abylinkin@users.noreply.github.com> Date: Mon, 16 Dec 2024 02:43:51 +0100 Subject: [PATCH 22/30] [PWGUD] Data Model Change: IR and Occupancy (#8987) Co-authored-by: ALICE Action Bot --- PWGUD/DataModel/SGTables.h | 4 +- PWGUD/DataModel/UDTables.h | 20 +++++- PWGUD/TableProducer/CMakeLists.txt | 4 +- PWGUD/TableProducer/Converters/CMakeLists.txt | 4 ++ .../UDCollisionSelExtrasConverter.cxx | 59 +++++++++++++++ PWGUD/TableProducer/DGCandProducer.cxx | 35 ++++++++- PWGUD/TableProducer/SGCandProducer.cxx | 71 ++++++++++++++----- PWGUD/TableProducer/UPCCandidateProducer.cxx | 4 +- PWGUD/Tasks/sgPIDSpectraTable.cxx | 27 ++++--- 9 files changed, 195 insertions(+), 33 deletions(-) create mode 100644 PWGUD/TableProducer/Converters/UDCollisionSelExtrasConverter.cxx diff --git a/PWGUD/DataModel/SGTables.h b/PWGUD/DataModel/SGTables.h index a9bcd664063..bf9ef68da96 100644 --- a/PWGUD/DataModel/SGTables.h +++ b/PWGUD/DataModel/SGTables.h @@ -31,9 +31,11 @@ DECLARE_SOA_COLUMN(GS, gs, int); DECLARE_SOA_COLUMN(ZNA, zna, float); DECLARE_SOA_COLUMN(ZNC, znc, float); DECLARE_SOA_COLUMN(Ntr, ntr, int); +DECLARE_SOA_COLUMN(Occ, occ, int); +DECLARE_SOA_COLUMN(Ir, ir, float); } // namespace sgevent DECLARE_SOA_TABLE(SGEvents, "AOD", "SGEVENT", // o2::soa::Index<>, - sgevent::Run, sgevent::Flag, sgevent::GS, sgevent::ZNA, sgevent::ZNC, sgevent::Ntr); + sgevent::Run, sgevent::Flag, sgevent::GS, sgevent::ZNA, sgevent::ZNC, sgevent::Ntr, sgevent::Occ, sgevent::Ir); // sgevent::Run, sgevent::Flag); using SGEvent = SGEvents::iterator; namespace sgtrack diff --git a/PWGUD/DataModel/UDTables.h b/PWGUD/DataModel/UDTables.h index 8c5a796a578..b3f1f2354a2 100644 --- a/PWGUD/DataModel/UDTables.h +++ b/PWGUD/DataModel/UDTables.h @@ -101,6 +101,11 @@ DECLARE_SOA_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, float); //! sum of am DECLARE_SOA_COLUMN(TimeFV0A, timeFV0A, float); //! FV0A average time DECLARE_SOA_COLUMN(TriggerMaskFV0A, triggerMaskFV0A, uint8_t); //! FV0 trigger mask DECLARE_SOA_COLUMN(ChFV0A, chFV0A, uint8_t); //! number of FV0A active channels +DECLARE_SOA_COLUMN(OccupancyInTime, occupancyInTime, int); +DECLARE_SOA_COLUMN(HadronicRate, hadronicRate, double); +DECLARE_SOA_COLUMN(Trs, trs, int); +DECLARE_SOA_COLUMN(Trofs, trofs, int); +DECLARE_SOA_COLUMN(Hmpr, hmpr, int); // Gap Side Information DECLARE_SOA_COLUMN(GapSide, gapSide, uint8_t); // 0 for side A, 1 for side C, 2 for both sides (or use an enum for better readability) // FIT selection flags @@ -203,13 +208,25 @@ DECLARE_SOA_TABLE(UDCollisionsSels, "AOD", "UDCOLLISIONSEL", udcollision::BBFV0A, udcollision::BGFV0A, udcollision::BBFDDA, udcollision::BBFDDC, udcollision::BGFDDA, udcollision::BGFDDC); -DECLARE_SOA_TABLE(UDCollisionSelExtras, "AOD", "UDCOLSELEXTRA", +DECLARE_SOA_TABLE(UDCollisionSelExtras_000, "AOD", "UDCOLSELEXTRA", udcollision::ChFT0A, //! number of active channels in FT0A udcollision::ChFT0C, //! number of active channels in FT0C udcollision::ChFDDA, //! number of active channels in FDDA udcollision::ChFDDC, //! number of active channels in FDDC udcollision::ChFV0A); //! number of active channels in FV0A +DECLARE_SOA_TABLE_VERSIONED(UDCollisionSelExtras_001, "AOD", "UDCOLSELEXTRA", 1, + udcollision::ChFT0A, //! number of active channels in FT0A + udcollision::ChFT0C, //! number of active channels in FT0C + udcollision::ChFDDA, //! number of active channels in FDDA + udcollision::ChFDDC, //! number of active channels in FDDC + udcollision::ChFV0A, //! number of active channels in FV0A + udcollision::OccupancyInTime, //! Occupancy + udcollision::HadronicRate, //! Interaction Rate + udcollision::Trs, + udcollision::Trofs, + udcollision::Hmpr); + // central barrel-specific selections DECLARE_SOA_TABLE(UDCollisionsSelsCent, "AOD", "UDCOLSELCNT", udcollision::DBcTOR, @@ -233,6 +250,7 @@ DECLARE_SOA_TABLE(UDMcCollsLabels, "AOD", "UDMCCOLLSLABEL", udcollision::UDMcCollisionId); using UDCollisions = UDCollisions_001; +using UDCollisionSelExtras = UDCollisionSelExtras_001; using UDCollision = UDCollisions::iterator; using SGCollision = SGCollisions::iterator; diff --git a/PWGUD/TableProducer/CMakeLists.txt b/PWGUD/TableProducer/CMakeLists.txt index 8234d926ef2..cc9943b366d 100644 --- a/PWGUD/TableProducer/CMakeLists.txt +++ b/PWGUD/TableProducer/CMakeLists.txt @@ -13,12 +13,12 @@ add_subdirectory(Converters) o2physics_add_dpl_workflow(dgcand-producer SOURCES DGCandProducer.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGCutparHolder + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGCutparHolder O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(sgcand-producer SOURCES SGCandProducer.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::SGCutParHolder + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::SGCutParHolder O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(dgbccand-producer diff --git a/PWGUD/TableProducer/Converters/CMakeLists.txt b/PWGUD/TableProducer/Converters/CMakeLists.txt index 3bcb34f6ac2..55267c0785b 100644 --- a/PWGUD/TableProducer/Converters/CMakeLists.txt +++ b/PWGUD/TableProducer/Converters/CMakeLists.txt @@ -20,3 +20,7 @@ o2physics_add_dpl_workflow(collisions-converter PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(collisionselextras-converter + SOURCES UDCollisionSelExtrasConverter.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGUD/TableProducer/Converters/UDCollisionSelExtrasConverter.cxx b/PWGUD/TableProducer/Converters/UDCollisionSelExtrasConverter.cxx new file mode 100644 index 00000000000..1fa1882e7d5 --- /dev/null +++ b/PWGUD/TableProducer/Converters/UDCollisionSelExtrasConverter.cxx @@ -0,0 +1,59 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file UDCollisionSelExtrasConverter.cxx +/// \brief Converts UDCollisionSelExtras table from version 000 to 001 + +/// This task allows for the conversion of the UDCollisionSelExtras table from the version 000, +/// to include occupancy and interaction rate +/// to the version 001, that includes it + +/// executable name o2-analysis-ud-collisionselectras-converter + +/// \author Sasha Bylinkin + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "PWGUD/DataModel/UDTables.h" + +using namespace o2; +using namespace o2::framework; + +// Converts UDCollisions for version 000 to 001 +struct UDCollisionSelExtrasConverter { + Produces udCollisionSelExtras_001; + + void process(o2::aod::UDCollisionSelExtras_000 const& collisions) + { + + for (const auto& collision : collisions) { + + udCollisionSelExtras_001(collision.chFT0A(), + collision.chFT0C(), + collision.chFDDA(), + collision.chFDDC(), + collision.chFV0A(), + 0, // dummy occupancy + 0.0f, // dummy rate + 0, // dummy trs + 0, // dummy trofs + 0); // dummy hmpr + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGUD/TableProducer/DGCandProducer.cxx b/PWGUD/TableProducer/DGCandProducer.cxx index 027cfd376ee..f7c9ff038ec 100644 --- a/PWGUD/TableProducer/DGCandProducer.cxx +++ b/PWGUD/TableProducer/DGCandProducer.cxx @@ -15,9 +15,11 @@ #include #include #include +#include "CCDB/BasicCCDBManager.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "ReconstructionDataFormats/Vertex.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/UPCHelpers.h" #include "PWGUD/Core/DGSelector.h" @@ -27,6 +29,8 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct DGCandProducer { + Service ccdb; + ctpRateFetcher mRateFetcher; // get a DGCutparHolder DGCutparHolder diffCuts = DGCutparHolder(); Configurable DGCuts{"DGCuts", {}, "DG event cuts"}; @@ -39,6 +43,7 @@ struct DGCandProducer { // data tables Produces outputCollisions; Produces outputCollisionsSels; + Produces outputCollisionSelExtras; Produces outputCollsLabels; Produces outputZdcs; Produces outputZdcsReduced; @@ -198,7 +203,9 @@ struct DGCandProducer { void init(InitContext&) { LOGF(debug, " beginning of init reached"); - + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); diffCuts = (DGCutparHolder)DGCuts; const int nXbinsInStatH = 25; @@ -250,6 +257,31 @@ struct DGCandProducer { } registry.get(HIST("reco/Stat"))->Fill(1., 1.); auto bc = collision.foundBC_as(); + int trs = 0; + if (collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + trs = 1; + } + int trofs = 0; + if (collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + trofs = 1; + } + int hmpr = 0; + if (collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + hmpr = 1; + } + double ir = 0.; + const uint64_t ts = bc.timestamp(); + const int runnumber = bc.runNumber(); + if (bc.has_zdc()) { + ir = mRateFetcher.fetch(ccdb.service, ts, runnumber, "ZNC hadronic") * 1.e-3; + } + uint8_t chFT0A = 0; + uint8_t chFT0C = 0; + uint8_t chFDDA = 0; + uint8_t chFDDC = 0; + uint8_t chFV0A = 0; + int occ = 0; + occ = collision.trackOccupancyInTimeRange(); LOGF(debug, " BC id %d", bc.globalBC()); // fill FIT histograms @@ -289,6 +321,7 @@ struct DGCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); + outputCollisionSelExtras(chFT0A, chFT0C, chFDDA, chFDDC, chFV0A, occ, ir, trs, trofs, hmpr); outputCollsLabels(collision.globalIndex()); // update DGTracks tables diff --git a/PWGUD/TableProducer/SGCandProducer.cxx b/PWGUD/TableProducer/SGCandProducer.cxx index 967e7a838d0..424e7d44b7f 100644 --- a/PWGUD/TableProducer/SGCandProducer.cxx +++ b/PWGUD/TableProducer/SGCandProducer.cxx @@ -12,16 +12,22 @@ #include #include #include +#include "CCDB/BasicCCDBManager.h" #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" #include "ReconstructionDataFormats/Vertex.h" -#include "Common/CCDB/EventSelectionParams.h" -#include "Common/DataModel/EventSelection.h" #include "CommonConstants/LHCConstants.h" #include "DataFormatsFIT/Triggers.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" -#include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/EventSelection.h" #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/UPCHelpers.h" #include "PWGUD/Core/SGSelector.h" @@ -29,8 +35,22 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::dataformats; struct SGCandProducer { + Service ccdb; + // data inputs + using CCs = soa::Join; + using CC = CCs::iterator; + using BCs = soa::Join; + using BC = BCs::iterator; + using TCs = soa::Join; + using FWs = aod::FwdTracks; // get an SGCutparHolder SGCutParHolder sameCuts = SGCutParHolder(); // SGCutparHolder Configurable SGCuts{"SGCuts", {}, "SG event cuts"}; @@ -46,14 +66,15 @@ struct SGCandProducer { // Configurables to decide which tables are filled Configurable fillTrackTables{"fillTrackTables", true, "Fill track tables"}; Configurable fillFwdTrackTables{"fillFwdTrackTables", true, "Fill forward track tables"}; - // SG selector SGSelector sgSelector; + ctpRateFetcher mRateFetcher; // data tables Produces outputSGCollisions; Produces outputCollisions; Produces outputCollisionsSels; + Produces outputCollisionSelExtras; Produces outputCollsLabels; Produces outputZdcs; Produces udZdcsReduced; @@ -73,19 +94,6 @@ struct SGCandProducer { "registry", {}}; - // data inputs - using CCs = soa::Join; - using CC = CCs::iterator; - using BCs = soa::Join; - using BC = BCs::iterator; - using TCs = soa::Join; - using FWs = aod::FwdTracks; - // function to update UDFwdTracks, UDFwdTracksExtra template void updateUDFwdTrackTables(TFwdTrack const& fwdtrack, uint64_t const& bcnum) @@ -165,6 +173,9 @@ struct SGCandProducer { void init(InitContext&) { + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); sameCuts = (SGCutParHolder)SGCuts; registry.add("reco/Stat", "Cut statistics; Selection criterion; Collisions", {HistType::kTH1F, {{14, -0.5, 13.5}}}); } @@ -206,7 +217,25 @@ struct SGCandProducer { return; } registry.get(HIST("reco/Stat"))->Fill(6., 1.); + int trs = 0; + if (collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + trs = 1; + } + int trofs = 0; + if (collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + trofs = 1; + } + int hmpr = 0; + if (collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + hmpr = 1; + } auto bc = collision.foundBC_as(); + double ir = 0.; + const uint64_t ts = bc.timestamp(); + const int runnumber = bc.runNumber(); + if (bc.has_zdc()) { + ir = mRateFetcher.fetch(ccdb.service, ts, runnumber, "ZNC hadronic") * 1.e-3; + } auto newbc = bc; // obtain slice of compatible BCs @@ -229,6 +258,13 @@ struct SGCandProducer { return; } upchelpers::FITInfo fitInfo{}; + uint8_t chFT0A = 0; + uint8_t chFT0C = 0; + uint8_t chFDDA = 0; + uint8_t chFDDC = 0; + uint8_t chFV0A = 0; + int occ = 0; + occ = collision.trackOccupancyInTimeRange(); udhelpers::getFITinfo(fitInfo, newbc, bcs, ft0s, fv0as, fdds); // update SG candidates tables int upc_flag = 0; @@ -249,6 +285,7 @@ struct SGCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); + outputCollisionSelExtras(chFT0A, chFT0C, chFDDA, chFDDC, chFV0A, occ, ir, trs, trofs, hmpr); outputCollsLabels(collision.globalIndex()); if (newbc.has_zdc()) { auto zdc = newbc.zdc(); diff --git a/PWGUD/TableProducer/UPCCandidateProducer.cxx b/PWGUD/TableProducer/UPCCandidateProducer.cxx index 5eba6e0c2ef..f93bea732b4 100644 --- a/PWGUD/TableProducer/UPCCandidateProducer.cxx +++ b/PWGUD/TableProducer/UPCCandidateProducer.cxx @@ -1466,7 +1466,7 @@ struct UpcCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); - eventCandidatesSelExtras(chFT0A, chFT0C, chFDDA, chFDDC, chFV0A); + eventCandidatesSelExtras(chFT0A, chFT0C, chFDDA, chFDDC, chFV0A, 0, 0, 0, 0, 0); eventCandidatesSelsFwd(fitInfo.distClosestBcV0A, fitInfo.distClosestBcT0A, amplitudesT0A, @@ -1724,7 +1724,7 @@ struct UpcCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); - eventCandidatesSelExtras(chFT0A, chFT0C, chFDDA, chFDDC, chFV0A); + eventCandidatesSelExtras(chFT0A, chFT0C, chFDDA, chFDDC, chFV0A, 0, 0, 0, 0, 0); eventCandidatesSelsFwd(fitInfo.distClosestBcV0A, fitInfo.distClosestBcT0A, amplitudesT0A, diff --git a/PWGUD/Tasks/sgPIDSpectraTable.cxx b/PWGUD/Tasks/sgPIDSpectraTable.cxx index f8e6e69373c..9a370403a6b 100644 --- a/PWGUD/Tasks/sgPIDSpectraTable.cxx +++ b/PWGUD/Tasks/sgPIDSpectraTable.cxx @@ -52,6 +52,11 @@ struct SGPIDSpectraTable { Configurable itsChi2_cut{"itsChi2_cut", 36, "Max itsChi2NCl"}; Configurable eta_cut{"eta_cut", 0.9, "Track Pseudorapidity"}; Configurable pt_cut{"pt_cut", 0.1, "Track Pt"}; + Configurable occ_cut{"occ_cut", 200, "Maximum Occupancy"}; + Configurable occ_bit1_cut{"occ_bit1_cut", 0, "Check NoCollInTimeRangeStandard"}; + Configurable occ_bit2_cut{"occ_bit2_cut", 0, "Check NoCollInRofStandard"}; + Configurable occ_bit3_cut{"occ_bit3_cut", 0, "Check NoHighMultCollInPrevRof"}; + Configurable ir_cut{"ir_cut", 100, "Maximum IR"}; // initialize histogram registry HistogramRegistry registry{ "registry", @@ -63,7 +68,7 @@ struct SGPIDSpectraTable { } // define data types - using UDCollisionsFull = soa::Join; // UDCollisions + using UDCollisionsFull = soa::Join; // UDCollisions using UDCollisionFull = UDCollisionsFull::iterator; using UDTracksFull = soa::Join; @@ -76,6 +81,17 @@ struct SGPIDSpectraTable { return; } // fill collision histograms + // check occupancies: + if (occ_bit1_cut && !coll.trs()) + return; + if (occ_bit2_cut && !coll.trofs()) + return; + if (occ_bit3_cut && !coll.hmpr()) + return; + if (coll.occupancyInTime() > occ_cut) + return; + if (coll.hadronicRate() > ir_cut) + return; // int truegapSide = sgSelector.trueGap(dgcand, FV0_cut, ZDC_cut); // select PV contributors std::vector parameters = {PV_cut, dcaZ_cut, dcaXY_cut, tpcChi2_cut, tpcNClsFindable_cut, itsChi2_cut, eta_cut, pt_cut}; @@ -91,7 +107,7 @@ struct SGPIDSpectraTable { } if (!goodtracks) return; - SGevents(coll.runNumber(), coll.flags(), truegapSide, coll.energyCommonZNA(), coll.energyCommonZNC(), goodtracks); + SGevents(coll.runNumber(), coll.flags(), truegapSide, coll.energyCommonZNA(), coll.energyCommonZNC(), goodtracks, coll.occupancyInTime(), coll.hadronicRate()); // SGevents(coll.runNumber(), coll.flags()); for (auto t : tracks) { if (trackselector(t, parameters)) { @@ -107,14 +123,7 @@ struct SGPIDSpectraTable { tofpr = t.hasTOF() ? t.tofNSigmaPr() : -999; tofel = t.hasTOF() ? t.tofNSigmaEl() : -999; tpcde = t.hasTPC() ? t.tpcNSigmaDe() : -999; - // tpctr = t.hasTPC() ? t.tpcNSigmaTr() : -999; - // tpche = t.hasTPC() ? t.tpcNSigmaHe() : -999; - // tpcal = t.hasTPC() ? t.tpcNSigmaAl() : -999; tofde = t.hasTOF() ? t.tofNSigmaDe() : -999; - // toftr = t.hasTOF() ? t.tofNSigmaTr() : -999; - // tofhe = t.hasTOF() ? t.tofNSigmaHe() : -999; - // tofal = t.hasTOF() ? t.tofNSigmaAl() : -999; - // SGtracks(SGevents.lastIndex(),a.Pt(),a.Eta(),a.Phi(),t.sign(),tpcpi, tpcka, tpcpr, tpcel, tofpi, tofka, tofpr, tofel, tpcmu, tofmu, tpcde, tpctr, tpche, tpcal, tofde, toftr, tofhe, tofal); SGtracks(SGevents.lastIndex(), a.Pt(), a.Eta(), a.Phi(), t.sign(), tpcpi, tpcka, tpcpr, tpcel, tofpi, tofka, tofpr, tofel, tpcmu, tofmu, tpcde, tofde); } } From 06dd8ee4e87d157aa84dce257b8f674ee2f24451 Mon Sep 17 00:00:00 2001 From: abilandz Date: Mon, 16 Dec 2024 02:59:10 +0100 Subject: [PATCH 23/30] [PWGCF] new group of QA histos + minor fixes (#8998) --- .../Core/MuPa-Configurables.h | 3 + .../Core/MuPa-DataMembers.h | 46 +- .../Core/MuPa-Enums.h | 32 + .../Core/MuPa-MemberFunctions.h | 758 +++++++++++++----- .../Tasks/multiparticle-correlations-ab.cxx | 1 - 5 files changed, 633 insertions(+), 207 deletions(-) diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h index 7c5012a3804..30c3e38eca5 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h @@ -49,6 +49,9 @@ struct : ConfigurableGroup { Configurable> cfBookQAEventHistograms2D{"cfBookQAEventHistograms2D", {"1-Multiplicity_vs_ReferenceMultiplicity", "1-Multiplicity_vs_NContributors", "1-Multiplicity_vs_Centrality", "1-Multiplicity_vs_Vertex_z", "1-Multiplicity_vs_Occupancy", "1-ReferenceMultiplicity_vs_NContributors", "1-ReferenceMultiplicity_vs_Centrality", "1-ReferenceMultiplicity_vs_Vertex_z", "1-ReferenceMultiplicity_vs_Occupancy", "1-NContributors_vs_Centrality", "1-NContributors_vs_Vertex_z", "1-NContributors_vs_Occupancy", "1-Centrality_vs_Vertex_z", "1-Centrality_vs_Occupancy", "0-Centrality_vs_ImpactParameter", "1-Vertex_z_vs_Occupancy", "0-MultNTracksPV_vs_MultNTracksGlobal", "0-CentFT0C_vs_CentNTPV", "0-CentFT0M_vs_CentNTPV", "0-CentRun2V0M_vs_CentRun2SPDTracklets", "1-TrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange", "1-CurrentRunDuration_vs_InteractionRate"}, "book (1) or do not book (0) this QA 2D event histogram"}; Configurable cfFillQAParticleHistograms2D{"cfFillQAParticleHistograms2D", false, "if false, all QA 2D particle histograms are not filled. if true, only the ones for which fBookQAParticleHistograms2D[...] is true, are filled"}; Configurable> cfBookQAParticleHistograms2D{"cfBookQAParticleHistograms2D", {"1-Pt_vs_dcaXY"}, "book (1) or do not book (0) this QA 2D particle histogram"}; + Configurable cfFillQAParticleEventHistograms2D{"cfFillQAParticleEventHistograms2D", false, "if false, all QA 2D particle event histograms are not filled. if true, only the ones for which fBookQAParticleEventHistograms2D[...] is true, are filled"}; + Configurable> cfBookQAParticleEventHistograms2D{"cfBookQAParticleEventHistograms2D", {"1-CurrentRunDuration_vs_itsNCls", "1-CurrentRunDuration_vs_itsNClsNegEtaEbyE", "1-CurrentRunDuration_vs_itsNClsPosEtaEbyE", "1-CurrentRunDuration_vs_Eta0804EbyE", "1-CurrentRunDuration_vs_Eta0400EbyE", "1-CurrentRunDuration_vs_Eta0004EbyE", "1-CurrentRunDuration_vs_Eta0408EbyE", "1-CurrentRunDuration_vs_Pt0005EbyE", "1-CurrentRunDuration_vs_Pt0510EbyE", "1-CurrentRunDuration_vs_Pt1050EbyE"}, "book (1) or do not book (0) this QA 2D particle event histogram"}; + } cf_qa; // *) Event histograms: diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h index 01cd067855f..b09eb50a02d 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h @@ -84,27 +84,43 @@ struct EventByEventQuantities { // Remark 1: I keep new histograms in this group, until I need them permanently in the analysis. Then, they are moved to EventHistograms or ParticleHistograms (yes, even if they are 2D). // Remark 2: All 2D histograms book as TH2F, due to "stmem error" in terminate (see .cxx for further details) struct QualityAssurance { - TList* fQAList = NULL; //! event-by-event + // [reco, sim][before, after]. Type dimension is bin. + Float_t fReferenceMultiplicity[eReferenceMultiplicityEstimators_N] = {0.}; // used mostly in QA correlation plots TString fReferenceMultiplicityEstimatorName[eReferenceMultiplicityEstimators_N] = {""}; // TBI 20241123 add comment Float_t fCentrality[eCentralityEstimators_N] = {0.}; // used mostly in QA correlation plots TString fCentralityEstimatorName[eCentralityEstimators_N] = {""}; // TBI 20241123 add comment Float_t fOccupancy[eOccupancyEstimators_N] = {0.}; // used mostly in QA correlation plots TString fOccupancyEstimatorName[eOccupancyEstimators_N] = {""}; // TBI 20241123 add comment -} qa; // "qa" is a common label for objects in this struct + +} qa; // "qa" is a common label for objects in this struct // *) Event histograms: struct EventHistograms { diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h index b7a904d1578..7fdd8054b94 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h @@ -278,6 +278,38 @@ enum eQAParticleHistograms2D { eQAParticleHistograms2D_N }; +enum eQAParticleEventHistograms2D { + // In this category I do correlation vs. some-event-property. + // The < ... > goes over all particles in that event. + // All < ... > over particles are calculated with helper TProfile + // For instance: vs. current run duration + eCurrentRunDuration_vs_itsNClsEbyE, + eCurrentRunDuration_vs_itsNClsNegEtaEbyE, + eCurrentRunDuration_vs_itsNClsPosEtaEbyE, + eCurrentRunDuration_vs_Eta0804EbyE, + eCurrentRunDuration_vs_Eta0400EbyE, + eCurrentRunDuration_vs_Eta0004EbyE, + eCurrentRunDuration_vs_Eta0408EbyE, + eCurrentRunDuration_vs_Pt0005EbyE, + eCurrentRunDuration_vs_Pt0510EbyE, + eCurrentRunDuration_vs_Pt1050EbyE, + eQAParticleEventHistograms2D_N +}; + +enum eQAParticleEventProEbyE { + eitsNClsEbyE = 1, // Labels average in a given event (therefore "EbyE" is appended). Yes, from one, because it runs over bin content and entries in TProfile for most of the time. + eitsNClsNegEtaEbyE, // in a given event for eta < 0 + eitsNClsPosEtaEbyE, // in a given event for eta > 0 + eEta0804EbyE, // in a given event for -0.8 < eta < -0.4 + eEta0400EbyE, // in a given event for -0.4 < eta < 0.0 + eEta0004EbyE, // in a given event for 0.0 < eta < 0.4 + eEta0408EbyE, // in a given event for 0.4 < eta < 0.8 + ePt0005EbyE, // in a given event for 0.0 < pt < 0.5 + ePt0510EbyE, // in a given event for 0.5 < pt < 1.0 + ePt1050EbyE, // in a given event for 1.0 < pt < 5.0 + eQAParticleEventProEbyE_N +}; + enum eReferenceMultiplicityEstimators { // Run 3: eMultTPC = 0, diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h index 8cd74c814d5..58358985a5d 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h @@ -574,6 +574,27 @@ void DefaultConfiguration() } } + // **) Names of QA 2D particle event histograms: + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_itsNClsEbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), ph.fParticleHistogramsName[eitsNCls].Data()).Data(); + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eitsNCls].Data()).Append("NegEtaEbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eitsNCls].Data()).Append("PosEtaEbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0804EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0804EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0400EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0400EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0004EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0004EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0408EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0408EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Pt0005EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[ePt].Data()).Append("0005EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Pt0510EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[ePt].Data()).Append("0510EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Pt1050EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[ePt].Data()).Append("1050EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + + // ... + + // ***) Quick insanity check that all names are set: + for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) { + if (qa.fQAParticleEventHistogramsName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fQAParticleEventHistogramsName2D[%d] is not set, check corresponding enum eQAParticleEventHistograms2D \033[0m", __FUNCTION__, __LINE__, t); + } + } + // ** Eta separations: es.fCalculateEtaSeparations = cf_es.cfCalculateEtaSeparations; es.fCalculateEtaSeparationsAsFunctionOf[AFO_INTEGRATED] = cf_es.cfCalculateEtaSeparationsAsFunctionOfIntegrated && es.fCalculateEtaSeparations; @@ -683,44 +704,42 @@ void DefaultBooking() // By default all event histograms are booked. Set this flag to kFALSE to switch off booking of all event histograms: eh.fFillEventHistograms = cf_eh.cfFillEventHistograms; - if (eh.fFillEventHistograms) { - // *) By default all event histograms are booked. If you do not want particular event histogram to be booked, - // use configurable array cfBookEventHistograms, where you can specify name of the histogram accompanied with flags 1 (book) or 0 (do not book). - // Supported format: "someName-0" and "someName-1", where "-" is a field separator. - // Ordering of the flags in that array is interpreted through ordering of enums in enum eEventHistograms. - auto lBookEventHistograms = cf_eh.cfBookEventHistograms.value; // this is now the local version of that string array from configurable. - if (lBookEventHistograms.size() != eEventHistograms_N) { - LOGF(info, "\033[1;31m lBookEventHistograms.size() = %d\033[0m", lBookEventHistograms.size()); - LOGF(info, "\033[1;31m eEventHistograms_N) = %d\033[0m", static_cast(eEventHistograms_N)); - LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfBookEventHistograms, and number of entries in enum eEventHistograms \n \033[0m", __FUNCTION__, __LINE__); - } - - // *) Insanity check on the content and ordering of histogram names in the initialization in configurable cfBookEventHistograms: - // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. - for (Int_t name = 0; name < eEventHistograms_N; name++) { - // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. - if (!TString(lBookEventHistograms[name]).EndsWith(eh.fEventHistogramsName[name].Data())) { - LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookEventHistograms => name = %d, lBookEventHistograms[%d] = \"%s\", eh.fEventHistogramsName[%d] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, name, TString(lBookEventHistograms[name]).Data(), name, eh.fEventHistogramsName[name].Data()); - } - } - - // I append "&& eh.fFillEventHistograms" below, to switch off booking of all event histograms with one common flag: - eh.fBookEventHistograms[eNumberOfEvents] = Alright(lBookEventHistograms[eNumberOfEvents]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eTotalMultiplicity] = Alright(lBookEventHistograms[eTotalMultiplicity]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eMultiplicity] = Alright(lBookEventHistograms[eMultiplicity]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eReferenceMultiplicity] = Alright(lBookEventHistograms[eReferenceMultiplicity]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eCentrality] = Alright(lBookEventHistograms[eCentrality]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eVertex_x] = Alright(lBookEventHistograms[eVertex_x]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eVertex_y] = Alright(lBookEventHistograms[eVertex_y]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eVertex_z] = Alright(lBookEventHistograms[eVertex_z]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eNContributors] = Alright(lBookEventHistograms[eNContributors]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eImpactParameter] = Alright(lBookEventHistograms[eImpactParameter]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eEventPlaneAngle] = Alright(lBookEventHistograms[eEventPlaneAngle]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eOccupancy] = Alright(lBookEventHistograms[eOccupancy]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eInteractionRate] = Alright(lBookEventHistograms[eInteractionRate]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eCurrentRunDuration] = Alright(lBookEventHistograms[eCurrentRunDuration]) && eh.fFillEventHistograms; - eh.fBookEventHistograms[eMultMCNParticlesEta08] = Alright(lBookEventHistograms[eMultMCNParticlesEta08]) && eh.fFillEventHistograms; - } // end of if (eh.fFillEventHistograms) + // *) By default all event histograms are booked. If you do not want particular event histogram to be booked, + // use configurable array cfBookEventHistograms, where you can specify name of the histogram accompanied with flags 1 (book) or 0 (do not book). + // Supported format: "someName-0" and "someName-1", where "-" is a field separator. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eEventHistograms. + auto lBookEventHistograms = cf_eh.cfBookEventHistograms.value; // this is now the local version of that string array from configurable. + if (lBookEventHistograms.size() != eEventHistograms_N) { + LOGF(info, "\033[1;31m lBookEventHistograms.size() = %d\033[0m", lBookEventHistograms.size()); + LOGF(info, "\033[1;31m eEventHistograms_N) = %d\033[0m", static_cast(eEventHistograms_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfBookEventHistograms, and number of entries in enum eEventHistograms \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of histogram names in the initialization in configurable cfBookEventHistograms: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (Int_t name = 0; name < eEventHistograms_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookEventHistograms[name]).EndsWith(eh.fEventHistogramsName[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookEventHistograms => name = %d, lBookEventHistograms[%d] = \"%s\", eh.fEventHistogramsName[%d] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, name, TString(lBookEventHistograms[name]).Data(), name, eh.fEventHistogramsName[name].Data()); + } + } + + // I append "&& eh.fFillEventHistograms" below, to switch off booking of all event histograms with one common flag: + eh.fBookEventHistograms[eNumberOfEvents] = Alright(lBookEventHistograms[eNumberOfEvents]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eTotalMultiplicity] = Alright(lBookEventHistograms[eTotalMultiplicity]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eMultiplicity] = Alright(lBookEventHistograms[eMultiplicity]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eReferenceMultiplicity] = Alright(lBookEventHistograms[eReferenceMultiplicity]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eCentrality] = Alright(lBookEventHistograms[eCentrality]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eVertex_x] = Alright(lBookEventHistograms[eVertex_x]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eVertex_y] = Alright(lBookEventHistograms[eVertex_y]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eVertex_z] = Alright(lBookEventHistograms[eVertex_z]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eNContributors] = Alright(lBookEventHistograms[eNContributors]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eImpactParameter] = Alright(lBookEventHistograms[eImpactParameter]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eEventPlaneAngle] = Alright(lBookEventHistograms[eEventPlaneAngle]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eOccupancy] = Alright(lBookEventHistograms[eOccupancy]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eInteractionRate] = Alright(lBookEventHistograms[eInteractionRate]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eCurrentRunDuration] = Alright(lBookEventHistograms[eCurrentRunDuration]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eMultMCNParticlesEta08] = Alright(lBookEventHistograms[eMultMCNParticlesEta08]) && eh.fFillEventHistograms; // b) Event histograms 2D: // TBI 20240515 Ideally, all 2D shall go to QA group, see below @@ -730,150 +749,175 @@ void DefaultBooking() // By default all 1D particle histograms are booked. Set this flag to kFALSE to switch off booking of all 1D particle histograms: ph.fFillParticleHistograms = cf_ph.cfFillParticleHistograms; - if (ph.fFillParticleHistograms) { - // *) If you do not want particular particle histogram to be booked, use configurable array cfBookParticleHistograms, where you can specify flags 1 (book) or 0 (do not book). - // Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms. // TBI 20240124 is this safe enough? - auto lBookParticleHistograms = cf_ph.cfBookParticleHistograms.value; // this is now the local version of that string array from configurable. - if (lBookParticleHistograms.size() != eParticleHistograms_N) { - LOGF(info, "\033[1;31m lBookParticleHistograms.size() = %d\033[0m", lBookParticleHistograms.size()); - LOGF(info, "\033[1;31m eParticleHistograms_N) = %d\033[0m", static_cast(eParticleHistograms_N)); - LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleHistograms, and number of entries in enum eParticleHistograms \n \033[0m", __FUNCTION__, __LINE__); - } - - // *) Insanity check on the content and ordering of particle histograms in the initialization in configurable cfBookParticleHistograms: - // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. - for (Int_t name = 0; name < eParticleHistograms_N; name++) { - // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. - if (!TString(lBookParticleHistograms[name]).EndsWith(ph.fParticleHistogramsName[name].Data())) { - LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleHistograms => name = %d, lBookParticleHistograms[name] = \"%s\", ph.fParticleHistogramsName[name] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleHistograms[name]).Data(), ph.fParticleHistogramsName[name].Data()); - } - } - - // I append "&& ph.fFillParticleHistograms" below, to switch off booking of all 1D particle histograms with one common flag: - ph.fBookParticleHistograms[ePhi] = Alright(lBookParticleHistograms[ePhi]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[ePt] = Alright(lBookParticleHistograms[ePt]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[eEta] = Alright(lBookParticleHistograms[eEta]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[eCharge] = Alright(lBookParticleHistograms[eCharge]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcNClsFindable] = Alright(lBookParticleHistograms[etpcNClsFindable]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcNClsShared] = Alright(lBookParticleHistograms[etpcNClsShared]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcNClsFound] = Alright(lBookParticleHistograms[etpcNClsFound]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcNClsCrossedRows] = Alright(lBookParticleHistograms[etpcNClsCrossedRows]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[eitsNCls] = Alright(lBookParticleHistograms[eitsNCls]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[eitsNClsInnerBarrel] = Alright(lBookParticleHistograms[eitsNClsInnerBarrel]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcCrossedRowsOverFindableCls] = Alright(lBookParticleHistograms[etpcCrossedRowsOverFindableCls]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcFoundOverFindableCls] = Alright(lBookParticleHistograms[etpcFoundOverFindableCls]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[etpcFractionSharedCls] = Alright(lBookParticleHistograms[etpcFractionSharedCls]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[edcaXY] = Alright(lBookParticleHistograms[edcaXY]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[edcaZ] = Alright(lBookParticleHistograms[edcaZ]) && ph.fFillParticleHistograms; - ph.fBookParticleHistograms[ePDG] = Alright(lBookParticleHistograms[ePDG]) && ph.fFillParticleHistograms; - // Remark #1: I do not need here anythig for etrackCutFlagFb1, etrackCutFlagFb2, ... eisGlobalTrack, because they are booleans - // Remark #2: Nothing special here for ePtDependentDCAxyParameterization, because that is a string. - } // end of if(ph.fFillParticleHistograms) + // *) If you do not want particular particle histogram to be booked, use configurable array cfBookParticleHistograms, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms. // TBI 20240124 is this safe enough? + auto lBookParticleHistograms = cf_ph.cfBookParticleHistograms.value; // this is now the local version of that string array from configurable. + if (lBookParticleHistograms.size() != eParticleHistograms_N) { + LOGF(info, "\033[1;31m lBookParticleHistograms.size() = %d\033[0m", lBookParticleHistograms.size()); + LOGF(info, "\033[1;31m eParticleHistograms_N) = %d\033[0m", static_cast(eParticleHistograms_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleHistograms, and number of entries in enum eParticleHistograms \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of particle histograms in the initialization in configurable cfBookParticleHistograms: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (Int_t name = 0; name < eParticleHistograms_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookParticleHistograms[name]).EndsWith(ph.fParticleHistogramsName[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleHistograms => name = %d, lBookParticleHistograms[name] = \"%s\", ph.fParticleHistogramsName[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleHistograms[name]).Data(), ph.fParticleHistogramsName[name].Data()); + } + } + + // I append "&& ph.fFillParticleHistograms" below, to switch off booking of all 1D particle histograms with one common flag: + ph.fBookParticleHistograms[ePhi] = Alright(lBookParticleHistograms[ePhi]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[ePt] = Alright(lBookParticleHistograms[ePt]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eEta] = Alright(lBookParticleHistograms[eEta]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eCharge] = Alright(lBookParticleHistograms[eCharge]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsFindable] = Alright(lBookParticleHistograms[etpcNClsFindable]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsShared] = Alright(lBookParticleHistograms[etpcNClsShared]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsFound] = Alright(lBookParticleHistograms[etpcNClsFound]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsCrossedRows] = Alright(lBookParticleHistograms[etpcNClsCrossedRows]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eitsNCls] = Alright(lBookParticleHistograms[eitsNCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eitsNClsInnerBarrel] = Alright(lBookParticleHistograms[eitsNClsInnerBarrel]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcCrossedRowsOverFindableCls] = Alright(lBookParticleHistograms[etpcCrossedRowsOverFindableCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcFoundOverFindableCls] = Alright(lBookParticleHistograms[etpcFoundOverFindableCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcFractionSharedCls] = Alright(lBookParticleHistograms[etpcFractionSharedCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[edcaXY] = Alright(lBookParticleHistograms[edcaXY]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[edcaZ] = Alright(lBookParticleHistograms[edcaZ]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[ePDG] = Alright(lBookParticleHistograms[ePDG]) && ph.fFillParticleHistograms; + // Remark #1: I do not need here anythig for etrackCutFlagFb1, etrackCutFlagFb2, ... eisGlobalTrack, because they are booleans + // Remark #2: Nothing special here for ePtDependentDCAxyParameterization, because that is a string. // d) Particle histograms 2D: // By default all 2D particle histograms are booked. Set this flag to kFALSE to switch off booking of all 2D particle histograms: ph.fFillParticleHistograms2D = cf_ph.cfFillParticleHistograms2D; - if (ph.fFillParticleHistograms2D) { - // If you do not want particular 2D particle histogram to be booked, use configurable array cfBookParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). - // *) Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms2D. - auto lBookParticleHistograms2D = cf_ph.cfBookParticleHistograms2D.value; // this is now the local version of that string array from configurable - // TBI 20241113 For some reason, the default values of configurable "cfBookParticleHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being - if (lBookParticleHistograms2D.size() != eParticleHistograms2D_N) { - LOGF(info, "\033[1;31m lBookParticleHistograms2D.size() = %d\033[0m", lBookParticleHistograms2D.size()); - LOGF(info, "\033[1;31m eParticleHistograms2D_N) = %d\033[0m", static_cast(eParticleHistograms2D_N)); - LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleHistograms2D, and number of entries in enum eParticleHistograms2D \n \033[0m", __FUNCTION__, __LINE__); - } + // If you do not want particular 2D particle histogram to be booked, use configurable array cfBookParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // *) Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms2D. + auto lBookParticleHistograms2D = cf_ph.cfBookParticleHistograms2D.value; // this is now the local version of that string array from configurable + // TBI 20241113 For some reason, the default values of configurable "cfBookParticleHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being + if (lBookParticleHistograms2D.size() != eParticleHistograms2D_N) { + LOGF(info, "\033[1;31m lBookParticleHistograms2D.size() = %d\033[0m", lBookParticleHistograms2D.size()); + LOGF(info, "\033[1;31m eParticleHistograms2D_N) = %d\033[0m", static_cast(eParticleHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleHistograms2D, and number of entries in enum eParticleHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } - // *) Insanity check on the content and ordering of 2D particle histograms in the initialization in configurable cfBookParticleHistograms2D: - // TBI 20241109 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. - for (Int_t name = 0; name < eParticleHistograms2D_N; name++) { - // TBI 20241109 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. - if (!TString(lBookParticleHistograms2D[name]).EndsWith(ph.fParticleHistogramsName2D[name].Data())) { - LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleHistograms2D => name = %d, lBookParticleHistograms2D[name] = \"%s\", ph.fParticleHistogramsName2D[name] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleHistograms2D[name]).Data(), ph.fParticleHistogramsName2D[name].Data()); - } + // *) Insanity check on the content and ordering of 2D particle histograms in the initialization in configurable cfBookParticleHistograms2D: + // TBI 20241109 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (Int_t name = 0; name < eParticleHistograms2D_N; name++) { + // TBI 20241109 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookParticleHistograms2D[name]).EndsWith(ph.fParticleHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleHistograms2D => name = %d, lBookParticleHistograms2D[name] = \"%s\", ph.fParticleHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleHistograms2D[name]).Data(), ph.fParticleHistogramsName2D[name].Data()); } + } - // I append "&& ph.fFillParticleHistograms2D" below, to switch off booking of all 2D particle histograms with one common flag: - ph.fBookParticleHistograms2D[ePhiPt] = Alright(lBookParticleHistograms2D[ePhiPt]) && ph.fFillParticleHistograms2D; - ph.fBookParticleHistograms2D[ePhiEta] = Alright(lBookParticleHistograms2D[ePhiEta]) && ph.fFillParticleHistograms2D; - } // end of if (ph.fFillParticleHistograms2D) + // I append "&& ph.fFillParticleHistograms2D" below, to switch off booking of all 2D particle histograms with one common flag: + ph.fBookParticleHistograms2D[ePhiPt] = Alright(lBookParticleHistograms2D[ePhiPt]) && ph.fFillParticleHistograms2D; + ph.fBookParticleHistograms2D[ePhiEta] = Alright(lBookParticleHistograms2D[ePhiEta]) && ph.fFillParticleHistograms2D; // e) QA: // **) QA 2D event histograms: qa.fFillQAEventHistograms2D = cf_qa.cfFillQAEventHistograms2D; - if (qa.fFillQAEventHistograms2D) { - // *) If you do not want particular 2D event histogram to be booked, use configurable array cfBookQAEventHistograms2D, where you can specify flags 1 (book) or 0 (do not book). - // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAEventHistograms2D - auto lBookQAEventHistograms2D = cf_qa.cfBookQAEventHistograms2D.value; // this is now the local version of that string array from configurable - // TBI 20241115 For some reason, the default values of configurable "cfBookQAEventHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being - if (lBookQAEventHistograms2D.size() != eQAEventHistograms2D_N) { - LOGF(info, "\033[1;31m lBookQAEventHistograms2D.size() = %d\033[0m", lBookQAEventHistograms2D.size()); - LOGF(info, "\033[1;31m eQAEventHistograms2D_N = %d\033[0m", static_cast(eQAEventHistograms2D_N)); - LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAEventHistograms2D, and number of entries in enum eQAEventHistograms2D \n \033[0m", __FUNCTION__, __LINE__); - } - - // *) Insanity check on the content and ordering of QA 2D event histograms in the initialization in configurable cfBookQAEventHistograms2D: - // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. - for (Int_t name = 0; name < eQAEventHistograms2D_N; name++) { - // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. - if (!TString(lBookQAEventHistograms2D[name]).EndsWith(qa.fEventHistogramsName2D[name].Data())) { - LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAEventHistograms2D => name = %d, lBookQAEventHistograms2D[name] = \"%s\", qa.fEventHistogramsName2D[name] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAEventHistograms2D[name]).Data(), qa.fEventHistogramsName2D[name].Data()); - } - } - - // I append "&& qa.fFillQAEventHistograms2D" below, to switch off booking of all 2D event histograms with one common flag: - qa.fBookQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eMultiplicity_vs_NContributors] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_NContributors]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eMultiplicity_vs_Centrality] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Centrality]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eMultiplicity_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eMultiplicity_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Occupancy]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eNContributors_vs_Centrality] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Centrality]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eNContributors_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eNContributors_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Occupancy]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCentrality_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eCentrality_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCentrality_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eCentrality_vs_Occupancy]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCentrality_vs_ImpactParameter] = Alright(lBookQAEventHistograms2D[eCentrality_vs_ImpactParameter]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eVertex_z_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eVertex_z_vs_Occupancy]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal] = Alright(lBookQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets] = Alright(lBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange]) && qa.fFillQAEventHistograms2D; - qa.fBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; - } // end of if (qa.fFillQAEventHistograms2D) + // *) If you do not want particular 2D event histogram to be booked, use configurable array cfBookQAEventHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAEventHistograms2D + auto lBookQAEventHistograms2D = cf_qa.cfBookQAEventHistograms2D.value; // this is now the local version of that string array from configurable + // TBI 20241115 For some reason, the default values of configurable "cfBookQAEventHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being + if (lBookQAEventHistograms2D.size() != eQAEventHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQAEventHistograms2D.size() = %d\033[0m", lBookQAEventHistograms2D.size()); + LOGF(info, "\033[1;31m eQAEventHistograms2D_N = %d\033[0m", static_cast(eQAEventHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAEventHistograms2D, and number of entries in enum eQAEventHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D event histograms in the initialization in configurable cfBookQAEventHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (Int_t name = 0; name < eQAEventHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQAEventHistograms2D[name]).EndsWith(qa.fEventHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAEventHistograms2D => name = %d, lBookQAEventHistograms2D[name] = \"%s\", qa.fEventHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAEventHistograms2D[name]).Data(), qa.fEventHistogramsName2D[name].Data()); + } + } + + // I append "&& qa.fFillQAEventHistograms2D" below, to switch off booking of all 2D event histograms with one common flag: + qa.fBookQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_NContributors] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_NContributors]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_Centrality] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Centrality]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_Centrality] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Centrality]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eCentrality_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eCentrality_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_ImpactParameter] = Alright(lBookQAEventHistograms2D[eCentrality_vs_ImpactParameter]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eVertex_z_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eVertex_z_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal] = Alright(lBookQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets] = Alright(lBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; // **) QA 2D particle histograms: qa.fFillQAParticleHistograms2D = cf_qa.cfFillQAParticleHistograms2D; - if (qa.fFillQAParticleHistograms2D) { - // *) If you do not want particular 2D particle histogram to be booked, use configurable array cfBookQAParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). - // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAParticleHistograms2D. - auto lBookQAParticleHistograms2D = (vector)cf_qa.cfBookQAParticleHistograms2D; // this is now the local version of that int array from configurable - if (lBookQAParticleHistograms2D.size() != eQAParticleHistograms2D_N) { - LOGF(info, "\033[1;31m lBookQAParticleHistograms2D.size() = %d\033[0m", lBookQAParticleHistograms2D.size()); - LOGF(info, "\033[1;31m eQAParticleHistograms2D_N = %d\033[0m", static_cast(eQAParticleHistograms2D_N)); - LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAParticleHistograms2D, and number of entries in enum eParticleHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + // *) If you do not want particular 2D particle histogram to be booked, use configurable array cfBookQAParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAParticleHistograms2D. + auto lBookQAParticleHistograms2D = cf_qa.cfBookQAParticleHistograms2D.value; // this is now the local version of that string array from configurable + if (lBookQAParticleHistograms2D.size() != eQAParticleHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQAParticleHistograms2D.size() = %d\033[0m", lBookQAParticleHistograms2D.size()); + LOGF(info, "\033[1;31m eQAParticleHistograms2D_N = %d\033[0m", static_cast(eQAParticleHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAParticleHistograms2D, and number of entries in enum eParticleHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D particle histograms in the initialization in configurable cfBookQAParticleHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (Int_t name = 0; name < eQAParticleHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQAParticleHistograms2D[name]).EndsWith(qa.fParticleHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAParticleHistograms2D => name = %d, lBookQAParticleHistograms2D[name] = \"%s\", qa.fParticleHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAParticleHistograms2D[name]).Data(), qa.fParticleHistogramsName2D[name].Data()); } + } - // *) Insanity check on the content and ordering of QA 2D particle histograms in the initialization in configurable cfBookQAParticleHistograms2D: - // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. - for (Int_t name = 0; name < eQAParticleHistograms2D_N; name++) { - // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. - if (!TString(lBookQAParticleHistograms2D[name]).EndsWith(qa.fParticleHistogramsName2D[name].Data())) { - LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAParticleHistograms2D => name = %d, lBookQAParticleHistograms2D[name] = \"%s\", qa.fParticleHistogramsName2D[name] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAParticleHistograms2D[name]).Data(), qa.fParticleHistogramsName2D[name].Data()); - } + // I append "&& qa.fFillQAParticleHistograms2D" below, to switch off booking of all 2D particle histograms with one common flag: + qa.fBookQAParticleHistograms2D[ePt_vs_dcaXY] = Alright(lBookQAParticleHistograms2D[ePt_vs_dcaXY]) && qa.fFillQAParticleHistograms2D; + + // **) QA 2D particle event histograms: + qa.fFillQAParticleEventHistograms2D = cf_qa.cfFillQAParticleEventHistograms2D; + + // *) If you do not want particular 2D particle event histogram to be booked, use configurable array cfBookQAParticleEventHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAParticleEventHistograms2D. + auto lBookQAParticleEventHistograms2D = cf_qa.cfBookQAParticleEventHistograms2D.value; // this is now the local version of that string array from configurable + if (lBookQAParticleEventHistograms2D.size() != eQAParticleEventHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQAParticleEventHistograms2D.size() = %d\033[0m", lBookQAParticleEventHistograms2D.size()); + LOGF(info, "\033[1;31m eQAParticleEventHistograms2D_N = %d\033[0m", static_cast(eQAParticleEventHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAParticleEventHistograms2D, and number of entries in enum eParticleEventHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D particle event histograms in the initialization in configurable cfBookQAParticleEventHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (Int_t name = 0; name < eQAParticleEventHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQAParticleEventHistograms2D[name]).EndsWith(qa.fQAParticleEventHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAParticleEventHistograms2D => name = %d, lBookQAParticleEventHistograms2D[name] = \"%s\", qa.fParticleEventHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAParticleEventHistograms2D[name]).Data(), qa.fQAParticleEventHistogramsName2D[name].Data()); } + } - // I append "&& qa.fFillQAParticleHistograms2D" below, to switch off booking of all 2D particle histograms with one common flag: - qa.fBookQAParticleHistograms2D[ePt_vs_dcaXY] = Alright(lBookQAParticleHistograms2D[ePt_vs_dcaXY]) && qa.fFillQAParticleHistograms2D; - } // end of if (qa.fFillQAParticleHistograms2D) + // I append "&& qa.fFillQAParticleEventHistograms2D" below, to switch off booking of all 2D particle event histograms with one common flag: + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE]) && qa.fFillQAParticleEventHistograms2D; // ... @@ -891,6 +935,7 @@ void DefaultBinning() // TBI 20240114 If some of these values are going to change frequently, add support for them in MuPa-Configurables.h, // in the same way I did it for DefaultCuts(). + // Remark: If // a) Default binning for event histograms; // b) Default binning for particle histograms 1D; @@ -947,21 +992,9 @@ void DefaultBinning() eh.fEventHistogramsBins[eEventPlaneAngle][1] = -o2::constants::math::PI; // just in case somebody uses the convention -Pi < EP < Pi, instead of 0 < EP < 2Pi eh.fEventHistogramsBins[eEventPlaneAngle][2] = o2::constants::math::TwoPI; - if (ec.fsEventCuts[eOccupancyEstimator].EqualTo("TrackOccupancyInTimeRange", TString::kIgnoreCase)) { - eh.fEventHistogramsBins[eOccupancy][0] = 150; - eh.fEventHistogramsBins[eOccupancy][1] = 0.; - eh.fEventHistogramsBins[eOccupancy][2] = 15000.; - } else if (ec.fsEventCuts[eOccupancyEstimator].EqualTo("FT0COccupancyInTimeRange", TString::kIgnoreCase)) { // keep in sync with values below for 2D QA - eh.fEventHistogramsBins[eOccupancy][0] = 1000; - eh.fEventHistogramsBins[eOccupancy][1] = 0.; - eh.fEventHistogramsBins[eOccupancy][2] = 100000.; - } - // For 2D QA correlation plot, temporarily I set it to maximum of the two above: - if (qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange]) { - eh.fEventHistogramsBins[eOccupancy][0] = 1000; // keep in sync. with definition above - eh.fEventHistogramsBins[eOccupancy][1] = 0.; - eh.fEventHistogramsBins[eOccupancy][2] = 100000.; - } + eh.fEventHistogramsBins[eOccupancy][0] = 1000; + eh.fEventHistogramsBins[eOccupancy][1] = 0.; + eh.fEventHistogramsBins[eOccupancy][2] = 100000.; eh.fEventHistogramsBins[eInteractionRate][0] = 1000; eh.fEventHistogramsBins[eInteractionRate][1] = 0.; @@ -969,7 +1002,7 @@ void DefaultBinning() eh.fEventHistogramsBins[eCurrentRunDuration][0] = 10000; eh.fEventHistogramsBins[eCurrentRunDuration][1] = 0.; - eh.fEventHistogramsBins[eCurrentRunDuration][2] = 100000.; + eh.fEventHistogramsBins[eCurrentRunDuration][2] = 10000.; // b) Default binning for particle histograms 1D: ph.fParticleHistogramsBins[ePhi][0] = 360; @@ -1012,13 +1045,13 @@ void DefaultBinning() ph.fParticleHistogramsBins[eitsNClsInnerBarrel][1] = 0.; ph.fParticleHistogramsBins[eitsNClsInnerBarrel][2] = 10.; - ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][0] = 250; + ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][0] = 1000; ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][1] = 0.; - ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][2] = 5000; + ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][2] = 10; - ph.fParticleHistogramsBins[etpcFoundOverFindableCls][0] = 250; + ph.fParticleHistogramsBins[etpcFoundOverFindableCls][0] = 1000; ph.fParticleHistogramsBins[etpcFoundOverFindableCls][1] = 0.; - ph.fParticleHistogramsBins[etpcFoundOverFindableCls][2] = 5000.; + ph.fParticleHistogramsBins[etpcFoundOverFindableCls][2] = 10.; ph.fParticleHistogramsBins[etpcFractionSharedCls][0] = 110; ph.fParticleHistogramsBins[etpcFractionSharedCls][1] = -1.; // yes, I saw here entries with negative values TBI 20240507 check what are these values @@ -1357,7 +1390,7 @@ void DefaultCuts() // **) event cuts defined via [min, max): // Remark: I use this one also for events cuts set only via min or via max. - // In this case, I set eithe min or max intentionally to some value which never can be met (see below example for "MinVertexDistanceFromIP") + // In this case, I set either min or max intentionally to some value which never can be met (see below example for "MinVertexDistanceFromIP") auto lNumberOfEvents = (std::vector)cf_ec.cfNumberOfEvents; ec.fdEventCuts[eNumberOfEvents][eMin] = lNumberOfEvents[eMin]; ec.fdEventCuts[eNumberOfEvents][eMax] = lNumberOfEvents[eMax]; @@ -1621,6 +1654,10 @@ void SpecificCuts(TString whichSpecificCuts) pc.fdParticleCuts[etpcNClsCrossedRows][eMin] = 70.; pc.fdParticleCuts[etpcNClsCrossedRows][eMax] = 1000.; + pc.fUseParticleCuts[etpcCrossedRowsOverFindableCls] = kTRUE; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMin] = 0.8; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax] = 1000.; + break; // ... @@ -2153,6 +2190,9 @@ Bool_t Skip(Int_t recOrSim) void BookAndNestAllLists() { // *) QA; + // **) QA event histograms; + // **) QA particle histograms; + // **) QA particle event histograms; // *) Control event histograms; // *) Control particle histograms; // *) Correlations; @@ -2176,6 +2216,30 @@ void BookAndNestAllLists() qa.fQAList->SetOwner(kTRUE); fBaseList->Add(qa.fQAList); + // **) QA event histograms; + if (qa.fFillQAEventHistograms2D) { + qa.fQAEventList = new TList(); + qa.fQAEventList->SetName("QAEvent"); + qa.fQAEventList->SetOwner(kTRUE); + qa.fQAList->Add(qa.fQAEventList); // yes, this one is nested within base QA TList + } + + // **) QA particle histograms; + if (qa.fFillQAParticleHistograms2D) { + qa.fQAParticleList = new TList(); + qa.fQAParticleList->SetName("QAParticle"); + qa.fQAParticleList->SetOwner(kTRUE); + qa.fQAList->Add(qa.fQAParticleList); // yes, this one is nested within base QA TList + } + + // **) QA particle event histograms; + if (qa.fFillQAParticleEventHistograms2D) { + qa.fQAParticleEventList = new TList(); + qa.fQAParticleEventList->SetName("QAParticleEvent"); + qa.fQAParticleEventList->SetOwner(kTRUE); + qa.fQAList->Add(qa.fQAParticleEventList); // yes, this one is nested within base QA TList + } + // *) Event cuts: ec.fEventCutsList = new TList(); ec.fEventCutsList->SetName("EventCuts"); @@ -2277,7 +2341,8 @@ void BookQAHistograms() // a) Book the profile holding flags; // b) Common local variables; // c) Book specific QA 2D event histograms; - // d) Book specific QA 2D particle histograms. + // d) Book specific QA 2D particle histograms; + // e) Book specific QA 2D particle event histograms. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -2296,7 +2361,7 @@ void BookQAHistograms() } // a) Book the profile holding flags: - qa.fQAHistogramsPro = new TProfile("fQAHistogramsPro", "flags for QA histograms", 4, 0., 4.); + qa.fQAHistogramsPro = new TProfile("fQAHistogramsPro", "flags for QA histograms", 5, 0., 5.); qa.fQAHistogramsPro->SetStats(kFALSE); qa.fQAHistogramsPro->SetLineColor(eColor); qa.fQAHistogramsPro->SetFillColor(eFillColor); @@ -2306,8 +2371,10 @@ void BookQAHistograms() qa.fQAHistogramsPro->Fill(1.5, static_cast(qa.fFillQAEventHistograms2D)); qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(3, "fFillQAParticleHistograms2D"); qa.fQAHistogramsPro->Fill(2.5, static_cast(qa.fFillQAParticleHistograms2D)); - qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(4, "fRebin"); - qa.fQAHistogramsPro->Fill(3.5, static_cast(qa.fRebin)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(4, "fFillQAParticleEventHistograms2D"); + qa.fQAHistogramsPro->Fill(3.5, static_cast(qa.fFillQAParticleEventHistograms2D)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(5, "fRebin"); + qa.fQAHistogramsPro->Fill(4.5, static_cast(qa.fRebin)); // ... @@ -2605,7 +2672,7 @@ void BookQAHistograms() qa.fQAEventHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); qa.fQAEventHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); qa.fQAEventHistograms2D[t][rs][ba]->SetOption("col"); - qa.fQAList->Add(qa.fQAEventHistograms2D[t][rs][ba]); + qa.fQAEventList->Add(qa.fQAEventHistograms2D[t][rs][ba]); } // for(Int_t ba=0;ba<2;ba++) } // for(Int_t rs=0;rs<2;rs++) // reco/sim } // for(Int_t t=0;tSetLineColor(ec.fBeforeAfterColor[ba]); qa.fQAParticleHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); qa.fQAParticleHistograms2D[t][rs][ba]->SetOption("col"); - qa.fQAList->Add(qa.fQAParticleHistograms2D[t][rs][ba]); + qa.fQAParticleList->Add(qa.fQAParticleHistograms2D[t][rs][ba]); } // for(Int_t ba=0;ba<2;ba++) } // for(Int_t rs=0;rs<2;rs++) // reco/sim } // for(Int_t t=0;t(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + // nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = static_cast(ph.fParticleHistogramsBins[eitsNCls][0]); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = 100; + min_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = ph.fParticleHistogramsBins[eitsNCls][1]; + max_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = ph.fParticleHistogramsBins[eitsNCls][2]; + title_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = TString::Format("#LT%s#GT", FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data())); + + // *) "eCurrentRunDuration_vs_itsNClsNegEtaEbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = 100; + min_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][1]; + max_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][2]; + title_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = TString::Format("#LT%s#GT, #eta < 0", FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data())); + + // *) "eCurrentRunDuration_vs_itsNClsPosEtaEbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = 100; + min_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][1]; + max_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][2]; + title_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = TString::Format("#LT%s#GT, #eta > 0", FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data())); + + // *) "eCurrentRunDuration_vs_Eta0804EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = -1.0; // TBI 20241214 intentionally temporarily overshooting, to trace down overflow and underflow, if any + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = 1.0; // TBI 20241214 intentionally temporarily overshooting, to trace down overflow and underflow, if any + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = TString::Format("#LT%s#GT, -0.8 < #eta < -0.4", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Eta0400EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = -1.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = 1.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = TString::Format("#LT%s#GT, -0.4 < #eta < 0.0", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Eta0004EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = -1.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = 1.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = TString::Format("#LT%s#GT, 0.0 < #eta < 0.4", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Eta0408EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = -1.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = 1.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = TString::Format("#LT%s#GT, 0.4 < #eta < 0.8", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Pt0005EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = 400; + min_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = 0.0; // TBI 20241214 intentionally temporarilyovershooting, to trace down overflow and underflow, if any + max_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = 10.0; // TBI 20241214 intentionally temporarily overshooting, to trace down overflow and underflow, if any + title_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = TString::Format("#LT%s#GT, 0.0 < p_{T} < 0.5 GeV/c", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // *) "eCurrentRunDuration_vs_Pt0510EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = 400; + min_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = 0.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = 10.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = TString::Format("#LT%s#GT, 0.5 < p_{T} < 1.0 GeV/c", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // *) "eCurrentRunDuration_vs_Pt1050EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = 400; + min_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = 0.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = 10.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = TString::Format("#LT%s#GT, 1.0 < p_{T} < 5.0 GeV/c", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // ... + + // *) Quick insanity check on title_x_ParticleEvent and title_y_ParticleEvent: + for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) { + if (title_x_ParticleEvent[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_x_ParticleEvent[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + if (title_y_ParticleEvent[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_y_ParticleEvent[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // Okay, let's book 'em all: + for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eQAParticleEventHistograms2D + { + if (!qa.fBookQAParticleEventHistograms2D[t]) { + continue; + } + for (Int_t rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (Int_t ba = 0; ba < 2; ba++) // before/after cuts + { + + if (ba == eBefore) { // TBI 20241214 re-think if I need these additional QA particle event histos before cuts + continue; + } + + qa.fQAParticleEventHistograms2D[t][rs][ba] = new TH2F( + Form("fQAParticleEventHistograms2D[%s][%s][%s]", qa.fQAParticleEventHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + Form("%s, %s, %s", "__RUN_NUMBER__", gc.srs_long[rs].Data(), gc.sba_long[ba].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + nBins_x_ParticleEvent[t], min_x_ParticleEvent[t], max_x_ParticleEvent[t], nBins_y_ParticleEvent[t], min_y_ParticleEvent[t], max_y_ParticleEvent[t]); + + qa.fQAParticleEventHistograms2D[t][rs][ba]->GetXaxis()->SetTitle(title_x_ParticleEvent[t].Data()); + qa.fQAParticleEventHistograms2D[t][rs][ba]->GetYaxis()->SetTitle(title_y_ParticleEvent[t].Data()); + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetOption("col"); + qa.fQAParticleEventList->Add(qa.fQAParticleEventHistograms2D[t][rs][ba]); + } // for(Int_t ba=0;ba<2;ba++) + } // for(Int_t rs=0;rs<2;rs++) // reco/sim + } // for(Int_t t=0;tGetXaxis()->SetBinLabel(eitsNClsEbyE, "#LTitsNCls#GT"); // TBI 20241214 this bin labeling is not really needed, as I never save this TProfile persistently + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eitsNClsNegEtaEbyE, "#LTitsNClsNegEta#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eitsNClsPosEtaEbyE, "#LTitsNClsPosEta#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0804EbyE, "#LTEta0804EbyE#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0400EbyE, "#LTEta0400EbyE#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0004EbyE, "#LTEta0004EbyE#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0408EbyE, "#LTEta0408EbyE#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(ePt0005EbyE, "#LTPt0005EbyE#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(ePt0510EbyE, "#LTPt0510EbyE#GT"); + qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(ePt1050EbyE, "#LTPt1050EbyE#GT"); + } + } + if (tc.fVerbose) { ExitFunction(__FUNCTION__); } @@ -4526,6 +4785,25 @@ void PropagateRunNumber() } // for(Int_t rs=0;rs<2;rs++) // reco/sim } // for (Int_t t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + // *) particle event histograms 2D: + for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eParticleEventHistograms2D + { + for (Int_t rs = 0; rs < 2; rs++) // reco/sim + { + for (Int_t ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAParticleEventHistograms2D[t][rs][ba]) { + continue; + } + histTitle = qa.fQAParticleEventHistograms2D[t][rs][ba]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(Int_t ba=0;ba<2;ba++) + } // for(Int_t rs=0;rs<2;rs++) // reco/sim + } // for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eParticleEventHistograms2D + // *) particle cuts: for (Int_t rs = 0; rs < 2; rs++) // reco/sim { @@ -4678,7 +4956,8 @@ void ResetEventByEventQuantities() // a) Event-by-event quantities; // b) Q-vectors; // c) Reset ebe containers for nested loops; - // d) Fisher-Yates algorithm. + // d) Fisher-Yates algorithm; + // e) QA. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -4790,6 +5069,17 @@ void ResetEventByEventQuantities() tc.fRandomIndices = NULL; } + // e) QA: + for (Int_t rs = 0; rs < 2; rs++) // reco/sim + { + for (Int_t ba = 0; ba < 2; ba++) // before/after cuts + { + if (qa.fQAParticleEventProEbyE[rs][ba]) { + qa.fQAParticleEventProEbyE[rs][ba]->Reset(); + } + } + } + if (tc.fVerbose) { ExitFunction(__FUNCTION__); } @@ -5710,6 +6000,24 @@ void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) !qa.fQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate][eRec][ba]->Fill(ebye.fCurrentRunDuration, ebye.fInteractionRate); } + if (qa.fFillQAParticleEventHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba]) { + // This is a special category, where I do correlation vs. some-event-property. + // I use 'number of combinations' as a weight, which here reduces simply to the 'number of entries' weight. + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eitsNClsEbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eitsNClsEbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eitsNClsNegEtaEbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eitsNClsNegEtaEbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eitsNClsPosEtaEbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eitsNClsPosEtaEbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0804EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0804EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0400EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0400EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0004EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0004EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0408EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0408EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(ePt0005EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(ePt0005EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(ePt0510EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(ePt0510EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(ePt1050EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(ePt1050EbyE)); + + // ... + + } // if (qa.fFillQAParticleEventHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba]) { + // ... and corresponding MC truth simulated (Run 3 specific) // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx if constexpr (rs == eRecAndSim) { @@ -5794,7 +6102,8 @@ void CheckUnderflowAndOverflow() // c) Particle histograms 1D; // d) Particle histograms 2D; // e) QA Event histograms 2D; - // f) QA Particle histograms 2D. + // f) QA Particle histograms 2D; + // g) QA Particle event histograms 2D. if (tc.fVerboseForEachParticle) { StartFunction(__FUNCTION__); @@ -5944,6 +6253,42 @@ void CheckUnderflowAndOverflow() } // for (Int_t rs = 0; rs < 2; rs++) // reco/sim } // for (Int_t t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + // g) QA Particle event histograms 2D: + // TBI 20241212 I never validated this code block + for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eQAParticleEventHistograms2D + { + for (Int_t rs = 0; rs < 2; rs++) // reco/sim + { + for (Int_t ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAParticleEventHistograms2D[t][rs][ba]) { + continue; + } + + // Underflow and overflow in x: + for (Int_t binY = 0; binY <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(0, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in x variable in fParticleEventHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsX() + 1, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in x variable in fParticleEventHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + } // for (Int_t binY = 0; binY <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + + // Underflow and overflow in y: + for (Int_t binX = 0; binX <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(binX, 0)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in y variable in fParticleEventHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(binX, qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsY() + 1)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in y variable in fParticleEventHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + } // for (Int_t binX = 0; binX <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + } // for (Int_t ba = 0; ba < 2; ba++) // before/after cuts + } // for (Int_t rs = 0; rs < 2; rs++) // reco/sim + } // for (Int_t t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eParticleEventHistograms2D + if (tc.fVerboseForEachParticle) { ExitFunction(__FUNCTION__); } @@ -6763,14 +7108,45 @@ void FillParticleHistograms(T const& track, eBeforeAfter ba, Int_t weight = 1) // 2D: if (ph.fFillParticleHistograms2D) { - !ph.fParticleHistograms2D[ePhiPt][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiPt][eRec][ba]->Fill(track.phi(), track.pt(), weight); // 3 2 + !ph.fParticleHistograms2D[ePhiPt][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiPt][eRec][ba]->Fill(track.phi(), track.pt(), weight); !ph.fParticleHistograms2D[ePhiEta][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiEta][eRec][ba]->Fill(track.phi(), track.eta(), weight); } // if (ph.fFillParticleHistograms2D) { // QA: if (qa.fFillQAParticleHistograms2D) { - !qa.fQAParticleHistograms2D[ePt_vs_dcaXY][eRec][ba] ? true : qa.fQAParticleHistograms2D[ePt_vs_dcaXY][eRec][ba]->Fill(track.pt(), track.dcaXY()); + !qa.fQAParticleHistograms2D[ePt_vs_dcaXY][eRec][ba] ? true : qa.fQAParticleHistograms2D[ePt_vs_dcaXY][eRec][ba]->Fill(track.pt(), track.dcaXY(), weight); } + if (qa.fFillQAParticleEventHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba]) { + // Here I only fill the helper profile to get average of requested particle variable for current event: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eitsNClsEbyE) - 0.5, track.itsNCls(), weight); + + if (track.eta() < 0.) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eitsNClsNegEtaEbyE) - 0.5, track.itsNCls(), weight); + } else if (track.eta() > 0.) { // TBI 20241214 for the time being, I do not care about the corner case eta = 0. + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eitsNClsPosEtaEbyE) - 0.5, track.itsNCls(), weight); + } + + if (-0.8 < track.eta() && track.eta() < -0.4) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0804EbyE) - 0.5, track.eta(), weight); + } else if (-0.4 < track.eta() && track.eta() < 0.0) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0400EbyE) - 0.5, track.eta(), weight); + } else if (0.0 < track.eta() && track.eta() < 0.4) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0004EbyE) - 0.5, track.eta(), weight); + } else if (0.4 < track.eta() && track.eta() < 0.8) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0408EbyE) - 0.5, track.eta(), weight); + } + + if (0.0 < track.pt() && track.pt() < 0.5) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(ePt0005EbyE) - 0.5, track.pt(), weight); + } else if (0.5 < track.pt() && track.pt() < 1.0) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(ePt0510EbyE) - 0.5, track.pt(), weight); + } else if (1.0 < track.pt() && track.pt() < 5.0) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(ePt1050EbyE) - 0.5, track.pt(), weight); + } + + // ... + + } // if (qa.fFillQAParticleEventHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba]) { // ... and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1) // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx index 6bf5b16249f..13652b66836 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx @@ -122,7 +122,6 @@ struct MultiparticleCorrelationsAB // this name is used in lower-case format to DefaultCuts(); // here default values for cuts are either hardwired, or defined through default binning to ease bookeeping, // or values for cuts provided via configurables are taken into account // Remark: DefaultCuts() has to be called after DefaultBinning() - // *) Specific cuts: if (tc.fUseSpecificCuts) { SpecificCuts(tc.fWhichSpecificCuts); // after default cuts are applied, on top of them apply analysis-specific cuts. Has to be called after DefaultBinning() and DefaultCuts() From 72e8f89bda764866a1ef41f8604b8fcd1f59b8b7 Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Mon, 16 Dec 2024 04:23:21 +0100 Subject: [PATCH 24/30] [PWGLF] check the existence of centrality calibrations (#9002) --- PWGLF/TableProducer/Nuspex/ebyeMaker.cxx | 90 ++++++++++++++---------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx index 98580beb99b..ac4836d204d 100644 --- a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx +++ b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx @@ -392,39 +392,41 @@ struct ebyeMaker { } o2::base::Propagator::initFieldFromGRP(grpo); TList* callst = ccdb->getForTimeStamp("Centrality/Estimators", bc.timestamp()); - auto getccdb = [callst](const char* ccdbhname) { - TH1* h = reinterpret_cast(callst->FindObject(ccdbhname)); - return h; - }; - auto getformulaccdb = [callst](const char* ccdbhname) { - TFormula* f = reinterpret_cast(callst->FindObject(ccdbhname)); - return f; - }; - Run2V0MInfo.mhVtxAmpCorrV0A = getccdb("hVtx_fAmplitude_V0A_Normalized"); - Run2V0MInfo.mhVtxAmpCorrV0C = getccdb("hVtx_fAmplitude_V0C_Normalized"); - Run2V0MInfo.mhMultSelCalib = getccdb("hMultSelCalib_V0M"); - Run2V0MInfo.mMCScale = getformulaccdb(TString::Format("%s-V0M", genName->c_str()).Data()); - if ((Run2V0MInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0MInfo.mhVtxAmpCorrV0C != nullptr) && (Run2V0MInfo.mhMultSelCalib != nullptr)) { - if (genName->length() != 0) { - if (Run2V0MInfo.mMCScale != nullptr) { - for (int ixpar = 0; ixpar < 6; ++ixpar) { - Run2V0MInfo.mMCScalePars[ixpar] = Run2V0MInfo.mMCScale->GetParameter(ixpar); + if (callst != nullptr) { + auto getccdb = [callst](const char* ccdbhname) { + TH1* h = reinterpret_cast(callst->FindObject(ccdbhname)); + return h; + }; + auto getformulaccdb = [callst](const char* ccdbhname) { + TFormula* f = reinterpret_cast(callst->FindObject(ccdbhname)); + return f; + }; + Run2V0MInfo.mhVtxAmpCorrV0A = getccdb("hVtx_fAmplitude_V0A_Normalized"); + Run2V0MInfo.mhVtxAmpCorrV0C = getccdb("hVtx_fAmplitude_V0C_Normalized"); + Run2V0MInfo.mhMultSelCalib = getccdb("hMultSelCalib_V0M"); + Run2V0MInfo.mMCScale = getformulaccdb(TString::Format("%s-V0M", genName->c_str()).Data()); + if ((Run2V0MInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0MInfo.mhVtxAmpCorrV0C != nullptr) && (Run2V0MInfo.mhMultSelCalib != nullptr)) { + if (genName->length() != 0) { + if (Run2V0MInfo.mMCScale != nullptr) { + for (int ixpar = 0; ixpar < 6; ++ixpar) { + Run2V0MInfo.mMCScalePars[ixpar] = Run2V0MInfo.mMCScale->GetParameter(ixpar); + } + } else { + LOGF(fatal, "MC Scale information from V0M for run %d not available", bc.runNumber()); } - } else { - LOGF(fatal, "MC Scale information from V0M for run %d not available", bc.runNumber()); } - } - Run2V0MInfo.mCalibrationStored = true; - } else { - LOGF(fatal, "Calibration information from V0M for run %d corrupted", bc.runNumber()); - } - if (doprocessRun2) { - Run2CL0Info.mhVtxAmpCorr = getccdb("hVtx_fnSPDClusters0_Normalized"); - Run2CL0Info.mhMultSelCalib = getccdb("hMultSelCalib_CL0"); - if ((Run2CL0Info.mhVtxAmpCorr != nullptr) && (Run2CL0Info.mhMultSelCalib != nullptr)) { - Run2CL0Info.mCalibrationStored = true; + Run2V0MInfo.mCalibrationStored = true; } else { - LOGF(fatal, "Calibration information from CL0 multiplicity for run %d corrupted", bc.runNumber()); + LOGF(fatal, "Calibration information from V0M for run %d corrupted", bc.runNumber()); + } + if (doprocessRun2) { + Run2CL0Info.mhVtxAmpCorr = getccdb("hVtx_fnSPDClusters0_Normalized"); + Run2CL0Info.mhMultSelCalib = getccdb("hMultSelCalib_CL0"); + if ((Run2CL0Info.mhVtxAmpCorr != nullptr) && (Run2CL0Info.mhMultSelCalib != nullptr)) { + Run2CL0Info.mCalibrationStored = true; + } else { + LOGF(fatal, "Calibration information from CL0 multiplicity for run %d corrupted", bc.runNumber()); + } } } } else { @@ -482,7 +484,7 @@ struct ebyeMaker { float multFV0M = multFV0A + multFV0C; v0m = scaleMC(multFV0M, Run2V0MInfo.mMCScalePars); LOGF(debug, "Unscaled v0m: %f, scaled v0m: %f", multFV0M, v0m); - } else { + } else if (Run2V0MInfo.mCalibrationStored) { v0m = multFV0A * Run2V0MInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0A->FindFixBin(zvtx)) + multFV0C * Run2V0MInfo.mhVtxAmpCorrV0C->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0C->FindFixBin(zvtx)); } @@ -560,6 +562,8 @@ struct ebyeMaker { // antid and antip QA histos.add("QA/tpcSignal", ";#it{p}_{TPC} (GeV/#it{c});d#it{E}/d#it{x}_{TPC} (a.u.)", HistType::kTH2F, {momAxis, tpcAxis}); histos.add("QA/tpcSignalPr", ";#it{p}_{TPC} (GeV/#it{c});d#it{E}/d#it{x}_{TPC} (a.u.)", HistType::kTH2F, {momAxis, tpcAxis}); + // histos.add("QA/itsSignal", ";#it{p}_{ITS} (GeV/#it{c});d#it{E}/d#it{x}_{ITS} (a.u.)", HistType::kTH2F, {momAxis, tpcAxis}); + // histos.add("QA/itsSignalPr", ";#it{p}_{ITS} (GeV/#it{c});d#it{E}/d#it{x}_{ITS} (a.u.)", HistType::kTH2F, {momAxis, tpcAxis}); tofMass[0] = histos.add("QA/tofMass_p", ";Centrality (%);#it{p}_{T} (GeV/#it{c});Mass (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, tofMassAxis}); tofMass[1] = histos.add("QA/tofMass_d", ";Centrality (%);#it{p}_{T} (GeV/#it{c});Mass (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, tofMassAxis}); @@ -1035,9 +1039,12 @@ struct ebyeMaker { continue; float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); - float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); - if (!(collision.sel7() && collision.alias_bit(kINT7)) && (!kINT7Intervals || (kINT7Intervals && ((cV0M >= 10 && cV0M < 30) || cV0M > 50)))) - continue; + float cV0M = -999.f; + if (Run2V0MInfo.mCalibrationStored) { + Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + if (!(collision.sel7() && collision.alias_bit(kINT7)) && (!kINT7Intervals || (kINT7Intervals && ((cV0M >= 10 && cV0M < 30) || cV0M > 50)))) + continue; + } auto centralityCl0 = 105.0f; if (Run2CL0Info.mCalibrationStored) { @@ -1118,7 +1125,10 @@ struct ebyeMaker { continue; float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); - float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + float cV0M = -999.f; + if (Run2V0MInfo.mCalibrationStored) { + Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + } histos.fill(HIST("QA/zVtx"), collision.posZ()); @@ -1232,7 +1242,10 @@ struct ebyeMaker { continue; float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); - float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + float cV0M = -999.f; + if (Run2V0MInfo.mCalibrationStored) { + Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + } histos.fill(HIST("QA/zVtx"), collision.posZ()); @@ -1301,7 +1314,10 @@ struct ebyeMaker { continue; float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); - float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + float cV0M = -999.f; + if (Run2V0MInfo.mCalibrationStored) { + Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + } histos.fill(HIST("QA/zVtx"), collision.posZ()); From 094e04d8d7a88a2b2df70638f54ebed5c24f0541 Mon Sep 17 00:00:00 2001 From: upasanasharma31 <84681984+upasanasharma31@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:00:02 +0530 Subject: [PATCH 25/30] [DPG] Redefine the Histogram for the mother (#8992) --- DPG/Tasks/AOTTrack/qaEfficiency.cxx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/DPG/Tasks/AOTTrack/qaEfficiency.cxx b/DPG/Tasks/AOTTrack/qaEfficiency.cxx index 991266fe14b..e8965bb265e 100644 --- a/DPG/Tasks/AOTTrack/qaEfficiency.cxx +++ b/DPG/Tasks/AOTTrack/qaEfficiency.cxx @@ -76,9 +76,6 @@ static constexpr const char* particleTitle[nParticles] = {"e", "#mu", "#pi", "K" static constexpr int PDGs[nParticles] = {11, 13, 211, 321, 2212, 1000010020, 1000010030, 1000020030, 1000020040, -11, -13, -211, -321, -2212, -1000010020, -1000010030, -1000020030, -1000020040}; -// Histograms -std::shared_ptr hPtmotherGenerated; // histogram to store pT of Xi and Lambda - // Pt std::array, nParticles> hPtIts; std::array, nParticles> hPtTpc; @@ -106,6 +103,7 @@ std::array, nParticles> hPtItsTpcStr; std::array, nParticles> hPtTrkItsTpcStr; std::array, nParticles> hPtItsTpcTofStr; std::array, nParticles> hPtGeneratedStr; +std::array, nParticles> hPtmotherGenerated; // histogram to store pT of mother std::array, nParticles> hdecaylengthmother; // histogram to store decaylength of mother // Pt for secondaries from material @@ -366,6 +364,7 @@ struct QaEfficiency { hPtTrkItsTpcStr[histogramIndex] = histos.add(Form("MC/pdg%i/pt/str/trk/its_tpc", PDGs[histogramIndex]), "ITS-TPC tracks (reco from weak decays) " + tagPt, kTH1D, {axisPt}); hPtItsTpcTofStr[histogramIndex] = histos.add(Form("MC/pdg%i/pt/str/its_tpc_tof", PDGs[histogramIndex]), "ITS-TPC-TOF tracks (from weak decays) " + tagPt, kTH1D, {axisPt}); hPtGeneratedStr[histogramIndex] = histos.add(Form("MC/pdg%i/pt/str/generated", PDGs[histogramIndex]), "Generated (from weak decays) " + tagPt, kTH1D, {axisPt}); + hPtmotherGenerated[histogramIndex] = histos.add(Form("MC/pdg%i/pt/str/generated_mother", PDGs[histogramIndex]), "Generated Mother " + tagPt, kTH1D, {axisPt}); hdecaylengthmother[histogramIndex] = histos.add(Form("MC/pdg%i/pt/str/decayLength", PDGs[histogramIndex]), "Decay Length of mother particle" + tagPt, kTH1D, {axisPt}); // Ter @@ -663,9 +662,6 @@ struct QaEfficiency { histos.add("MC/occ_cent/reco/neg/its", "ITS Negative ", kTH3D, {axisOcc, axisCent, axisPt}); } - AxisSpec axisPtMother{ptBins, "#it{p}_{T} (GeV/#it{c})"}; - hPtmotherGenerated = histos.add("MC/mother/pt/generated", "Generated pT of mother Lambda or Xi", kTH1D, {axisPtMother}); - static_for<0, 1>([&](auto pdgSign) { makeMCHistograms(doEl); makeMCHistograms(doMu); @@ -1267,7 +1263,7 @@ struct QaEfficiency { break; } if (motherIsAccepted) { - hPtmotherGenerated->Fill(mother.pt()); // Fill generated pT for Lambda + hPtmotherGenerated[histogramIndex]->Fill(mother.pt()); // Fill generated pT for mother } } } From ddc10e56d50812d37415a63b4410bef5361fbbad Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Mon, 16 Dec 2024 10:57:33 +0100 Subject: [PATCH 26/30] [PWGLF] change in derivedcascadeanalysis.cxx (#8966) Co-authored-by: Lucia Anna Tarasovicova --- .../Strangeness/derivedcascadeanalysis.cxx | 143 +++++++++++------- 1 file changed, 89 insertions(+), 54 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx index 824266cdd5e..9f024183737 100644 --- a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx @@ -72,6 +72,7 @@ struct derivedCascadeAnalysis { ConfigurableAxis axisMass{"axisMass", {200, 1.222f, 1.422f}, "range of invariant mass, in case of omega take 1.572f, 1.772f"}; Configurable isXi{"isXi", 1, "Apply cuts for Xi identification"}; + Configurable usePbPbCentrality{"usePbPbCentrality", 1, "If true, use centFt0C, else use centFT0M"}; Configurable minOccupancy{"minOccupancy", -1, "Minimal occupancy"}; Configurable maxOccupancy{"maxOccupancy", -1, "Maximal occupancy"}; Configurable minOccupancyFT0{"minOccupancyFT0", -1, "Minimal occupancy"}; @@ -195,6 +196,7 @@ struct derivedCascadeAnalysis { void init(InitContext const&) { histos.add("hEventVertexZ", "hEventVertexZ", kTH1F, {vertexZ}); + histos.add("hEventMultFt0C", "", kTH1F, {{500, 0, 5000}}); histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{101, 0, 101}}); histos.add("hEventSelection", "hEventSelection", kTH1F, {{21, 0, 21}}); histos.add("hOccupancyVsOccupFt0VsCentrality", "", kTH3F, {axisOccupancy, axisOccupancyFt0, {100, 0, 100}}); @@ -328,10 +330,22 @@ struct derivedCascadeAnalysis { if (doprocessCascadesMCforEff) { histos.add("hGenEvents", "", HistType::kTH2F, {{axisNch}, {2, 0, 2}}); histos.add("hCentralityVsMultMC", "", kTH2F, {{101, 0.0f, 101.0f}, axisNch}); + histos.add("hGenMultMCFT0C", "", kTH1F, {{500, 0, 5000}}); + histos.add("hGenMCNParticlesEta10", "", kTH1F, {{500, 0, 5000}}); histos.add("hCentralityVsNcoll_beforeEvSel", "", kTH2F, {{101, 0.0f, 101.0f}, {50, 0.f, 50.f}}); histos.add("hCentralityVsNcoll_afterEvSel", "", kTH2F, {{101, 0.0f, 101.0f}, {50, 0.f, 50.f}}); + histos.add("h2dGenXiMinusEta", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenXiMinusEtaPosDaughter", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenXiMinusEtaNegDaughter", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenXiMinusEtaBach", "", kTH1F, {{30, -2, 2}}); + + histos.add("h2dGenOmegaMinusEta", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenOmegaMinusEtaPosDaughter", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenOmegaMinusEtaNegDaughter", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenOmegaMinusEtaBach", "", kTH1F, {{30, -2, 2}}); + histos.add("h2dGenXiMinus", "h2dGenXiMinus", kTH2D, {{101, 0.0f, 101.0f}, axisPt}); histos.add("h2dGenXiPlus", "h2dGenXiPlus", kTH2D, {{101, 0.0f, 101.0f}, axisPt}); histos.add("h2dGenOmegaMinus", "h2dGenOmegaMinus", kTH2D, {{101, 0.0f, 101.0f}, axisPt}); @@ -392,11 +406,14 @@ struct derivedCascadeAnalysis { if (fillHists) histos.fill(HIST("hEventSelection"), 0.5 /* all collisions */); + float centrality = coll.centFT0C(); + if (!usePbPbCentrality) + centrality = coll.centFT0M(); if (qaFlags.doBefSelEventMultCorr) { histos.fill(HIST("hEventNchCorrelationBefCuts"), coll.multNTracksPVeta1(), coll.multNTracksGlobal()); - histos.fill(HIST("hEventPVcontributorsVsCentralityBefCuts"), coll.centFT0C(), coll.multNTracksPVeta1()); - histos.fill(HIST("hEventGlobalTracksVsCentralityBefCuts"), coll.centFT0C(), coll.multNTracksGlobal()); + histos.fill(HIST("hEventPVcontributorsVsCentralityBefCuts"), centrality, coll.multNTracksPVeta1()); + histos.fill(HIST("hEventGlobalTracksVsCentralityBefCuts"), centrality, coll.multNTracksGlobal()); } if (eventSelectionFlags.doTriggerTVXEventCut && !coll.selection_bit(aod::evsel::kIsTriggerTVX)) { @@ -417,7 +434,7 @@ struct derivedCascadeAnalysis { if (fillHists) histos.fill(HIST("hEventSelection"), 3.5 /* collisions after sel pvz sel*/); - if (coll.centFT0C() > centMax || coll.centFT0C() < centMin) { + if (centrality > centMax || centrality < centMin) { return false; } if (fillHists) @@ -466,9 +483,9 @@ struct derivedCascadeAnalysis { histos.fill(HIST("hEventSelection"), 11.5 /* Not at TF border */); if (eventSelectionFlags.doMultiplicityCorrCut) { - if (coll.multNTracksGlobal() < (1343.3 * TMath::Exp(-0.0443259 * coll.centFT0C()) - 50) || coll.multNTracksGlobal() > (2098.9 * TMath::Exp(-0.0332444 * coll.centFT0C()))) + if (coll.multNTracksGlobal() < (1343.3 * TMath::Exp(-0.0443259 * centrality) - 50) || coll.multNTracksGlobal() > (2098.9 * TMath::Exp(-0.0332444 * centrality))) return false; - if (coll.multNTracksPVeta1() < (3703 * TMath::Exp(-0.0455483 * coll.centFT0C()) - 150) || coll.multNTracksPVeta1() > (4937.33 * TMath::Exp(-0.0372668 * coll.centFT0C()) + 20)) + if (coll.multNTracksPVeta1() < (3703 * TMath::Exp(-0.0455483 * centrality) - 150) || coll.multNTracksPVeta1() > (4937.33 * TMath::Exp(-0.0372668 * centrality) + 20)) return false; } if (fillHists) @@ -527,12 +544,13 @@ struct derivedCascadeAnalysis { histos.fill(HIST("hEventSelection"), 20.5 /* Occupancy FT0 selection */); if (fillHists) { - histos.fill(HIST("hOccupancyVsOccupFt0VsCentrality"), occupancy, occupancyFT0, coll.centFT0C()); - histos.fill(HIST("hEventCentrality"), coll.centFT0C()); + histos.fill(HIST("hOccupancyVsOccupFt0VsCentrality"), occupancy, occupancyFT0, centrality); + histos.fill(HIST("hEventCentrality"), centrality); histos.fill(HIST("hEventVertexZ"), coll.posZ()); + histos.fill(HIST("hEventMultFt0C"), coll.multFT0C()); histos.fill(HIST("hEventNchCorrelationAfCuts"), coll.multNTracksPVeta1(), coll.multNTracksGlobal()); - histos.fill(HIST("hEventPVcontributorsVsCentrality"), coll.centFT0C(), coll.multNTracksPVeta1()); - histos.fill(HIST("hEventGlobalTracksVsCentrality"), coll.centFT0C(), coll.multNTracksGlobal()); + histos.fill(HIST("hEventPVcontributorsVsCentrality"), centrality, coll.multNTracksPVeta1()); + histos.fill(HIST("hEventGlobalTracksVsCentrality"), centrality, coll.multNTracksGlobal()); } return true; @@ -699,6 +717,10 @@ struct derivedCascadeAnalysis { if (!IsEventAccepted(coll, true)) return; + float centrality = coll.centFT0C(); + if (!usePbPbCentrality) + centrality = coll.centFT0M(); + for (auto& casc : Cascades) { int counter = -1; @@ -722,12 +744,12 @@ struct derivedCascadeAnalysis { if (qaFlags.doBefSelCheck) { if (isPositive) - histos.fill(HIST("InvMassBefSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), invmass, coll.centFT0C()); + histos.fill(HIST("InvMassBefSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), invmass, centrality); if (isNegative) - histos.fill(HIST("InvMassBefSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), invmass, coll.centFT0C()); + histos.fill(HIST("InvMassBefSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), invmass, centrality); } - if (!IsCascadeCandidateAccepted(casc, counter, coll.centFT0C())) + if (!IsCascadeCandidateAccepted(casc, counter, centrality)) continue; counter += 13; @@ -769,23 +791,23 @@ struct derivedCascadeAnalysis { if (casc.sign() < 0) { if (qaFlags.doFillNsigmaTPCHistProton) - histos.fill(HIST("hNsigmaProton"), posExtra.tpcNSigmaPr(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaProton"), posExtra.tpcNSigmaPr(), fullMomentumPosDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistV0Pion) - histos.fill(HIST("hNsigmaPionNeg"), negExtra.tpcNSigmaPi(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionNeg"), negExtra.tpcNSigmaPi(), fullmomentumNegDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && isXi) - histos.fill(HIST("hNsigmaPionNegBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionNegBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && !isXi) - histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); } else if (casc.sign() > 0) { if (qaFlags.doFillNsigmaTPCHistV0Pion) - histos.fill(HIST("hNsigmaPionPos"), posExtra.tpcNSigmaPi(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionPos"), posExtra.tpcNSigmaPi(), fullMomentumPosDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistProton) - histos.fill(HIST("hNsigmaProtonNeg"), negExtra.tpcNSigmaPr(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaProtonNeg"), negExtra.tpcNSigmaPr(), fullmomentumNegDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && isXi) - histos.fill(HIST("hNsigmaPionPosBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionPosBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && !isXi) - histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); } if (casc.sign() < 0) { @@ -834,12 +856,12 @@ struct derivedCascadeAnalysis { if (posExtra.hasTOF()) { if (candidateSelectionFlags.doNTOFSigmaProtonCut && casc.sign() < 0) { - histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullMomentumPosDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPr()) > candidateSelectionValues.nsigmatofPr && fullMomentumPosDaugh > 0.6) continue; } if (candidateSelectionFlags.doNTOFSigmaV0PionCut && casc.sign() > 0) { - histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullMomentumPosDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPi()) > candidateSelectionValues.nsigmatofPion) continue; } @@ -848,12 +870,12 @@ struct derivedCascadeAnalysis { if (negExtra.hasTOF()) { if (candidateSelectionFlags.doNTOFSigmaProtonCut && casc.sign() > 0) { - histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullmomentumNegDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPr()) > candidateSelectionValues.nsigmatofPr && fullmomentumNegDaugh > 0.6) continue; } if (candidateSelectionFlags.doNTOFSigmaV0PionCut && casc.sign() < 0) { - histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullmomentumNegDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPi()) > candidateSelectionValues.nsigmatofPion) continue; } @@ -870,7 +892,7 @@ struct derivedCascadeAnalysis { } if (bachExtra.hasTOF() && candidateSelectionFlags.doNTOFSigmaBachelorCut) { - histos.fill(HIST("hNsigmaTOFBachelorPion"), casc.tofNSigmaXiPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFBachelorPion"), casc.tofNSigmaXiPi(), fullmomentumBachelor, centrality); if (TMath::Abs(casc.tofNSigmaXiPi()) > candidateSelectionValues.nsigmatofBachPion) continue; } @@ -893,7 +915,7 @@ struct derivedCascadeAnalysis { } if (bachExtra.hasTOF() && candidateSelectionFlags.doNTOFSigmaBachelorCut) { - histos.fill(HIST("hNsigmaTOFBachelorKaon"), casc.tofNSigmaOmKa(), TMath::Sqrt(TMath::Power(casc.pxbach(), 2) + TMath::Power(casc.pybach(), 2) + TMath::Power(casc.pzbach(), 2)), coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFBachelorKaon"), casc.tofNSigmaOmKa(), TMath::Sqrt(TMath::Power(casc.pxbach(), 2) + TMath::Power(casc.pybach(), 2) + TMath::Power(casc.pzbach(), 2)), centrality); if (TMath::Abs(casc.tofNSigmaOmKa()) > candidateSelectionValues.nsigmatofBachKaon) continue; } @@ -908,9 +930,9 @@ struct derivedCascadeAnalysis { } } if (isPositive) - histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), invmass, coll.centFT0C()); + histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), invmass, centrality); if (isNegative) - histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), invmass, coll.centFT0C()); + histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), invmass, centrality); if (qaFlags.doOccupancyCheck) { float occupancy = -1; @@ -920,7 +942,7 @@ struct derivedCascadeAnalysis { occupancy = coll.ft0cOccupancyInTimeRange(); static_for<0, 9>([&](auto i) { constexpr int index = i.value; - if (coll.centFT0C() < centralityIntervals[index + 1] && coll.centFT0C() > centralityIntervals[index]) { + if (centrality < centralityIntervals[index + 1] && centrality > centralityIntervals[index]) { if (isPositive) histos.fill(HIST("InvMassAfterSelCent") + HIST(Index[index]) + HIST("/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), invmass, occupancy); if (isNegative) @@ -981,7 +1003,9 @@ struct derivedCascadeAnalysis { { if (!IsEventAccepted(coll, true)) return; - + float centrality = coll.centFT0C(); + if (!usePbPbCentrality) + centrality = coll.centFT0M(); for (auto& casc : Cascades) { float mass = -1; if (isXi) @@ -1003,9 +1027,9 @@ struct derivedCascadeAnalysis { // To have trace of how it was before selections if (qaFlags.doBefSelCheck) { if (isPositive) - histos.fill(HIST("InvMassBefSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), mass, coll.centFT0C()); + histos.fill(HIST("InvMassBefSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), mass, centrality); if (isNegative) - histos.fill(HIST("InvMassBefSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), mass, coll.centFT0C()); + histos.fill(HIST("InvMassBefSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), mass, centrality); } if (!casc.has_cascMCCore()) @@ -1023,7 +1047,7 @@ struct derivedCascadeAnalysis { isTrueMCCascadeDecay = true; float ptmc = RecoDecay::sqrtSumOfSquares(cascMC.pxMC(), cascMC.pyMC()); - if (!IsCascadeCandidateAccepted(casc, counter, coll.centFT0C())) + if (!IsCascadeCandidateAccepted(casc, counter, centrality)) continue; counter += 13; @@ -1061,13 +1085,13 @@ struct derivedCascadeAnalysis { if (isNegative) { if (qaFlags.doFillNsigmaTPCHistProton) - histos.fill(HIST("hNsigmaProton"), posExtra.tpcNSigmaPr(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaProton"), posExtra.tpcNSigmaPr(), fullMomentumPosDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistV0Pion) - histos.fill(HIST("hNsigmaPionNeg"), negExtra.tpcNSigmaPi(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionNeg"), negExtra.tpcNSigmaPi(), fullmomentumNegDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && isXi) - histos.fill(HIST("hNsigmaPionNegBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionNegBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && !isXi) - histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); if (candidateSelectionFlags.doNTPCSigmaCut) { if (TMath::Abs(posExtra.tpcNSigmaPr()) > candidateSelectionValues.nsigmatpcPr || TMath::Abs(negExtra.tpcNSigmaPi()) > candidateSelectionValues.nsigmatpcPi) @@ -1079,13 +1103,13 @@ struct derivedCascadeAnalysis { } if (isPositive) { if (qaFlags.doFillNsigmaTPCHistV0Pion) - histos.fill(HIST("hNsigmaPionPos"), posExtra.tpcNSigmaPi(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionPos"), posExtra.tpcNSigmaPi(), fullMomentumPosDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistProton) - histos.fill(HIST("hNsigmaProtonNeg"), negExtra.tpcNSigmaPr(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaProtonNeg"), negExtra.tpcNSigmaPr(), fullmomentumNegDaugh, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && isXi) - histos.fill(HIST("hNsigmaPionPosBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaPionPosBach"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); if (qaFlags.doFillNsigmaTPCHistPionBach && !isXi) - histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaKaon"), bachExtra.tpcNSigmaPi(), fullmomentumBachelor, centrality); if (candidateSelectionFlags.doNTPCSigmaCut) { if (TMath::Abs(posExtra.tpcNSigmaPi()) > candidateSelectionValues.nsigmatpcPi || TMath::Abs(negExtra.tpcNSigmaPr()) > candidateSelectionValues.nsigmatpcPr) @@ -1120,12 +1144,12 @@ struct derivedCascadeAnalysis { if (posExtra.hasTOF()) { if (candidateSelectionFlags.doNTOFSigmaProtonCut && isNegative) { - histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullMomentumPosDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPr()) > candidateSelectionValues.nsigmatofPr && fullMomentumPosDaugh > 0.6) continue; } if (candidateSelectionFlags.doNTOFSigmaV0PionCut && isPositive) { - histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullMomentumPosDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullMomentumPosDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPi()) > candidateSelectionValues.nsigmatofPion) continue; } @@ -1133,12 +1157,12 @@ struct derivedCascadeAnalysis { if (negExtra.hasTOF()) { if (candidateSelectionFlags.doNTOFSigmaProtonCut && isPositive) { - histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFProton"), casc.tofNSigmaXiLaPr(), fullmomentumNegDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPr()) > candidateSelectionValues.nsigmatofPr && fullmomentumNegDaugh > 0.6) continue; } if (candidateSelectionFlags.doNTOFSigmaV0PionCut && isNegative) { - histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullmomentumNegDaugh, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFV0Pion"), casc.tofNSigmaXiLaPi(), fullmomentumNegDaugh, centrality); if (TMath::Abs(casc.tofNSigmaXiLaPi()) > candidateSelectionValues.nsigmatofPion) continue; } @@ -1154,7 +1178,7 @@ struct derivedCascadeAnalysis { } if (bachExtra.hasTOF() && candidateSelectionFlags.doNTOFSigmaBachelorCut) { - histos.fill(HIST("hNsigmaTOFBachelorPion"), casc.tofNSigmaXiPi(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFBachelorPion"), casc.tofNSigmaXiPi(), fullmomentumBachelor, centrality); if (TMath::Abs(casc.tofNSigmaXiPi()) > candidateSelectionValues.nsigmatofBachPion) continue; } @@ -1170,7 +1194,7 @@ struct derivedCascadeAnalysis { } if (bachExtra.hasTOF() && candidateSelectionFlags.doNTOFSigmaBachelorCut) { - histos.fill(HIST("hNsigmaTOFBachelorKaon"), casc.tofNSigmaOmKa(), fullmomentumBachelor, coll.centFT0C()); + histos.fill(HIST("hNsigmaTOFBachelorKaon"), casc.tofNSigmaOmKa(), fullmomentumBachelor, centrality); if (TMath::Abs(casc.tofNSigmaOmKa()) > candidateSelectionValues.nsigmatofBachKaon) continue; } @@ -1187,20 +1211,20 @@ struct derivedCascadeAnalysis { } if (isPositive) { - histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), mass, coll.centFT0C()); + histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), mass, centrality); if (isTrueMCCascadeDecay) - histos.fill(HIST("hPositiveCascadePtForEfficiency"), ptmc, mass, coll.centFT0C()); + histos.fill(HIST("hPositiveCascadePtForEfficiency"), ptmc, mass, centrality); } if (isNegative) { - histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), mass, coll.centFT0C()); + histos.fill(HIST("InvMassAfterSel/h") + HIST(charge[1]) + HIST("Cascade"), casc.pt(), mass, centrality); if (isTrueMCCascadeDecay) - histos.fill(HIST("hNegativeCascadePtForEfficiency"), ptmc, mass, coll.centFT0C()); + histos.fill(HIST("hNegativeCascadePtForEfficiency"), ptmc, mass, centrality); } if (isTrueMCCascade) { if (isPositive) - histos.fill(HIST("InvMassAfterSelMCrecTruth/h") + HIST(charge[0]) + HIST("Cascade"), ptmc, mass, coll.centFT0C()); + histos.fill(HIST("InvMassAfterSelMCrecTruth/h") + HIST(charge[0]) + HIST("Cascade"), ptmc, mass, centrality); if (isNegative) - histos.fill(HIST("InvMassAfterSelMCrecTruth/h") + HIST(charge[1]) + HIST("Cascade"), ptmc, mass, coll.centFT0C()); + histos.fill(HIST("InvMassAfterSelMCrecTruth/h") + HIST(charge[1]) + HIST("Cascade"), ptmc, mass, centrality); } if (qaFlags.doOccupancyCheck) { float occupancy = -1; @@ -1210,7 +1234,7 @@ struct derivedCascadeAnalysis { occupancy = coll.ft0cOccupancyInTimeRange(); static_for<0, 9>([&](auto i) { constexpr int index = i.value; - if (coll.centFT0C() < centralityIntervals[index + 1] && coll.centFT0C() > centralityIntervals[index]) { + if (centrality < centralityIntervals[index + 1] && centrality > centralityIntervals[index]) { if (isPositive) { histos.fill(HIST("InvMassAfterSelCent") + HIST(Index[index]) + HIST("/h") + HIST(charge[0]) + HIST("Cascade"), casc.pt(), mass, occupancy); if (isTrueMCCascadeDecay) @@ -1313,6 +1337,10 @@ struct derivedCascadeAnalysis { if (cascMC.pdgCode() == 3312) { histos.fill(HIST("h2dGenXiMinus"), centrality, ptmc); + histos.fill(HIST("h2dGenXiMinusEta"), RecoDecay::eta(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()})); + histos.fill(HIST("h2dGenXiMinusEtaPosDaughter"), RecoDecay::eta(std::array{cascMC.pxPosMC(), cascMC.pyPosMC(), cascMC.pzPosMC()})); + histos.fill(HIST("h2dGenXiMinusEtaNegDaughter"), RecoDecay::eta(std::array{cascMC.pxNegMC(), cascMC.pyNegMC(), cascMC.pzNegMC()})); + histos.fill(HIST("h2dGenXiMinusEtaBach"), RecoDecay::eta(std::array{cascMC.pxBachMC(), cascMC.pyBachMC(), cascMC.pzBachMC()})); histos.fill(HIST("h2dGenXiMinusVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); histos.fill(HIST("h2dGenXiMinusVsCentOccupancy"), ptmc, centrality, occupancy); } @@ -1323,6 +1351,10 @@ struct derivedCascadeAnalysis { } if (cascMC.pdgCode() == 3334) { histos.fill(HIST("h2dGenOmegaMinus"), centrality, ptmc); + histos.fill(HIST("h2dGenOmegaMinusEta"), RecoDecay::eta(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()})); + histos.fill(HIST("h2dGenOmegaMinusEtaPosDaughter"), RecoDecay::eta(std::array{cascMC.pxPosMC(), cascMC.pyPosMC(), cascMC.pzPosMC()})); + histos.fill(HIST("h2dGenOmegaMinusEtaNegDaughter"), RecoDecay::eta(std::array{cascMC.pxNegMC(), cascMC.pyNegMC(), cascMC.pzNegMC()})); + histos.fill(HIST("h2dGenOmegaMinusEtaBach"), RecoDecay::eta(std::array{cascMC.pxBachMC(), cascMC.pyBachMC(), cascMC.pzBachMC()})); histos.fill(HIST("h2dGenOmegaMinusVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); histos.fill(HIST("h2dGenOmegaMinusVsCentOccupancy"), ptmc, centrality, occupancy); } @@ -1371,6 +1403,9 @@ struct derivedCascadeAnalysis { histos.fill(HIST("hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); + histos.fill(HIST("hGenMultMCFT0C"), mcCollision.multMCFT0C()); + histos.fill(HIST("hGenMCNParticlesEta10"), mcCollision.multMCNParticlesEta10()); + if (atLeastOne) { histos.fill(HIST("hGenEvents"), mcCollision.multMCNParticlesEta05(), 1.5 /* at least 1 rec. event*/); } From 5de34a60300da7a16891c985ee2ca4bc827454fa Mon Sep 17 00:00:00 2001 From: SCHOTTER Romain <47983209+romainschotter@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:23:17 +0100 Subject: [PATCH 27/30] [PWGDQ] Enable building K0s-K0s pairs (#8865) --- PWGDQ/Tasks/quarkoniaToHyperons.cxx | 814 +++++++++++++++++----------- 1 file changed, 499 insertions(+), 315 deletions(-) diff --git a/PWGDQ/Tasks/quarkoniaToHyperons.cxx b/PWGDQ/Tasks/quarkoniaToHyperons.cxx index f2fc85498a3..6133ee4e090 100644 --- a/PWGDQ/Tasks/quarkoniaToHyperons.cxx +++ b/PWGDQ/Tasks/quarkoniaToHyperons.cxx @@ -9,6 +9,12 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // +/// \file quarkoniaToHyperons.cxx +/// \brief quarkonia --> hyperon antihyperon analysis task +/// +/// \author David Dobrigkeit Chinellato , Austrian Academy of Sciences & SMI +/// \author Romain Schotter , Austrian Academy of Sciences & SMI +// // V0 analysis task // ================ // @@ -16,6 +22,7 @@ // standard analysis output. It is meant to be run over // derived data. // +// // Comments, questions, complaints, suggestions? // Please write to: // romain.schotter@cern.ch @@ -26,13 +33,15 @@ #include #include #include +#include +#include +#include #include #include #include #include #include -#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -60,28 +69,28 @@ #include "EventFiltering/ZorroSummary.h" // constants -const float ctauXiPDG = 4.91; // from PDG -const float ctauOmegaPDG = 2.461; // from PDG +const float ctauXiPDG = 4.91; // Xi PDG lifetime +const float ctauOmegaPDG = 2.461; // Omega PDG lifetime using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; -using dauTracks = soa::Join; -using dauMCTracks = soa::Join; -using v0Candidates = soa::Join; -// using v0MCCandidates = soa::Join; -using v0MCCandidates = soa::Join; +using DauTracks = soa::Join; +using DauMCTracks = soa::Join; +using V0Candidates = soa::Join; +// using V0MCCandidates = soa::Join; +using V0MCCandidates = soa::Join; -using cascadeCandidates = soa::Join; -using cascadeMCCandidates = soa::Join; +using CascadeCandidates = soa::Join; +using CascadeMCCandidates = soa::Join; // simple checkers, but ensure 64 bit integers -#define bitset(var, nbit) ((var) |= (static_cast(1) << static_cast(nbit))) -#define bitcheck(var, nbit) ((var) & (static_cast(1) << static_cast(nbit))) +#define BITSET(var, nbit) ((var) |= (static_cast(1) << static_cast(nbit))) +#define BITCHECK(var, nbit) ((var) & (static_cast(1) << static_cast(nbit))) -struct quarkoniaToHyperons { +struct QuarkoniaToHyperons { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // master analysis switches @@ -93,6 +102,7 @@ struct quarkoniaToHyperons { // switch on/off event selections Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; + Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; @@ -103,6 +113,7 @@ struct quarkoniaToHyperons { Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable buildK0sK0sPairs{"buildK0sK0sPairs", false, "Build K0s K0s from charmonia decay"}; Configurable buildLaLaBarPairs{"buildLaLaBarPairs", false, "Build Lambda antiLambda from charmonia decay"}; Configurable buildXiXiBarPairs{"buildXiXiBarPairs", false, "Build Xi antiXi from charmonia decay"}; Configurable buildOmOmBarPairs{"buildOmOmBarPairs", false, "Build Omega antiOmega from charmonia decay"}; @@ -148,10 +159,10 @@ struct quarkoniaToHyperons { Configurable requireNegITSonly{"v0Selections.requireNegITSonly", false, "require that negative track is ITSonly (overrides TPC quality)"}; // PID (TPC/TOF) - Configurable TpcPidNsigmaCut{"v0Selections.TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable TofPidNsigmaCutLaPr{"v0Selections.TofPidNsigmaCutLaPr", 1e+6, "TofPidNsigmaCutLaPr"}; - Configurable TofPidNsigmaCutLaPi{"v0Selections.TofPidNsigmaCutLaPi", 1e+6, "TofPidNsigmaCutLaPi"}; - Configurable TofPidNsigmaCutK0Pi{"v0Selections.TofPidNsigmaCutK0Pi", 1e+6, "TofPidNsigmaCutK0Pi"}; + Configurable tpcPidNsigmaCut{"v0Selections.tpcPidNsigmaCut", 5, "tpcPidNsigmaCut"}; + Configurable tofPidNsigmaCutLaPr{"v0Selections.tofPidNsigmaCutLaPr", 1e+6, "tofPidNsigmaCutLaPr"}; + Configurable tofPidNsigmaCutLaPi{"v0Selections.tofPidNsigmaCutLaPi", 1e+6, "tofPidNsigmaCutLaPi"}; + Configurable tofPidNsigmaCutK0Pi{"v0Selections.tofPidNsigmaCutK0Pi", 1e+6, "tofPidNsigmaCutK0Pi"}; // PID (TOF) Configurable maxDeltaTimeProton{"v0Selections.maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; @@ -196,11 +207,11 @@ struct quarkoniaToHyperons { Configurable requireNegITSonly{"cascSelections.requireNegITSonly", false, "require that negative track is ITSonly (overrides TPC quality)"}; // PID (TPC/TOF) - Configurable TpcPidNsigmaCut{"cascSelections.TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable TofPidNsigmaCutLaPr{"cascSelections.TofPidNsigmaCutLaPr", 1e+6, "TofPidNsigmaCutLaPr"}; - Configurable TofPidNsigmaCutLaPi{"cascSelections.TofPidNsigmaCutLaPi", 1e+6, "TofPidNsigmaCutLaPi"}; - Configurable TofPidNsigmaCutXiPi{"cascSelections.TofPidNsigmaCutXiPi", 1e+6, "TofPidNsigmaCutXiPi"}; - Configurable TofPidNsigmaCutOmKa{"cascSelections.TofPidNsigmaCutOmKa", 1e+6, "TofPidNsigmaCutOmKa"}; + Configurable tpcPidNsigmaCut{"cascSelections.tpcPidNsigmaCut", 5, "tpcPidNsigmaCut"}; + Configurable tofPidNsigmaCutLaPr{"cascSelections.tofPidNsigmaCutLaPr", 1e+6, "tofPidNsigmaCutLaPr"}; + Configurable tofPidNsigmaCutLaPi{"cascSelections.tofPidNsigmaCutLaPi", 1e+6, "tofPidNsigmaCutLaPi"}; + Configurable tofPidNsigmaCutXiPi{"cascSelections.tofPidNsigmaCutXiPi", 1e+6, "tofPidNsigmaCutXiPi"}; + Configurable tofPidNsigmaCutOmKa{"cascSelections.tofPidNsigmaCutOmKa", 1e+6, "tofPidNsigmaCutOmKa"}; // PID (TOF) Configurable maxDeltaTimeProton{"cascSelections.maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; @@ -216,10 +227,10 @@ struct quarkoniaToHyperons { // UPC selections SGSelector sgSelector; struct : ConfigurableGroup { - Configurable FV0cut{"upcCuts.FV0cut", 100., "FV0A threshold"}; - Configurable FT0Acut{"upcCuts.FT0Acut", 200., "FT0A threshold"}; - Configurable FT0Ccut{"upcCuts.FT0Ccut", 100., "FT0C threshold"}; - Configurable ZDCcut{"upcCuts.ZDCcut", 10., "ZDC threshold"}; + Configurable fv0Cut{"upcCuts.fv0Cut", 100., "FV0A threshold"}; + Configurable ft0aCut{"upcCuts.ft0aCut", 200., "FT0A threshold"}; + Configurable ft0cCut{"upcCuts.ft0cCut", 100., "FT0C threshold"}; + Configurable zdcCut{"upcCuts.zdcCut", 10., "ZDC threshold"}; // Configurable gapSel{"upcCuts.gapSel", 2, "Gap selection"}; } upcCuts; @@ -300,6 +311,10 @@ struct quarkoniaToHyperons { ConfigurableAxis axisOmegaMass{"axisOmegaMass", {500, 1.670f, 1.675f}, "Omega mass (GeV/#it{c}^{2})"}; ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {200, -10.0f, 10.0f}, "N sigma TPC"}; + // AP plot axes + ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; + ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; + // Track quality axes ConfigurableAxis axisTPCrows{"axisTPCrows", {160, 0.0f, 160.0f}, "N TPC rows"}; ConfigurableAxis axisITSclus{"axisITSclus", {7, 0.0f, 7.0f}, "N ITS Clusters"}; @@ -313,7 +328,7 @@ struct quarkoniaToHyperons { // For manual sliceBy PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; - enum selection : uint64_t { selCosPA = 0, + enum Selection : uint64_t { selCosPA = 0, selRadius, selRadiusMax, selDCANegToPV, @@ -385,61 +400,61 @@ struct quarkoniaToHyperons { void init(InitContext const&) { // initialise bit masks - maskTopological = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); - maskTopoNoV0Radius = (uint64_t(1) << selCosPA) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); - maskTopoNoDCANegToPV = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); - maskTopoNoDCAPosToPV = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); - maskTopoNoCosPA = (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); - maskTopoNoDCAV0Dau = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selRadiusMax); - maskTopoNoDCAV0ToPV = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); - - maskK0ShortSpecific = (uint64_t(1) << selK0ShortRapidity) | (uint64_t(1) << selK0ShortCTau) | (uint64_t(1) << selK0ShortArmenteros) | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selK0ShortMassWindow) | (uint64_t(1) << selLambdaMassRejection); - maskLambdaSpecific = (uint64_t(1) << selLambdaRapidity) | (uint64_t(1) << selLambdaCTau) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selLambdaMassWindow) | (uint64_t(1) << selK0ShortMassRejection); - maskAntiLambdaSpecific = (uint64_t(1) << selLambdaRapidity) | (uint64_t(1) << selLambdaCTau) | (uint64_t(1) << selConsiderAntiLambda) | (uint64_t(1) << selAntiLambdaMassWindow) | (uint64_t(1) << selK0ShortMassRejection); + maskTopological = (static_cast(1) << selCosPA) | (static_cast(1) << selRadius) | (static_cast(1) << selDCANegToPV) | (static_cast(1) << selDCAPosToPV) | (static_cast(1) << selDCAV0ToPV) | (static_cast(1) << selDCAV0Dau) | (static_cast(1) << selRadiusMax); + maskTopoNoV0Radius = (static_cast(1) << selCosPA) | (static_cast(1) << selDCANegToPV) | (static_cast(1) << selDCAPosToPV) | (static_cast(1) << selDCAV0ToPV) | (static_cast(1) << selDCAV0Dau) | (static_cast(1) << selRadiusMax); + maskTopoNoDCANegToPV = (static_cast(1) << selCosPA) | (static_cast(1) << selRadius) | (static_cast(1) << selDCAPosToPV) | (static_cast(1) << selDCAV0ToPV) | (static_cast(1) << selDCAV0Dau) | (static_cast(1) << selRadiusMax); + maskTopoNoDCAPosToPV = (static_cast(1) << selCosPA) | (static_cast(1) << selRadius) | (static_cast(1) << selDCANegToPV) | (static_cast(1) << selDCAV0ToPV) | (static_cast(1) << selDCAV0Dau) | (static_cast(1) << selRadiusMax); + maskTopoNoCosPA = (static_cast(1) << selRadius) | (static_cast(1) << selDCANegToPV) | (static_cast(1) << selDCAPosToPV) | (static_cast(1) << selDCAV0ToPV) | (static_cast(1) << selDCAV0Dau) | (static_cast(1) << selRadiusMax); + maskTopoNoDCAV0Dau = (static_cast(1) << selCosPA) | (static_cast(1) << selRadius) | (static_cast(1) << selDCANegToPV) | (static_cast(1) << selDCAPosToPV) | (static_cast(1) << selDCAV0ToPV) | (static_cast(1) << selRadiusMax); + maskTopoNoDCAV0ToPV = (static_cast(1) << selCosPA) | (static_cast(1) << selRadius) | (static_cast(1) << selDCANegToPV) | (static_cast(1) << selDCAPosToPV) | (static_cast(1) << selDCAV0Dau) | (static_cast(1) << selRadiusMax); + + maskK0ShortSpecific = (static_cast(1) << selK0ShortRapidity) | (static_cast(1) << selK0ShortCTau) | (static_cast(1) << selK0ShortArmenteros) | (static_cast(1) << selConsiderK0Short) | (static_cast(1) << selK0ShortMassWindow) | (static_cast(1) << selLambdaMassRejection); + maskLambdaSpecific = (static_cast(1) << selLambdaRapidity) | (static_cast(1) << selLambdaCTau) | (static_cast(1) << selConsiderLambda) | (static_cast(1) << selLambdaMassWindow) | (static_cast(1) << selK0ShortMassRejection); + maskAntiLambdaSpecific = (static_cast(1) << selLambdaRapidity) | (static_cast(1) << selLambdaCTau) | (static_cast(1) << selConsiderAntiLambda) | (static_cast(1) << selAntiLambdaMassWindow) | (static_cast(1) << selK0ShortMassRejection); // ask for specific TPC/TOF PID selections maskTrackProperties = 0; if (v0Selections.requirePosITSonly) { - maskTrackProperties = maskTrackProperties | (uint64_t(1) << selPosItsOnly) | (uint64_t(1) << selPosGoodITSTrack); + maskTrackProperties = maskTrackProperties | (static_cast(1) << selPosItsOnly) | (static_cast(1) << selPosGoodITSTrack); } else { - maskTrackProperties = maskTrackProperties | (uint64_t(1) << selPosGoodTPCTrack) | (uint64_t(1) << selPosGoodITSTrack); + maskTrackProperties = maskTrackProperties | (static_cast(1) << selPosGoodTPCTrack) | (static_cast(1) << selPosGoodITSTrack); // TPC signal is available: ask for positive track PID - if (v0Selections.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut - maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTPCPIDPositivePion); - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTPCPIDPositiveProton); - maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTPCPIDPositivePion); + if (v0Selections.tpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (static_cast(1) << selTPCPIDPositivePion); + maskLambdaSpecific = maskLambdaSpecific | (static_cast(1) << selTPCPIDPositiveProton); + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (static_cast(1) << selTPCPIDPositivePion); } // TOF PID - if (v0Selections.TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut - maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaPositivePionK0Short) | (uint64_t(1) << selTOFDeltaTPositivePionK0Short); - if (v0Selections.TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaPositiveProtonLambda) | (uint64_t(1) << selTOFDeltaTPositiveProtonLambda); - if (v0Selections.TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut - maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaPositivePionLambda) | (uint64_t(1) << selTOFDeltaTPositivePionLambda); + if (v0Selections.tofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (static_cast(1) << selTOFNSigmaPositivePionK0Short) | (static_cast(1) << selTOFDeltaTPositivePionK0Short); + if (v0Selections.tofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut + maskLambdaSpecific = maskLambdaSpecific | (static_cast(1) << selTOFNSigmaPositiveProtonLambda) | (static_cast(1) << selTOFDeltaTPositiveProtonLambda); + if (v0Selections.tofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (static_cast(1) << selTOFNSigmaPositivePionLambda) | (static_cast(1) << selTOFDeltaTPositivePionLambda); } if (v0Selections.requireNegITSonly) { - maskTrackProperties = maskTrackProperties | (uint64_t(1) << selNegItsOnly) | (uint64_t(1) << selNegGoodITSTrack); + maskTrackProperties = maskTrackProperties | (static_cast(1) << selNegItsOnly) | (static_cast(1) << selNegGoodITSTrack); } else { - maskTrackProperties = maskTrackProperties | (uint64_t(1) << selNegGoodTPCTrack) | (uint64_t(1) << selNegGoodITSTrack); + maskTrackProperties = maskTrackProperties | (static_cast(1) << selNegGoodTPCTrack) | (static_cast(1) << selNegGoodITSTrack); // TPC signal is available: ask for negative track PID - if (v0Selections.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut - maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTPCPIDNegativePion); - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTPCPIDNegativePion); - maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTPCPIDNegativeProton); + if (v0Selections.tpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (static_cast(1) << selTPCPIDNegativePion); + maskLambdaSpecific = maskLambdaSpecific | (static_cast(1) << selTPCPIDNegativePion); + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (static_cast(1) << selTPCPIDNegativeProton); } // TOF PID - if (v0Selections.TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut - maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaNegativePionK0Short) | (uint64_t(1) << selTOFDeltaTNegativePionK0Short); - if (v0Selections.TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda); - if (v0Selections.TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut - maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativeProtonLambda) | (uint64_t(1) << selTOFDeltaTNegativeProtonLambda); + if (v0Selections.tofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (static_cast(1) << selTOFNSigmaNegativePionK0Short) | (static_cast(1) << selTOFDeltaTNegativePionK0Short); + if (v0Selections.tofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut + maskLambdaSpecific = maskLambdaSpecific | (static_cast(1) << selTOFNSigmaNegativePionLambda) | (static_cast(1) << selTOFDeltaTNegativePionLambda); + if (v0Selections.tofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (static_cast(1) << selTOFNSigmaNegativeProtonLambda) | (static_cast(1) << selTOFDeltaTNegativeProtonLambda); } if (v0Selections.skipTPConly) { - maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selPosNotTPCOnly) | (uint64_t(1) << selNegNotTPCOnly); - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selPosNotTPCOnly) | (uint64_t(1) << selNegNotTPCOnly); - maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selPosNotTPCOnly) | (uint64_t(1) << selNegNotTPCOnly); + maskK0ShortSpecific = maskK0ShortSpecific | (static_cast(1) << selPosNotTPCOnly) | (static_cast(1) << selNegNotTPCOnly); + maskLambdaSpecific = maskLambdaSpecific | (static_cast(1) << selPosNotTPCOnly) | (static_cast(1) << selNegNotTPCOnly); + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (static_cast(1) << selPosNotTPCOnly) | (static_cast(1) << selNegNotTPCOnly); } // Primary particle selection, central to analysis @@ -455,18 +470,19 @@ struct quarkoniaToHyperons { histos.add("hEventSelection", "hEventSelection", kTH1F, {{20, -0.5f, +19.5f}}); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "kIsVertexITSTPC"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsVertexTOFmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTRDmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kNoSameBunchPileup"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoCollInTimeRangeStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeNarrow"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "Below min occup."); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "Above max occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "Above max occup."); histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); histos.add("hCentralityVsNch", "hCentralityVsNch", kTH2F, {axisCentrality, axisNch}); @@ -489,6 +505,44 @@ struct quarkoniaToHyperons { } // histograms versus mass + if (buildK0sK0sPairs) { + histos.add("K0sK0s/h3dMassK0sK0s", "h3dMassK0sK0s", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + if (!isPP) { + // Non-UPC info + histos.add("K0sK0s/h3dMassK0sK0sHadronic", "h3dMassK0sK0sHadronic", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + // UPC info + histos.add("K0sK0s/h3dMassK0sK0sSGA", "h3dMassK0sK0sSGA", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dMassK0sK0sSGC", "h3dMassK0sK0sSGC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dMassK0sK0sDG", "h3dMassK0sK0sDG", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + histos.add("K0sK0s/h2dNbrOfK0ShortVsCentrality", "h2dNbrOfK0ShortVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + // QA plot + // Candidates after K0s selections + histos.add("K0sK0s/K0s/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("K0sK0s/K0s/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("K0sK0s/K0s/hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {axisDCAdau}); + histos.add("K0sK0s/K0s/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("K0sK0s/K0s/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("K0sK0s/K0s/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("K0sK0s/K0s/hV0DecayLength", "hDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("K0sK0s/K0s/hV0InvMassWindow", "hInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("K0sK0s/K0s/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisLambdaMass, axisK0Mass}); + histos.add("K0sK0s/K0s/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); + histos.add("K0sK0s/K0s/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("K0sK0s/K0s/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("K0sK0s/K0s/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("K0sK0s/K0s/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + if (doMCAssociation) { + histos.add("K0sK0s/h3dInvMassTrueEtaC1S", "h3dInvMassTrueEtaC1S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTrueJPsi", "h3dInvMassTrueJPsi", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTrueChiC0", "h3dInvMassTrueChiC0", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTrueChiC1", "h3dInvMassTrueChiC1", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTrueHC", "h3dInvMassTrueHC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTrueChiC2", "h3dInvMassTrueChiC2", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTrueEtaC2S", "h3dInvMassTrueEtaC2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("K0sK0s/h3dInvMassTruePsi2S", "h3dInvMassTruePsi2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + } if (buildLaLaBarPairs) { histos.add("LaLaBar/h3dMassLaLabar", "h3dMassLaLabar", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); if (!isPP) { @@ -499,7 +553,6 @@ struct quarkoniaToHyperons { histos.add("LaLaBar/h3dMassLaLabarSGC", "h3dMassLaLabarSGC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); histos.add("LaLaBar/h3dMassLaLabarDG", "h3dMassLaLabarDG", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); } - histos.add("LaLaBar/h2dNbrOfK0ShortVsCentrality", "h2dNbrOfK0ShortVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); histos.add("LaLaBar/h2dNbrOfLambdaVsCentrality", "h2dNbrOfLambdaVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); histos.add("LaLaBar/h2dNbrOfAntiLambdaVsCentrality", "h2dNbrOfAntiLambdaVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); // QA plot @@ -703,12 +756,12 @@ struct quarkoniaToHyperons { int64_t timeStampML = collision.timestamp(); if (mlConfigurations.timestampCCDB.value != -1) timeStampML = mlConfigurations.timestampCCDB.value; - LoadMachines(timeStampML); + loadMachines(timeStampML); } } // function to load models for ML-based classifiers - void LoadMachines(int64_t timeStampML) + void loadMachines(int64_t timeStampML) { if (mlConfigurations.loadCustomModelsFromCCDB) { ccdbApi.init(ccdbConfigurations.ccdburl); @@ -752,7 +805,7 @@ struct quarkoniaToHyperons { } template - bool IsEventAccepted(TCollision collision, bool fillHists) + bool isEventAccepted(TCollision collision, bool fillHists) // check whether the collision passes our collision selections { if (fillHists) @@ -763,11 +816,11 @@ struct quarkoniaToHyperons { if (fillHists) histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); - if (std::abs(collision.posZ()) > 10.f) { + if (requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); + histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { return false; @@ -781,58 +834,64 @@ struct quarkoniaToHyperons { if (fillHists) histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + if (std::abs(collision.posZ()) > 10.f) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); + if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 5 /* Contains at least one ITS-TPC track */); + histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 6 /* PV position consistency check */); + histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 7 /* PV with at least one contributor matched with TOF */); + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TRD */); + histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 9 /* Not at same bunch pile-up */); + histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); if (requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 10 /* No other collision within +/- 10 microseconds */); + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 10 microseconds */); if (requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 4 microseconds */); + histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 4 microseconds */); if (minOccupancy > 0 && collision.trackOccupancyInTimeRange() < minOccupancy) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 12 /* Below min occupancy */); + histos.fill(HIST("hEventSelection"), 13 /* Below min occupancy */); if (maxOccupancy > 0 && collision.trackOccupancyInTimeRange() > maxOccupancy) { return false; } if (fillHists) - histos.fill(HIST("hEventSelection"), 13 /* Above max occupancy */); + histos.fill(HIST("hEventSelection"), 14 /* Above max occupancy */); return true; } @@ -863,7 +922,7 @@ struct quarkoniaToHyperons { // 0 --> Single Gap - A side // 1 --> Single Gap - C side // 2 --> Double Gap - both A & C sides - selGapSide = sgSelector.trueGap(collision, upcCuts.FV0cut, upcCuts.FT0Acut, upcCuts.FT0Ccut, upcCuts.ZDCcut); + selGapSide = sgSelector.trueGap(collision, upcCuts.fv0Cut, upcCuts.ft0aCut, upcCuts.ft0cCut, upcCuts.zdcCut); histos.fill(HIST("hGapSide"), gapSide); histos.fill(HIST("hSelGapSide"), selGapSide); histos.fill(HIST("hEventCentralityVsSelGapSide"), centrality, selGapSide <= 2 ? selGapSide : -1); @@ -891,145 +950,145 @@ struct quarkoniaToHyperons { // v0 radius min/max selections if (v0.v0radius() > v0Selections.v0radius) - bitset(bitMap, selRadius); + BITSET(bitMap, selRadius); if (v0.v0radius() < v0Selections.v0radiusMax) - bitset(bitMap, selRadiusMax); + BITSET(bitMap, selRadiusMax); // DCA proton and pion to PV for Lambda and AntiLambda decay hypotheses - if (TMath::Abs(v0.dcapostopv()) > v0Selections.dcaprotontopv && - TMath::Abs(v0.dcanegtopv()) > v0Selections.dcapiontopv) { - bitset(bitMap, selDCAPosToPV); - bitset(bitMap, selDCANegToPV); - } else if (TMath::Abs(v0.dcapostopv()) > v0Selections.dcapiontopv && - TMath::Abs(v0.dcanegtopv()) > v0Selections.dcaprotontopv) { - bitset(bitMap, selDCAPosToPV); - bitset(bitMap, selDCANegToPV); + if (std::fabs(v0.dcapostopv()) > v0Selections.dcaprotontopv && + std::fabs(v0.dcanegtopv()) > v0Selections.dcapiontopv) { + BITSET(bitMap, selDCAPosToPV); + BITSET(bitMap, selDCANegToPV); + } else if (std::fabs(v0.dcapostopv()) > v0Selections.dcapiontopv && + std::fabs(v0.dcanegtopv()) > v0Selections.dcaprotontopv) { + BITSET(bitMap, selDCAPosToPV); + BITSET(bitMap, selDCANegToPV); } // V0 cosine of pointing angle if (v0.v0cosPA() > v0Selections.v0cospa) - bitset(bitMap, selCosPA); + BITSET(bitMap, selCosPA); // DCA between v0 daughters if (v0.dcaV0daughters() < v0Selections.dcav0dau) - bitset(bitMap, selDCAV0Dau); + BITSET(bitMap, selDCAV0Dau); // DCA V0 to prim vtx if (v0.dcav0topv() > v0Selections.dcav0topv) - bitset(bitMap, selDCAV0ToPV); + BITSET(bitMap, selDCAV0ToPV); // // rapidity // - if (TMath::Abs(rapidityLambda) < v0Selections.rapidityCut) - bitset(bitMap, selLambdaRapidity); - if (TMath::Abs(rapidityK0Short) < v0Selections.rapidityCut) - bitset(bitMap, selK0ShortRapidity); + if (std::fabs(rapidityLambda) < v0Selections.rapidityCut) + BITSET(bitMap, selLambdaRapidity); + if (std::fabs(rapidityK0Short) < v0Selections.rapidityCut) + BITSET(bitMap, selK0ShortRapidity); // // invariant mass window // - if (TMath::Abs(v0.mK0Short() - pdgDB->Mass(310)) < v0Selections.v0MassWindow) - bitset(bitMap, selK0ShortMassWindow); - if (TMath::Abs(v0.mLambda() - pdgDB->Mass(3122)) < v0Selections.v0MassWindow) - bitset(bitMap, selLambdaMassWindow); - if (TMath::Abs(v0.mAntiLambda() - pdgDB->Mass(3122)) < v0Selections.v0MassWindow) - bitset(bitMap, selAntiLambdaMassWindow); + if (std::fabs(v0.mK0Short() - o2::constants::physics::MassK0Short) < v0Selections.v0MassWindow) + BITSET(bitMap, selK0ShortMassWindow); + if (std::fabs(v0.mLambda() - o2::constants::physics::MassLambda0) < v0Selections.v0MassWindow) + BITSET(bitMap, selLambdaMassWindow); + if (std::fabs(v0.mAntiLambda() - o2::constants::physics::MassLambda0Bar) < v0Selections.v0MassWindow) + BITSET(bitMap, selAntiLambdaMassWindow); // // competing mass rejection // - if (TMath::Abs(v0.mK0Short() - pdgDB->Mass(310)) > v0Selections.compMassRejection) - bitset(bitMap, selK0ShortMassRejection); - if (TMath::Abs(v0.mLambda() - pdgDB->Mass(3122)) > v0Selections.compMassRejection) - bitset(bitMap, selLambdaMassRejection); + if (std::fabs(v0.mK0Short() - o2::constants::physics::MassK0Short) > v0Selections.compMassRejection) + BITSET(bitMap, selK0ShortMassRejection); + if (std::fabs(v0.mLambda() - o2::constants::physics::MassLambda0) > v0Selections.compMassRejection) + BITSET(bitMap, selLambdaMassRejection); - auto posTrackExtra = v0.template posTrackExtra_as(); - auto negTrackExtra = v0.template negTrackExtra_as(); + auto posTrackExtra = v0.template posTrackExtra_as(); + auto negTrackExtra = v0.template negTrackExtra_as(); // // ITS quality flags // if (posTrackExtra.itsNCls() >= v0Selections.minITSclusters) - bitset(bitMap, selPosGoodITSTrack); + BITSET(bitMap, selPosGoodITSTrack); if (negTrackExtra.itsNCls() >= v0Selections.minITSclusters) - bitset(bitMap, selNegGoodITSTrack); + BITSET(bitMap, selNegGoodITSTrack); // // TPC quality flags // if (posTrackExtra.tpcCrossedRows() >= v0Selections.minTPCrows) - bitset(bitMap, selPosGoodTPCTrack); + BITSET(bitMap, selPosGoodTPCTrack); if (negTrackExtra.tpcCrossedRows() >= v0Selections.minTPCrows) - bitset(bitMap, selNegGoodTPCTrack); + BITSET(bitMap, selNegGoodTPCTrack); // // TPC PID // - if (fabs(posTrackExtra.tpcNSigmaPi()) < v0Selections.TpcPidNsigmaCut) - bitset(bitMap, selTPCPIDPositivePion); - if (fabs(posTrackExtra.tpcNSigmaPr()) < v0Selections.TpcPidNsigmaCut) - bitset(bitMap, selTPCPIDPositiveProton); - if (fabs(negTrackExtra.tpcNSigmaPi()) < v0Selections.TpcPidNsigmaCut) - bitset(bitMap, selTPCPIDNegativePion); - if (fabs(negTrackExtra.tpcNSigmaPr()) < v0Selections.TpcPidNsigmaCut) - bitset(bitMap, selTPCPIDNegativeProton); + if (std::fabs(posTrackExtra.tpcNSigmaPi()) < v0Selections.tpcPidNsigmaCut) + BITSET(bitMap, selTPCPIDPositivePion); + if (std::fabs(posTrackExtra.tpcNSigmaPr()) < v0Selections.tpcPidNsigmaCut) + BITSET(bitMap, selTPCPIDPositiveProton); + if (std::fabs(negTrackExtra.tpcNSigmaPi()) < v0Selections.tpcPidNsigmaCut) + BITSET(bitMap, selTPCPIDNegativePion); + if (std::fabs(negTrackExtra.tpcNSigmaPr()) < v0Selections.tpcPidNsigmaCut) + BITSET(bitMap, selTPCPIDNegativeProton); // // TOF PID in DeltaT // Positive track - if (fabs(v0.posTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) - bitset(bitMap, selTOFDeltaTPositiveProtonLambda); - if (fabs(v0.posTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) - bitset(bitMap, selTOFDeltaTPositivePionLambda); - if (fabs(v0.posTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) - bitset(bitMap, selTOFDeltaTPositivePionK0Short); + if (std::fabs(v0.posTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) + BITSET(bitMap, selTOFDeltaTPositiveProtonLambda); + if (std::fabs(v0.posTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) + BITSET(bitMap, selTOFDeltaTPositivePionLambda); + if (std::fabs(v0.posTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) + BITSET(bitMap, selTOFDeltaTPositivePionK0Short); // Negative track - if (fabs(v0.negTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) - bitset(bitMap, selTOFDeltaTNegativeProtonLambda); - if (fabs(v0.negTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) - bitset(bitMap, selTOFDeltaTNegativePionLambda); - if (fabs(v0.negTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) - bitset(bitMap, selTOFDeltaTNegativePionK0Short); + if (std::fabs(v0.negTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) + BITSET(bitMap, selTOFDeltaTNegativeProtonLambda); + if (std::fabs(v0.negTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) + BITSET(bitMap, selTOFDeltaTNegativePionLambda); + if (std::fabs(v0.negTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) + BITSET(bitMap, selTOFDeltaTNegativePionK0Short); // // TOF PID in NSigma // Positive track - if (fabs(v0.tofNSigmaLaPr()) < v0Selections.TofPidNsigmaCutLaPr) - bitset(bitMap, selTOFNSigmaPositiveProtonLambda); - if (fabs(v0.tofNSigmaALaPi()) < v0Selections.TofPidNsigmaCutLaPi) - bitset(bitMap, selTOFNSigmaPositivePionLambda); - if (fabs(v0.tofNSigmaK0PiPlus()) < v0Selections.TofPidNsigmaCutK0Pi) - bitset(bitMap, selTOFNSigmaPositivePionK0Short); + if (std::fabs(v0.tofNSigmaLaPr()) < v0Selections.tofPidNsigmaCutLaPr) + BITSET(bitMap, selTOFNSigmaPositiveProtonLambda); + if (std::fabs(v0.tofNSigmaALaPi()) < v0Selections.tofPidNsigmaCutLaPi) + BITSET(bitMap, selTOFNSigmaPositivePionLambda); + if (std::fabs(v0.tofNSigmaK0PiPlus()) < v0Selections.tofPidNsigmaCutK0Pi) + BITSET(bitMap, selTOFNSigmaPositivePionK0Short); // Negative track - if (fabs(v0.tofNSigmaALaPr()) < v0Selections.TofPidNsigmaCutLaPr) - bitset(bitMap, selTOFNSigmaNegativeProtonLambda); - if (fabs(v0.tofNSigmaLaPi()) < v0Selections.TofPidNsigmaCutLaPi) - bitset(bitMap, selTOFNSigmaNegativePionLambda); - if (fabs(v0.tofNSigmaK0PiMinus()) < v0Selections.TofPidNsigmaCutK0Pi) - bitset(bitMap, selTOFNSigmaNegativePionK0Short); + if (std::fabs(v0.tofNSigmaALaPr()) < v0Selections.tofPidNsigmaCutLaPr) + BITSET(bitMap, selTOFNSigmaNegativeProtonLambda); + if (std::fabs(v0.tofNSigmaLaPi()) < v0Selections.tofPidNsigmaCutLaPi) + BITSET(bitMap, selTOFNSigmaNegativePionLambda); + if (std::fabs(v0.tofNSigmaK0PiMinus()) < v0Selections.tofPidNsigmaCutK0Pi) + BITSET(bitMap, selTOFNSigmaNegativePionK0Short); // // ITS only tag if (posTrackExtra.tpcCrossedRows() < 1) - bitset(bitMap, selPosItsOnly); + BITSET(bitMap, selPosItsOnly); if (negTrackExtra.tpcCrossedRows() < 1) - bitset(bitMap, selNegItsOnly); + BITSET(bitMap, selNegItsOnly); // // TPC only tag if (posTrackExtra.detectorMap() != o2::aod::track::TPC) - bitset(bitMap, selPosNotTPCOnly); + BITSET(bitMap, selPosNotTPCOnly); if (negTrackExtra.detectorMap() != o2::aod::track::TPC) - bitset(bitMap, selNegNotTPCOnly); + BITSET(bitMap, selNegNotTPCOnly); // // proper lifetime if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) - bitset(bitMap, selLambdaCTau); + BITSET(bitMap, selLambdaCTau); if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) - bitset(bitMap, selK0ShortCTau); + BITSET(bitMap, selK0ShortCTau); // // armenteros - if (v0.qtarm() * v0Selections.armPodCut > TMath::Abs(v0.alpha()) || v0Selections.armPodCut < 1e-4) - bitset(bitMap, selK0ShortArmenteros); + if (v0.qtarm() * v0Selections.armPodCut > std::fabs(v0.alpha()) || v0Selections.armPodCut < 1e-4) + BITSET(bitMap, selK0ShortArmenteros); return bitMap; } @@ -1049,14 +1108,14 @@ struct quarkoniaToHyperons { return false; // DCA proton and pion to PV for Lambda and AntiLambda decay hypotheses if (casc.sign() < 0) { // Xi- or Omega- --> positive/negative daughter = proton/pion - if (TMath::Abs(casc.dcapostopv()) < cascSelections.dcaprotontopv) + if (std::fabs(casc.dcapostopv()) < cascSelections.dcaprotontopv) return false; - if (TMath::Abs(casc.dcanegtopv()) < cascSelections.dcapiontopv) + if (std::fabs(casc.dcanegtopv()) < cascSelections.dcapiontopv) return false; } else { // Xi+ or Omega+ --> positive/negative daughter = pion/proton - if (TMath::Abs(casc.dcapostopv()) < cascSelections.dcapiontopv) + if (std::fabs(casc.dcapostopv()) < cascSelections.dcapiontopv) return false; - if (TMath::Abs(casc.dcanegtopv()) < cascSelections.dcaprotontopv) + if (std::fabs(casc.dcanegtopv()) < cascSelections.dcaprotontopv) return false; } // V0 cosine of pointing angle @@ -1075,13 +1134,13 @@ struct quarkoniaToHyperons { if (casc.cascradius() > cascSelections.cascradiusMax) return false; // DCA bachelor selection - if (TMath::Abs(casc.dcabachtopv()) < cascSelections.dcabachtopv) + if (std::fabs(casc.dcabachtopv()) < cascSelections.dcabachtopv) return false; // Bachelor-baryon cosPA selection if (casc.bachBaryonCosPA() < cascSelections.bachbaryoncospa) return false; // DCA bachelor-baryon selection - if (TMath::Abs(casc.bachBaryonDCAxyToPV()) < cascSelections.dcaxybachbaryontopv) + if (std::fabs(casc.bachBaryonDCAxyToPV()) < cascSelections.dcaxybachbaryontopv) return false; // casc cosine of pointing angle if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascSelections.casccospa) @@ -1093,30 +1152,30 @@ struct quarkoniaToHyperons { // // rapidity // - if (TMath::Abs(rapidity) > cascSelections.rapidityCut) + if (std::fabs(rapidity) > cascSelections.rapidityCut) return false; // // invariant mass window // - if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascSelections.v0MassWindow) + if (std::fabs(casc.mLambda() - o2::constants::physics::MassLambda0) > cascSelections.v0MassWindow) return false; - if (isXi && TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascSelections.cascMassWindow) + if (isXi && std::fabs(casc.mXi() - o2::constants::physics::MassXiMinus) > cascSelections.cascMassWindow) return false; - if (!isXi && TMath::Abs(casc.mOmega() - pdgDB->Mass(3334)) > cascSelections.cascMassWindow) + if (!isXi && std::fabs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) > cascSelections.cascMassWindow) return false; // // competing mass rejection // - if (isXi && TMath::Abs(casc.mOmega() - pdgDB->Mass(3334)) < cascSelections.compMassRejection) + if (isXi && std::fabs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < cascSelections.compMassRejection) return false; - if (!isXi && TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) < cascSelections.compMassRejection) + if (!isXi && std::fabs(casc.mXi() - o2::constants::physics::MassXiMinus) < cascSelections.compMassRejection) return false; - auto bachTrackExtra = casc.template bachTrackExtra_as(); - auto posTrackExtra = casc.template posTrackExtra_as(); - auto negTrackExtra = casc.template negTrackExtra_as(); + auto bachTrackExtra = casc.template bachTrackExtra_as(); + auto posTrackExtra = casc.template posTrackExtra_as(); + auto negTrackExtra = casc.template negTrackExtra_as(); // // ITS quality flags @@ -1141,19 +1200,19 @@ struct quarkoniaToHyperons { // // TPC PID // - if (isXi && fabs(bachTrackExtra.tpcNSigmaPi()) > cascSelections.TpcPidNsigmaCut) + if (isXi && std::fabs(bachTrackExtra.tpcNSigmaPi()) > cascSelections.tpcPidNsigmaCut) return false; - if (!isXi && fabs(bachTrackExtra.tpcNSigmaKa()) > cascSelections.TpcPidNsigmaCut) + if (!isXi && std::fabs(bachTrackExtra.tpcNSigmaKa()) > cascSelections.tpcPidNsigmaCut) return false; if (casc.sign() < 0) { // Xi- or Omega- --> positive/negative daughter = proton/pion - if (fabs(posTrackExtra.tpcNSigmaPr()) > cascSelections.TpcPidNsigmaCut) + if (std::fabs(posTrackExtra.tpcNSigmaPr()) > cascSelections.tpcPidNsigmaCut) return false; - if (fabs(negTrackExtra.tpcNSigmaPi()) > cascSelections.TpcPidNsigmaCut) + if (std::fabs(negTrackExtra.tpcNSigmaPi()) > cascSelections.tpcPidNsigmaCut) return false; } else { // Xi+ or Omega+ --> positive/negative daughter = pion/proton - if (fabs(posTrackExtra.tpcNSigmaPi()) > cascSelections.TpcPidNsigmaCut) + if (std::fabs(posTrackExtra.tpcNSigmaPi()) > cascSelections.tpcPidNsigmaCut) return false; - if (fabs(negTrackExtra.tpcNSigmaPr()) > cascSelections.TpcPidNsigmaCut) + if (std::fabs(negTrackExtra.tpcNSigmaPr()) > cascSelections.tpcPidNsigmaCut) return false; } @@ -1161,36 +1220,36 @@ struct quarkoniaToHyperons { // TOF PID in DeltaT // Bachelor track if (bachTrackExtra.hasTOF()) { - if (isXi && fabs(casc.bachTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) + if (isXi && std::fabs(casc.bachTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) return false; - if (!isXi && fabs(casc.bachTOFDeltaTOmKa()) > cascSelections.maxDeltaTimeKaon) + if (!isXi && std::fabs(casc.bachTOFDeltaTOmKa()) > cascSelections.maxDeltaTimeKaon) return false; } // Positive track if (posTrackExtra.hasTOF()) { if (casc.sign() < 0) { // Xi- or Omega- --> positive daughter = proton - if (isXi && fabs(casc.posTOFDeltaTXiPr()) > cascSelections.maxDeltaTimeProton) + if (isXi && std::fabs(casc.posTOFDeltaTXiPr()) > cascSelections.maxDeltaTimeProton) return false; - if (!isXi && fabs(casc.posTOFDeltaTOmPr()) > cascSelections.maxDeltaTimeProton) + if (!isXi && std::fabs(casc.posTOFDeltaTOmPr()) > cascSelections.maxDeltaTimeProton) return false; } else { // Xi+ or Omega+ --> positive daughter = pion - if (isXi && fabs(casc.posTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) + if (isXi && std::fabs(casc.posTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) return false; - if (!isXi && fabs(casc.posTOFDeltaTOmPi()) > cascSelections.maxDeltaTimePion) + if (!isXi && std::fabs(casc.posTOFDeltaTOmPi()) > cascSelections.maxDeltaTimePion) return false; } } // Negative track if (negTrackExtra.hasTOF()) { if (casc.sign() < 0) { // Xi- or Omega- --> negative daughter = pion - if (isXi && fabs(casc.negTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) + if (isXi && std::fabs(casc.negTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) return false; - if (!isXi && fabs(casc.negTOFDeltaTOmPi()) > cascSelections.maxDeltaTimePion) + if (!isXi && std::fabs(casc.negTOFDeltaTOmPi()) > cascSelections.maxDeltaTimePion) return false; } else { // Xi+ or Omega+ --> negative daughter = proton - if (isXi && fabs(casc.negTOFDeltaTXiPr()) > cascSelections.maxDeltaTimeProton) + if (isXi && std::fabs(casc.negTOFDeltaTXiPr()) > cascSelections.maxDeltaTimeProton) return false; - if (!isXi && fabs(casc.negTOFDeltaTOmPr()) > cascSelections.maxDeltaTimeProton) + if (!isXi && std::fabs(casc.negTOFDeltaTOmPr()) > cascSelections.maxDeltaTimeProton) return false; } } @@ -1199,36 +1258,36 @@ struct quarkoniaToHyperons { // TOF PID in NSigma // Bachelor track if (bachTrackExtra.hasTOF()) { - if (isXi && fabs(casc.tofNSigmaXiPi()) > cascSelections.TofPidNsigmaCutXiPi) + if (isXi && std::fabs(casc.tofNSigmaXiPi()) > cascSelections.tofPidNsigmaCutXiPi) return false; - if (!isXi && fabs(casc.tofNSigmaOmKa()) > cascSelections.TofPidNsigmaCutOmKa) + if (!isXi && std::fabs(casc.tofNSigmaOmKa()) > cascSelections.tofPidNsigmaCutOmKa) return false; } // Positive track if (posTrackExtra.hasTOF()) { if (casc.sign() < 0) { // Xi- or Omega- --> positive daughter = proton - if (isXi && fabs(casc.tofNSigmaXiLaPr()) > cascSelections.TofPidNsigmaCutLaPr) + if (isXi && std::fabs(casc.tofNSigmaXiLaPr()) > cascSelections.tofPidNsigmaCutLaPr) return false; - if (!isXi && fabs(casc.tofNSigmaOmLaPr()) > cascSelections.TofPidNsigmaCutLaPr) + if (!isXi && std::fabs(casc.tofNSigmaOmLaPr()) > cascSelections.tofPidNsigmaCutLaPr) return false; } else { // Xi+ or Omega+ --> positive daughter = pion - if (isXi && fabs(casc.tofNSigmaXiLaPi()) > cascSelections.TofPidNsigmaCutLaPi) + if (isXi && std::fabs(casc.tofNSigmaXiLaPi()) > cascSelections.tofPidNsigmaCutLaPi) return false; - if (!isXi && fabs(casc.tofNSigmaOmLaPi()) > cascSelections.TofPidNsigmaCutLaPi) + if (!isXi && std::fabs(casc.tofNSigmaOmLaPi()) > cascSelections.tofPidNsigmaCutLaPi) return false; } } // Negative track if (negTrackExtra.hasTOF()) { if (casc.sign() < 0) { // Xi- or Omega- --> negative daughter = pion - if (isXi && fabs(casc.tofNSigmaXiLaPr()) > cascSelections.TofPidNsigmaCutLaPi) + if (isXi && std::fabs(casc.tofNSigmaXiLaPr()) > cascSelections.tofPidNsigmaCutLaPi) return false; - if (!isXi && fabs(casc.tofNSigmaOmLaPr()) > cascSelections.TofPidNsigmaCutLaPi) + if (!isXi && std::fabs(casc.tofNSigmaOmLaPr()) > cascSelections.tofPidNsigmaCutLaPi) return false; } else { // Xi+ or Omega+ --> negative daughter = proton - if (isXi && fabs(casc.tofNSigmaXiLaPi()) > cascSelections.TofPidNsigmaCutLaPr) + if (isXi && std::fabs(casc.tofNSigmaXiLaPi()) > cascSelections.tofPidNsigmaCutLaPr) return false; - if (!isXi && fabs(casc.tofNSigmaOmLaPi()) > cascSelections.TofPidNsigmaCutLaPr) + if (!isXi && std::fabs(casc.tofNSigmaOmLaPi()) > cascSelections.tofPidNsigmaCutLaPr) return false; } } @@ -1278,19 +1337,19 @@ struct quarkoniaToHyperons { // check for specific particle species if (v0.pdgCode() == 310 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -211) { - bitset(bitMap, selConsiderK0Short); + BITSET(bitMap, selConsiderK0Short); if (v0.isPhysicalPrimary()) - bitset(bitMap, selPhysPrimK0Short); + BITSET(bitMap, selPhysPrimK0Short); } if (v0.pdgCode() == 3122 && v0.pdgCodePositive() == 2212 && v0.pdgCodeNegative() == -211) { - bitset(bitMap, selConsiderLambda); + BITSET(bitMap, selConsiderLambda); if (v0.isPhysicalPrimary()) - bitset(bitMap, selPhysPrimLambda); + BITSET(bitMap, selPhysPrimLambda); } if (v0.pdgCode() == -3122 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -2212) { - bitset(bitMap, selConsiderAntiLambda); + BITSET(bitMap, selConsiderAntiLambda); if (v0.isPhysicalPrimary()) - bitset(bitMap, selPhysPrimAntiLambda); + BITSET(bitMap, selPhysPrimAntiLambda); } return bitMap; } @@ -1369,24 +1428,67 @@ struct quarkoniaToHyperons { { // fill QA information about hyperon - antihyperon pair if (type == 0) { if constexpr (requires { hyperon.mK0Short(); antiHyperon.mK0Short(); }) { // check if v0 information is available - auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); - auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + + float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassKaonNeutral / (hyperon.p() + 1E-10); + float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassKaonNeutral / (antiHyperon.p() + 1E-10); + + // Candidates after K0s selections + histos.fill(HIST("K0sK0s/K0s/hPosDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("K0sK0s/K0s/hNegDCAToPV"), hyperon.dcanegtopv()); + histos.fill(HIST("K0sK0s/K0s/hDCAV0Daughters"), hyperon.dcaV0daughters()); + histos.fill(HIST("K0sK0s/K0s/hDCAV0ToPV"), hyperon.dcav0topv()); + histos.fill(HIST("K0sK0s/K0s/hV0PointingAngle"), hyperon.v0cosPA()); + histos.fill(HIST("K0sK0s/K0s/hV0Radius"), hyperon.v0radius()); + histos.fill(HIST("K0sK0s/K0s/hV0DecayLength"), hyperonDecayLength); + histos.fill(HIST("K0sK0s/K0s/hV0InvMassWindow"), hyperon.mK0Short() - o2::constants::physics::MassK0Short); + histos.fill(HIST("K0sK0s/K0s/h2dCompetingMassRej"), hyperon.mLambda(), hyperon.mK0Short()); + histos.fill(HIST("K0sK0s/K0s/h2dArmenteros"), hyperon.alpha(), hyperon.qtarm()); // cross-check + histos.fill(HIST("K0sK0s/K0s/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPi()); + histos.fill(HIST("K0sK0s/K0s/hNegTPCNsigma"), negTrackExtraHyperon.tpcNSigmaPi()); + histos.fill(HIST("K0sK0s/K0s/h2dPositiveITSvsTPCpts"), posTrackExtraHyperon.tpcCrossedRows(), posTrackExtraHyperon.itsNCls()); + histos.fill(HIST("K0sK0s/K0s/h2dNegativeITSvsTPCpts"), negTrackExtraHyperon.tpcCrossedRows(), negTrackExtraHyperon.itsNCls()); + // Candidates after K0s selections + histos.fill(HIST("K0sK0s/K0s/hPosDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("K0sK0s/K0s/hNegDCAToPV"), antiHyperon.dcanegtopv()); + histos.fill(HIST("K0sK0s/K0s/hDCAV0Daughters"), antiHyperon.dcaV0daughters()); + histos.fill(HIST("K0sK0s/K0s/hDCAV0ToPV"), antiHyperon.dcav0topv()); + histos.fill(HIST("K0sK0s/K0s/hV0PointingAngle"), antiHyperon.v0cosPA()); + histos.fill(HIST("K0sK0s/K0s/hV0Radius"), antiHyperon.v0radius()); + histos.fill(HIST("K0sK0s/K0s/hV0DecayLength"), antiHyperonDecayLength); + histos.fill(HIST("K0sK0s/K0s/hV0InvMassWindow"), antiHyperon.mK0Short() - o2::constants::physics::MassK0Short); + histos.fill(HIST("K0sK0s/K0s/h2dCompetingMassRej"), antiHyperon.mLambda(), antiHyperon.mK0Short()); + histos.fill(HIST("K0sK0s/K0s/h2dArmenteros"), antiHyperon.alpha(), antiHyperon.qtarm()); // cross-check + histos.fill(HIST("K0sK0s/K0s/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); + histos.fill(HIST("K0sK0s/K0s/hNegTPCNsigma"), negTrackExtraAntiHyperon.tpcNSigmaPi()); + histos.fill(HIST("K0sK0s/K0s/h2dPositiveITSvsTPCpts"), posTrackExtraAntiHyperon.tpcCrossedRows(), posTrackExtraAntiHyperon.itsNCls()); + histos.fill(HIST("K0sK0s/K0s/h2dNegativeITSvsTPCpts"), negTrackExtraAntiHyperon.tpcCrossedRows(), negTrackExtraAntiHyperon.itsNCls()); + } + } + if (type == 1) { + if constexpr (requires { hyperon.mK0Short(); antiHyperon.mK0Short(); }) { // check if v0 information is available + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); - auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); - auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassLambda0 / (hyperon.p() + 1E-10); float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassLambda0 / (antiHyperon.p() + 1E-10); // Candidates after Lambda selections histos.fill(HIST("LaLaBar/Lambda/hPosDCAToPV"), hyperon.dcapostopv()); - histos.fill(HIST("LaLaBar/Lambda/hNegDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("LaLaBar/Lambda/hNegDCAToPV"), hyperon.dcanegtopv()); histos.fill(HIST("LaLaBar/Lambda/hDCAV0Daughters"), hyperon.dcaV0daughters()); histos.fill(HIST("LaLaBar/Lambda/hDCAV0ToPV"), hyperon.dcav0topv()); histos.fill(HIST("LaLaBar/Lambda/hV0PointingAngle"), hyperon.v0cosPA()); histos.fill(HIST("LaLaBar/Lambda/hV0Radius"), hyperon.v0radius()); histos.fill(HIST("LaLaBar/Lambda/hV0DecayLength"), hyperonDecayLength); - histos.fill(HIST("LaLaBar/Lambda/hV0InvMassWindow"), hyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("LaLaBar/Lambda/hV0InvMassWindow"), hyperon.mLambda() - o2::constants::physics::MassLambda0); histos.fill(HIST("LaLaBar/Lambda/h2dCompetingMassRej"), hyperon.mLambda(), hyperon.mK0Short()); histos.fill(HIST("LaLaBar/Lambda/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPr()); histos.fill(HIST("LaLaBar/Lambda/hNegTPCNsigma"), negTrackExtraHyperon.tpcNSigmaPi()); @@ -1400,7 +1502,7 @@ struct quarkoniaToHyperons { histos.fill(HIST("LaLaBar/AntiLambda/hV0PointingAngle"), antiHyperon.v0cosPA()); histos.fill(HIST("LaLaBar/AntiLambda/hV0Radius"), antiHyperon.v0radius()); histos.fill(HIST("LaLaBar/AntiLambda/hV0DecayLength"), antiHyperonDecayLength); - histos.fill(HIST("LaLaBar/AntiLambda/hV0InvMassWindow"), antiHyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("LaLaBar/AntiLambda/hV0InvMassWindow"), antiHyperon.mLambda() - o2::constants::physics::MassLambda0); histos.fill(HIST("LaLaBar/AntiLambda/h2dCompetingMassRej"), antiHyperon.mLambda(), antiHyperon.mK0Short()); histos.fill(HIST("LaLaBar/AntiLambda/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); histos.fill(HIST("LaLaBar/AntiLambda/hNegTPCNsigma"), negTrackExtraAntiHyperon.tpcNSigmaPr()); @@ -1408,15 +1510,15 @@ struct quarkoniaToHyperons { histos.fill(HIST("LaLaBar/AntiLambda/h2dNegativeITSvsTPCpts"), negTrackExtraAntiHyperon.tpcCrossedRows(), negTrackExtraAntiHyperon.itsNCls()); } } - if (type == 1) { + if (type == 2) { if constexpr (requires { hyperon.dcabachtopv(); antiHyperon.dcabachtopv(); }) { // check if Cascade information is available - auto bachTrackExtraHyperon = hyperon.template bachTrackExtra_as(); - auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); - auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + auto bachTrackExtraHyperon = hyperon.template bachTrackExtra_as(); + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); - auto bachTrackExtraAntiHyperon = antiHyperon.template bachTrackExtra_as(); - auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); - auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + auto bachTrackExtraAntiHyperon = antiHyperon.template bachTrackExtra_as(); + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassXiMinus / (hyperon.p() + 1E-10); float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassXiMinus / (antiHyperon.p() + 1E-10); @@ -1424,7 +1526,7 @@ struct quarkoniaToHyperons { // Candidates after Xi selections histos.fill(HIST("XiXiBar/Xi/hBachDCAToPV"), hyperon.dcabachtopv()); histos.fill(HIST("XiXiBar/Xi/hPosDCAToPV"), hyperon.dcapostopv()); - histos.fill(HIST("XiXiBar/Xi/hNegDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("XiXiBar/Xi/hNegDCAToPV"), hyperon.dcanegtopv()); histos.fill(HIST("XiXiBar/Xi/hDCACascDaughters"), hyperon.dcacascdaughters()); histos.fill(HIST("XiXiBar/Xi/hDCAV0Daughters"), hyperon.dcaV0daughters()); histos.fill(HIST("XiXiBar/Xi/hDCAV0ToPV"), hyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); @@ -1433,8 +1535,8 @@ struct quarkoniaToHyperons { histos.fill(HIST("XiXiBar/Xi/hCascPointingAngle"), hyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); histos.fill(HIST("XiXiBar/Xi/hCascRadius"), hyperon.cascradius()); histos.fill(HIST("XiXiBar/Xi/hCascDecayLength"), hyperonDecayLength); - histos.fill(HIST("XiXiBar/Xi/hV0InvMassWindow"), hyperon.mLambda() - pdgDB->Mass(3122)); - histos.fill(HIST("XiXiBar/Xi/hCascInvMassWindow"), hyperon.mXi() - pdgDB->Mass(3312)); + histos.fill(HIST("XiXiBar/Xi/hV0InvMassWindow"), hyperon.mLambda() - o2::constants::physics::MassLambda0); + histos.fill(HIST("XiXiBar/Xi/hCascInvMassWindow"), hyperon.mXi() - o2::constants::physics::MassXiMinus); histos.fill(HIST("XiXiBar/Xi/h2dCompetingMassRej"), hyperon.mXi(), hyperon.mOmega()); histos.fill(HIST("XiXiBar/Xi/hBachTPCNsigma"), bachTrackExtraHyperon.tpcNSigmaPi()); histos.fill(HIST("XiXiBar/Xi/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPr()); @@ -1445,7 +1547,7 @@ struct quarkoniaToHyperons { // Candidates after AntiXi selections histos.fill(HIST("XiXiBar/AntiXi/hBachDCAToPV"), antiHyperon.dcabachtopv()); histos.fill(HIST("XiXiBar/AntiXi/hPosDCAToPV"), antiHyperon.dcapostopv()); - histos.fill(HIST("XiXiBar/AntiXi/hNegDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("XiXiBar/AntiXi/hNegDCAToPV"), antiHyperon.dcanegtopv()); histos.fill(HIST("XiXiBar/AntiXi/hDCACascDaughters"), antiHyperon.dcacascdaughters()); histos.fill(HIST("XiXiBar/AntiXi/hDCAV0Daughters"), antiHyperon.dcaV0daughters()); histos.fill(HIST("XiXiBar/AntiXi/hDCAV0ToPV"), antiHyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); @@ -1454,8 +1556,8 @@ struct quarkoniaToHyperons { histos.fill(HIST("XiXiBar/AntiXi/hCascPointingAngle"), antiHyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); histos.fill(HIST("XiXiBar/AntiXi/hCascRadius"), antiHyperon.cascradius()); histos.fill(HIST("XiXiBar/AntiXi/hCascDecayLength"), antiHyperonDecayLength); - histos.fill(HIST("XiXiBar/AntiXi/hV0InvMassWindow"), antiHyperon.mLambda() - pdgDB->Mass(3122)); - histos.fill(HIST("XiXiBar/AntiXi/hCascInvMassWindow"), antiHyperon.mXi() - pdgDB->Mass(3312)); + histos.fill(HIST("XiXiBar/AntiXi/hV0InvMassWindow"), antiHyperon.mLambda() - o2::constants::physics::MassLambda0); + histos.fill(HIST("XiXiBar/AntiXi/hCascInvMassWindow"), antiHyperon.mXi() - o2::constants::physics::MassXiMinus); histos.fill(HIST("XiXiBar/AntiXi/h2dCompetingMassRej"), antiHyperon.mXi(), antiHyperon.mOmega()); histos.fill(HIST("XiXiBar/AntiXi/hBachTPCNsigma"), bachTrackExtraAntiHyperon.tpcNSigmaPi()); histos.fill(HIST("XiXiBar/AntiXi/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); @@ -1465,15 +1567,15 @@ struct quarkoniaToHyperons { histos.fill(HIST("XiXiBar/AntiXi/h2dNegativeITSvsTPCpts"), negTrackExtraAntiHyperon.tpcCrossedRows(), negTrackExtraAntiHyperon.itsNCls()); } } - if (type == 2) { + if (type == 3) { if constexpr (requires { hyperon.dcabachtopv(); antiHyperon.dcabachtopv(); }) { // check if Cascade information is available - auto bachTrackExtraHyperon = hyperon.template bachTrackExtra_as(); - auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); - auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + auto bachTrackExtraHyperon = hyperon.template bachTrackExtra_as(); + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); - auto bachTrackExtraAntiHyperon = antiHyperon.template bachTrackExtra_as(); - auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); - auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + auto bachTrackExtraAntiHyperon = antiHyperon.template bachTrackExtra_as(); + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassOmegaMinus / (hyperon.p() + 1E-10); float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassOmegaMinus / (antiHyperon.p() + 1E-10); @@ -1481,7 +1583,7 @@ struct quarkoniaToHyperons { // Candidates after Omega selections histos.fill(HIST("OmOmBar/Omega/hBachDCAToPV"), hyperon.dcabachtopv()); histos.fill(HIST("OmOmBar/Omega/hPosDCAToPV"), hyperon.dcapostopv()); - histos.fill(HIST("OmOmBar/Omega/hNegDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("OmOmBar/Omega/hNegDCAToPV"), hyperon.dcanegtopv()); histos.fill(HIST("OmOmBar/Omega/hDCACascDaughters"), hyperon.dcacascdaughters()); histos.fill(HIST("OmOmBar/Omega/hDCAV0Daughters"), hyperon.dcaV0daughters()); histos.fill(HIST("OmOmBar/Omega/hDCAV0ToPV"), hyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); @@ -1490,8 +1592,8 @@ struct quarkoniaToHyperons { histos.fill(HIST("OmOmBar/Omega/hCascPointingAngle"), hyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); histos.fill(HIST("OmOmBar/Omega/hCascRadius"), hyperon.cascradius()); histos.fill(HIST("OmOmBar/Omega/hCascDecayLength"), hyperonDecayLength); - histos.fill(HIST("OmOmBar/Omega/hV0InvMassWindow"), hyperon.mLambda() - pdgDB->Mass(3122)); - histos.fill(HIST("OmOmBar/Omega/hCascInvMassWindow"), hyperon.mOmega() - pdgDB->Mass(3334)); + histos.fill(HIST("OmOmBar/Omega/hV0InvMassWindow"), hyperon.mLambda() - o2::constants::physics::MassLambda0); + histos.fill(HIST("OmOmBar/Omega/hCascInvMassWindow"), hyperon.mOmega() - o2::constants::physics::MassOmegaMinus); histos.fill(HIST("OmOmBar/Omega/h2dCompetingMassRej"), hyperon.mXi(), hyperon.mOmega()); histos.fill(HIST("OmOmBar/Omega/hBachTPCNsigma"), bachTrackExtraHyperon.tpcNSigmaKa()); histos.fill(HIST("OmOmBar/Omega/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPr()); @@ -1502,7 +1604,7 @@ struct quarkoniaToHyperons { // Candidates after AntiOmega selections histos.fill(HIST("OmOmBar/AntiOmega/hBachDCAToPV"), antiHyperon.dcabachtopv()); histos.fill(HIST("OmOmBar/AntiOmega/hPosDCAToPV"), antiHyperon.dcapostopv()); - histos.fill(HIST("OmOmBar/AntiOmega/hNegDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("OmOmBar/AntiOmega/hNegDCAToPV"), antiHyperon.dcanegtopv()); histos.fill(HIST("OmOmBar/AntiOmega/hDCACascDaughters"), antiHyperon.dcacascdaughters()); histos.fill(HIST("OmOmBar/AntiOmega/hDCAV0Daughters"), antiHyperon.dcaV0daughters()); histos.fill(HIST("OmOmBar/AntiOmega/hDCAV0ToPV"), antiHyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); @@ -1511,8 +1613,8 @@ struct quarkoniaToHyperons { histos.fill(HIST("OmOmBar/AntiOmega/hCascPointingAngle"), antiHyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); histos.fill(HIST("OmOmBar/AntiOmega/hCascRadius"), antiHyperon.cascradius()); histos.fill(HIST("OmOmBar/AntiOmega/hCascDecayLength"), antiHyperonDecayLength); - histos.fill(HIST("OmOmBar/AntiOmega/hV0InvMassWindow"), antiHyperon.mLambda() - pdgDB->Mass(3122)); - histos.fill(HIST("OmOmBar/AntiOmega/hCascInvMassWindow"), antiHyperon.mOmega() - pdgDB->Mass(3334)); + histos.fill(HIST("OmOmBar/AntiOmega/hV0InvMassWindow"), antiHyperon.mLambda() - o2::constants::physics::MassLambda0); + histos.fill(HIST("OmOmBar/AntiOmega/hCascInvMassWindow"), antiHyperon.mOmega() - o2::constants::physics::MassOmegaMinus); histos.fill(HIST("OmOmBar/AntiOmega/h2dCompetingMassRej"), antiHyperon.mXi(), antiHyperon.mOmega()); histos.fill(HIST("OmOmBar/AntiOmega/hBachTPCNsigma"), bachTrackExtraAntiHyperon.tpcNSigmaKa()); histos.fill(HIST("OmOmBar/AntiOmega/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); @@ -1533,16 +1635,18 @@ struct quarkoniaToHyperons { float invmass = -1; if (type == 0) - invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassLambda0, o2::constants::physics::MassLambda0Bar}); + invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassKaonNeutral, o2::constants::physics::MassKaonNeutral}); if (type == 1) - invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassXiPlusBar}); + invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassLambda0, o2::constants::physics::MassLambda0Bar}); if (type == 2) + invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassXiPlusBar}); + if (type == 3) invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassOmegaPlusBar}); float rapidity = RecoDecay::y(std::array{hyperon.px() + antiHyperon.px(), hyperon.py() + antiHyperon.py(), hyperon.pz() + antiHyperon.pz()}, invmass); // rapidity cut on the quarkonium mother - if (!doMCAssociation && TMath::Abs(rapidity) > rapidityCut) + if (!doMCAssociation && std::fabs(rapidity) > rapidityCut) return; // fillV0sInfo(lambda, antiLambda, centrality); @@ -1562,7 +1666,63 @@ struct quarkoniaToHyperons { float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); - if (TMath::Abs(rapiditymc) > rapidityCut) + if (std::fabs(rapiditymc) > rapidityCut) + return; + + if (hyperonMC.pdgCodeMother() == 441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(1S) + histos.fill(HIST("K0sK0s/h3dInvMassTrueEtaC1S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // J/psi + histos.fill(HIST("K0sK0s/h3dInvMassTrueJPsi"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 10441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC0 + histos.fill(HIST("K0sK0s/h3dInvMassTrueChiC0"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 20443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC1 + histos.fill(HIST("K0sK0s/h3dInvMassTrueChiC1"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 10443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // hC + histos.fill(HIST("K0sK0s/h3dInvMassTrueHC"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 445 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC2 + histos.fill(HIST("K0sK0s/h3dInvMassTrueChiC2"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(2S) + histos.fill(HIST("K0sK0s/h3dInvMassTrueEtaC2S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // Psi(2S) + histos.fill(HIST("K0sK0s/h3dInvMassTruePsi2S"), centrality, ptmc, invmass); + } + } + } + + histos.fill(HIST("K0sK0s/h3dMassK0sK0s"), centrality, pt, invmass); + if (!isPP) { // in case of PbPb data + if (gapSide == 0) + histos.fill(HIST("K0sK0s/h3dMassK0sK0sSGA"), centrality, pt, invmass); + else if (gapSide == 1) + histos.fill(HIST("K0sK0s/h3dMassK0sK0sSGC"), centrality, pt, invmass); + else if (gapSide == 2) + histos.fill(HIST("K0sK0s/h3dMassK0sK0sDG"), centrality, pt, invmass); + else + histos.fill(HIST("K0sK0s/h3dMassK0sK0sHadronic"), centrality, pt, invmass); + } + fillQAplot(collision, hyperon, antiHyperon, type); + } + if (type == 1) { + if (doMCAssociation) { + if constexpr (requires { hyperon.template v0MCCore_as>(); }) { // check if MC information is available + auto hyperonMC = hyperon.template v0MCCore_as>(); + auto antiHyperonMC = antiHyperon.template v0MCCore_as>(); + + if (hyperonMC.pdgCodeMother() != antiHyperonMC.pdgCodeMother()) { + return; + } + + float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); + float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); + + if (std::fabs(rapiditymc) > rapidityCut) return; if (hyperonMC.pdgCodeMother() == 441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(1S) @@ -1603,9 +1763,9 @@ struct quarkoniaToHyperons { else histos.fill(HIST("LaLaBar/h3dMassLaLabarHadronic"), centrality, pt, invmass); } - fillQAplot(collision, hyperon, antiHyperon, 0); + fillQAplot(collision, hyperon, antiHyperon, type); } - if (type == 1) { + if (type == 2) { if (doMCAssociation) { if constexpr (requires { hyperon.template cascMCCore_as>(); }) { // check if MC information is available auto hyperonMC = hyperon.template cascMCCore_as>(); @@ -1618,7 +1778,7 @@ struct quarkoniaToHyperons { float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); - if (TMath::Abs(rapiditymc) > rapidityCut) + if (std::fabs(rapiditymc) > rapidityCut) return; if (hyperonMC.pdgCodeMother() == 441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(1S) @@ -1659,9 +1819,9 @@ struct quarkoniaToHyperons { else histos.fill(HIST("XiXiBar/h3dMassXiXibarHadronic"), centrality, pt, invmass); } - fillQAplot(collision, hyperon, antiHyperon, 1); + fillQAplot(collision, hyperon, antiHyperon, type); } - if (type == 2) { + if (type == 3) { if (doMCAssociation) { if constexpr (requires { hyperon.template cascMCCore_as>(); }) { // check if MC information is available auto hyperonMC = hyperon.template cascMCCore_as>(); @@ -1674,7 +1834,7 @@ struct quarkoniaToHyperons { float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); - if (TMath::Abs(rapiditymc) > rapidityCut) + if (std::fabs(rapiditymc) > rapidityCut) return; if (hyperonMC.pdgCodeMother() == 100441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(2S) @@ -1697,7 +1857,7 @@ struct quarkoniaToHyperons { else histos.fill(HIST("OmOmBar/h3dMassOmOmbarHadronic"), centrality, pt, invmass); } - fillQAplot(collision, hyperon, antiHyperon, 2); + fillQAplot(collision, hyperon, antiHyperon, type); } } @@ -1705,7 +1865,7 @@ struct quarkoniaToHyperons { template bool checkTrackIndices(THyperon hyperon, THyperon antiHyperon) { - if constexpr (requires { hyperon.template bachTrackExtra_as(); }) { // cascade case: check if bachelor information is available + if constexpr (requires { hyperon.template bachTrackExtra_as(); }) { // cascade case: check if bachelor information is available // check that bachelor track from hyperon is different from daughter tracks of antiHyperon if (hyperon.bachTrackExtraId() == antiHyperon.bachTrackExtraId() || hyperon.bachTrackExtraId() == antiHyperon.posTrackExtraId() || @@ -1738,14 +1898,14 @@ struct quarkoniaToHyperons { void buildHyperonAntiHyperonPairs(TCollision const& collision, THyperons const& fullHyperons, std::vector selHypIndices, std::vector selAntiHypIndices, float centrality, uint8_t gapSide, int type) { // 1st loop over all v0s/cascades - for (auto& hyperon : fullHyperons) { + for (const auto& hyperon : fullHyperons) { // select only v0s matching Lambda selections if (!selHypIndices[hyperon.globalIndex() - fullHyperons.offset()]) { // local index needed due to collisions grouping continue; } // 2nd loop over all v0s/cascade - for (auto& antiHyperon : fullHyperons) { + for (const auto& antiHyperon : fullHyperons) { // select only v0s matching Anti-Lambda selections if (!selAntiHypIndices[antiHyperon.globalIndex() - fullHyperons.offset()]) { // local index needed due to collisions grouping continue; @@ -1771,7 +1931,7 @@ struct quarkoniaToHyperons { // ______________________________________________________ // Real data processing - no MC subscription - void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, cascadeCandidates const& fullCascades, dauTracks const&) + void processRealData(soa::Join::iterator const& collision, V0Candidates const& fullV0s, CascadeCandidates const& fullCascades, DauTracks const&) { // Fire up CCDB if (cfgSkimmedProcessing || @@ -1781,7 +1941,7 @@ struct quarkoniaToHyperons { initCCDB(collision); } - if (!IsEventAccepted(collision, true)) { + if (!isEventAccepted(collision, true)) { return; } @@ -1796,11 +1956,11 @@ struct quarkoniaToHyperons { // __________________________________________ // perform main analysis // - if (buildLaLaBarPairs) { // Look at V0s + if (buildK0sK0sPairs || buildLaLaBarPairs) { // Look at V0s std::vector selK0ShortIndices(fullV0s.size()); std::vector selLambdaIndices(fullV0s.size()); std::vector selAntiLambdaIndices(fullV0s.size()); - for (auto& v0 : fullV0s) { + for (const auto& v0 : fullV0s) { if (std::abs(v0.negativeeta()) > v0Selections.daughterEtaCut || std::abs(v0.positiveeta()) > v0Selections.daughterEtaCut) continue; // remove acceptance that's badly reproduced by MC / superfluous in future @@ -1810,8 +1970,8 @@ struct quarkoniaToHyperons { uint64_t selMap = computeReconstructionBitmap(v0, collision, v0.yLambda(), v0.yK0Short(), v0.pt()); // consider for histograms for all species - selMap = selMap | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selConsiderAntiLambda); - selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda); + selMap = selMap | (static_cast(1) << selConsiderK0Short) | (static_cast(1) << selConsiderLambda) | (static_cast(1) << selConsiderAntiLambda); + selMap = selMap | (static_cast(1) << selPhysPrimK0Short) | (static_cast(1) << selPhysPrimLambda) | (static_cast(1) << selPhysPrimAntiLambda); analyseV0Candidate(v0, v0.pt(), selMap, selK0ShortIndices, selLambdaIndices, selAntiLambdaIndices, fullV0s.offset()); } // end v0 loop @@ -1821,21 +1981,33 @@ struct quarkoniaToHyperons { int nLambdas = std::count(selLambdaIndices.begin(), selLambdaIndices.end(), true); int nAntiLambdas = std::count(selAntiLambdaIndices.begin(), selAntiLambdaIndices.end(), true); - // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision - histos.fill(HIST("LaLaBar/h2dNbrOfK0ShortVsCentrality"), centrality, nK0Shorts); - histos.fill(HIST("LaLaBar/h2dNbrOfLambdaVsCentrality"), centrality, nLambdas); - histos.fill(HIST("LaLaBar/h2dNbrOfAntiLambdaVsCentrality"), centrality, nAntiLambdas); - - // Check the number of Lambdas and antiLambdas - // needs at least 1 of each - if (!buildSameSignPairs && nLambdas >= 1 && nAntiLambdas >= 1) { // consider Lambda antiLambda pairs - buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 0); - } - if (buildSameSignPairs && nLambdas > 1) { // consider Lambda Lambda pairs - buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selLambdaIndices, centrality, selGapSide, 0); + if (buildK0sK0sPairs) { + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + histos.fill(HIST("K0sK0s/h2dNbrOfK0ShortVsCentrality"), centrality, nK0Shorts); + + // Check the number of K0Short + // needs at least 2 to form K0s-K0s pairs + if (nK0Shorts >= 2) { // consider K0s K0s pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selK0ShortIndices, selK0ShortIndices, centrality, selGapSide, 0); + } } - if (buildSameSignPairs && nAntiLambdas > 1) { // consider antiLambda antiLambda pairs - buildHyperonAntiHyperonPairs(collision, fullV0s, selAntiLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 0); + + if (buildLaLaBarPairs) { + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + histos.fill(HIST("LaLaBar/h2dNbrOfLambdaVsCentrality"), centrality, nLambdas); + histos.fill(HIST("LaLaBar/h2dNbrOfAntiLambdaVsCentrality"), centrality, nAntiLambdas); + + // Check the number of Lambdas and antiLambdas + // needs at least 1 of each + if (!buildSameSignPairs && nLambdas >= 1 && nAntiLambdas >= 1) { // consider Lambda antiLambda pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 1); + } + if (buildSameSignPairs && nLambdas > 1) { // consider Lambda Lambda pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selLambdaIndices, centrality, selGapSide, 1); + } + if (buildSameSignPairs && nAntiLambdas > 1) { // consider antiLambda antiLambda pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selAntiLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 1); + } } } @@ -1844,7 +2016,7 @@ struct quarkoniaToHyperons { std::vector selAntiXiIndices(fullCascades.size()); std::vector selOmIndices(fullCascades.size()); std::vector selAntiOmIndices(fullCascades.size()); - for (auto& cascade : fullCascades) { + for (const auto& cascade : fullCascades) { if (std::abs(cascade.negativeeta()) > cascSelections.daughterEtaCut || std::abs(cascade.positiveeta()) > cascSelections.daughterEtaCut || std::abs(cascade.bacheloreta()) > cascSelections.daughterEtaCut) @@ -1880,13 +2052,13 @@ struct quarkoniaToHyperons { // Check the number of Lambdas and antiLambdas // needs at least 1 of each if (!buildSameSignPairs && nXis >= 1 && nAntiXis >= 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selAntiXiIndices, centrality, selGapSide, 1); + buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selAntiXiIndices, centrality, selGapSide, 2); } if (buildSameSignPairs && nXis > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selXiIndices, centrality, selGapSide, 1); + buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selXiIndices, centrality, selGapSide, 2); } if (buildSameSignPairs && nAntiXis > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiXiIndices, selAntiXiIndices, centrality, selGapSide, 1); + buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiXiIndices, selAntiXiIndices, centrality, selGapSide, 2); } } if (buildOmOmBarPairs) { @@ -1896,13 +2068,13 @@ struct quarkoniaToHyperons { // Check the number of Lambdas and antiLambdas // needs at least 1 of each if (!buildSameSignPairs && nOmegas >= 1 && nAntiOmegas >= 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selAntiOmIndices, centrality, selGapSide, 2); + buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selAntiOmIndices, centrality, selGapSide, 3); } if (buildSameSignPairs && nOmegas > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selOmIndices, centrality, selGapSide, 2); + buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selOmIndices, centrality, selGapSide, 3); } if (buildSameSignPairs && nAntiOmegas > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiOmIndices, selAntiOmIndices, centrality, selGapSide, 2); + buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiOmIndices, selAntiOmIndices, centrality, selGapSide, 3); } } } @@ -1910,7 +2082,7 @@ struct quarkoniaToHyperons { // ______________________________________________________ // Simulated processing (subscribes to MC information too) - void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, cascadeMCCandidates const& fullCascades, dauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&, soa::Join const&) + void processMonteCarlo(soa::Join::iterator const& collision, V0MCCandidates const& fullV0s, CascadeMCCandidates const& fullCascades, DauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&, soa::Join const&) { // Fire up CCDB if (cfgSkimmedProcessing || @@ -1920,7 +2092,7 @@ struct quarkoniaToHyperons { initCCDB(collision); } - if (!IsEventAccepted(collision, true)) { + if (!isEventAccepted(collision, true)) { return; } @@ -1934,11 +2106,11 @@ struct quarkoniaToHyperons { // __________________________________________ // perform main analysis - if (buildLaLaBarPairs) { // Look at V0s + if (buildK0sK0sPairs || buildLaLaBarPairs) { // Look at V0s std::vector selK0ShortIndices(fullV0s.size()); std::vector selLambdaIndices(fullV0s.size()); std::vector selAntiLambdaIndices(fullV0s.size()); - for (auto& v0 : fullV0s) { + for (const auto& v0 : fullV0s) { if (std::abs(v0.negativeeta()) > v0Selections.daughterEtaCut || std::abs(v0.positiveeta()) > v0Selections.daughterEtaCut) continue; // remove acceptance that's badly reproduced by MC / superfluous in future @@ -1951,7 +2123,7 @@ struct quarkoniaToHyperons { float ymc = 1e-3; if (v0MC.pdgCode() == 310) ymc = RecoDecay::y(std::array{v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC(), v0MC.pzPosMC() + v0MC.pzNegMC()}, o2::constants::physics::MassKaonNeutral); - else if (TMath::Abs(v0MC.pdgCode()) == 3122) + else if (std::fabs(v0MC.pdgCode()) == 3122) ymc = RecoDecay::y(std::array{v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC(), v0MC.pzPosMC() + v0MC.pzNegMC()}, o2::constants::physics::MassLambda); uint64_t selMap = computeReconstructionBitmap(v0, collision, ymc, ymc, ptmc); @@ -1959,8 +2131,8 @@ struct quarkoniaToHyperons { // consider only associated candidates if asked to do so, disregard association if (!doMCAssociation) { - selMap = selMap | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selConsiderAntiLambda); - selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda); + selMap = selMap | (static_cast(1) << selConsiderK0Short) | (static_cast(1) << selConsiderLambda) | (static_cast(1) << selConsiderAntiLambda); + selMap = selMap | (static_cast(1) << selPhysPrimK0Short) | (static_cast(1) << selPhysPrimLambda) | (static_cast(1) << selPhysPrimAntiLambda); } analyseV0Candidate(v0, ptmc, selMap, selK0ShortIndices, selLambdaIndices, selAntiLambdaIndices, fullV0s.offset()); @@ -1971,19 +2143,31 @@ struct quarkoniaToHyperons { int nLambdas = std::count(selLambdaIndices.begin(), selLambdaIndices.end(), true); int nAntiLambdas = std::count(selAntiLambdaIndices.begin(), selAntiLambdaIndices.end(), true); - // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision - histos.fill(HIST("LaLaBar/h2dNbrOfK0ShortVsCentrality"), centrality, nK0Shorts); - histos.fill(HIST("LaLaBar/h2dNbrOfLambdaVsCentrality"), centrality, nLambdas); - histos.fill(HIST("LaLaBar/h2dNbrOfAntiLambdaVsCentrality"), centrality, nAntiLambdas); + if (buildK0sK0sPairs) { + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + histos.fill(HIST("K0sK0s/h2dNbrOfK0ShortVsCentrality"), centrality, nK0Shorts); - if (!buildSameSignPairs && nLambdas >= 1 && nAntiLambdas >= 1) { // consider Lambda antiLambda pairs - buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 0); - } - if (buildSameSignPairs && nLambdas > 1) { // consider Lambda Lambda pairs - buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selLambdaIndices, centrality, selGapSide, 0); + // Check the number of K0Short + // needs at least 2 to form K0s-K0s pairs + if (nK0Shorts >= 2) { // consider K0s K0s pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selK0ShortIndices, selK0ShortIndices, centrality, selGapSide, 0); + } } - if (buildSameSignPairs && nAntiLambdas > 1) { // consider antiLambda antiLambda pairs - buildHyperonAntiHyperonPairs(collision, fullV0s, selAntiLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 0); + + if (buildLaLaBarPairs) { + // fill the histograms with the number of reconstructed Lambda/antiLambda per collision + histos.fill(HIST("LaLaBar/h2dNbrOfLambdaVsCentrality"), centrality, nLambdas); + histos.fill(HIST("LaLaBar/h2dNbrOfAntiLambdaVsCentrality"), centrality, nAntiLambdas); + + if (!buildSameSignPairs && nLambdas >= 1 && nAntiLambdas >= 1) { // consider Lambda antiLambda pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 1); + } + if (buildSameSignPairs && nLambdas > 1) { // consider Lambda Lambda pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selLambdaIndices, centrality, selGapSide, 1); + } + if (buildSameSignPairs && nAntiLambdas > 1) { // consider antiLambda antiLambda pairs + buildHyperonAntiHyperonPairs(collision, fullV0s, selAntiLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 1); + } } } @@ -1992,7 +2176,7 @@ struct quarkoniaToHyperons { std::vector selAntiXiIndices(fullCascades.size()); std::vector selOmIndices(fullCascades.size()); std::vector selAntiOmIndices(fullCascades.size()); - for (auto& cascade : fullCascades) { + for (const auto& cascade : fullCascades) { if (std::abs(cascade.negativeeta()) > cascSelections.daughterEtaCut || std::abs(cascade.positiveeta()) > cascSelections.daughterEtaCut || std::abs(cascade.bacheloreta()) > cascSelections.daughterEtaCut) @@ -2004,9 +2188,9 @@ struct quarkoniaToHyperons { auto cascadeMC = cascade.cascMCCore_as>(); float ymc = 1e-3; - if (TMath::Abs(cascadeMC.pdgCode()) == 3312) + if (std::fabs(cascadeMC.pdgCode()) == 3312) ymc = RecoDecay::y(std::array{cascadeMC.pxMC(), cascadeMC.pyMC(), cascadeMC.pzMC()}, o2::constants::physics::MassXiMinus); - else if (TMath::Abs(cascadeMC.pdgCode()) == 3334) + else if (std::fabs(cascadeMC.pdgCode()) == 3334) ymc = RecoDecay::y(std::array{cascadeMC.pxMC(), cascadeMC.pyMC(), cascadeMC.pzMC()}, o2::constants::physics::MassOmegaMinus); if (buildXiXiBarPairs) { @@ -2039,13 +2223,13 @@ struct quarkoniaToHyperons { // Check the number of Lambdas and antiLambdas // needs at least 1 of each if (!buildSameSignPairs && nXis >= 1 && nAntiXis >= 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selAntiXiIndices, centrality, selGapSide, 1); + buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selAntiXiIndices, centrality, selGapSide, 2); } if (buildSameSignPairs && nXis > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selXiIndices, centrality, selGapSide, 1); + buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selXiIndices, centrality, selGapSide, 2); } if (buildSameSignPairs && nAntiXis > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiXiIndices, selAntiXiIndices, centrality, selGapSide, 1); + buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiXiIndices, selAntiXiIndices, centrality, selGapSide, 2); } } if (buildOmOmBarPairs) { @@ -2055,24 +2239,24 @@ struct quarkoniaToHyperons { // Check the number of Lambdas and antiLambdas // needs at least 1 of each if (!buildSameSignPairs && nOmegas >= 1 && nAntiOmegas >= 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selAntiOmIndices, centrality, selGapSide, 2); + buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selAntiOmIndices, centrality, selGapSide, 3); } if (buildSameSignPairs && nOmegas > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selOmIndices, centrality, selGapSide, 2); + buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selOmIndices, centrality, selGapSide, 3); } if (buildSameSignPairs && nAntiOmegas > 1) { - buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiOmIndices, selAntiOmIndices, centrality, selGapSide, 2); + buildHyperonAntiHyperonPairs(collision, fullCascades, selAntiOmIndices, selAntiOmIndices, centrality, selGapSide, 3); } } } } - PROCESS_SWITCH(quarkoniaToHyperons, processRealData, "process as if real data", true); - PROCESS_SWITCH(quarkoniaToHyperons, processMonteCarlo, "process as if MC", false); + PROCESS_SWITCH(QuarkoniaToHyperons, processRealData, "process as if real data", true); + PROCESS_SWITCH(QuarkoniaToHyperons, processMonteCarlo, "process as if MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } From 755993fd12df5b1a823b2ac44dcf7a64ba1bb532 Mon Sep 17 00:00:00 2001 From: Rrantu <156880782+Rrantu@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:43:09 +0800 Subject: [PATCH 28/30] =?UTF-8?q?[PWGHF]=20Implementation=20of=20Xic?= =?UTF-8?q?=E2=81=B0=20reconstruction=20using=20the=20Kalman=20Filter=20me?= =?UTF-8?q?thod=20(#9001)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataModel/CandidateReconstructionTables.h | 58 ++ PWGHF/DataModel/CandidateSelectionTables.h | 19 +- PWGHF/TableProducer/CMakeLists.txt | 10 + .../candidateCreatorXic0Omegac0.cxx | 564 +++++++++++++++++- .../candidateSelectorXic0ToXiPiKf.cxx | 560 +++++++++++++++++ .../TableProducer/treeCreatorXic0ToXiPiKf.cxx | 231 +++++++ 6 files changed, 1405 insertions(+), 37 deletions(-) create mode 100644 PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx create mode 100644 PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 15647b2ca9a..009735144a7 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -1258,43 +1258,58 @@ DECLARE_SOA_COLUMN(ErrorDecayLengthXYCharmBaryon, errorDecayLengthXYCharmBaryon, // KFParticle results DECLARE_SOA_COLUMN(KfDcaXYPiFromOmegac, kfDcaXYPiFromOmegac, float); +DECLARE_SOA_COLUMN(KfDcaXYPiFromXic, kfDcaXYPiFromXic, float); DECLARE_SOA_COLUMN(KfDcaXYCascToPv, kfDcaXYCascToPv, float); DECLARE_SOA_COLUMN(Chi2GeoV0, chi2GeoV0, float); DECLARE_SOA_COLUMN(Chi2GeoCasc, chi2GeoCasc, float); DECLARE_SOA_COLUMN(Chi2GeoOmegac, chi2GeoOmegac, float); +DECLARE_SOA_COLUMN(Chi2GeoXic, chi2GeoXic, float); DECLARE_SOA_COLUMN(Chi2MassV0, chi2MassV0, float); DECLARE_SOA_COLUMN(Chi2MassCasc, chi2MassCasc, float); DECLARE_SOA_COLUMN(V0ldl, v0ldl, float); DECLARE_SOA_COLUMN(Cascldl, cascldl, float); DECLARE_SOA_COLUMN(Omegacldl, omegacldl, float); +DECLARE_SOA_COLUMN(Xicldl, xicldl, float); DECLARE_SOA_COLUMN(Chi2TopoV0ToPv, chi2TopoV0ToPv, float); DECLARE_SOA_COLUMN(Chi2TopoCascToPv, chi2TopoCascToPv, float); DECLARE_SOA_COLUMN(Chi2TopoPiFromOmegacToPv, chi2TopoPiFromOmegacToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoPiFromXicToPv, chi2TopoPiFromXicToPv, float); DECLARE_SOA_COLUMN(Chi2TopoOmegacToPv, chi2TopoOmegacToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoXicToPv, chi2TopoXicToPv, float); DECLARE_SOA_COLUMN(Chi2TopoV0ToCasc, chi2TopoV0ToCasc, float); DECLARE_SOA_COLUMN(Chi2TopoCascToOmegac, chi2TopoCascToOmegac, float); +DECLARE_SOA_COLUMN(Chi2TopoCascToXic, chi2TopoCascToXic, float); DECLARE_SOA_COLUMN(DecayLenXYLambda, decayLenXYLambda, float); DECLARE_SOA_COLUMN(DecayLenXYCasc, decayLenXYCasc, float); DECLARE_SOA_COLUMN(DecayLenXYOmegac, decayLenXYOmegac, float); +DECLARE_SOA_COLUMN(DecayLenXYXic, decayLenXYXic, float); DECLARE_SOA_COLUMN(CosPaV0ToCasc, cosPaV0ToCasc, float); DECLARE_SOA_COLUMN(CosPaCascToOmegac, cosPaCascToOmegac, float); +DECLARE_SOA_COLUMN(CosPaCascToXic, cosPaCascToXic, float); DECLARE_SOA_COLUMN(CosPaXYV0ToCasc, cosPaXYV0ToCasc, float); DECLARE_SOA_COLUMN(CosPaXYCascToOmegac, cosPaXYCascToOmegac, float); +DECLARE_SOA_COLUMN(CosPaXYCascToXic, cosPaXYCascToXic, float); DECLARE_SOA_COLUMN(KfMassV0, kfMassV0, float); DECLARE_SOA_COLUMN(KfMassCasc, kfMassCasc, float); DECLARE_SOA_COLUMN(KfMassOmegac, kfMassOmegac, float); DECLARE_SOA_COLUMN(KfRapOmegac, kfRapOmegac, float); +DECLARE_SOA_COLUMN(KfRapXic, kfRapXic, float); DECLARE_SOA_COLUMN(KfptPiFromOmegac, kfptPiFromOmegac, float); +DECLARE_SOA_COLUMN(KfptPiFromXic, kfptPiFromXic, float); DECLARE_SOA_COLUMN(KfptOmegac, kfptOmegac, float); +DECLARE_SOA_COLUMN(KfptXic, kfptXic, float); DECLARE_SOA_COLUMN(CosThetaStarPiFromOmegac, cosThetaStarPiFromOmegac, float); +DECLARE_SOA_COLUMN(CosThetaStarPiFromXic, cosThetaStarPiFromXic, float); DECLARE_SOA_COLUMN(V0Ndf, v0Ndf, float); DECLARE_SOA_COLUMN(CascNdf, cascNdf, float); DECLARE_SOA_COLUMN(OmegacNdf, omegacNdf, float); +DECLARE_SOA_COLUMN(XicNdf, xicNdf, float); DECLARE_SOA_COLUMN(MassV0Ndf, massV0Ndf, float); DECLARE_SOA_COLUMN(MassCascNdf, massCascNdf, float); DECLARE_SOA_COLUMN(V0Chi2OverNdf, v0Chi2OverNdf, float); DECLARE_SOA_COLUMN(CascChi2OverNdf, cascChi2OverNdf, float); DECLARE_SOA_COLUMN(OmegacChi2OverNdf, omegacChi2OverNdf, float); +DECLARE_SOA_COLUMN(XicChi2OverNdf, xicChi2OverNdf, float); DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); @@ -1443,6 +1458,49 @@ DECLARE_SOA_TABLE(HfOmegacKf, "AOD", "HFOMEGACKF", //! hf_cand_xic0_omegac0::V0Chi2OverNdf, hf_cand_xic0_omegac0::CascChi2OverNdf, hf_cand_xic0_omegac0::OmegacChi2OverNdf, hf_cand_xic0_omegac0::MassV0Chi2OverNdf, hf_cand_xic0_omegac0::MassCascChi2OverNdf); +DECLARE_SOA_TABLE(HfCandToXiPiKf, "AOD", "HFCANDTOXIPIKF", //! + o2::soa::Index<>, + hf_cand_xic0_omegac0::CollisionId, hf_cand_xic0_omegac0::XPv, hf_cand_xic0_omegac0::YPv, hf_cand_xic0_omegac0::ZPv, + hf_cand_xic0_omegac0::XDecayVtxCharmBaryon, hf_cand_xic0_omegac0::YDecayVtxCharmBaryon, hf_cand_xic0_omegac0::ZDecayVtxCharmBaryon, + hf_cand_xic0_omegac0::XDecayVtxCascade, hf_cand_xic0_omegac0::YDecayVtxCascade, hf_cand_xic0_omegac0::ZDecayVtxCascade, + hf_cand_xic0_omegac0::XDecayVtxV0, hf_cand_xic0_omegac0::YDecayVtxV0, hf_cand_xic0_omegac0::ZDecayVtxV0, + hf_cand_xic0_omegac0::SignDecay, + hf_cand_xic0_omegac0::CovVtxCharmBaryon0, hf_cand_xic0_omegac0::CovVtxCharmBaryon1, hf_cand_xic0_omegac0::CovVtxCharmBaryon2, hf_cand_xic0_omegac0::CovVtxCharmBaryon3, hf_cand_xic0_omegac0::CovVtxCharmBaryon4, hf_cand_xic0_omegac0::CovVtxCharmBaryon5, + hf_cand_xic0_omegac0::PxCharmBaryon, hf_cand_xic0_omegac0::PyCharmBaryon, hf_cand_xic0_omegac0::PzCharmBaryon, + hf_cand_xic0_omegac0::PxCasc, hf_cand_xic0_omegac0::PyCasc, hf_cand_xic0_omegac0::PzCasc, + hf_cand_xic0_omegac0::PxBachFromCharmBaryon, hf_cand_xic0_omegac0::PyBachFromCharmBaryon, hf_cand_xic0_omegac0::PzBachFromCharmBaryon, + hf_cand_xic0_omegac0::PxLambda, hf_cand_xic0_omegac0::PyLambda, hf_cand_xic0_omegac0::PzLambda, + hf_cand_xic0_omegac0::PxBachFromCasc, hf_cand_xic0_omegac0::PyBachFromCasc, hf_cand_xic0_omegac0::PzBachFromCasc, + hf_cand_xic0_omegac0::PxPosV0Dau, hf_cand_xic0_omegac0::PyPosV0Dau, hf_cand_xic0_omegac0::PzPosV0Dau, + hf_cand_xic0_omegac0::PxNegV0Dau, hf_cand_xic0_omegac0::PyNegV0Dau, hf_cand_xic0_omegac0::PzNegV0Dau, + hf_cand_xic0_omegac0::ImpactParCascXY, hf_cand_xic0_omegac0::ImpactParBachFromCharmBaryonXY, hf_cand_xic0_omegac0::ImpactParCascZ, hf_cand_xic0_omegac0::ImpactParBachFromCharmBaryonZ, + hf_cand_xic0_omegac0::ErrImpactParCascXY, hf_cand_xic0_omegac0::ErrImpactParBachFromCharmBaryonXY, + hf_cand_xic0_omegac0::V0Id, v0data::PosTrackId, v0data::NegTrackId, hf_cand_xic0_omegac0::CascadeId, hf_cand_xic0_omegac0::BachelorFromCharmBaryonId, cascdata::BachelorId, + hf_cand_xic0_omegac0::InvMassLambda, hf_cand_xic0_omegac0::InvMassCascade, hf_cand_xic0_omegac0::InvMassCharmBaryon, + hf_cand_xic0_omegac0::CosPAV0, hf_cand_xic0_omegac0::CosPACharmBaryon, hf_cand_xic0_omegac0::CosPACasc, hf_cand_xic0_omegac0::CosPAXYV0, hf_cand_xic0_omegac0::CosPAXYCharmBaryon, hf_cand_xic0_omegac0::CosPAXYCasc, + hf_cand_xic0_omegac0::CTauOmegac, hf_cand_xic0_omegac0::CTauCascade, hf_cand_xic0_omegac0::CTauV0, hf_cand_xic0_omegac0::CTauXic, + hf_cand_xic0_omegac0::EtaV0PosDau, hf_cand_xic0_omegac0::EtaV0NegDau, hf_cand_xic0_omegac0::EtaBachFromCasc, hf_cand_xic0_omegac0::EtaBachFromCharmBaryon, + hf_cand_xic0_omegac0::EtaCharmBaryon, hf_cand_xic0_omegac0::EtaCascade, hf_cand_xic0_omegac0::EtaV0, + hf_cand_xic0_omegac0::DcaXYToPvV0Dau0, hf_cand_xic0_omegac0::DcaXYToPvV0Dau1, hf_cand_xic0_omegac0::DcaXYToPvCascDau, + hf_cand_xic0_omegac0::DcaZToPvV0Dau0, hf_cand_xic0_omegac0::DcaZToPvV0Dau1, hf_cand_xic0_omegac0::DcaZToPvCascDau, + hf_cand_xic0_omegac0::DcaCascDau, hf_cand_xic0_omegac0::DcaV0Dau, hf_cand_xic0_omegac0::DcaCharmBaryonDau, + hf_cand_xic0_omegac0::DecLenCharmBaryon, hf_cand_xic0_omegac0::DecLenCascade, hf_cand_xic0_omegac0::DecLenV0, hf_cand_xic0_omegac0::ErrorDecayLengthCharmBaryon, hf_cand_xic0_omegac0::ErrorDecayLengthXYCharmBaryon, + hf_cand_xic0_omegac0::KfDcaXYPiFromXic, hf_cand_xic0_omegac0::KfDcaXYCascToPv, + hf_cand_xic0_omegac0::Chi2GeoV0, hf_cand_xic0_omegac0::Chi2GeoCasc, hf_cand_xic0_omegac0::Chi2GeoXic, + hf_cand_xic0_omegac0::Chi2MassV0, hf_cand_xic0_omegac0::Chi2MassCasc, + hf_cand_xic0_omegac0::V0ldl, hf_cand_xic0_omegac0::Cascldl, hf_cand_xic0_omegac0::Xicldl, + hf_cand_xic0_omegac0::Chi2TopoV0ToPv, hf_cand_xic0_omegac0::Chi2TopoCascToPv, hf_cand_xic0_omegac0::Chi2TopoPiFromXicToPv, hf_cand_xic0_omegac0::Chi2TopoXicToPv, + hf_cand_xic0_omegac0::Chi2TopoV0ToCasc, hf_cand_xic0_omegac0::Chi2TopoCascToXic, + hf_cand_xic0_omegac0::DecayLenXYLambda, hf_cand_xic0_omegac0::DecayLenXYCasc, hf_cand_xic0_omegac0::DecayLenXYXic, + hf_cand_xic0_omegac0::CosPaV0ToCasc, hf_cand_xic0_omegac0::CosPaCascToXic, hf_cand_xic0_omegac0::CosPaXYV0ToCasc, hf_cand_xic0_omegac0::CosPaXYCascToXic, + hf_cand_xic0_omegac0::KfRapXic, + hf_cand_xic0_omegac0::KfptPiFromXic, hf_cand_xic0_omegac0::KfptXic, + hf_cand_xic0_omegac0::CosThetaStarPiFromXic, + hf_cand_xic0_omegac0::V0Ndf, hf_cand_xic0_omegac0::CascNdf, hf_cand_xic0_omegac0::XicNdf, + hf_cand_xic0_omegac0::MassV0Ndf, hf_cand_xic0_omegac0::MassCascNdf, + hf_cand_xic0_omegac0::V0Chi2OverNdf, hf_cand_xic0_omegac0::CascChi2OverNdf, hf_cand_xic0_omegac0::XicChi2OverNdf, + hf_cand_xic0_omegac0::MassV0Chi2OverNdf, hf_cand_xic0_omegac0::MassCascChi2OverNdf); + // table with results of reconstruction level MC matching DECLARE_SOA_TABLE(HfXicToXiPiMCRec, "AOD", "HFXICXIPIMCREC", //! hf_cand_xic0_omegac0::FlagMcMatchRec, diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index 583c30a5de2..60ba4850953 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -136,11 +136,11 @@ DECLARE_SOA_TABLE(HfMlDsToKKPi, "AOD", "HFMLDS", //! namespace hf_sel_candidate_dstar { -DECLARE_SOA_COLUMN(IsSelDstarToD0Pi, isSelDstarToD0Pi, bool); //! checking if all four of following check pass -DECLARE_SOA_COLUMN(IsRecoD0Flag, isRecoD0Flag, bool); //! checking DecayType::D0ToPiK of D0prong -DECLARE_SOA_COLUMN(IsRecoTopol, isRecoTopol, bool); //! checking conjugate independent Topological selection on Dstar -DECLARE_SOA_COLUMN(IsRecoCand, isRecoCand, bool); //! checking conjugate dependent Topological selecton on Dstar -DECLARE_SOA_COLUMN(IsRecoPid, isRecoPid, bool); //! checking PID selection on daughters of D0Prong +DECLARE_SOA_COLUMN(IsSelDstarToD0Pi, isSelDstarToD0Pi, bool); //! checking if all four of following check pass +DECLARE_SOA_COLUMN(IsRecoD0Flag, isRecoD0Flag, bool); //! checking DecayType::D0ToPiK of D0prong +DECLARE_SOA_COLUMN(IsRecoTopol, isRecoTopol, bool); //! checking conjugate independent Topological selection on Dstar +DECLARE_SOA_COLUMN(IsRecoCand, isRecoCand, bool); //! checking conjugate dependent Topological selecton on Dstar +DECLARE_SOA_COLUMN(IsRecoPid, isRecoPid, bool); //! checking PID selection on daughters of D0Prong DECLARE_SOA_COLUMN(MlProbDstarToD0Pi, mlProbDstarToD0Pi, std::vector); //! ML probability for Dstar to D0Pi } // namespace hf_sel_candidate_dstar @@ -307,7 +307,7 @@ DECLARE_SOA_COLUMN(IsSelXicToPiKP, isSelXicToPiKP, int); //! DECLARE_SOA_COLUMN(MlProbXicToPKPi, mlProbXicToPKPi, std::vector); //! DECLARE_SOA_COLUMN(MlProbXicToPiKP, mlProbXicToPiKP, std::vector); //! // XicPlus to Xi Pi Pi -DECLARE_SOA_COLUMN(IsSelXicToXiPiPi, isSelXicToXiPiPi, int); //! +DECLARE_SOA_COLUMN(IsSelXicToXiPiPi, isSelXicToXiPiPi, int); //! DECLARE_SOA_COLUMN(MlProbXicToXiPiPi, mlProbXicToXiPiPi, std::vector); //! } // namespace hf_sel_candidate_xic @@ -357,6 +357,13 @@ DECLARE_SOA_TABLE(HfSelToXiPi, "AOD", "HFSELTOXIPI", hf_sel_toxipi::TpcNSigmaPiFromCharmBaryon, hf_sel_toxipi::TpcNSigmaPiFromCasc, hf_sel_toxipi::TpcNSigmaPiFromLambda, hf_sel_toxipi::TpcNSigmaPrFromLambda, hf_sel_toxipi::TofNSigmaPiFromCharmBaryon, hf_sel_toxipi::TofNSigmaPiFromCasc, hf_sel_toxipi::TofNSigmaPiFromLambda, hf_sel_toxipi::TofNSigmaPrFromLambda); +DECLARE_SOA_TABLE(HfSelToXiPiKf, "AOD", "HFSELTOXIPIKF", + hf_sel_toxipi::StatusPidCharmBaryon, hf_sel_toxipi::StatusPidCascade, hf_sel_toxipi::StatusPidLambda, + hf_sel_toxipi::StatusInvMassCharmBaryon, hf_sel_toxipi::StatusInvMassCascade, hf_sel_toxipi::StatusInvMassLambda, + hf_sel_toxipi::ResultSelections, hf_sel_toxipi::PidTpcInfoStored, hf_sel_toxipi::PidTofInfoStored, + hf_sel_toxipi::TpcNSigmaPiFromCharmBaryon, hf_sel_toxipi::TpcNSigmaPiFromCasc, hf_sel_toxipi::TpcNSigmaPiFromLambda, hf_sel_toxipi::TpcNSigmaPrFromLambda, + hf_sel_toxipi::TofNSigmaPiFromCharmBaryon, hf_sel_toxipi::TofNSigmaPiFromCasc, hf_sel_toxipi::TofNSigmaPiFromLambda, hf_sel_toxipi::TofNSigmaPrFromLambda); + namespace hf_sel_toomegapi { DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index f1ac9e9087a..a9d71f86da1 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -167,6 +167,11 @@ o2physics_add_dpl_workflow(candidate-selector-omegac0-to-omega-pi PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(candidate-selector-xic0-to-xi-pi-kf + SOURCES candidateSelectorXic0ToXiPiKf.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(candidate-selector-to-xi-pi SOURCES candidateSelectorToXiPi.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -254,6 +259,11 @@ o2physics_add_dpl_workflow(tree-creator-to-xi-pi PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(tree-creator-xic0-to-xi-pi-kf + SOURCES treeCreatorXic0ToXiPiKf.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(tree-creator-xic-to-p-k-pi SOURCES treeCreatorXicToPKPi.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx index 199dc5c7477..8e67ac22696 100644 --- a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx +++ b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx @@ -79,6 +79,7 @@ struct HfCandidateCreatorXic0Omegac0 { Produces rowCandToOmegaPi; Produces rowCandToOmegaK; Produces kfCandidateData; + Produces kfCandidateXicData; Configurable propagateToPCA{"propagateToPCA", false, "create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; @@ -177,14 +178,61 @@ struct HfCandidateCreatorXic0Omegac0 { float chi2MassCasc; float etaOmegac; } kfOmegac0Candidate; + + struct { + float chi2GeoV0; + float ldlV0; + float chi2TopoV0ToPv; + float chi2GeoCasc; + float ldlCasc; + float chi2TopoCascToPv; + float decayLenXYLambda; + float decayLenXYCasc; + float cosPaV0ToCasc; + float cosPaXYV0ToCasc; + float cosPaV0ToPv; + float cosPaXYV0ToPv; + float cosPaCascToXic; + float cosPaXYCascToXic; + float cosPaCascToPv; + float cosPaXYCascToPv; + float massV0; + float massCasc; + float ptPiFromXic; + float ptXic; + float rapXic; + float massXic; + float cosThetaStarPiFromXic; + float chi2TopoPiFromXicToPv; + float kfDcaXYPiFromXic; + float chi2TopoV0ToCasc; + float chi2TopoCascToXic; + float decayLenXYXic; + float chi2GeoXic; + float kfDcaV0Dau; + float kfDcaCascDau; + float kfDcaXicDau; + float kfDcaXYCascToPv; + float chi2TopoXicToPv; + float cosPaXicToPv; + float cosPaXYXicToPv; + float ldlXic; + float ctV0; + float ctCasc; + float ctXic; + float ctOmegac; + float chi2MassV0; + float chi2MassCasc; + float etaXic; + } kfXic0Candidate; void init(InitContext const&) { - std::array allProcesses = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentToOmegaPi, doprocessOmegacToOmegaPiWithKFParticle, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK}; + std::array allProcesses = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentToOmegaPi, doprocessOmegacToOmegaPiWithKFParticle, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK, doprocessXicToXiPiWithKFParticle}; if (std::accumulate(allProcesses.begin(), allProcesses.end(), 0) == 0) { LOGP(fatal, "No process function enabled, please select one for at least one channel."); } - std::array processesToXiPi = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi}; + std::array processesToXiPi = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessXicToXiPiWithKFParticle}; if (std::accumulate(processesToXiPi.begin(), processesToXiPi.end(), 0) > 1) { LOGP(fatal, "One and only one ToXiPi process function must be enabled at a time."); } @@ -203,7 +251,7 @@ struct HfCandidateCreatorXic0Omegac0 { LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); } if (nProcessesCollisions == 1) { - if ((doprocessNoCentToXiPi && !doprocessCollisions) || (doprocessNoCentToXiPiTraCasc && !doprocessCollisions) || (doprocessNoCentToOmegaPi && !doprocessCollisions) || (doprocessNoCentToOmegaK && !doprocessCollisions) || (doprocessOmegacToOmegaPiWithKFParticle && !doprocessCollisions)) { + if ((doprocessNoCentToXiPi && !doprocessCollisions) || (doprocessNoCentToXiPiTraCasc && !doprocessCollisions) || (doprocessNoCentToOmegaPi && !doprocessCollisions) || (doprocessNoCentToOmegaK && !doprocessCollisions) || (doprocessOmegacToOmegaPiWithKFParticle && !doprocessCollisions) || (doprocessXicToXiPiWithKFParticle && !doprocessCollisions)) { LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); } if ((doprocessCentFT0CToXiPi && !doprocessCollisionsCentFT0C) || (doprocessCentFT0CToOmegaPi && !doprocessCollisionsCentFT0C) || (doprocessCentFT0CToOmegaK && !doprocessCollisionsCentFT0C)) { @@ -214,31 +262,34 @@ struct HfCandidateCreatorXic0Omegac0 { } } - hInvMassCharmBaryonToXiPi = registry.add("hInvMassCharmBaryonToXiPi", "Charm baryon invariant mass - #Xi #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 2.2, 3.1}}}); - hInvMassCharmBaryonToOmegaPi = registry.add("hInvMassCharmBaryonToOmegaPi", "Charm baryon invariant mass - #Omega #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 2.2, 3.1}}}); - hInvMassCharmBaryonToOmegaK = registry.add("hInvMassCharmBaryonToOmegaK", "Charm baryon invariant mass - #Omega K decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 2.2, 3.1}}}); - hFitterStatusToXiPi = registry.add("hFitterStatusToXiPi", "Charm DCAFitter status - #Xi #pi vtx;status;entries", {HistType::kTH1F, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) - hFitterStatusToOmegaPi = registry.add("hFitterStatusToOmegaPi", "Charm DCAFitter status - #Omega #pi vtx ;status;entries", {HistType::kTH1F, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) - hFitterStatusToOmegaK = registry.add("hFitterStatusToOmegaK", "Charm DCAFitter status - #Omega K vtx;status;entries", {HistType::kTH1F, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) - hCandidateCounterToXiPi = registry.add("hCandidateCounterToXiPi", "Candidate counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1F, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table - hCandidateCounterToOmegaPi = registry.add("hCandidateCounterToOmegaPi", "Candidate counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1F, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table - hCandidateCounterToOmegaK = registry.add("hCandidateCounterToOmegaK", "Candidate counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1F, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table - hCascadesCounterToXiPi = registry.add("hCascadesCounterToXiPi", "Cascades counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1F, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table - hCascadesCounterToOmegaPi = registry.add("hCascadesCounterToOmegaPi", "Cascades counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1F, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table - hCascadesCounterToOmegaK = registry.add("hCascadesCounterToOmegaK", "Cascades counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1F, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table + hInvMassCharmBaryonToXiPi = registry.add("hInvMassCharmBaryonToXiPi", "Charm baryon invariant mass - #Xi #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); + hInvMassCharmBaryonToOmegaPi = registry.add("hInvMassCharmBaryonToOmegaPi", "Charm baryon invariant mass - #Omega #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); + hInvMassCharmBaryonToOmegaK = registry.add("hInvMassCharmBaryonToOmegaK", "Charm baryon invariant mass - #Omega K decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); + hFitterStatusToXiPi = registry.add("hFitterStatusToXiPi", "Charm DCAFitter status - #Xi #pi vtx;status;entries", {HistType::kTH1D, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) + hFitterStatusToOmegaPi = registry.add("hFitterStatusToOmegaPi", "Charm DCAFitter status - #Omega #pi vtx ;status;entries", {HistType::kTH1D, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) + hFitterStatusToOmegaK = registry.add("hFitterStatusToOmegaK", "Charm DCAFitter status - #Omega K vtx;status;entries", {HistType::kTH1D, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) + hCandidateCounterToXiPi = registry.add("hCandidateCounterToXiPi", "Candidate counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table + hCandidateCounterToOmegaPi = registry.add("hCandidateCounterToOmegaPi", "Candidate counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table + hCandidateCounterToOmegaK = registry.add("hCandidateCounterToOmegaK", "Candidate counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table + hCascadesCounterToXiPi = registry.add("hCascadesCounterToXiPi", "Cascades counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table + hCascadesCounterToOmegaPi = registry.add("hCascadesCounterToOmegaPi", "Cascades counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table + hCascadesCounterToOmegaK = registry.add("hCascadesCounterToOmegaK", "Cascades counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table // KFparticle variables hist - registry.add("hKFParticleV0TopoChi2", "hKFParticleV0TopoChi2", kTH1F, {{1000, -0.10f, 100.0f}}); - registry.add("hKFParticleCascTopoChi2", "hKFParticleCascTopoChi2", kTH1F, {{1000, -0.1f, 100.0f}}); - registry.add("hKFParticleCascBachTopoChi2", "hKFParticleCascBachTopoChi2", kTH1F, {{1000, -0.1f, 100.0f}}); - registry.add("hKFParticleDcaCharmBaryonDau", "hKFParticleDcaCharmBaryonDau", kTH1F, {{1000, -0.1f, 100.0f}}); - registry.add("hKFParticleDcaXYV0DauToPv", "hKFParticleDcaXYV0DauToPv", kTH1F, {{1000, -0.1f, 100.0f}}); - registry.add("hKFParticleDcaXYCascBachToPv", "hKFParticleDcaXYCascBachToPv", kTH1F, {{1000, -0.1f, 100.0f}}); - registry.add("hKfLambda_ldl", "hKfLambda_ldl", kTH1F, {{1000, 0.0f, 1000.0f}}); - registry.add("hKfOmega_ldl", "hKfOmega_ldl", kTH1F, {{1000, 0.0f, 1000.0f}}); - registry.add("hKfOmegaC0_ldl", "hKfOmegaC0_ldl", kTH1F, {{1000, 0.0f, 1000.0f}}); - registry.add("hDcaXYCascadeToPVKf", "hDcaXYCascadeToPVKf", kTH1F, {{1000, 0.0f, 2.0f}}); - registry.add("hInvMassOmegaMinus", "hInvMassOmegaMinus", kTH1F, {{1000, 1.6f, 2.0f}}); + registry.add("hKFParticleV0TopoChi2", "hKFParticleV0TopoChi2", kTH1D, {{1000, -0.10f, 100.0f}}); + registry.add("hKFParticleCascTopoChi2", "hKFParticleCascTopoChi2", kTH1D, {{1000, -0.1f, 100.0f}}); + registry.add("hKFParticleCascBachTopoChi2", "hKFParticleCascBachTopoChi2", kTH1D, {{1000, -0.1f, 100.0f}}); + registry.add("hKFParticleDcaCharmBaryonDau", "hKFParticleDcaCharmBaryonDau", kTH1D, {{1000, -0.1f, 100.0f}}); + registry.add("hKFParticleDcaXYV0DauToPv", "hKFParticleDcaXYV0DauToPv", kTH1D, {{1000, -0.1f, 100.0f}}); + registry.add("hKFParticleDcaXYCascBachToPv", "hKFParticleDcaXYCascBachToPv", kTH1D, {{1000, -0.1f, 100.0f}}); + registry.add("hKfLambda_ldl", "hKfLambda_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); + registry.add("hKfOmega_ldl", "hKfOmega_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); + registry.add("hKfXi_ldl", "hKfXi_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); + registry.add("hKfOmegaC0_ldl", "hKfOmegaC0_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); + registry.add("hKfXiC0_ldl", "hKfXiC0_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); + registry.add("hDcaXYCascadeToPVKf", "hDcaXYCascadeToPVKf", kTH1D, {{1000, 0.0f, 2.0f}}); + registry.add("hInvMassOmegaMinus", "hInvMassOmegaMinus", kTH1D, {{1000, 1.6f, 2.0f}}); + registry.add("hInvMassXiMinus", "hInvMassXiMinus", kTH1D, {{1000, 1.25f, 1.65f}}); hfEvSel.addHistograms(registry); // collision monitoring @@ -614,7 +665,7 @@ struct HfCandidateCreatorXic0Omegac0 { } } // loop over LF Cascade-bachelor candidates - } // end of run function + } // end of run function template void runKfOmegac0CreatorWithKFParticle(Coll const&, @@ -1039,8 +1090,437 @@ struct HfCandidateCreatorXic0Omegac0 { v0Chi2OverNdf, cascChi2OverNdf, charmbaryonChi2OverNdf, v0Chi2OverNdf_m, cascChi2OverNdf_m); } // loop over LF Cascade-bachelor candidates - } // end of run function + } // end of run function + //========================================================== + template + void runKfXic0CreatorWithKFParticle(Coll const&, + aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, + MyKfTracks const&, + MyKfCascTable const&, KFCascadesLinked const&, + aod::HfCascLf2Prongs const& candidates, + Hist& hInvMassCharmBaryon, + Hist& hFitterStatus, + Hist& hCandidateCounter, + Hist& hCascadesCounter) + { + for (const auto& cand : candidates) { + hCandidateCounter->Fill(1); + + auto collision = cand.collision_as(); + // set the magnetic field from CCDB + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); + magneticField = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>>>> Magnetic field: " << magneticField; + runNumber = bc.runNumber(); + } + df.setBz(magneticField); + KFParticle::SetField(magneticField); + // bachelor from Xic0 + auto trackCharmBachelor = cand.prong0_as(); + + auto cascAodElement = cand.cascade_as(); + hCascadesCounter->Fill(0); + int v0index = cascAodElement.v0Id(); + if (!cascAodElement.has_kfCascData()) { + continue; + } + auto casc = cascAodElement.kfCascData_as(); + hCascadesCounter->Fill(1); + auto trackCascDauCharged = casc.bachelor_as(); // pion <- xi track + auto trackV0Dau0 = casc.posTrack_as(); // V0 positive daughter track + auto trackV0Dau1 = casc.negTrack_as(); // V0 negative daughter track + + auto bachCharge = trackCascDauCharged.signed1Pt() > 0 ? +1 : -1; + + //// pion & p TrackParCov + auto trackParCovV0Dau0 = getTrackParCov(trackV0Dau0); + auto trackParCovV0Dau1 = getTrackParCov(trackV0Dau1); + // pion <- casc TrackParCov + auto XiDauChargedTrackParCov = getTrackParCov(trackCascDauCharged); + // convert tracks into KFParticle object + KFPTrack kfTrack0 = createKFPTrackFromTrack(trackV0Dau0); + KFPTrack kfTrack1 = createKFPTrackFromTrack(trackV0Dau1); + KFPTrack kfTrackBach = createKFPTrackFromTrack(trackCascDauCharged); + + KFParticle kfPosPr(kfTrack0, kProton); + KFParticle kfNegPi(kfTrack1, kPiMinus); + KFParticle kfNegBachPi(kfTrackBach, kPiMinus); + KFParticle kfPosPi(kfTrack0, kPiPlus); + KFParticle kfNegPr(kfTrack1, kProton); + KFParticle kfPosBachPi(kfTrackBach, kPiPlus); + + KFParticle kfBachPion; + KFParticle kfPos; + KFParticle kfNeg; + if (bachCharge < 0) { + kfPos = kfPosPr; + kfNeg = kfNegPi; + kfBachPion = kfNegBachPi; + } else { + kfPos = kfPosPi; + kfNeg = kfNegPr; + kfBachPion = kfPosBachPi; + } + + //__________________________________________ + //*>~<* step 1 : construct V0 with KF + const KFParticle* v0Daughters[2] = {&kfPos, &kfNeg}; + // construct V0 + KFParticle kfV0; + kfV0.SetConstructMethod(kfConstructMethod); + try { + kfV0.Construct(v0Daughters, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct cascade V0 from daughter tracks: " << e.what(); + continue; + } + + // mass window cut on lambda before mass constraint + float massLam, sigLam; + kfV0.GetMass(massLam, sigLam); + if (TMath::Abs(massLam - MassLambda0) > lambdaMassWindow) + continue; + + // err_mass>0 of Lambda + if (sigLam <= 0) + continue; + // chi2>0 && NDF>0 for selecting Lambda + if ((kfV0.GetNDF() <= 0 || kfV0.GetChi2() <= 0)) + continue; + + kfXic0Candidate.chi2GeoV0 = kfV0.GetChi2(); + KFParticle kfV0MassConstrained = kfV0; + kfV0MassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassLambda); // set mass constrain to Lambda + if (kfUseV0MassConstraint) { + KFParticle kfV0 = kfV0MassConstrained; + } + kfV0.TransportToDecayVertex(); + + //__________________________________________ + //*>~<* step 2 : reconstruct cascade(Xi) with KF + const KFParticle* XiDaugthers[2] = {&kfBachPion, &kfV0}; + // construct cascade + KFParticle kfXi; + kfXi.SetConstructMethod(kfConstructMethod); + try { + kfXi.Construct(XiDaugthers, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct Xi from V0 and bachelor track: " << e.what(); + continue; + } + + float massCasc, sigCasc; + kfXi.GetMass(massCasc, sigCasc); + // err_massXi > 0 + if (sigCasc <= 0) + continue; + + if (std::abs(massCasc - MassXiMinus) > massToleranceCascade) + continue; + // chi2>0 && NDF>0 + if (kfXi.GetNDF() <= 0 || kfXi.GetChi2() <= 0) + continue; + kfXic0Candidate.chi2GeoCasc = kfXi.GetChi2(); + KFParticle kfXiMassConstrained = kfXi; + kfXiMassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassXiMinus); // set mass constrain to XiMinus + if (kfUseCascadeMassConstraint) { + // set mass constraint if requested + KFParticle kfXi = kfXiMassConstrained; + } + registry.fill(HIST("hInvMassXiMinus"), massCasc); + kfXi.TransportToDecayVertex(); + + //__________________________________________ + //*>~<* step 3 : reconstruc Xic0 with KF + // Create KF charm bach Pion from track + KFPTrack kfTrackBachPion = createKFPTrackFromTrack(trackCharmBachelor); + KFParticle kfCharmBachPion(kfTrackBachPion, kPiPlus); + const KFParticle* XiC0Daugthers[2] = {&kfCharmBachPion, &kfXi}; + + // construct XiC0 + KFParticle kfXiC0; + kfXiC0.SetConstructMethod(kfConstructMethod); + try { + kfXiC0.Construct(XiC0Daugthers, 2); + } catch (std::runtime_error& e) { + LOG(debug) << "Failed to construct XiC0 from Cascade and bachelor pion track: " << e.what(); + continue; + } + float massXiC0, sigXiC0; + kfXiC0.GetMass(massXiC0, sigXiC0); + if (sigXiC0 <= 0) + continue; + // chi2>0 && NDF>0 + if (kfXiC0.GetNDF() <= 0 || kfXiC0.GetChi2() <= 0) + continue; + + hFitterStatus->Fill(0); + hCandidateCounter->Fill(2); + kfXiC0.TransportToDecayVertex(); + // PV + KFPVertex kfVertex = createKFPVertexFromCollision(collision); + KFParticle kfPV(kfVertex); + + // set production vertex; + kfNeg.SetProductionVertex(kfV0); + kfPos.SetProductionVertex(kfV0); + + KFParticle kfBachPionToXi = kfBachPion; + KFParticle kfV0ToCasc = kfV0; + kfBachPionToXi.SetProductionVertex(kfXi); + kfV0ToCasc.SetProductionVertex(kfXi); + + KFParticle kfXiToXiC = kfXi; + KFParticle kfCharmBachPionToXiC = kfCharmBachPion; + kfCharmBachPionToXiC.SetProductionVertex(kfXiC0); + kfXiToXiC.SetProductionVertex(kfXiC0); + + // KFParticle to PV + KFParticle kfV0ToPv = kfV0; + KFParticle kfXiToPv = kfXi; + KFParticle kfXic0ToPv = kfXiC0; + KFParticle kfPiFromXicToPv = kfCharmBachPion; + + kfV0ToPv.SetProductionVertex(kfPV); + kfXiToPv.SetProductionVertex(kfPV); + kfXic0ToPv.SetProductionVertex(kfPV); + kfPiFromXicToPv.SetProductionVertex(kfPV); + //------------get updated daughter tracks after vertex fit --------------- + auto trackParVarCharmBachelor = getTrackParCovFromKFP(kfCharmBachPionToXiC, o2::track::PID::Pion, -bachCharge); // chrambaryon bach pion + trackParVarCharmBachelor.setAbsCharge(1); + + XiDauChargedTrackParCov = getTrackParCovFromKFP(kfBachPionToXi, o2::track::PID::Pion, bachCharge); // Cascade bach pion + XiDauChargedTrackParCov.setAbsCharge(1); + o2::track::TrackParCov trackCasc = getTrackParCovFromKFP(kfXiToXiC, kfXiToXiC.GetPDG(), bachCharge); + trackCasc.setAbsCharge(1); + + trackParCovV0Dau0 = getTrackParCovFromKFP(kfPos, kfPos.GetPDG(), 1); // V0 postive daughter + trackParCovV0Dau0.setAbsCharge(1); + trackParCovV0Dau1 = getTrackParCovFromKFP(kfNeg, kfNeg.GetPDG(), -1); // V0 negtive daughter + trackParCovV0Dau1.setAbsCharge(1); + + //-------------------------- V0 info--------------------------- + // pseudorapidity + float pseudorapV0Dau0 = kfPos.GetEta(); + float pseudorapV0Dau1 = kfNeg.GetEta(); + + // info from from KFParticle + std::array pVecV0 = {kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz()}; // pVec stands for vector containing the 3-momentum components + std::array vertexV0 = {kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}; + std::array pVecV0Dau0 = {kfPos.GetPx(), kfPos.GetPy(), kfPos.GetPz()}; + std::array pVecV0Dau1 = {kfNeg.GetPx(), kfNeg.GetPy(), kfNeg.GetPz()}; + + //-------------------reconstruct cascade track------------------ + // pseudorapidity + float pseudorapCascBachelor = kfBachPionToXi.GetEta(); + + // info from KFParticle + std::array vertexCasc = {kfXi.GetX(), kfXi.GetY(), kfXi.GetZ()}; + std::array pVecCascBachelor = {kfBachPionToXi.GetPx(), kfBachPionToXi.GetPy(), kfBachPionToXi.GetPz()}; + + auto primaryVertex = getPrimaryVertex(collision); + std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; + std::array vertexCharmBaryonFromFitter = {0.0, 0.0, 0.0}; // This variable get from DCAfitter in default process, in KF process it is set as 0. + std::array pVecCharmBachelorAsD; + pVecCharmBachelorAsD[0] = kfCharmBachPionToXiC.GetPx(); + pVecCharmBachelorAsD[1] = kfCharmBachPionToXiC.GetPy(); + pVecCharmBachelorAsD[2] = kfCharmBachPionToXiC.GetPz(); + + std::array pVecCharmBaryon = {kfXiC0.GetPx(), kfXiC0.GetPy(), kfXiC0.GetPz()}; + std::array coordVtxCharmBaryon = {kfXiC0.GetX(), kfXiC0.GetY(), kfXiC0.GetZ()}; + auto covVtxCharmBaryon = kfXiC0.CovarianceMatrix(); + float covMatrixPV[6]; + kfVertex.GetCovarianceMatrix(covMatrixPV); + + // impact parameters + gpu::gpustd::array impactParameterV0Dau0; + gpu::gpustd::array impactParameterV0Dau1; + gpu::gpustd::array impactParameterKaFromCasc; + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Dau0, 2.f, matCorr, &impactParameterV0Dau0); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Dau1, 2.f, matCorr, &impactParameterV0Dau1); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, XiDauChargedTrackParCov, 2.f, matCorr, &impactParameterKaFromCasc); + float dcaxyV0Dau0 = impactParameterV0Dau0[0]; + float dcaxyV0Dau1 = impactParameterV0Dau1[0]; + float dcaxyCascBachelor = impactParameterKaFromCasc[0]; + float dcazV0Dau0 = impactParameterV0Dau0[1]; + float dcazV0Dau1 = impactParameterV0Dau1[1]; + float dcazCascBachelor = impactParameterKaFromCasc[1]; + + // pseudorapidity + float pseudorapCharmBachelor = kfCharmBachPionToXiC.GetEta(); + + // impact parameters + o2::dataformats::DCA impactParameterCasc; + o2::dataformats::DCA impactParameterCharmBachelor; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarCharmBachelor, 2.f, matCorr, &impactParameterCharmBachelor); + float impactParBachFromCharmBaryonXY = impactParameterCharmBachelor.getY(); + float impactParBachFromCharmBaryonZ = impactParameterCharmBachelor.getZ(); + + // computing decay length and ctau + float decLenCharmBaryon = RecoDecay::distance(pvCoord, coordVtxCharmBaryon); + float decLenCascade = RecoDecay::distance(coordVtxCharmBaryon, vertexCasc); + float decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); + + double phiCharmBaryon, thetaCharmBaryon; + getPointDirection(std::array{kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}, coordVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon); + auto errorDecayLengthCharmBaryon = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); + auto errorDecayLengthXYCharmBaryon = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phiCharmBaryon, 0.) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, 0.)); + + // fill test histograms + hInvMassCharmBaryon->Fill(massXiC0); + hCandidateCounter->Fill(3); + + //// KFParticle table information + // KF chi2 + auto v0NDF = kfV0.GetNDF(); + auto v0Chi2OverNdf = kfXic0Candidate.chi2GeoV0 / v0NDF; + + auto cascNDF = kfXi.GetNDF(); + auto cascChi2OverNdf = kfXic0Candidate.chi2GeoCasc / cascNDF; + + kfXic0Candidate.chi2GeoXic = kfXiC0.GetChi2(); + auto charmbaryonNDF = kfXiC0.GetNDF(); + auto charmbaryonChi2OverNdf = kfXic0Candidate.chi2GeoXic / charmbaryonNDF; + + kfXic0Candidate.chi2MassV0 = kfV0MassConstrained.GetChi2(); + auto v0NDF_m = kfV0MassConstrained.GetNDF(); + auto v0Chi2OverNdf_m = kfXic0Candidate.chi2MassV0 / v0NDF_m; + + kfXic0Candidate.chi2MassCasc = kfXiMassConstrained.GetChi2(); + auto cascNDF_m = kfXiMassConstrained.GetNDF(); + auto cascChi2OverNdf_m = kfXic0Candidate.chi2MassCasc / cascNDF_m; + + // KF topo Chi2 + kfXic0Candidate.chi2TopoV0ToPv = kfV0ToPv.GetChi2(); + kfXic0Candidate.chi2TopoCascToPv = kfXiToPv.GetChi2(); + kfXic0Candidate.chi2TopoPiFromXicToPv = kfPiFromXicToPv.GetChi2(); + kfXic0Candidate.chi2TopoXicToPv = kfXic0ToPv.GetChi2(); + + auto cascBachTopoChi2 = kfBachPionToXi.GetChi2(); + kfXic0Candidate.chi2TopoV0ToCasc = kfV0ToCasc.GetChi2(); + kfXic0Candidate.chi2TopoCascToXic = kfXiToXiC.GetChi2(); + + // KF ldl + kfXic0Candidate.ldlV0 = ldlFromKF(kfV0, kfPV); + kfXic0Candidate.ldlCasc = ldlFromKF(kfXi, kfPV); + kfXic0Candidate.ldlXic = ldlFromKF(kfXiC0, kfPV); + + // KF dca + kfXic0Candidate.kfDcaXYPiFromXic = kfCharmBachPionToXiC.GetDistanceFromVertexXY(kfPV); + kfXic0Candidate.kfDcaV0Dau = kfNeg.GetDistanceFromParticle(kfPos); + kfXic0Candidate.kfDcaCascDau = kfBachPionToXi.GetDistanceFromParticle(kfV0ToCasc); + kfXic0Candidate.kfDcaXYCascToPv = kfXiToXiC.GetDistanceFromVertexXY(kfPV); + kfXic0Candidate.kfDcaXicDau = kfCharmBachPionToXiC.GetDistanceFromParticle(kfXiToXiC); + + // KF decay length + float DecayLxy_Lam, err_DecayLxy_Lam; + kfV0ToCasc.GetDecayLengthXY(DecayLxy_Lam, err_DecayLxy_Lam); + kfXic0Candidate.decayLenXYLambda = DecayLxy_Lam; + + float DecayLxy_Casc, err_DecayLxy_Casc; + kfXiToXiC.GetDecayLengthXY(DecayLxy_Casc, err_DecayLxy_Casc); + kfXic0Candidate.decayLenXYCasc = DecayLxy_Casc; + + float DecayLxy_Xic0, err_DecayLxy_Xic0; + kfXic0ToPv.GetDecayLengthXY(DecayLxy_Xic0, err_DecayLxy_Xic0); + kfXic0Candidate.decayLenXYXic = DecayLxy_Xic0; + + // KF cosPA + kfXic0Candidate.cosPaV0ToPv = cpaFromKF(kfV0, kfPV); + kfXic0Candidate.cosPaCascToPv = cpaFromKF(kfXi, kfPV); + kfXic0Candidate.cosPaXicToPv = cpaFromKF(kfXiC0, kfPV); + kfXic0Candidate.cosPaXYV0ToPv = cpaXYFromKF(kfV0, kfPV); + kfXic0Candidate.cosPaXYCascToPv = cpaXYFromKF(kfXi, kfPV); + kfXic0Candidate.cosPaXYXicToPv = cpaXYFromKF(kfXiC0, kfPV); + + kfXic0Candidate.cosPaV0ToCasc = cpaFromKF(kfV0, kfXi); + kfXic0Candidate.cosPaCascToXic = cpaFromKF(kfXi, kfXiC0); + kfXic0Candidate.cosPaXYV0ToCasc = cpaXYFromKF(kfV0, kfXi); + kfXic0Candidate.cosPaXYCascToXic = cpaXYFromKF(kfXi, kfXiC0); + // KF mass + kfXic0Candidate.massV0 = massLam; + kfXic0Candidate.massCasc = massCasc; + kfXic0Candidate.massXic = massXiC0; + + // KF pT + kfXic0Candidate.ptPiFromXic = kfCharmBachPionToXiC.GetPt(); + kfXic0Candidate.ptXic = kfXiC0.GetPt(); + + // KF rapidity + kfXic0Candidate.rapXic = kfXiC0.GetRapidity(); + + // KF cosThetaStar + kfXic0Candidate.cosThetaStarPiFromXic = cosThetaStarFromKF(0, 4332, 211, 3312, kfCharmBachPionToXiC, kfXiToXiC); + + // KF ct + kfXic0Candidate.ctV0 = kfV0.GetLifeTime(); + kfXic0Candidate.ctCasc = kfXi.GetLifeTime(); + kfXic0Candidate.ctXic = kfXiC0.GetLifeTime(); + kfXic0Candidate.ctOmegac = kfXiC0.GetLifeTime(); + + // KF eta + kfXic0Candidate.etaXic = kfXiC0.GetEta(); + + // fill KF hist + registry.fill(HIST("hKFParticleCascBachTopoChi2"), cascBachTopoChi2); + registry.fill(HIST("hKFParticleV0TopoChi2"), kfXic0Candidate.chi2TopoV0ToCasc); + registry.fill(HIST("hKFParticleCascTopoChi2"), kfXic0Candidate.chi2TopoCascToXic); + registry.fill(HIST("hKFParticleDcaCharmBaryonDau"), kfXic0Candidate.kfDcaXicDau); + registry.fill(HIST("hKFParticleDcaXYCascBachToPv"), dcaxyCascBachelor); + registry.fill(HIST("hKFParticleDcaXYV0DauToPv"), dcaxyV0Dau0); + registry.fill(HIST("hKfLambda_ldl"), kfXic0Candidate.ldlV0); + registry.fill(HIST("hKfXi_ldl"), kfXic0Candidate.ldlCasc); + registry.fill(HIST("hKfXiC0_ldl"), kfXic0Candidate.ldlXic); + registry.fill(HIST("hDcaXYCascadeToPVKf"), kfXic0Candidate.kfDcaXYCascToPv); + + // fill kf table + kfCandidateXicData(collision.globalIndex(), + pvCoord[0], pvCoord[1], pvCoord[2], + vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], + vertexCasc[0], vertexCasc[1], vertexCasc[2], + vertexV0[0], vertexV0[1], vertexV0[2], + trackCascDauCharged.sign(), + covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], + pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], + kfXiToXiC.GetPx(), kfXiToXiC.GetPy(), kfXiToXiC.GetPz(), + pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], + pVecV0[0], pVecV0[1], pVecV0[2], + pVecCascBachelor[0], pVecCascBachelor[1], pVecCascBachelor[2], + pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], + pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], + impactParameterCasc.getY(), impactParBachFromCharmBaryonXY, + impactParameterCasc.getZ(), impactParBachFromCharmBaryonZ, + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), + v0index, casc.posTrackId(), casc.negTrackId(), + casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + kfXic0Candidate.massV0, kfXic0Candidate.massCasc, kfXic0Candidate.massXic, + kfXic0Candidate.cosPaV0ToPv, kfXic0Candidate.cosPaXicToPv, kfXic0Candidate.cosPaCascToPv, kfXic0Candidate.cosPaXYV0ToPv, kfXic0Candidate.cosPaXYXicToPv, kfXic0Candidate.cosPaXYCascToPv, + kfXic0Candidate.ctOmegac, kfXic0Candidate.ctCasc, kfXic0Candidate.ctV0, kfXic0Candidate.ctXic, + pseudorapV0Dau0, pseudorapV0Dau1, pseudorapCascBachelor, pseudorapCharmBachelor, + kfXic0Candidate.etaXic, kfXi.GetEta(), kfV0.GetEta(), + dcaxyV0Dau0, dcaxyV0Dau1, dcaxyCascBachelor, + dcazV0Dau0, dcazV0Dau1, dcazCascBachelor, + kfXic0Candidate.kfDcaCascDau, kfXic0Candidate.kfDcaV0Dau, kfXic0Candidate.kfDcaXicDau, + decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon, + kfXic0Candidate.kfDcaXYPiFromXic, kfXic0Candidate.kfDcaXYCascToPv, + kfXic0Candidate.chi2GeoV0, kfXic0Candidate.chi2GeoCasc, kfXic0Candidate.chi2GeoXic, kfXic0Candidate.chi2MassV0, kfXic0Candidate.chi2MassCasc, + kfXic0Candidate.ldlV0, kfXic0Candidate.ldlCasc, kfXic0Candidate.ldlXic, + kfXic0Candidate.chi2TopoV0ToPv, kfXic0Candidate.chi2TopoCascToPv, kfXic0Candidate.chi2TopoPiFromXicToPv, kfXic0Candidate.chi2TopoXicToPv, + kfXic0Candidate.chi2TopoV0ToCasc, kfXic0Candidate.chi2TopoCascToXic, + kfXic0Candidate.decayLenXYLambda, kfXic0Candidate.decayLenXYCasc, kfXic0Candidate.decayLenXYXic, + kfXic0Candidate.cosPaV0ToCasc, kfXic0Candidate.cosPaCascToXic, kfXic0Candidate.cosPaXYV0ToCasc, kfXic0Candidate.cosPaXYCascToXic, + kfXic0Candidate.rapXic, kfXic0Candidate.ptPiFromXic, kfXic0Candidate.ptXic, + kfXic0Candidate.cosThetaStarPiFromXic, + v0NDF, cascNDF, charmbaryonNDF, v0NDF_m, cascNDF_m, + v0Chi2OverNdf, cascChi2OverNdf, charmbaryonChi2OverNdf, v0Chi2OverNdf_m, cascChi2OverNdf_m); + + } // loop over LF Cascade-bachelor candidates + } /// @brief process function w/o centrality selections void processNoCentToXiPi(soa::Join const& collisions, aod::BCsWithTimestamps const& bcWithTimeStamps, @@ -1089,6 +1569,17 @@ struct HfCandidateCreatorXic0Omegac0 { } PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processOmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); + void processXicToXiPiWithKFParticle(aod::Collisions const& collisions, + aod::BCsWithTimestamps const& bcWithTimeStamps, + MyKfTracks const& tracks, + MyKfCascTable const& cascades, + KFCascadesLinked const& cascadeLinks, + aod::HfCascLf2Prongs const& candidates) + { + runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processXicToXiPiWithKFParticle, "Run candidate creator w/o centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); + void processNoCentToOmegaK(soa::Join const& collisions, aod::BCsWithTimestamps const& bcWithTimeStamps, TracksWCovDca const& tracks, @@ -1267,7 +1758,7 @@ struct HfCandidateCreatorXic0Omegac0Mc { // inspect for which zPvPosMax cut was set for reconstructed void init(InitContext& initContext) { - std::array procCollisionsXicToXiPi{doprocessMcXicToXiPi, doprocessMcXicToXiPiFT0m, doprocessMcXicToXiPiFT0c}; + std::array procCollisionsXicToXiPi{doprocessMcXicToXiPi, doprocessMcXicToXiPiFT0m, doprocessMcXicToXiPiFT0c, doprocessMcXicToXiPiKf}; if (std::accumulate(procCollisionsXicToXiPi.begin(), procCollisionsXicToXiPi.end(), 0) > 1) { LOGP(fatal, "At most one process function for XicToXiPi collision study can be enabled at a time."); } @@ -1768,8 +2259,8 @@ struct HfCandidateCreatorXic0Omegac0Mc { } } } // close loop on MCParticles - } // close loop on MCCollisions - } // close process + } // close loop on MCCollisions + } // close process void processDoNoMc(aod::Collisions::iterator const&) { @@ -1788,6 +2279,17 @@ struct HfCandidateCreatorXic0Omegac0Mc { } PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPi, "Run Xic0 to xi pi MC process function - no centrality", false); + void processMcXicToXiPiKf(aod::HfCandToXiPiKf const& candidates, + MyTracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcColls, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) + { + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiKf, "Run Xic0 to xi pi MC process function - no centrality", false); + void processMcXicToXiPiFT0m(aod::HfCandToXiPi const& candidates, MyTracksWMc const& tracks, aod::McParticles const& mcParticles, diff --git a/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx b/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx new file mode 100644 index 00000000000..f83192eb3e8 --- /dev/null +++ b/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx @@ -0,0 +1,560 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file candidateSelectorToXiPi.cxx +/// \brief Xic0 → Xi Pi selection task +/// \author Ran Tu , Fudan University + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectorPID.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::analysis; + +enum pidInfoStored { + kPiFromLam = 0, + kPrFromLam, + kPiFromCasc, + kPiFromCharm +}; + +/// Struct for applying Xic0 -> Xi pi selection cuts +struct HfCandidateSelectorXic0ToXiPiKf { + Produces hfSelToXiPi; + + // LF analysis selections + Configurable radiusCascMin{"radiusCascMin", 0.5, "Min cascade radius"}; + Configurable radiusV0Min{"radiusV0Min", 1.1, "Min V0 radius"}; + Configurable cosPAV0Min{"cosPAV0Min", 0.97, "Min valueCosPA V0"}; + Configurable cosPACascMin{"cosPACascMin", 0.97, "Min value CosPA cascade"}; + Configurable dcaCascDauMax{"dcaCascDauMax", 1.0, "Max DCA cascade daughters"}; + Configurable dcaV0DauMax{"dcaV0DauMax", 1.0, "Max DCA V0 daughters"}; + Configurable dcaBachToPvMin{"dcaBachToPvMin", 0.04, "DCA Bach To PV"}; + Configurable dcaNegToPvMin{"dcaNegToPvMin", 0.06, "DCA Neg To PV"}; + Configurable dcaPosToPvMin{"dcaPosToPvMin", 0.06, "DCA Pos To PV"}; + Configurable v0MassWindow{"v0MassWindow", 0.01, "V0 mass window"}; + Configurable cascadeMassWindow{"cascadeMassWindow", 0.01, "Cascade mass window"}; + Configurable applyTrkSelLf{"applyTrkSelLf", true, "Apply track selection for LF daughters"}; + + // limit charm baryon invariant mass spectrum + Configurable invMassCharmBaryonMin{"invMassCharmBaryonMin", 2.0, "Lower limit invariant mass spectrum charm baryon"}; // 2.4 Omegac0 only + Configurable invMassCharmBaryonMax{"invMassCharmBaryonMax", 3.1, "Upper limit invariant mass spectrum charm baryon"}; + + // kinematic selections + Configurable etaTrackCharmBachMax{"etaTrackCharmBachMax", 0.8, "Max absolute value of eta for charm baryon bachelor"}; + Configurable etaTrackLFDauMax{"etaTrackLFDauMax", 1.0, "Max absolute value of eta for V0 and cascade daughters"}; + Configurable ptPiFromCascMin{"ptPiFromCascMin", 0.15, "Min pT pion <- casc"}; + Configurable ptPiFromCharmBaryonMin{"ptPiFromCharmBaryonMin", 0.2, "Min pT pi <- charm baryon"}; + + Configurable impactParameterXYPiFromCharmBaryonMin{"impactParameterXYPiFromCharmBaryonMin", 0., "Min dcaxy pi from charm baryon track to PV"}; + Configurable impactParameterXYPiFromCharmBaryonMax{"impactParameterXYPiFromCharmBaryonMax", 10., "Max dcaxy pi from charm baryon track to PV"}; + Configurable impactParameterZPiFromCharmBaryonMin{"impactParameterZPiFromCharmBaryonMin", 0., "Min dcaz pi from charm baryon track to PV"}; + Configurable impactParameterZPiFromCharmBaryonMax{"impactParameterZPiFromCharmBaryonMax", 10., "Max dcaz pi from charm baryon track to PV"}; + + Configurable impactParameterXYCascMin{"impactParameterXYCascMin", 0., "Min dcaxy cascade track to PV"}; + Configurable impactParameterXYCascMax{"impactParameterXYCascMax", 10., "Max dcaxy cascade track to PV"}; + Configurable impactParameterZCascMin{"impactParameterZCascMin", 0., "Min dcaz cascade track to PV"}; + Configurable impactParameterZCascMax{"impactParameterZCascMax", 10., "Max dcaz cascade track to PV"}; + + Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; + Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; + + Configurable dcaCharmBaryonDauMax{"dcaCharmBaryonDauMax", 2.0, "Max DCA charm baryon daughters"}; + + // PID options + Configurable usePidTpcOnly{"usePidTpcOnly", false, "Perform PID using only TPC"}; + Configurable usePidTpcTofCombined{"usePidTpcTofCombined", true, "Perform PID using TPC & TOF"}; + + // PID - TPC selections + + Configurable ptPrPidTpcMin{"ptPrPidTpcMin", -1, "Lower bound of track pT for TPC PID for proton selection"}; + Configurable ptPrPidTpcMax{"ptPrPidTpcMax", 9999.9, "Upper bound of track pT for TPC PID for proton selection"}; + Configurable nSigmaTpcPrMax{"nSigmaTpcPrMax", 3., "Nsigma cut on TPC only for proton selection"}; + Configurable nSigmaTpcCombinedPrMax{"nSigmaTpcCombinedPrMax", 0., "Nsigma cut on TPC combined with TOF for proton selection"}; + + Configurable ptPiPidTpcMin{"ptPiPidTpcMin", -1, "Lower bound of track pT for TPC PID for pion selection"}; + Configurable ptPiPidTpcMax{"ptPiPidTpcMax", 9999.9, "Upper bound of track pT for TPC PID for pion selection"}; + Configurable nSigmaTpcPiMax{"nSigmaTpcPiMax", 3., "Nsigma cut on TPC only for pion selection"}; + Configurable nSigmaTpcCombinedPiMax{"nSigmaTpcCombinedPiMax", 0., "Nsigma cut on TPC combined with TOF for pion selection"}; + + // PID - TOF selections + + Configurable ptPrPidTofMin{"ptPrPidTofMin", -1, "Lower bound of track pT for TOF PID for proton selection"}; + Configurable ptPrPidTofMax{"ptPrPidTofMax", 9999.9, "Upper bound of track pT for TOF PID for proton selection"}; + Configurable nSigmaTofPrMax{"nSigmaTofPrMax", 3., "Nsigma cut on TOF only for proton selection"}; + Configurable nSigmaTofCombinedPrMax{"nSigmaTofCombinedPrMax", 0., "Nsigma cut on TOF combined with TPC for proton selection"}; + + Configurable ptPiPidTofMin{"ptPiPidTofMin", -1, "Lower bound of track pT for TOF PID for pion selection"}; + Configurable ptPiPidTofMax{"ptPiPidTofMax", 9999.9, "Upper bound of track pT for TOF PID for pion selection"}; + Configurable nSigmaTofPiMax{"nSigmaTofPiMax", 3., "Nsigma cut on TOF only for pion selection"}; + Configurable nSigmaTofCombinedPiMax{"nSigmaTofCombinedPiMax", 0., "Nsigma cut on TOF combined with TOF for pion selection"}; + + // detector clusters selections + Configurable nClustersTpcMin{"nClustersTpcMin", 70, "Minimum number of TPC clusters requirement"}; + Configurable nTpcCrossedRowsMin{"nTpcCrossedRowsMin", 70, "Minimum number of TPC crossed rows requirement"}; + Configurable tpcCrossedRowsOverFindableClustersRatioMin{"tpcCrossedRowsOverFindableClustersRatioMin", 0.8, "Minimum ratio TPC crossed rows over findable clusters requirement"}; + Configurable tpcChi2PerClusterMax{"tpcChi2PerClusterMax", 4, "Maximum value of chi2 fit over TPC clusters"}; + Configurable nClustersItsMin{"nClustersItsMin", 3, "Minimum number of ITS clusters requirement for pi <- charm baryon"}; + Configurable nClustersItsInnBarrMin{"nClustersItsInnBarrMin", 1, "Minimum number of ITS clusters in inner barrel requirement for pi <- charm baryon"}; + Configurable itsChi2PerClusterMax{"itsChi2PerClusterMax", 36, "Maximum value of chi2 fit over ITS clusters for pi <- charm baryon"}; + + TrackSelectorPr selectorProton; + TrackSelectorPi selectorPion; + + using TracksSel = soa::Join; + using TracksSelLf = soa::Join; + + HistogramRegistry registry{"registry"}; // for QA of selections + + OutputObj hInvMassCharmBaryon{TH1D("hInvMassCharmBaryon", "Charm baryon invariant mass;inv mass;entries", 500, 2.3, 3.1)}; + + void init(InitContext const&) + { + selectorProton.setRangePtTpc(ptPrPidTpcMin, ptPrPidTpcMax); + selectorProton.setRangeNSigmaTpc(-nSigmaTpcPrMax, nSigmaTpcPrMax); + selectorProton.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedPrMax, nSigmaTpcCombinedPrMax); + selectorProton.setRangePtTof(ptPrPidTofMin, ptPrPidTofMax); + selectorProton.setRangeNSigmaTof(-nSigmaTofPrMax, nSigmaTofPrMax); + selectorProton.setRangeNSigmaTofCondTpc(-nSigmaTofCombinedPrMax, nSigmaTofCombinedPrMax); + + selectorPion.setRangePtTpc(ptPiPidTpcMin, ptPiPidTpcMax); + selectorPion.setRangeNSigmaTpc(-nSigmaTpcPiMax, nSigmaTpcPiMax); + selectorPion.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedPiMax, nSigmaTpcCombinedPiMax); + selectorPion.setRangePtTof(ptPiPidTofMin, ptPiPidTofMax); + selectorPion.setRangeNSigmaTof(-nSigmaTofPiMax, nSigmaTofPiMax); + selectorPion.setRangeNSigmaTofCondTpc(-nSigmaTofCombinedPiMax, nSigmaTofCombinedPiMax); + + const AxisSpec axisSel{2, -0.5, 1.5, "status"}; + + registry.add("hSelPID", "hSelPID;status;entries", {HistType::kTH1D, {{12, 0., 12.}}}); + registry.add("hStatusCheck", "Check consecutive selections status;status;entries", {HistType::kTH1D, {{12, 0., 12.}}}); + + // for QA of the selections (bin 0 -> candidates that did not pass the selection, bin 1 -> candidates that passed the selection) + registry.add("hSelSignDec", "hSelSignDec;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelEtaPosV0Dau", "hSelEtaPosV0Dau;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelEtaNegV0Dau", "hSelEtaNegV0Dau;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelEtaPiFromCasc", "hSelEtaPiFromCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelEtaPiFromCharm", "hSelEtaPiFromCharm;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelRadCasc", "hSelRadCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelRadV0", "hSelRadV0;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelCosPACasc", "hSelCosPACasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelCosPAV0", "hSelCosPAV0;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCACascDau", "hSelDCACascDau;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCAV0Dau", "hSelDCAV0Dau;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCACharmDau", "hSelDCACharmDau;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCAXYPrimPi", "hSelDCAXYPrimPi;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCAZPrimPi", "hSelDCAZPrimPi;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCAXYCasc", "hSelDCAXYCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDCAZCasc", "hSelDCAZCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelPtPiFromCasc", "hSelPtPiFromCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelPtPiFromCharm", "hSelPtPiFromCharm;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelTPCQualityPiFromCharm", "hSelTPCQualityPiFromCharm;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelTPCQualityPiFromLam", "hSelTPCQualityPiFromLam;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelTPCQualityPrFromLam", "hSelTPCQualityPrFromLam;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelTPCQualityPiFromCasc", "hSelTPCQualityPiFromCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelITSQualityPiFromCharm", "hSelITSQualityPiFromCharm;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelMassLam", "hSelMassLam;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelMassCasc", "hSelMassCasc;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelMassCharmBaryon", "hSelMassCharmBaryon;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDcaXYToPvV0Daughters", "hSelDcaXYToPvV0Daughters;status;entries", {HistType::kTH1D, {axisSel}}); + registry.add("hSelDcaXYToPvPiFromCasc", "hSelDcaXYToPvPiFromCasc;status;entries", {HistType::kTH1D, {axisSel}}); + } + + void process(aod::HfCandToXiPiKf const& candidates, + TracksSel const& tracks, + TracksSelLf const& lfTracks) + { + + // looping over charm baryon candidates + for (const auto& candidate : candidates) { + + bool resultSelections = true; // True if the candidate passes all the selections, False otherwise + + auto trackV0PosDauId = candidate.posTrackId(); // positive V0 daughter + auto trackV0NegDauId = candidate.negTrackId(); // negative V0 daughter + auto trackPiFromCascId = candidate.bachelorId(); // pion <- cascade + auto trackPiFromCharmId = candidate.bachelorFromCharmBaryonId(); // pion <- charm baryon + auto trackV0PosDau = lfTracks.rawIteratorAt(trackV0PosDauId); + auto trackV0NegDau = lfTracks.rawIteratorAt(trackV0NegDauId); + auto trackPiFromCasc = lfTracks.rawIteratorAt(trackPiFromCascId); + auto trackPiFromCharm = tracks.rawIteratorAt(trackPiFromCharmId); + + auto trackPiFromLam = trackV0NegDau; + auto trackPrFromLam = trackV0PosDau; + + int8_t signDecay = candidate.signDecay(); // sign of pi <- cascade + + if (signDecay > 0) { + trackPiFromLam = trackV0PosDau; + trackPrFromLam = trackV0NegDau; + registry.fill(HIST("hSelSignDec"), 1); // anti-particle decay + } else if (signDecay < 0) { + registry.fill(HIST("hSelSignDec"), 0); // particle decay + } + + // eta selection + double etaV0PosDau = candidate.etaV0PosDau(); + double etaV0NegDau = candidate.etaV0NegDau(); + double etaPiFromCasc = candidate.etaBachFromCasc(); + double etaPiFromCharmBaryon = candidate.etaBachFromCharmBaryon(); + if (std::abs(etaV0PosDau) > etaTrackLFDauMax) { + resultSelections = false; + registry.fill(HIST("hSelEtaPosV0Dau"), 0); + } else { + registry.fill(HIST("hSelEtaPosV0Dau"), 1); + } + if (std::abs(etaV0NegDau) > etaTrackLFDauMax) { + resultSelections = false; + registry.fill(HIST("hSelEtaNegV0Dau"), 0); + } else { + registry.fill(HIST("hSelEtaNegV0Dau"), 1); + } + if (std::abs(etaPiFromCasc) > etaTrackLFDauMax) { + resultSelections = false; + registry.fill(HIST("hSelEtaPiFromCasc"), 0); + } else { + registry.fill(HIST("hSelEtaPiFromCasc"), 1); + } + if (std::abs(etaPiFromCharmBaryon) > etaTrackCharmBachMax) { + resultSelections = false; + registry.fill(HIST("hSelEtaPiFromCharm"), 0); + } else { + registry.fill(HIST("hSelEtaPiFromCharm"), 1); + } + + // minimum radius cut (LFcut) + if (RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxCascade(), candidate.yDecayVtxCascade()) < radiusCascMin) { + resultSelections = false; + registry.fill(HIST("hSelRadCasc"), 0); + } else { + registry.fill(HIST("hSelRadCasc"), 1); + } + if (RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxV0(), candidate.yDecayVtxV0()) < radiusV0Min) { + resultSelections = false; + registry.fill(HIST("hSelRadV0"), 0); + } else { + registry.fill(HIST("hSelRadV0"), 1); + } + + // cosPA (LFcut) + if (candidate.cosPACasc() < cosPACascMin) { + resultSelections = false; + registry.fill(HIST("hSelCosPACasc"), 0); + } else { + registry.fill(HIST("hSelCosPACasc"), 1); + } + if (candidate.cosPAV0() < cosPAV0Min) { + resultSelections = false; + registry.fill(HIST("hSelCosPAV0"), 0); + } else { + registry.fill(HIST("hSelCosPAV0"), 1); + } + + // cascade and v0 daughters dca cut (LF cut) + if (candidate.dcaCascDau() > dcaCascDauMax) { + resultSelections = false; + registry.fill(HIST("hSelDCACascDau"), 0); + } else { + registry.fill(HIST("hSelDCACascDau"), 1); + } + + if (candidate.dcaV0Dau() > dcaV0DauMax) { + resultSelections = false; + registry.fill(HIST("hSelDCAV0Dau"), 0); + } else { + registry.fill(HIST("hSelDCAV0Dau"), 1); + } + + // dca charm baryon daughters cut + if (candidate.dcaCharmBaryonDau() > dcaCharmBaryonDauMax) { + resultSelections = false; + registry.fill(HIST("hSelDCACharmDau"), 0); + } else { + registry.fill(HIST("hSelDCACharmDau"), 1); + } + + // dcaXY v0 daughters to PV cut + if (std::abs(candidate.dcaXYToPvV0Dau0()) < dcaPosToPvMin || std::abs(candidate.dcaXYToPvV0Dau1()) < dcaNegToPvMin) { + resultSelections = false; + registry.fill(HIST("hSelDcaXYToPvV0Daughters"), 0); + } else { + registry.fill(HIST("hSelDcaXYToPvV0Daughters"), 1); + } + + // dcaXY ka <-- cascade to PV cut + if (std::abs(candidate.dcaXYToPvCascDau()) < dcaBachToPvMin) { + resultSelections = false; + registry.fill(HIST("hSelDcaXYToPvPiFromCasc"), 0); + } else { + registry.fill(HIST("hSelDcaXYToPvPiFromCasc"), 1); + } + + // cut on charm bachelor pion dcaXY and dcaZ + if ((std::abs(candidate.impactParBachFromCharmBaryonXY()) < impactParameterXYPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonXY()) > impactParameterXYPiFromCharmBaryonMax)) { + resultSelections = false; + registry.fill(HIST("hSelDCAXYPrimPi"), 0); + } else { + registry.fill(HIST("hSelDCAXYPrimPi"), 1); + } + if ((std::abs(candidate.impactParBachFromCharmBaryonZ()) < impactParameterZPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonZ()) > impactParameterZPiFromCharmBaryonMax)) { + resultSelections = false; + registry.fill(HIST("hSelDCAZPrimPi"), 0); + } else { + registry.fill(HIST("hSelDCAZPrimPi"), 1); + } + + // cut on cascade dcaXY and dcaZ + if ((std::abs(candidate.impactParCascXY()) < impactParameterXYCascMin) || (std::abs(candidate.impactParCascXY()) > impactParameterXYCascMax)) { + resultSelections = false; + registry.fill(HIST("hSelDCAXYCasc"), 0); + } else { + registry.fill(HIST("hSelDCAXYCasc"), 1); + } + if ((std::abs(candidate.impactParCascZ()) < impactParameterZCascMin) || (std::abs(candidate.impactParCascZ()) > impactParameterZCascMax)) { + resultSelections = false; + registry.fill(HIST("hSelDCAZCasc"), 0); + } else { + registry.fill(HIST("hSelDCAZCasc"), 1); + } + + // pT selections + double ptPiFromCasc = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCasc(), candidate.pyBachFromCasc()); + double ptPiFromCharmBaryon = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()); + if (std::abs(ptPiFromCasc) < ptPiFromCascMin) { + resultSelections = false; + registry.fill(HIST("hSelPtPiFromCasc"), 0); + } else { + registry.fill(HIST("hSelPtPiFromCasc"), 1); + } + if (std::abs(ptPiFromCharmBaryon) < ptPiFromCharmBaryonMin) { + resultSelections = false; + registry.fill(HIST("hSelPtPiFromCharm"), 0); + } else { + registry.fill(HIST("hSelPtPiFromCharm"), 1); + } + + // TPC clusters selections + if (applyTrkSelLf) { + if (!isSelectedTrackTpcQuality(trackPiFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + resultSelections = false; + registry.fill(HIST("hSelTPCQualityPiFromLam"), 0); + } else { + registry.fill(HIST("hSelTPCQualityPiFromLam"), 1); + } + if (!isSelectedTrackTpcQuality(trackPrFromLam, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + resultSelections = false; + registry.fill(HIST("hSelTPCQualityPrFromLam"), 0); + } else { + registry.fill(HIST("hSelTPCQualityPrFromLam"), 1); + } + if (!isSelectedTrackTpcQuality(trackPiFromCasc, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + resultSelections = false; + registry.fill(HIST("hSelTPCQualityPiFromCasc"), 0); + } else { + registry.fill(HIST("hSelTPCQualityPiFromCasc"), 1); + } + } + if (!isSelectedTrackTpcQuality(trackPiFromCharm, nClustersTpcMin, nTpcCrossedRowsMin, tpcCrossedRowsOverFindableClustersRatioMin, tpcChi2PerClusterMax)) { + resultSelections = false; + registry.fill(HIST("hSelTPCQualityPiFromCharm"), 0); + } else { + registry.fill(HIST("hSelTPCQualityPiFromCharm"), 1); + } + + // ITS clusters selection + if (!isSelectedTrackItsQuality(trackPiFromCharm, nClustersItsMin, itsChi2PerClusterMax) || trackPiFromCharm.itsNClsInnerBarrel() < nClustersItsInnBarrMin) { + resultSelections = false; + registry.fill(HIST("hSelITSQualityPiFromCharm"), 0); + } else { + registry.fill(HIST("hSelITSQualityPiFromCharm"), 1); + } + + // track-level PID selection + + // for TrackSelectorPID + int statusPidPrFromLam = -999; + int statusPidPiFromLam = -999; + int statusPidPiFromCasc = -999; + int statusPidPiFromCharmBaryon = -999; + + bool statusPidLambda = false; + bool statusPidCascade = false; + bool statusPidCharmBaryon = false; + + int infoTpcStored = 0; + int infoTofStored = 0; + + if (usePidTpcOnly == usePidTpcTofCombined) { + LOGF(fatal, "Check the PID configurables, usePidTpcOnly and usePidTpcTofCombined can't have the same value"); + } + + if (trackPiFromLam.hasTPC()) { + SETBIT(infoTpcStored, kPiFromLam); + } + if (trackPrFromLam.hasTPC()) { + SETBIT(infoTpcStored, kPrFromLam); + } + if (trackPiFromCasc.hasTPC()) { + SETBIT(infoTpcStored, kPiFromCasc); + } + if (trackPiFromCharm.hasTPC()) { + SETBIT(infoTpcStored, kPiFromCharm); + } + if (trackPiFromLam.hasTOF()) { + SETBIT(infoTofStored, kPiFromLam); + } + if (trackPrFromLam.hasTOF()) { + SETBIT(infoTofStored, kPrFromLam); + } + if (trackPiFromCasc.hasTOF()) { + SETBIT(infoTofStored, kPiFromCasc); + } + if (trackPiFromCharm.hasTOF()) { + SETBIT(infoTofStored, kPiFromCharm); + } + + if (usePidTpcOnly) { + statusPidPrFromLam = selectorProton.statusTpc(trackPrFromLam); + statusPidPiFromLam = selectorPion.statusTpc(trackPiFromLam); + statusPidPiFromCasc = selectorPion.statusTpc(trackPiFromCasc); + statusPidPiFromCharmBaryon = selectorPion.statusTpc(trackPiFromCharm); + } else if (usePidTpcTofCombined) { + statusPidPrFromLam = selectorProton.statusTpcOrTof(trackPrFromLam); + statusPidPiFromLam = selectorPion.statusTpcOrTof(trackPiFromLam); + statusPidPiFromCasc = selectorPion.statusTpcOrTof(trackPiFromCasc); + statusPidPiFromCharmBaryon = selectorPion.statusTpcOrTof(trackPiFromCharm); + } + + if (statusPidPrFromLam == TrackSelectorPID::Accepted && statusPidPiFromLam == TrackSelectorPID::Accepted) { + statusPidLambda = true; + if (resultSelections) { + registry.fill(HIST("hStatusCheck"), 0.5); + } + } + + if (statusPidPrFromLam == TrackSelectorPID::Accepted && statusPidPiFromLam == TrackSelectorPID::Accepted && statusPidPiFromCasc == TrackSelectorPID::Accepted) { + statusPidCascade = true; + if (resultSelections) { + registry.fill(HIST("hStatusCheck"), 1.5); + } + } + + if (statusPidPrFromLam == TrackSelectorPID::Accepted && statusPidPiFromLam == TrackSelectorPID::Accepted && statusPidPiFromCasc == TrackSelectorPID::Accepted && statusPidPiFromCharmBaryon == TrackSelectorPID::Accepted) { + statusPidCharmBaryon = true; + if (resultSelections) { + registry.fill(HIST("hStatusCheck"), 2.5); + } + } + + // invariant mass cuts + bool statusInvMassLambda = false; + bool statusInvMassCascade = false; + bool statusInvMassCharmBaryon = false; + + double invMassLambda = candidate.invMassLambda(); + double invMassCascade = candidate.invMassCascade(); + double invMassCharmBaryon = candidate.invMassCharmBaryon(); + + if (std::abs(invMassLambda - o2::constants::physics::MassLambda0) < v0MassWindow) { + statusInvMassLambda = true; + registry.fill(HIST("hSelMassLam"), 1); + if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && resultSelections) { + registry.fill(HIST("hStatusCheck"), 3.5); + } + } else { + registry.fill(HIST("hSelMassLam"), 0); + } + + if (std::abs(invMassCascade - o2::constants::physics::MassXiMinus) < cascadeMassWindow) { + statusInvMassCascade = true; + registry.fill(HIST("hSelMassCasc"), 1); + if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && resultSelections) { + registry.fill(HIST("hStatusCheck"), 4.5); + } + } else { + registry.fill(HIST("hSelMassCasc"), 0); + } + + if ((invMassCharmBaryon >= invMassCharmBaryonMin) && (invMassCharmBaryon <= invMassCharmBaryonMax)) { + statusInvMassCharmBaryon = true; + registry.fill(HIST("hSelMassCharmBaryon"), 1); + if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && statusInvMassCascade && resultSelections) { + registry.fill(HIST("hStatusCheck"), 5.5); + } + } else { + registry.fill(HIST("hSelMassCharmBaryon"), 0); + } + + hfSelToXiPi(statusPidCharmBaryon, statusPidCascade, statusPidLambda, statusInvMassCharmBaryon, statusInvMassCascade, statusInvMassLambda, resultSelections, infoTpcStored, infoTofStored, + trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), + trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); + + if (resultSelections) { + if (!statusPidLambda) { + registry.fill(HIST("hSelPID"), 0.5); + } + if (statusPidLambda) { + registry.fill(HIST("hSelPID"), 1.5); + } + if (!statusPidCascade) { + registry.fill(HIST("hSelPID"), 2.5); + } + if (statusPidCascade) { + registry.fill(HIST("hSelPID"), 3.5); + } + if (!statusPidCharmBaryon) { + registry.fill(HIST("hSelPID"), 4.5); + } + if (statusPidCharmBaryon) { + registry.fill(HIST("hSelPID"), 5.5); + } + if (!statusInvMassLambda) { + registry.fill(HIST("hSelPID"), 6.5); + } + if (statusInvMassLambda) { + registry.fill(HIST("hSelPID"), 7.5); + } + if (!statusInvMassCascade) { + registry.fill(HIST("hSelPID"), 8.5); + } + if (statusInvMassCascade) { + registry.fill(HIST("hSelPID"), 9.5); + } + if (!statusInvMassCharmBaryon) { + registry.fill(HIST("hSelPID"), 10.5); + } + if (statusInvMassCharmBaryon) { + registry.fill(HIST("hSelPID"), 11.5); + } + } + + if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && statusInvMassCascade && statusInvMassCharmBaryon && resultSelections) { + hInvMassCharmBaryon->Fill(invMassCharmBaryon); + } + } + } // end process +}; // end struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx b/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx new file mode 100644 index 00000000000..7cbc71277e5 --- /dev/null +++ b/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx @@ -0,0 +1,231 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file treeCreatorToXiPi.cxx +/// \brief Writer of the xic0 to Xi Pi candidates in the form of flat tables to be stored in TTrees. +/// In this file are defined and filled the output tables +/// +/// \author Ran Tu , Fudan University + +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/RecoDecay.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; + +namespace o2::aod +{ +namespace full +{ +DECLARE_SOA_COLUMN(InvMassLambda, invMassLambda, float); +DECLARE_SOA_COLUMN(InvMassCascade, invMassCascade, float); +DECLARE_SOA_COLUMN(InvMassCharmBaryon, invMassCharmBaryon, float); +DECLARE_SOA_COLUMN(DcaXYToPvV0Dau0, dcaXYToPvV0Dau0, float); +DECLARE_SOA_COLUMN(DcaXYToPvV0Dau1, dcaXYToPvV0Dau1, float); +DECLARE_SOA_COLUMN(DcaXYToPvCascDau, dcaXYToPvCascDau, float); +DECLARE_SOA_COLUMN(DcaCascDau, dcaCascDau, float); +DECLARE_SOA_COLUMN(DcaCharmBaryonDau, dcaCharmBaryonDau, float); +// from creator - MC +DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level +DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level +DECLARE_SOA_COLUMN(OriginRec, originRec, int8_t); +DECLARE_SOA_COLUMN(CollisionMatched, collisionMatched, bool); +// from selector +DECLARE_SOA_COLUMN(TpcNSigmaPiFromCharmBaryon, tpcNSigmaPiFromCharmBaryon, float); +DECLARE_SOA_COLUMN(TpcNSigmaPiFromCasc, tpcNSigmaPiFromCasc, float); +DECLARE_SOA_COLUMN(TpcNSigmaPiFromLambda, tpcNSigmaPiFromLambda, float); +DECLARE_SOA_COLUMN(TpcNSigmaPrFromLambda, tpcNSigmaPrFromLambda, float); +DECLARE_SOA_COLUMN(TofNSigmaPiFromCharmBaryon, tofNSigmaPiFromCharmBaryon, float); +DECLARE_SOA_COLUMN(TofNSigmaPiFromCasc, tofNSigmaPiFromCasc, float); +DECLARE_SOA_COLUMN(TofNSigmaPiFromLambda, tofNSigmaPiFromLambda, float); +DECLARE_SOA_COLUMN(TofNSigmaPrFromLambda, tofNSigmaPrFromLambda, float); +// from creator KF +DECLARE_SOA_COLUMN(KfDcaXYPiFromXic, kfDcaXYPiFromXic, float); +DECLARE_SOA_COLUMN(KfDcaXYCascToPv, kfDcaXYCascToPv, float); +DECLARE_SOA_COLUMN(Chi2GeoV0, chi2GeoV0, float); +DECLARE_SOA_COLUMN(Chi2GeoCasc, chi2GeoCasc, float); +DECLARE_SOA_COLUMN(Chi2GeoXic, chi2GeoXic, float); +DECLARE_SOA_COLUMN(Chi2MassV0, chi2MassV0, float); +DECLARE_SOA_COLUMN(Chi2MassCasc, chi2MassCasc, float); +DECLARE_SOA_COLUMN(V0ldl, v0ldl, float); +DECLARE_SOA_COLUMN(Cascldl, cascldl, float); +DECLARE_SOA_COLUMN(Xicldl, xicldl, float); +DECLARE_SOA_COLUMN(Chi2TopoV0ToPv, chi2TopoV0ToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoCascToPv, chi2TopoCascToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoPiFromXicToPv, chi2TopoPiFromXicToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoXicToPv, chi2TopoXicToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoV0ToCasc, chi2TopoV0ToCasc, float); +DECLARE_SOA_COLUMN(Chi2TopoCascToXic, chi2TopoCascToXic, float); +DECLARE_SOA_COLUMN(DecayLenXYLambda, decayLenXYLambda, float); +DECLARE_SOA_COLUMN(DecayLenXYCasc, decayLenXYCasc, float); +DECLARE_SOA_COLUMN(DecayLenXYXic, decayLenXYXic, float); +DECLARE_SOA_COLUMN(CosPaV0ToCasc, cosPaV0ToCasc, float); +DECLARE_SOA_COLUMN(CosPaV0ToPv, cosPaV0ToPv, float); +DECLARE_SOA_COLUMN(CosPaCascToXic, cosPaCascToXic, float); +DECLARE_SOA_COLUMN(CosPaCascToPv, cosPaCascToPv, float); +DECLARE_SOA_COLUMN(CosPaXicToPv, cosPaXicToPv, float); +DECLARE_SOA_COLUMN(KfRapXic, kfRapXic, float); +DECLARE_SOA_COLUMN(KfptPiFromXic, kfptPiFromXic, float); +DECLARE_SOA_COLUMN(KfptXic, kfptXic, float); +DECLARE_SOA_COLUMN(CosThetaStarPiFromXic, cosThetaStarPiFromXic, float); +DECLARE_SOA_COLUMN(CtXic, ctXic, float); +DECLARE_SOA_COLUMN(EtaXic, etaXic, float); +DECLARE_SOA_COLUMN(V0Ndf, v0Ndf, float); +DECLARE_SOA_COLUMN(CascNdf, cascNdf, float); +DECLARE_SOA_COLUMN(XicNdf, xicNdf, float); +DECLARE_SOA_COLUMN(MassV0Ndf, massV0Ndf, float); +DECLARE_SOA_COLUMN(MassCascNdf, massCascNdf, float); +DECLARE_SOA_COLUMN(V0Chi2OverNdf, v0Chi2OverNdf, float); +DECLARE_SOA_COLUMN(CascChi2OverNdf, cascChi2OverNdf, float); +DECLARE_SOA_COLUMN(XicChi2OverNdf, xicChi2OverNdf, float); +DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); +DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); + +} // namespace full + +DECLARE_SOA_TABLE(HfKfXicFulls, "AOD", "HFKFXICFULL", + full::TpcNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TofNSigmaPiFromCasc, + full::TpcNSigmaPiFromLambda, full::TofNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPrFromLambda, + full::KfDcaXYPiFromXic, full::DcaCascDau, full::DcaCharmBaryonDau, full::KfDcaXYCascToPv, + full::DcaXYToPvV0Dau0, full::DcaXYToPvV0Dau1, full::DcaXYToPvCascDau, + full::Chi2GeoV0, full::Chi2GeoCasc, full::Chi2GeoXic, + full::Chi2MassV0, full::Chi2MassCasc, + full::V0ldl, full::Cascldl, full::Xicldl, + full::Chi2TopoV0ToPv, full::Chi2TopoCascToPv, full::Chi2TopoPiFromXicToPv, full::Chi2TopoXicToPv, + full::Chi2TopoV0ToCasc, full::Chi2TopoCascToXic, + full::DecayLenXYLambda, full::DecayLenXYCasc, full::DecayLenXYXic, + full::CosPaV0ToCasc, full::CosPaV0ToPv, full::CosPaCascToXic, full::CosPaCascToPv, full::CosPaXicToPv, + full::InvMassLambda, full::InvMassCascade, full::InvMassCharmBaryon, + full::KfRapXic, full::KfptPiFromXic, full::KfptXic, + full::CosThetaStarPiFromXic, full::CtXic, full::EtaXic, + full::V0Ndf, full::CascNdf, full::XicNdf, + full::MassV0Ndf, full::MassCascNdf, + full::V0Chi2OverNdf, full::CascChi2OverNdf, full::XicChi2OverNdf, + full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, + full::FlagMcMatchRec, full::DebugMcRec, full::OriginRec, full::CollisionMatched); + +} // namespace o2::aod + +/// Writes the full information in an output TTree +struct HfTreeCreatorXic0ToXiPiKf { + + Produces rowKfCandidate; + + Configurable zPvCut{"zPvCut", 10., "Cut on absolute value of primary vertex z coordinate"}; + + using MyTrackTable = soa::Join; + + void init(InitContext const&) + { + } + + template + void fillKfCandidate(const T& candidate, int8_t flagMc, int8_t debugMc, int8_t originMc, bool collisionMatched) + { + + if (candidate.resultSelections() && candidate.statusPidCharmBaryon() && candidate.statusInvMassLambda() && candidate.statusInvMassCascade() && candidate.statusInvMassCharmBaryon()) { + + rowKfCandidate( + candidate.tpcNSigmaPiFromCharmBaryon(), + candidate.tofNSigmaPiFromCharmBaryon(), + candidate.tpcNSigmaPiFromCasc(), + candidate.tofNSigmaPiFromCasc(), + candidate.tpcNSigmaPiFromLambda(), + candidate.tofNSigmaPiFromLambda(), + candidate.tpcNSigmaPrFromLambda(), + candidate.tofNSigmaPrFromLambda(), + candidate.kfDcaXYPiFromXic(), + candidate.dcaCascDau(), + candidate.dcaCharmBaryonDau(), + candidate.kfDcaXYCascToPv(), + candidate.dcaXYToPvV0Dau0(), + candidate.dcaXYToPvV0Dau1(), + candidate.dcaXYToPvCascDau(), + candidate.chi2GeoV0(), + candidate.chi2GeoCasc(), + candidate.chi2GeoXic(), + candidate.chi2MassV0(), + candidate.chi2MassCasc(), + candidate.v0ldl(), + candidate.cascldl(), + candidate.xicldl(), + candidate.chi2TopoV0ToPv(), + candidate.chi2TopoCascToPv(), + candidate.chi2TopoPiFromXicToPv(), + candidate.chi2TopoXicToPv(), + candidate.chi2TopoV0ToCasc(), + candidate.chi2TopoCascToXic(), + candidate.decayLenXYLambda(), + candidate.decayLenXYCasc(), + candidate.decayLenXYXic(), + candidate.cosPaV0ToCasc(), + candidate.cosPAV0(), + candidate.cosPaCascToXic(), + candidate.cosPACasc(), + candidate.cosPACharmBaryon(), + candidate.invMassLambda(), + candidate.invMassCascade(), + candidate.invMassCharmBaryon(), + candidate.kfRapXic(), + candidate.kfptPiFromXic(), + candidate.kfptXic(), + candidate.cosThetaStarPiFromXic(), + candidate.ctauXic(), + candidate.etaCharmBaryon(), + candidate.v0Ndf(), + candidate.cascNdf(), + candidate.xicNdf(), + candidate.massV0Ndf(), + candidate.massCascNdf(), + candidate.v0Chi2OverNdf(), + candidate.cascChi2OverNdf(), + candidate.xicChi2OverNdf(), + candidate.massV0Chi2OverNdf(), + candidate.massCascChi2OverNdf(), + flagMc, + debugMc, + originMc, + collisionMatched); + } + } + + void processKfData(MyTrackTable const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfData, "Process KF data", false); + + void processKfMcXic0(MyTrackTable const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originRec(), candidate.collisionMatched()); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfMcXic0, "Process MC with information for xic0", false); + +}; // end of struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} From e4eea1844fa107a3b4dacab19e7ca958130f6d0a Mon Sep 17 00:00:00 2001 From: Junlee Kim Date: Mon, 16 Dec 2024 14:33:09 +0100 Subject: [PATCH 29/30] [PWGLF] separating pair combination (#8995) Co-authored-by: junleekim Co-authored-by: junleekim --- PWGLF/Tasks/Strangeness/lambdalambda.cxx | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdalambda.cxx b/PWGLF/Tasks/Strangeness/lambdalambda.cxx index 320b98db6d1..e974b812990 100644 --- a/PWGLF/Tasks/Strangeness/lambdalambda.cxx +++ b/PWGLF/Tasks/Strangeness/lambdalambda.cxx @@ -149,15 +149,15 @@ struct lambdalambda { AxisSpec PVzQaAxis = {300, -15.0, 15.0}; AxisSpec combAxis = {3, -0.5, 2.5}; - histos.add("Radius_V0V0_full", "", {HistType::kTH3F, {massAxis, ptAxis, RadiusAxis}}); - histos.add("CPA_V0V0_full", "", {HistType::kTH3F, {massAxis, ptAxis, CPAAxis}}); - histos.add("Distance_V0V0_full", "", {HistType::kTH3F, {massAxis, ptAxis, DistanceAxis}}); - histos.add("DCA_V0V0_full", "", {HistType::kTH3F, {massAxis, ptAxis, DCAAxis}}); + histos.add("Radius_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, RadiusAxis, combAxis}}); + histos.add("CPA_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, CPAAxis, combAxis}}); + histos.add("Distance_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DistanceAxis, combAxis}}); + histos.add("DCA_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCAAxis, combAxis}}); - histos.add("Radius_V0V0_sel", "", {HistType::kTH3F, {massAxis, ptAxis, RadiusAxis}}); - histos.add("CPA_V0V0_sel", "", {HistType::kTH3F, {massAxis, ptAxis, CPAAxis}}); - histos.add("Distance_V0V0_sel", "", {HistType::kTH3F, {massAxis, ptAxis, DistanceAxis}}); - histos.add("DCA_V0V0_sel", "", {HistType::kTH3F, {massAxis, ptAxis, DCAAxis}}); + histos.add("Radius_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, RadiusAxis, combAxis}}); + histos.add("CPA_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, CPAAxis, combAxis}}); + histos.add("Distance_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DistanceAxis, combAxis}}); + histos.add("DCA_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCAAxis, combAxis}}); histos.add("h_InvMass_same", "", {HistType::kTHnSparseF, {massAxis, ptAxis, centAxis, combAxis}}); histos.add("h_InvMass_mixed", "", {HistType::kTHnSparseF, {massAxis, ptAxis, centAxis, combAxis}}); @@ -300,8 +300,8 @@ struct lambdalambda { float getCPA(V01 const& v01, V02 const& v02) { ROOT::Math::XYZVector v01mom, v02mom; - v01mom.SetXYZ(v01.px(), v01.py(), v01.pz()); - v02mom.SetXYZ(v02.px(), v02.py(), v02.pz()); + v01mom.SetXYZ(v01.px() / v01.p(), v01.py() / v01.p(), v01.pz() / v01.p()); + v02mom.SetXYZ(v02.px() / v02.p(), v02.py() / v02.p(), v02.pz() / v02.p()); return v01mom.Dot(v02mom); } @@ -415,16 +415,16 @@ struct lambdalambda { if (std::abs(RecoV0V0.Rapidity()) > cfgV0V0RapMax) continue; - histos.fill(HIST("Radius_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getRadius(v01, v02)); - histos.fill(HIST("CPA_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getCPA(v01, v02)); - histos.fill(HIST("Distance_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getDistance(v01, v02)); - histos.fill(HIST("DCA_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getDCAofV0V0(v01, v02)); + histos.fill(HIST("Radius_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getRadius(v01, v02), V01Tag + V02Tag); + histos.fill(HIST("CPA_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getCPA(v01, v02), V01Tag + V02Tag); + histos.fill(HIST("Distance_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getDistance(v01, v02), V01Tag + V02Tag); + histos.fill(HIST("DCA_V0V0_full"), RecoV0V0.M(), RecoV0V0.Pt(), getDCAofV0V0(v01, v02), V01Tag + V02Tag); if (isSelectedV0V0(v01, v02)) { - histos.fill(HIST("Radius_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getRadius(v01, v02)); - histos.fill(HIST("CPA_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getCPA(v01, v02)); - histos.fill(HIST("Distance_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getDistance(v01, v02)); - histos.fill(HIST("DCA_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getDCAofV0V0(v01, v02)); + histos.fill(HIST("Radius_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getRadius(v01, v02), V01Tag + V02Tag); + histos.fill(HIST("CPA_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getCPA(v01, v02), V01Tag + V02Tag); + histos.fill(HIST("Distance_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getDistance(v01, v02), V01Tag + V02Tag); + histos.fill(HIST("DCA_V0V0_sel"), RecoV0V0.M(), RecoV0V0.Pt(), getDCAofV0V0(v01, v02), V01Tag + V02Tag); } if (cfgV0V0Sel && !isSelectedV0V0(v01, v02)) From b06b8ca70db42b4a14f1d321b050e43d23aab784 Mon Sep 17 00:00:00 2001 From: syano0822 <32352856+syano0822@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:49:28 +0900 Subject: [PATCH 30/30] =?UTF-8?q?[Common]=20MC=20information=20fuction=20i?= =?UTF-8?q?s=20added=20into=20Common/TableProducer/match-mft-m=E2=80=A6=20?= =?UTF-8?q?(#9004)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Satoshi Yano --- Common/DataModel/MatchMFTMuonData.h | 135 ++ Common/TableProducer/CMakeLists.txt | 5 + .../TableProducer/match-mft-mch-data-mc.cxx | 881 +++++++++++ Common/TableProducer/match-mft-mch-data.cxx | 1323 +++++++++-------- 4 files changed, 1688 insertions(+), 656 deletions(-) create mode 100644 Common/DataModel/MatchMFTMuonData.h create mode 100644 Common/TableProducer/match-mft-mch-data-mc.cxx diff --git a/Common/DataModel/MatchMFTMuonData.h b/Common/DataModel/MatchMFTMuonData.h new file mode 100644 index 00000000000..d1b59dc168c --- /dev/null +++ b/Common/DataModel/MatchMFTMuonData.h @@ -0,0 +1,135 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#ifndef COMMON_DATAMODEL_MATCHMFTMUONDATA_H_ +#define COMMON_DATAMODEL_MATCHMFTMUONDATA_H_ +#include "Framework/AnalysisDataModel.h" +#endif // COMMON_DATAMODEL_MATCHMFTMUONDATA_H_ + +namespace o2::aod +{ +namespace matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(DeltaPt, mDeltaPt, float); +DECLARE_SOA_COLUMN(DeltaEta, mDeltaEta, float); +DECLARE_SOA_COLUMN(DeltaPhi, mDeltaPhi, float); +DECLARE_SOA_COLUMN(DeltaX, mDeltaX, float); +DECLARE_SOA_COLUMN(DeltaY, mDeltaY, float); +DECLARE_SOA_COLUMN(GMuonPt, mGMuonPt, float); +DECLARE_SOA_COLUMN(GMuonEta, mGMuonEta, float); +DECLARE_SOA_COLUMN(PairQ, mPairQ, int16_t); +DECLARE_SOA_COLUMN(IsCorrectMatch, mIsCorrectMatch, bool); +} // namespace matching_params + +DECLARE_SOA_TABLE(MatchParams, "AOD", "MATCHING", + matching_params::GMuonPt, + matching_params::GMuonEta, + matching_params::PairQ, + matching_params::DeltaPt, + matching_params::DeltaX, + matching_params::DeltaY, + matching_params::DeltaEta, + matching_params::DeltaPhi, + matching_params::IsCorrectMatch); + +namespace tag_matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(DeltaPt, mDeltaPt, float); +DECLARE_SOA_COLUMN(DeltaEta, mDeltaEta, float); +DECLARE_SOA_COLUMN(DeltaPhi, mDeltaPhi, float); +DECLARE_SOA_COLUMN(DeltaX, mDeltaX, float); +DECLARE_SOA_COLUMN(DeltaY, mDeltaY, float); +DECLARE_SOA_COLUMN(GMuonPt, mGMuonPt, float); +DECLARE_SOA_COLUMN(GMuonEta, mGMuonEta, float); +DECLARE_SOA_COLUMN(PairQ, mPairQ, int16_t); +DECLARE_SOA_COLUMN(IsCorrectMatch, mIsCorrectMatch, bool); +} // namespace tag_matching_params + +DECLARE_SOA_TABLE(TagMatchParams, "AOD", "TAGMATCHING", + tag_matching_params::GMuonPt, + tag_matching_params::GMuonEta, + tag_matching_params::PairQ, + tag_matching_params::DeltaPt, + tag_matching_params::DeltaX, + tag_matching_params::DeltaY, + tag_matching_params::DeltaEta, + tag_matching_params::DeltaPhi, + tag_matching_params::IsCorrectMatch); + +namespace probe_matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(DeltaPt, mDeltaPt, float); +DECLARE_SOA_COLUMN(DeltaEta, mDeltaEta, float); +DECLARE_SOA_COLUMN(DeltaPhi, mDeltaPhi, float); +DECLARE_SOA_COLUMN(DeltaX, mDeltaX, float); +DECLARE_SOA_COLUMN(DeltaY, mDeltaY, float); +DECLARE_SOA_COLUMN(TagGMuonPt, mTagGMuonPt, float); +DECLARE_SOA_COLUMN(GMuonPt, mGMuonPt, float); +DECLARE_SOA_COLUMN(GMuonEta, mGMuonEta, float); +DECLARE_SOA_COLUMN(PairQ, mPairQ, int16_t); +DECLARE_SOA_COLUMN(IsCorrectMatch, mIsCorrectMatch, bool); +} // namespace probe_matching_params + +DECLARE_SOA_TABLE(ProbeMatchParams, "AOD", "PROBEMATCHING", + probe_matching_params::TagGMuonPt, + probe_matching_params::GMuonPt, + probe_matching_params::GMuonEta, + probe_matching_params::PairQ, + probe_matching_params::DeltaPt, + probe_matching_params::DeltaX, + probe_matching_params::DeltaY, + probe_matching_params::DeltaEta, + probe_matching_params::DeltaPhi, + probe_matching_params::IsCorrectMatch); + +namespace mix_matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(DeltaPt, mDeltaPt, float); +DECLARE_SOA_COLUMN(DeltaEta, mDeltaEta, float); +DECLARE_SOA_COLUMN(DeltaPhi, mDeltaPhi, float); +DECLARE_SOA_COLUMN(DeltaX, mDeltaX, float); +DECLARE_SOA_COLUMN(DeltaY, mDeltaY, float); +DECLARE_SOA_COLUMN(GMuonPt, mGMuonPt, float); +DECLARE_SOA_COLUMN(GMuonEta, mGMuonEta, float); +DECLARE_SOA_COLUMN(PairQ, mPairQ, int16_t); +DECLARE_SOA_COLUMN(IsCorrectMatch, mIsCorrectMatch, bool); +} // namespace mix_matching_params + +DECLARE_SOA_TABLE(MixMatchParams, "AOD", "MIXMATCHING", + mix_matching_params::GMuonPt, + mix_matching_params::GMuonEta, + mix_matching_params::PairQ, + mix_matching_params::DeltaPt, + mix_matching_params::DeltaX, + mix_matching_params::DeltaY, + mix_matching_params::DeltaEta, + mix_matching_params::DeltaPhi, + mix_matching_params::IsCorrectMatch); + +namespace muon_pair +{ +// matching parameters +DECLARE_SOA_COLUMN(Mass, mMass, float); +DECLARE_SOA_COLUMN(Pt, mPt, float); +DECLARE_SOA_COLUMN(Rap, mRap, float); +DECLARE_SOA_COLUMN(PairQ, mPairQ, int16_t); +} // namespace muon_pair + +DECLARE_SOA_TABLE(MuonPair, "AOD", "MUONPAIR", + muon_pair::PairQ, + muon_pair::Mass, + muon_pair::Pt, + muon_pair::Rap); + +} // namespace o2::aod diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 91513029f73..d0a9e6f5440 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -134,3 +134,8 @@ o2physics_add_dpl_workflow(mftmch-matching-data SOURCES match-mft-mch-data.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(mftmch-matching-data-mc + SOURCES match-mft-mch-data-mc.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) diff --git a/Common/TableProducer/match-mft-mch-data-mc.cxx b/Common/TableProducer/match-mft-mch-data-mc.cxx new file mode 100644 index 00000000000..4a03582489d --- /dev/null +++ b/Common/TableProducer/match-mft-mch-data-mc.cxx @@ -0,0 +1,881 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include +#include +#include +#include +#include + +#include "CCDB/BasicCCDBManager.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/MftmchMatchingML.h" +#include "Common/DataModel/MatchMFTMuonData.h" +#include "Common/Core/trackUtilities.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "DetectorsVertexing/VertexTrackMatcher.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" +#include "ReconstructionDataFormats/VtxTrackIndex.h" +#include "ReconstructionDataFormats/VtxTrackRef.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "CommonDataFormat/InteractionRecord.h" +#include "DetectorsVertexing/PVertexerParams.h" +#include "MathUtils/Primitive2D.h" +#include "DataFormatsGlobalTracking/RecoContainer.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/MatchMFTFT0.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Field/MagneticField.h" +#include "TGeoGlobalMagField.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "EventFiltering/Zorro.h" +#include "ReconstructionDataFormats/TrackFwd.h" +#include "Math/MatrixFunctions.h" +#include "Math/SMatrix.h" +#include "MFTTracking/Tracker.h" +#include "MCHTracking/TrackParam.h" +#include "MCHTracking/TrackExtrap.h" +#include "GlobalTracking/MatchGlobalFwd.h" +#include +#include +#include "TDatabasePDG.h" + +using namespace std; + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" + +using MyCollisions = aod::Collisions; +using MyBCs = soa::Join; +using MyMUONs = soa::Join; +using MyMFTs = soa::Join; + +using MyCollision = MyCollisions::iterator; +using MyBC = MyBCs::iterator; +using MyMUON = MyMUONs::iterator; +using MyMFT = MyMFTs::iterator; + +using SMatrix55 = ROOT::Math::SMatrix>; +using SMatrix5 = ROOT::Math::SVector; + +float mMu = TDatabasePDG::Instance()->GetParticle(13)->Mass(); +int mRunNumber; +/* + TLorentzVector muon1LV; + TLorentzVector muon2LV; + TLorentzVector dimuonLV; +*/ +unordered_map> map_mfttracks; +unordered_map> map_muontracks; +unordered_map map_collisions; +unordered_map map_has_mfttracks_collisions; +unordered_map map_has_muontracks_collisions; +unordered_map map_vtxz; +unordered_map map_nmfttrack; + +struct match_mft_mch_data_mc { + + //// Variables for matching method + Configurable fMatchingMethod{"cfgMatchingMethod", 0, ""}; + + //// Variables for selecting muon tracks + Configurable fEtaMchLow{"cfgEtaMchLow", -4.0f, ""}; + Configurable fEtaMchUp{"cfgEtaMchUp", -2.5f, ""}; + Configurable fRabsLow1{"cfgRabsLow1", 17.6f, ""}; + Configurable fRabsUp1{"cfgRabsUp1", 26.5f, ""}; + Configurable fRabsLow2{"cfgRabsLow2", 26.5f, ""}; + Configurable fRabsUp2{"cfgRabsUp2", 89.5f, ""}; + Configurable fPdcaUp1{"cfgPdcaUp1", 594.f, ""}; + Configurable fPdcaUp2{"cfgPdcaUp2", 324.f, ""}; + Configurable fTrackChi2MchUp{"cfgTrackChi2MchUp", 5.f, ""}; + Configurable fMatchingChi2MchMidUp{"cfgMatchingChi2MchMidUp", 999.f, ""}; + + //// Variables for selecting mft tracks + Configurable fEtaMftLow{"cfgEtaMftlow", -3.6f, ""}; + Configurable fEtaMftUp{"cfgEtaMftup", -2.5f, ""}; + Configurable fTrackNClustMftLow{"cfgTrackNClustMftLow", 7, ""}; + Configurable fTrackChi2MftUp{"cfgTrackChi2MftUp", 999.f, ""}; + + /// Variables to add preselection for the matching table + Configurable fPreselectMatchingX{"cfgPreselectMatchingX", 15.f, ""}; + Configurable fPreselectMatchingY{"cfgPreselectMatchingY", 15.f, ""}; + + /// Variables to event mixing criteria + Configurable fSaveMixedMatchingParamsRate{"cfgSaveMixedMatchingParamsRate", 0.002f, ""}; + Configurable fEventMaxDeltaNMFT{"cfgEventMaxDeltaNMFT", 1, ""}; + Configurable fEventMaxDeltaVtxZ{"cfgEventMaxDeltaVtxZ", 1.f, ""}; + + //// Variables for selecting tag muon + Configurable fTagMassWindowMin{"cfgTagMassWindowMin", 2.8f, ""}; + Configurable fTagMassWindowMax{"cfgTagMassWindowMax", 3.3f, ""}; + + //// Variables for ccdb + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + + //// Variables for Tag matching criteria + Configurable fSigmaXTagMuonCut{"cfgSigmaXTagMuonCut", 1.f, ""}; + Configurable fMeanXTagMuonCut{"cfgMeanXTagMuonCut", 0.f, ""}; + Configurable fSigmaYTagMuonCut{"cfgSigmaYTagMuonCut", 1.f, ""}; + Configurable fMeanYTagMuonCut{"cfgMeanYTagMuonCut", 1.f, ""}; + + Configurable fSigmaEtaTagMuonCut{"cfgSigmaEtaTagMuonCut", 0.2f, ""}; + Configurable fMeanEtaTagMuonCut{"cfgMeanEtaTagMuonCut", 0.f, ""}; + Configurable fSigmaPhiTagMuonCut{"cfgSigmaPhiTagMuonCut", 0.2f, ""}; + Configurable fMeanPhiTagMuonCut{"cfgMeanPhiTagMuonCut", 0.f, ""}; + + template + class FindTagAndProbe + { + private: + o2::dataformats::GlobalFwdTrack muontrack_at_pv[2]; + + TLorentzVector mDimuon; + MUON muontrack1; + MUON muontrack2; + Collision collision; + int tagIdx, probeIdx; + + int16_t mQ; + + inline void fillCovarianceArray(MUON const& muontrack, float cov[15]) const + { + cov[0] = muontrack.cXX(); + cov[1] = muontrack.cXY(); + cov[2] = muontrack.cYY(); + cov[3] = muontrack.cPhiX(); + cov[4] = muontrack.cPhiY(); + cov[5] = muontrack.cPhiPhi(); + cov[6] = muontrack.cTglX(); + cov[7] = muontrack.cTglY(); + cov[8] = muontrack.cTglPhi(); + cov[9] = muontrack.cTglTgl(); + cov[10] = muontrack.c1PtX(); + cov[11] = muontrack.c1PtY(); + cov[12] = muontrack.c1PtPhi(); + cov[13] = muontrack.c1PtTgl(); + cov[14] = muontrack.c1Pt21Pt2(); + } + + inline o2::dataformats::GlobalFwdTrack propagateMUONtoPV(MUON const& muontrack) const + { + const double mz = muontrack.z(); + const double mchi2 = muontrack.chi2(); + const float mx = muontrack.x(); + const float my = muontrack.y(); + const float mphi = muontrack.phi(); + const float mtgl = muontrack.tgl(); + const float m1pt = muontrack.signed1Pt(); + + float cov[15]; + fillCovarianceArray(muontrack, cov); + SMatrix5 tpars(mx, my, mphi, mtgl, m1pt); + SMatrix55 tcovs(cov, cov + 15); + + o2::track::TrackParCovFwd parcovmuontrack{mz, tpars, tcovs, mchi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + + o2::globaltracking::MatchGlobalFwd mMatching; + auto mchtrack = mMatching.FwdtoMCH(gtrack); + + o2::mch::TrackExtrap::extrapToVertex(mchtrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + o2::dataformats::GlobalFwdTrack extrap_muontrack; + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + + return extrap_muontrack; + } + + inline void setTagAndProbe() + { + if (muontrack1.pt() > muontrack2.pt()) { + tagIdx = 0; + probeIdx = 1; + } else { + tagIdx = 1; + probeIdx = 0; + } + } + + public: + inline FindTagAndProbe(const MUON& muon1, const MUON& muon2, const Collision& coll) + : muontrack_at_pv(), mDimuon(), muontrack1(muon1), muontrack2(muon2), collision(coll), tagIdx(-1), probeIdx(-1), mQ(0) + { + mQ = muontrack1.sign() + muontrack2.sign(); + setTagAndProbe(); + } + + void calcMuonPairAtPV() + { + muontrack_at_pv[0] = propagateMUONtoPV(muontrack1); + muontrack_at_pv[1] = propagateMUONtoPV(muontrack2); + TLorentzVector vMuon1, vMuon2; + vMuon1.SetPtEtaPhiM(muontrack_at_pv[0].getPt(), muontrack_at_pv[0].getEta(), muontrack_at_pv[0].getPhi(), mMu); + vMuon2.SetPtEtaPhiM(muontrack_at_pv[1].getPt(), muontrack_at_pv[1].getEta(), muontrack_at_pv[1].getPhi(), mMu); + mDimuon = vMuon1 + vMuon2; + } + inline int getTagMuonIndex() const { return tagIdx; } + inline int getProbeMuonIndex() const { return probeIdx; } + inline float getMass() const { return mDimuon.M(); } + inline float getPt() const { return mDimuon.Pt(); } + inline float getRap() const { return mDimuon.Rapidity(); } + inline int16_t getCharge() const { return mQ; } + inline const o2::dataformats::GlobalFwdTrack& getMuonAtPV(int idx) const { return muontrack_at_pv[idx]; } + }; // end of class FindTagAndProbe + + template + class MatchingParamsML + { + private: + MUON muontrack; + MFT mfttrack; + Collision collision; + + float mDX, mDY, mDPt, mDPhi, mDEta; + float mGlobalMuonPtAtDCA, mGlobalMuonEtaAtDCA, mGlobalMuonPhiAtDCA, mGlobalMuonDCAx, mGlobalMuonDCAy, mGlobalMuonQ; + int mMatchingType; + + o2::field::MagneticField* fieldB; + o2::globaltracking::MatchGlobalFwd mMatching; + + inline o2::track::TrackParCovFwd propagateMFTtoMatchingPlane() + { + double covArr[15]{0.0}; + SMatrix55 tmftcovs(covArr, covArr + 15); + + SMatrix5 tmftpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()); + o2::track::TrackParCovFwd extrap_mfttrack{mfttrack.z(), tmftpars, tmftcovs, mfttrack.chi2()}; + + double propVec[3] = {0.}; + float zPlane = 0.f; + if (mMatchingType == MCH_FIRST_CLUSTER) { + propVec[0] = muontrack.x() - mfttrack.x(); + propVec[1] = muontrack.y() - mfttrack.y(); + propVec[2] = muontrack.z() - mfttrack.z(); + zPlane = muontrack.z(); + } else if (mMatchingType == END_OF_ABSORBER || mMatchingType == BEGINING_OF_ABSORBER) { + auto extrap_muontrack = propagateMUONtoMatchingPlane(); + propVec[0] = extrap_muontrack.getX() - mfttrack.x(); + propVec[1] = extrap_muontrack.getY() - mfttrack.y(); + propVec[2] = extrap_muontrack.getZ() - mfttrack.z(); + zPlane = (mMatchingType == END_OF_ABSORBER) ? -505.f : -90.f; + } else { + zPlane = mfttrack.z(); + } + + double centerZ[3] = {mfttrack.x() + propVec[0] / 2., mfttrack.y() + propVec[1] / 2., mfttrack.z() + propVec[2] / 2.}; + float Bz = fieldB->getBz(centerZ); + extrap_mfttrack.propagateToZ(zPlane, Bz); // z in cm + return extrap_mfttrack; + } + + inline o2::dataformats::GlobalFwdTrack propagateMUONtoMatchingPlane() + { + float cov[15] = { + muontrack.cXX(), muontrack.cXY(), muontrack.cYY(), + muontrack.cPhiX(), muontrack.cPhiY(), muontrack.cPhiPhi(), + muontrack.cTglX(), muontrack.cTglY(), muontrack.cTglPhi(), + muontrack.cTglTgl(), muontrack.c1PtX(), muontrack.c1PtY(), + muontrack.c1PtPhi(), muontrack.c1PtTgl(), muontrack.c1Pt21Pt2()}; + + SMatrix5 tpars(muontrack.x(), muontrack.y(), muontrack.phi(), muontrack.tgl(), muontrack.signed1Pt()); + SMatrix55 tcovs(cov, cov + 15); + double chi2 = muontrack.chi2(); + + o2::track::TrackParCovFwd parcovmuontrack{muontrack.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + + auto mchtrack = mMatching.FwdtoMCH(gtrack); + + if (mMatchingType == MFT_LAST_CLUSTR) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchtrack, mfttrack.z()); + } else if (mMatchingType == END_OF_ABSORBER) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchtrack, -505.); + } else if (mMatchingType == BEGINING_OF_ABSORBER) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchtrack, -90.); + } + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + + o2::dataformats::GlobalFwdTrack extrap_muontrack; + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + return extrap_muontrack; + } + + inline o2::track::TrackParCovFwd propagateMFTtoDCA() + { + double covArr[15]{0.0}; + SMatrix55 tmftcovs(covArr, covArr + 15); + + SMatrix5 tmftpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()); + o2::track::TrackParCovFwd extrap_mfttrack{mfttrack.z(), tmftpars, tmftcovs, mfttrack.chi2()}; + + double propVec[3] = {}; + propVec[0] = collision.posX() - mfttrack.x(); + propVec[1] = collision.posY() - mfttrack.y(); + propVec[2] = collision.posZ() - mfttrack.z(); + + double centerZ[3] = {mfttrack.x() + propVec[0] / 2., mfttrack.y() + propVec[1] / 2., mfttrack.z() + propVec[2] / 2.}; + float Bz = fieldB->getBz(centerZ); + extrap_mfttrack.propagateToZ(collision.posZ(), Bz); // z in cm + return extrap_mfttrack; + } + + inline o2::dataformats::GlobalFwdTrack propagateMUONtoPV() + { + float cov[15] = { + muontrack.cXX(), muontrack.cXY(), muontrack.cYY(), + muontrack.cPhiX(), muontrack.cPhiY(), muontrack.cPhiPhi(), + muontrack.cTglX(), muontrack.cTglY(), muontrack.cTglPhi(), + muontrack.cTglTgl(), muontrack.c1PtX(), muontrack.c1PtY(), + muontrack.c1PtPhi(), muontrack.c1PtTgl(), muontrack.c1Pt21Pt2()}; + + SMatrix5 tpars(muontrack.x(), muontrack.y(), muontrack.phi(), muontrack.tgl(), muontrack.signed1Pt()); + SMatrix55 tcovs(cov, cov + 15); + double chi2 = muontrack.chi2(); + + o2::track::TrackParCovFwd parcovmuontrack{muontrack.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + + auto mchtrack = mMatching.FwdtoMCH(gtrack); + o2::mch::TrackExtrap::extrapToVertex(mchtrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + o2::dataformats::GlobalFwdTrack extrap_muontrack; + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + + return extrap_muontrack; + } + + public: + enum MATCHING_TYPE { MCH_FIRST_CLUSTER, + MFT_LAST_CLUSTR, + END_OF_ABSORBER, + BEGINING_OF_ABSORBER }; + + MatchingParamsML(MUON const& muon, MFT const& mft, Collision const& coll, int MType, o2::field::MagneticField* field) : muontrack(muon), mfttrack(mft), collision(coll), mDX(0.f), mDY(0.f), mDPt(0.f), mDPhi(0.f), mDEta(0.f), mGlobalMuonPtAtDCA(0.f), mGlobalMuonEtaAtDCA(0.f), mGlobalMuonPhiAtDCA(0.f), mGlobalMuonDCAx(0.f), mGlobalMuonDCAy(0.f), mGlobalMuonQ(0.f), mMatchingType(MType), fieldB(field) {} + void calcMatchingParams() + { + auto mfttrack_on_matchingP = propagateMFTtoMatchingPlane(); + auto muontrack_on_matchingP = propagateMUONtoMatchingPlane(); + + float dphiRaw = mfttrack_on_matchingP.getPhi() - muontrack_on_matchingP.getPhi(); + float dphi = TVector2::Phi_mpi_pi(dphiRaw); + float deta = mfttrack_on_matchingP.getEta() - muontrack_on_matchingP.getEta(); + + mDX = mfttrack_on_matchingP.getX() - muontrack_on_matchingP.getX(); + mDY = mfttrack_on_matchingP.getY() - muontrack_on_matchingP.getY(); + mDPt = mfttrack_on_matchingP.getPt() - muontrack_on_matchingP.getPt(); + mDPhi = dphi; + mDEta = deta; + } + + void calcGlobalMuonParams() + { + auto mfttrack_at_dca = propagateMFTtoDCA(); + auto muontrack_at_pv = propagateMUONtoPV(); + + float momentum = muontrack_at_pv.getP(); + float theta = mfttrack_at_dca.getTheta(); + float phiTrack = mfttrack_at_dca.getPhi(); + float px = momentum * std::sin(theta) * std::cos(phiTrack); + float py = momentum * std::sin(theta) * std::sin(phiTrack); + + mGlobalMuonQ = muontrack.sign() + mfttrack.sign(); + mGlobalMuonPtAtDCA = std::sqrt(px * px + py * py); + mGlobalMuonEtaAtDCA = mfttrack_at_dca.getEta(); + mGlobalMuonPhiAtDCA = mfttrack_at_dca.getPhi(); + mGlobalMuonDCAx = mfttrack_at_dca.getX() - collision.posX(); + mGlobalMuonDCAy = mfttrack_at_dca.getY() - collision.posY(); + } + + inline float getDx() const { return mDX; } + inline float getDy() const { return mDY; } + inline float getDphi() const { return mDPhi; } + inline float getDeta() const { return mDEta; } + inline float getDpt() const { return mDPt; } + inline float getGMPtAtDCA() const { return mGlobalMuonPtAtDCA; } + inline float getGMEtaAtDCA() const { return mGlobalMuonEtaAtDCA; } + inline float getGMPhiAtDCA() const { return mGlobalMuonPhiAtDCA; } + inline float getGMDcaX() const { return mGlobalMuonDCAx; } + inline float getGMDcaY() const { return mGlobalMuonDCAy; } + inline float getGMDcaXY() const { return std::sqrt(mGlobalMuonDCAx * mGlobalMuonDCAx + mGlobalMuonDCAy * mGlobalMuonDCAy); } + inline int16_t getGMQ() const { return static_cast(mGlobalMuonQ); } + + }; // end of class MatchingParamsML + + template + o2::dataformats::GlobalFwdTrack propagateMUONtoPV(MUON const& muontrack, Collisions const& collisions) + { + auto collision = collisions.rawIteratorAt(muontrack.collisionId()); + o2::globaltracking::MatchGlobalFwd mMatching; + o2::dataformats::GlobalFwdTrack extrap_muontrack; + + SMatrix5 tpars(muontrack.x(), muontrack.y(), muontrack.phi(), muontrack.tgl(), muontrack.signed1Pt()); + std::vector v1{muontrack.cXX(), muontrack.cXY(), muontrack.cYY(), + muontrack.cPhiX(), muontrack.cPhiY(), muontrack.cPhiPhi(), + muontrack.cTglX(), muontrack.cTglY(), muontrack.cTglPhi(), + muontrack.cTglTgl(), muontrack.c1PtX(), muontrack.c1PtY(), + muontrack.c1PtPhi(), muontrack.c1PtTgl(), muontrack.c1Pt21Pt2()}; + SMatrix55 tcovs(v1.begin(), v1.end()); + double chi2 = muontrack.chi2(); + o2::track::TrackParCovFwd parcovmuontrack{muontrack.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + auto mchtrack = mMatching.FwdtoMCH(gtrack); + + o2::mch::TrackExtrap::extrapToVertex(mchtrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + + return extrap_muontrack; + } + + inline bool isGoodTagDimuon(float M) + { + return !(M < fTagMassWindowMin || M > fTagMassWindowMax); + } + + inline bool isGoodTagMatching(float mDX, float mDY, float mDEta, float mDPhi) + { + float dxNorm = (mDX - fMeanXTagMuonCut) / (fSigmaXTagMuonCut * 3); + float dyNorm = (mDY - fMeanYTagMuonCut) / (fSigmaYTagMuonCut * 3); + float detaNorm = (mDEta - fMeanEtaTagMuonCut) / (fSigmaEtaTagMuonCut * 3); + float dphiNorm = (mDPhi - fMeanPhiTagMuonCut) / (fSigmaPhiTagMuonCut * 3); + + float rTagXY = dxNorm * dxNorm + dyNorm * dyNorm; + float rTagEtaPhi = detaNorm * detaNorm + dphiNorm * dphiNorm; + + return (rTagXY < 1.f && rTagEtaPhi > 0.f); + } + + template + bool isCorrectMatching(MUON const& muontrack, MFT const& mfttrack) + { + + int idmuon = muontrack.mcParticleId(); + int idmft = mfttrack.mcParticleId(); + + if (idmuon == -1 || idmft == -1) + return false; + if (idmuon != idmft) + return false; + else + return true; + }; + + template + bool isGoodMuonQuality(MUON muontrack) + { + if (!muontrack.has_collision()) + return false; + if (muontrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) + return false; + if (muontrack.chi2() > fTrackChi2MchUp) + return false; + if (fRabsLow1 > muontrack.rAtAbsorberEnd() || muontrack.rAtAbsorberEnd() > fRabsUp2) + return false; + if (muontrack.rAtAbsorberEnd() < fRabsUp1 && fPdcaUp1 < muontrack.pDca()) + return false; + if (muontrack.rAtAbsorberEnd() > fRabsLow2 && fPdcaUp2 < muontrack.pDca()) + return false; + return true; + } + + template + bool isGoodMuonKine(MUON muontrack) + { + if (fEtaMchLow > muontrack.getEta() || muontrack.getEta() > fEtaMchUp) + return false; + return true; + } + + template + bool isGoodMFTQuality(MFT mfttrack) + { + if (!mfttrack.has_collision()) + return false; + if (mfttrack.chi2() > fTrackChi2MftUp) + return false; + if (mfttrack.nClusters() < fTrackNClustMftLow) + return false; + return true; + } + + template + bool isGoodMFTKine(MFT mfttrack) + { + if (fEtaMftLow > mfttrack.getEta() || mfttrack.getEta() > fEtaMftUp) + return false; + return true; + } + + inline bool isPassMatchingPreselection(float Dx, float Dy) + { + return !(std::abs(Dx) > fPreselectMatchingX || std::abs(Dy) > fPreselectMatchingY); + } + + template + void setMUONs(MUONs const& muontracks, Collisions const& collisions) + { + for (auto muontrack : muontracks) { + if (!isGoodMuonQuality(muontrack)) + continue; + o2::dataformats::GlobalFwdTrack muontrack_at_pv = propagateMUONtoPV(muontrack, collisions); + if (!isGoodMuonKine(muontrack_at_pv)) + continue; + + auto collision = collisions.rawIteratorAt(muontrack.collisionId()); + + bool& has = map_has_muontracks_collisions[muontrack.collisionId()]; + has = true; + + vector& arr_muontracks = map_muontracks[collision.globalIndex()]; + arr_muontracks.push_back(muontrack.globalIndex()); + } + } + + template + o2::track::TrackParCovFwd PropagateMFTtoDCA(MFT const& mfttrack, Collisions const& collisions, o2::field::MagneticField* field) + { + auto collision = collisions.rawIteratorAt(mfttrack.collisionId()); + std::vector mftv1; + SMatrix55 mftcovs{mftv1.begin(), mftv1.end()}; + SMatrix5 mftpars = {mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()}; + o2::track::TrackParCovFwd mftpartrack = {mfttrack.z(), mftpars, mftcovs, mfttrack.chi2()}; + double propVec[3] = {fabs(mfttrack.x() - collision.posX()), + fabs(mfttrack.y() - collision.posY()), + fabs(mfttrack.z() - collision.posZ())}; + double centerZ[3] = {mfttrack.x() - propVec[0] / 2., + mfttrack.y() - propVec[1] / 2., + mfttrack.z() - propVec[2] / 2.}; + float Bz = field->getBz(centerZ); + mftpartrack.propagateToZ(collision.posZ(), Bz); + return mftpartrack; + } + + template + void setMFTs(MFTs const& mfttracks, Collisions const& collisions, o2::field::MagneticField* field) + { + for (auto mfttrack : mfttracks) { + if (!isGoodMFTQuality(mfttrack)) + continue; + + o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFTtoDCA(mfttrack, collisions, field); + if (!isGoodMFTKine(mfttrack_at_dca)) + continue; + + auto collision = collisions.rawIteratorAt(mfttrack.collisionId()); + + map_vtxz[mfttrack.collisionId()] = collision.posZ(); + map_nmfttrack[mfttrack.collisionId()] += 1; + + bool& has = map_has_mfttracks_collisions[mfttrack.collisionId()]; + has = true; + + vector& arr_mfttracks = map_mfttracks[collision.globalIndex()]; + arr_mfttracks.push_back(mfttrack.globalIndex()); + } + } + + Produces tableMatchingParams; + Produces tableTagMatchingParams; + Produces tableProbeMatchingParams; + Produces tableMixMatchingParams; + Produces tableMuonPair; + + Service ccdbManager; + + o2::field::MagneticField* fieldB; + o2::ccdb::CcdbApi ccdbApi; + + template + void initCCDB(BC const& bc) + { + if (mRunNumber == bc.runNumber()) + return; + + mRunNumber = bc.runNumber(); + std::map metadata; + auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, mRunNumber); + auto ts = soreor.first; + auto grpmag = ccdbApi.retrieveFromTFileAny(grpmagPath, metadata, ts); + o2::base::Propagator::initFieldFromGRP(grpmag); + if (!o2::base::GeometryManager::isGeometryLoaded()) { + ccdbManager->get(geoPath); + } + o2::mch::TrackExtrap::setField(); + fieldB = static_cast(TGeoGlobalMagField::Instance()->GetField()); + } + + void init(o2::framework::InitContext&) + { + ccdbManager->setURL(ccdburl); + ccdbManager->setCaching(true); + ccdbManager->setLocalObjectValidityChecking(); + ccdbManager->setFatalWhenNull(false); + ccdbApi.init(ccdburl); + mRunNumber = 0; + } + + void process(MyCollisions const& collisions, + MyBCs const& bcs, + MyMUONs const& muontracks, + MyMFTs const& mfttracks) + { + LOG(info) << "Process() "; + map_muontracks.clear(); + map_mfttracks.clear(); + map_collisions.clear(); + map_has_muontracks_collisions.clear(); + map_has_mfttracks_collisions.clear(); + + initCCDB(bcs.begin()); + setMUONs(muontracks, collisions); + setMFTs(mfttracks, collisions, fieldB); + + for (auto map_has_muontracks_collision : map_has_muontracks_collisions) { + auto idmuontrack_collisions = map_has_muontracks_collision.first; + for (auto map_has_mfttracks_collision : map_has_mfttracks_collisions) { + auto idmfttrack_collisions = map_has_mfttracks_collision.first; + if (idmuontrack_collisions != idmfttrack_collisions) + continue; + map_collisions[idmfttrack_collisions] = true; + } + } + + for (auto const& map_collision : map_collisions) { + auto const& collision = collisions.rawIteratorAt(map_collision.first); + + for (auto const& imuontrack1 : map_muontracks[map_collision.first]) { + auto const& muontrack1 = muontracks.rawIteratorAt(imuontrack1); + + for (auto const& imfttrack1 : map_mfttracks[map_collision.first]) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + + MatchingParamsML matching(muontrack1, mfttrack1, collision, fMatchingMethod, fieldB); + matching.calcMatchingParams(); + + if (!isPassMatchingPreselection(matching.getDx(), matching.getDy())) + continue; + + matching.calcGlobalMuonParams(); + + bool isTrue = isCorrectMatching(muontrack1, mfttrack1); + + tableMatchingParams(matching.getGMPtAtDCA(), + matching.getGMEtaAtDCA(), + static_cast(matching.getGMQ()), + matching.getDpt(), + matching.getDx(), + matching.getDy(), + matching.getDeta(), + matching.getDphi(), + isTrue); + } + + for (auto const& map_mfttrack : map_mfttracks) { + if (map_mfttrack.first == map_collision.first) + continue; + if (fabs(map_vtxz[map_mfttrack.first] - map_vtxz[map_collision.first]) > fEventMaxDeltaVtxZ) + continue; + if (fabs(map_nmfttrack[map_mfttrack.first] - map_nmfttrack[map_collision.first]) > fEventMaxDeltaNMFT) + continue; + + for (auto const& imfttrack1 : map_mfttrack.second) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + MatchingParamsML matching(muontrack1, mfttrack1, collision, fMatchingMethod, fieldB); + matching.calcMatchingParams(); + if (!isPassMatchingPreselection(matching.getDx(), matching.getDy())) + continue; + matching.calcGlobalMuonParams(); + + bool isTrue = isCorrectMatching(muontrack1, mfttrack1); + + tableMixMatchingParams(matching.getGMPtAtDCA(), + matching.getGMEtaAtDCA(), + static_cast(matching.getGMQ()), + matching.getDpt(), + matching.getDx(), + matching.getDy(), + matching.getDeta(), + matching.getDphi(), + isTrue); + } + } + + for (auto const& imuontrack2 : map_muontracks[map_collision.first]) { + + if (imuontrack1 >= imuontrack2) + continue; + + auto const& muontrack2 = muontracks.rawIteratorAt(imuontrack2); + + FindTagAndProbe tagdimuon(muontrack1, muontrack2, collision); + tagdimuon.calcMuonPairAtPV(); + tableMuonPair(tagdimuon.getCharge(), tagdimuon.getMass(), tagdimuon.getPt(), tagdimuon.getRap()); + + if (!isGoodTagDimuon(tagdimuon.getMass())) + continue; + + auto tagmuontrack = muontrack1; + auto probemuontrack = muontrack2; + + if (tagdimuon.getTagMuonIndex() == 1) { + tagmuontrack = muontrack2; + probemuontrack = muontrack1; + } + + int nTagMFTCand = 0; + int nProbeMFTCand = 0; + + int IndexTagMFTCand = -1; + float tagGMPtAtDCA = 0; + // float tagGMEtaAtDCA = 0; + + float minimumR = 9999.; + int minimumIndexProbeMFTCand = -1; + + unordered_map> map_tagMatchingParams; + unordered_map> map_probeMatchingParams; + + for (auto const& imfttrack1 : map_mfttracks[map_collision.first]) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + MatchingParamsML matchingTag(tagmuontrack, mfttrack1, collision, fMatchingMethod, fieldB); + matchingTag.calcMatchingParams(); + matchingTag.calcGlobalMuonParams(); + if (isGoodTagMatching(matchingTag.getDx(), matchingTag.getDy(), matchingTag.getDeta(), matchingTag.getDphi()) && + isPassMatchingPreselection(matchingTag.getDx(), matchingTag.getDy())) { + bool isTrue = isCorrectMatching(tagmuontrack, mfttrack1); + tableTagMatchingParams(matchingTag.getGMPtAtDCA(), + matchingTag.getGMEtaAtDCA(), + matchingTag.getGMQ(), + matchingTag.getDpt(), + matchingTag.getDx(), + matchingTag.getDy(), + matchingTag.getDeta(), + matchingTag.getDphi(), + isTrue); + IndexTagMFTCand = mfttrack1.globalIndex(); + tagGMPtAtDCA = matchingTag.getGMPtAtDCA(); + // tagGMEtaAtDCA = matchingTag.getGMEtaAtDCA(); + ++nTagMFTCand; + } + } // end of loop imfttrack1 + + if (nTagMFTCand != 1) + continue; + for (auto const& imfttrack1 : map_mfttracks[map_collision.first]) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + if (mfttrack1.globalIndex() == IndexTagMFTCand) + continue; + MatchingParamsML matchingProbe(probemuontrack, mfttrack1, collision, fMatchingMethod, fieldB); + matchingProbe.calcMatchingParams(); + if (isPassMatchingPreselection(matchingProbe.getDx(), matchingProbe.getDy())) { + float R = sqrt(matchingProbe.getDx() * matchingProbe.getDx() + matchingProbe.getDy() * matchingProbe.getDy()); + bool isTrue = isCorrectMatching(probemuontrack, mfttrack1); + matchingProbe.calcGlobalMuonParams(); + vector& probeMatchingParams = map_probeMatchingParams[nProbeMFTCand]; + probeMatchingParams.push_back(tagGMPtAtDCA); + probeMatchingParams.push_back(matchingProbe.getGMPtAtDCA()); + probeMatchingParams.push_back(matchingProbe.getGMEtaAtDCA()); + probeMatchingParams.push_back(matchingProbe.getGMQ()); + probeMatchingParams.push_back(matchingProbe.getDpt()); + probeMatchingParams.push_back(matchingProbe.getDx()); + probeMatchingParams.push_back(matchingProbe.getDy()); + probeMatchingParams.push_back(matchingProbe.getDeta()); + probeMatchingParams.push_back(matchingProbe.getDphi()); + probeMatchingParams.push_back(isTrue); + if (R < minimumR) { + minimumIndexProbeMFTCand = nProbeMFTCand; + minimumR = R; + } + ++nProbeMFTCand; + } + } // end of loop imfttrack1 + + if (nProbeMFTCand < 1) + continue; + + if (minimumIndexProbeMFTCand > -1) { + vector& probeMatchingParams = map_probeMatchingParams[minimumIndexProbeMFTCand]; + tableProbeMatchingParams(probeMatchingParams[0], + probeMatchingParams[1], + probeMatchingParams[2], + static_cast(probeMatchingParams[3]), + probeMatchingParams[4], + probeMatchingParams[5], + probeMatchingParams[6], + probeMatchingParams[7], + probeMatchingParams[8], + static_cast(probeMatchingParams[9])); + } + + } // end of loop imuontrack2 + } // end of loop imuontrack1 + } // end of loop map_collision + + } // end of processMC +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/Common/TableProducer/match-mft-mch-data.cxx b/Common/TableProducer/match-mft-mch-data.cxx index c151c74ba4d..b566d9531f8 100644 --- a/Common/TableProducer/match-mft-mch-data.cxx +++ b/Common/TableProducer/match-mft-mch-data.cxx @@ -14,11 +14,6 @@ #include #include -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/DataTypes.h" -#include "Framework/runDataProcessing.h" #include "CCDB/BasicCCDBManager.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/EventSelection.h" @@ -27,6 +22,7 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/MftmchMatchingML.h" +#include "Common/DataModel/MatchMFTMuonData.h" #include "Common/Core/trackUtilities.h" #include "PWGDQ/DataModel/ReducedInfoTables.h" #include "PWGDQ/Core/VarManager.h" @@ -65,277 +61,52 @@ #include #include "TDatabasePDG.h" +using namespace std; + using namespace o2; using namespace o2::soa; using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; -using SMatrix55 = ROOT::Math::SMatrix>; -using SMatrix5 = ROOT::Math::SVector; +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" -// using MyEvents = soa::Join; -// using MyEventsWithMults = soa::Join; -// using MyEventsWithFilter = soa::Join; -// using MyEventsWithMultsAndFilter = soa::Join; -// using MyEventsWithCent = soa::Join; -// using MyEventsWithCentAndMults = soa::Join; -using MyMuons = soa::Join; +using MyCollisions = aod::Collisions; +using MyBCs = soa::Join; +using MyMUONs = soa::Join; using MyMFTs = aod::MFTTracks; -// using MyMuonsWithCov = soa::Join; -// using MyMuonsColl = soa::Join; -// using MyMuonsCollWithCov = soa::Join; -using MyBCs = soa::Join; -using ExtBCs = soa::Join; - -float mMu = TDatabasePDG::Instance()->GetParticle(13)->Mass(); -TRandom* rnd = new TRandom(); +using MyCollision = MyCollisions::iterator; +using MyBC = MyBCs::iterator; +using MyMUON = MyMUONs::iterator; +using MyMFT = MyMFTs::iterator; -TLorentzVector muon1LV; -TLorentzVector muon2LV; -TLorentzVector dimuonLV; - -TVector3 V1; -TVector3 V2; - -namespace o2::aod -{ - -namespace muon_params -{ -DECLARE_SOA_COLUMN(TRACKCHI2, trackChi2, float); -DECLARE_SOA_COLUMN(RABS, rabs, float); -DECLARE_SOA_COLUMN(Q, q, int16_t); -DECLARE_SOA_COLUMN(PT, pt, float); -DECLARE_SOA_COLUMN(ETA, eta, float); -DECLARE_SOA_COLUMN(PHI, phi, float); -DECLARE_SOA_COLUMN(HASMFT, has_mft, bool); -} // namespace muon_params - -DECLARE_SOA_TABLE(MUONParams, "AOD", "MUON", - muon_params::TRACKCHI2, - muon_params::RABS, - muon_params::Q, - muon_params::PT, - muon_params::ETA, - muon_params::PHI, - muon_params::HASMFT); - -namespace mft_params -{ -DECLARE_SOA_COLUMN(NCLUST, nclust, int); -DECLARE_SOA_COLUMN(ISCA, isCA, bool); -DECLARE_SOA_COLUMN(TRACKCHI2, trackChi2, float); -DECLARE_SOA_COLUMN(Q, q, int16_t); -DECLARE_SOA_COLUMN(PT_AT_DCA, pt_dca, float); -DECLARE_SOA_COLUMN(ETA_AT_DCA, eta_dca, float); -DECLARE_SOA_COLUMN(PHI_AT_DCA, phi_dca, float); -DECLARE_SOA_COLUMN(DCAx, dcax, float); -DECLARE_SOA_COLUMN(DCAy, dcay, float); -} // namespace mft_params - -DECLARE_SOA_TABLE(MFTParams, "AOD", "MFT", - mft_params::NCLUST, - mft_params::ISCA, - mft_params::TRACKCHI2, - mft_params::Q, - mft_params::PT_AT_DCA, - mft_params::ETA_AT_DCA, - mft_params::PHI_AT_DCA, - mft_params::DCAx, - mft_params::DCAy); - -namespace matching_params -{ -// matching parameters -DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); -DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); - -DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); -DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); -DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); -DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); - -DECLARE_SOA_COLUMN(MchPt, mchpt, float); -DECLARE_SOA_COLUMN(MchEta, mcheta, float); -DECLARE_SOA_COLUMN(MchPhi, mchphi, float); -DECLARE_SOA_COLUMN(MchQ, mchq, float); - -DECLARE_SOA_COLUMN(MftPt, mftpt, float); -DECLARE_SOA_COLUMN(MftEta, mfteta, float); -DECLARE_SOA_COLUMN(MftPhi, mftphi, float); -DECLARE_SOA_COLUMN(MftQ, mftq, float); - -DECLARE_SOA_COLUMN(MftDCA, mftdca, float); - -} // namespace matching_params - -DECLARE_SOA_TABLE(MatchParams, "AOD", "MATCHING", - matching_params::DeltaPt, - matching_params::DeltaEta, - matching_params::DeltaPhi, - matching_params::DeltaX, - matching_params::DeltaY, - matching_params::MchPt, - matching_params::MchEta, - matching_params::MchQ, - matching_params::MftEta, - matching_params::MftQ); - -namespace mix_matching_params -{ -// matching parameters -DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); -DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); - -DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); -DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); -DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); -DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); - -DECLARE_SOA_COLUMN(MchPt, mchpt, float); -DECLARE_SOA_COLUMN(MchEta, mcheta, float); -DECLARE_SOA_COLUMN(MchPhi, mchphi, float); -DECLARE_SOA_COLUMN(MchQ, mchq, float); - -DECLARE_SOA_COLUMN(MftPt, mftpt, float); -DECLARE_SOA_COLUMN(MftEta, mfteta, float); -DECLARE_SOA_COLUMN(MftPhi, mftphi, float); -DECLARE_SOA_COLUMN(MftQ, mftq, float); -DECLARE_SOA_COLUMN(MftDCA, mftdca, float); -} // namespace mix_matching_params - -DECLARE_SOA_TABLE(MixMatchParams, "AOD", "MIXMATCHING", - mix_matching_params::DeltaPt, - mix_matching_params::DeltaEta, - mix_matching_params::DeltaPhi, - mix_matching_params::DeltaX, - mix_matching_params::DeltaY, - mix_matching_params::MchPt, - mix_matching_params::MchEta, - mix_matching_params::MchQ, - mix_matching_params::MftEta, - mix_matching_params::MftQ); - -namespace tag_matching_params -{ -// matching parameters -DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); -DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); -DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); -DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); - -DECLARE_SOA_COLUMN(MchPt, mchpt, float); -DECLARE_SOA_COLUMN(MchEta, mcheta, float); -DECLARE_SOA_COLUMN(MchQ, mchq, float); - -DECLARE_SOA_COLUMN(MftEta, mfteta, float); -DECLARE_SOA_COLUMN(MftQ, mftq, float); -DECLARE_SOA_COLUMN(IsTaged, isTaged, bool); -} // namespace tag_matching_params - -DECLARE_SOA_TABLE(TagMatchParams, "AOD", "TAGMATCHING", - tag_matching_params::DeltaPt, - tag_matching_params::DeltaEta, - tag_matching_params::DeltaPhi, - tag_matching_params::DeltaX, - tag_matching_params::DeltaY, - tag_matching_params::MchPt, - tag_matching_params::MchEta, - tag_matching_params::MchQ, - tag_matching_params::MftEta, - tag_matching_params::MftQ, - tag_matching_params::IsTaged); - -namespace probe_matching_params -{ -// matching parameters -DECLARE_SOA_COLUMN(NMFTCandTagMuon, nTagMFT, int); -DECLARE_SOA_COLUMN(NMFTCandProbeMuon, nProbeMFT, int); -DECLARE_SOA_COLUMN(TagMuonP, tagmuonp, float); - -DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); -DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); - -DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); -DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); -DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); -DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); -DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); - -DECLARE_SOA_COLUMN(MchPt, mchpt, float); -DECLARE_SOA_COLUMN(MchEta, mcheta, float); -DECLARE_SOA_COLUMN(MchPhi, mchphi, float); -DECLARE_SOA_COLUMN(MchQ, mchq, float); - -DECLARE_SOA_COLUMN(MftPt, mftpt, float); -DECLARE_SOA_COLUMN(MftEta, mfteta, float); -DECLARE_SOA_COLUMN(MftPhi, mftphi, float); -DECLARE_SOA_COLUMN(MftQ, mftq, float); -DECLARE_SOA_COLUMN(MftDCA, mftdca, float); -} // namespace probe_matching_params - -DECLARE_SOA_TABLE(ProbeMatchParams, "AOD", "PROBEMATCHING", - probe_matching_params::NMFTCandTagMuon, - probe_matching_params::NMFTCandProbeMuon, - probe_matching_params::TagMuonP, - probe_matching_params::DeltaPt, - probe_matching_params::DeltaEta, - probe_matching_params::DeltaPhi, - probe_matching_params::DeltaX, - probe_matching_params::DeltaY, - probe_matching_params::MchPt, - probe_matching_params::MchEta, - probe_matching_params::MchQ, - probe_matching_params::MftEta, - probe_matching_params::MftQ); - -namespace muon_pair -{ -DECLARE_SOA_COLUMN(NMFT, nMft, int); -DECLARE_SOA_COLUMN(Q, q, int16_t); -DECLARE_SOA_COLUMN(M, m, float); -DECLARE_SOA_COLUMN(Pt, pt, float); -DECLARE_SOA_COLUMN(Rap, rap, float); -} // namespace muon_pair - -DECLARE_SOA_TABLE(MuonPair, "AOD", "DIMUON", muon_pair::NMFT, muon_pair::Q, muon_pair::M, muon_pair::Pt, muon_pair::Rap); +using SMatrix55 = ROOT::Math::SMatrix>; +using SMatrix5 = ROOT::Math::SVector; -namespace tag_muon_pair -{ -DECLARE_SOA_COLUMN(NMFT, nMft, int); -DECLARE_SOA_COLUMN(Q, q, int16_t); -DECLARE_SOA_COLUMN(M, m, float); -DECLARE_SOA_COLUMN(Pt, pt, float); -DECLARE_SOA_COLUMN(Rap, rap, float); -} // namespace tag_muon_pair - -DECLARE_SOA_TABLE(TagMuonPair, "AOD", "TAGDIMUON", tag_muon_pair::NMFT, tag_muon_pair::Q, tag_muon_pair::M, tag_muon_pair::Pt, tag_muon_pair::Rap); -} // namespace o2::aod - -struct match_mft_mch_data { - - Produces matchingParams; - Produces tagmatchingParams; - Produces probematchingParams; - Produces mixmatchingParams; - Produces muonPairs; - Produces tagmuonPairs; - Produces muonParams; - Produces mftParams; - - HistogramRegistry registry{ - "registry", - {{"hMchP", "MCH track total momentum (at the first station); p [GeV/c]; Counts", {HistType::kTH1F, {{2000, 0, 200}}}}, - {"hMchCorrP", "MCH track total momentum (propagated to PV); p [GeV/c]; Counts", {HistType::kTH1F, {{2000, 0, 200}}}}, - {"hMassCorrMchPair", "Corrected MCH track pair mass (propagated to PV); m [GeV/c^{2}]; Counts", {HistType::kTH1F, {{1000, 0, 10}}}}}}; +float mMu = TDatabasePDG::Instance()->GetParticle(13)->Mass(); +int mRunNumber; +/* + TLorentzVector muon1LV; + TLorentzVector muon2LV; + TLorentzVector dimuonLV; +*/ +unordered_map> map_mfttracks; +unordered_map> map_muontracks; +unordered_map map_collisions; +unordered_map map_has_mfttracks_collisions; +unordered_map map_has_muontracks_collisions; +unordered_map map_vtxz; +unordered_map map_nmfttrack; + +struct match_mft_mch_data_mc { + + //// Variables for matching method + Configurable fMatchingMethod{"cfgMatchingMethod", 0, ""}; //// Variables for selecting muon tracks Configurable fEtaMchLow{"cfgEtaMchLow", -4.0f, ""}; @@ -356,8 +127,8 @@ struct match_mft_mch_data { Configurable fTrackChi2MftUp{"cfgTrackChi2MftUp", 999.f, ""}; /// Variables to add preselection for the matching table - Configurable fPreselectMatchingX{"cfgPreselectMatchingX", 999.f, ""}; - Configurable fPreselectMatchingY{"cfgPreselectMatchingY", 999.f, ""}; + Configurable fPreselectMatchingX{"cfgPreselectMatchingX", 15.f, ""}; + Configurable fPreselectMatchingY{"cfgPreselectMatchingY", 15.f, ""}; /// Variables to event mixing criteria Configurable fSaveMixedMatchingParamsRate{"cfgSaveMixedMatchingParamsRate", 0.002f, ""}; @@ -367,504 +138,744 @@ struct match_mft_mch_data { //// Variables for selecting tag muon Configurable fTagMassWindowMin{"cfgTagMassWindowMin", 2.8f, ""}; Configurable fTagMassWindowMax{"cfgTagMassWindowMax", 3.3f, ""}; - Configurable fTagXWindowLow{"cfgTagXWindowLow", -0.80f, ""}; - Configurable fTagXWindowUp{"cfgTagXWindowUp", 0.84f, ""}; - Configurable fTagYWindowLow{"cfgTagYWindowLow", -0.64f, ""}; - Configurable fTagYWindowUp{"cfgTagYWindowUp", 0.95f, ""}; - Configurable fTagPhiWindowLow{"cfgTagPhiWindowLow", -0.041f, ""}; - Configurable fTagPhiWindowUp{"cfgTagPhiWindowUp", 0.039f, ""}; - Configurable fTagEtaWindowLow{"cfgTagEtaWindowLow", -0.045f, ""}; - Configurable fTagEtaWindowUp{"cfgTagEtaWindowUp", 0.033f, ""}; - - //// Variables for selecting probe muon - Configurable fProbeXWindowLow{"cfgProbeXWindowLow", -10.f, ""}; - Configurable fProbeXWindowUp{"cfgProbeXWindowUp", 10.f, ""}; - Configurable fProbeYWindowLow{"cfgProbeYWindowLow", -10.f, ""}; - Configurable fProbeYWindowUp{"cfgProbeYWindowUp", 10.f, ""}; - Configurable fProbePhiWindowLow{"cfgProbePhiWindowLow", -1.0f, ""}; - Configurable fProbePhiWindowUp{"cfgProbePhiWindowUp", 1.0f, ""}; - Configurable fProbeEtaWindowLow{"cfgProbeEtaWindowLow", -1.0f, ""}; - Configurable fProbeEtaWindowUp{"cfgProbeEtaWindowUp", 1.0f, ""}; - - Service ccdb; + + //// Variables for ccdb Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - // o2::parameters::GRPMagField* grpmag = nullptr; - o2::globaltracking::MatchGlobalFwd mMatching; - o2::field::MagneticField* fieldB; + //// Variables for Tag matching criteria + Configurable fSigmaXTagMuonCut{"cfgSigmaXTagMuonCut", 1.f, ""}; + Configurable fMeanXTagMuonCut{"cfgMeanXTagMuonCut", 0.f, ""}; + Configurable fSigmaYTagMuonCut{"cfgSigmaYTagMuonCut", 1.f, ""}; + Configurable fMeanYTagMuonCut{"cfgMeanYTagMuonCut", 1.f, ""}; - o2::ccdb::CcdbApi ccdbApi; - int mRunNumber; + Configurable fSigmaEtaTagMuonCut{"cfgSigmaEtaTagMuonCut", 0.2f, ""}; + Configurable fMeanEtaTagMuonCut{"cfgMeanEtaTagMuonCut", 0.f, ""}; + Configurable fSigmaPhiTagMuonCut{"cfgSigmaPhiTagMuonCut", 0.2f, ""}; + Configurable fMeanPhiTagMuonCut{"cfgMeanPhiTagMuonCut", 0.f, ""}; - void init(o2::framework::InitContext&) + template + class FindTagAndProbe { - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - ccdbApi.init(ccdburl); - mRunNumber = 0; - } + private: + o2::dataformats::GlobalFwdTrack muontrack_at_pv[2]; + + TLorentzVector mDimuon; + MUON muontrack1; + MUON muontrack2; + Collision collision; + int tagIdx, probeIdx; + + int16_t mQ; + + inline void fillCovarianceArray(MUON const& muontrack, float cov[15]) const + { + cov[0] = muontrack.cXX(); + cov[1] = muontrack.cXY(); + cov[2] = muontrack.cYY(); + cov[3] = muontrack.cPhiX(); + cov[4] = muontrack.cPhiY(); + cov[5] = muontrack.cPhiPhi(); + cov[6] = muontrack.cTglX(); + cov[7] = muontrack.cTglY(); + cov[8] = muontrack.cTglPhi(); + cov[9] = muontrack.cTglTgl(); + cov[10] = muontrack.c1PtX(); + cov[11] = muontrack.c1PtY(); + cov[12] = muontrack.c1PtPhi(); + cov[13] = muontrack.c1PtTgl(); + cov[14] = muontrack.c1Pt21Pt2(); + } - void initCCDB(ExtBCs::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; + inline o2::dataformats::GlobalFwdTrack propagateMUONtoPV(MUON const& muontrack) const + { + const double mz = muontrack.z(); + const double mchi2 = muontrack.chi2(); + const float mx = muontrack.x(); + const float my = muontrack.y(); + const float mphi = muontrack.phi(); + const float mtgl = muontrack.tgl(); + const float m1pt = muontrack.signed1Pt(); + + float cov[15]; + fillCovarianceArray(muontrack, cov); + SMatrix5 tpars(mx, my, mphi, mtgl, m1pt); + SMatrix55 tcovs(cov, cov + 15); + + o2::track::TrackParCovFwd parcovmuontrack{mz, tpars, tcovs, mchi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + + o2::globaltracking::MatchGlobalFwd mMatching; + auto mchtrack = mMatching.FwdtoMCH(gtrack); + + o2::mch::TrackExtrap::extrapToVertex(mchtrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + o2::dataformats::GlobalFwdTrack extrap_muontrack; + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + + return extrap_muontrack; } - mRunNumber = bc.runNumber(); - std::map metadata; - auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, mRunNumber); - auto ts = soreor.first; - auto grpmag = ccdbApi.retrieveFromTFileAny(grpmagPath, metadata, ts); - o2::base::Propagator::initFieldFromGRP(grpmag); - if (!o2::base::GeometryManager::isGeometryLoaded()) { - ccdb->get(geoPath); + + inline void setTagAndProbe() + { + if (muontrack1.pt() > muontrack2.pt()) { + tagIdx = 0; + probeIdx = 1; + } else { + tagIdx = 1; + probeIdx = 0; + } } - o2::mch::TrackExtrap::setField(); - fieldB = static_cast(TGeoGlobalMagField::Instance()->GetField()); - } - enum ProagationPoint { ToVtx, - ToDCA }; + public: + inline FindTagAndProbe(const MUON& muon1, const MUON& muon2, const Collision& coll) + : muontrack_at_pv(), mDimuon(), muontrack1(muon1), muontrack2(muon2), collision(coll), tagIdx(-1), probeIdx(-1), mQ(0) + { + mQ = muontrack1.sign() + muontrack2.sign(); + setTagAndProbe(); + } - template - o2::dataformats::GlobalFwdTrack PropagateMUONTrack(T const& muon, int PropType) + void calcMuonPairAtPV() + { + muontrack_at_pv[0] = propagateMUONtoPV(muontrack1); + muontrack_at_pv[1] = propagateMUONtoPV(muontrack2); + TLorentzVector vMuon1, vMuon2; + vMuon1.SetPtEtaPhiM(muontrack_at_pv[0].getPt(), muontrack_at_pv[0].getEta(), muontrack_at_pv[0].getPhi(), mMu); + vMuon2.SetPtEtaPhiM(muontrack_at_pv[1].getPt(), muontrack_at_pv[1].getEta(), muontrack_at_pv[1].getPhi(), mMu); + mDimuon = vMuon1 + vMuon2; + } + inline int getTagMuonIndex() const { return tagIdx; } + inline int getProbeMuonIndex() const { return probeIdx; } + inline float getMass() const { return mDimuon.M(); } + inline float getPt() const { return mDimuon.Pt(); } + inline float getRap() const { return mDimuon.Rapidity(); } + inline int16_t getCharge() const { return mQ; } + inline const o2::dataformats::GlobalFwdTrack& getMuonAtPV(int idx) const { return muontrack_at_pv[idx]; } + }; // end of class FindTagAndProbe + + template + class MatchingParamsML { + private: + MUON muontrack; + MFT mfttrack; + Collision collision; + + float mDX, mDY, mDPt, mDPhi, mDEta; + float mGlobalMuonPtAtDCA, mGlobalMuonEtaAtDCA, mGlobalMuonPhiAtDCA, mGlobalMuonDCAx, mGlobalMuonDCAy, mGlobalMuonQ; + int mMatchingType; + + o2::field::MagneticField* fieldB; + o2::globaltracking::MatchGlobalFwd mMatching; + + inline o2::track::TrackParCovFwd propagateMFTtoMatchingPlane() + { + double covArr[15]{0.0}; + SMatrix55 tmftcovs(covArr, covArr + 15); + + SMatrix5 tmftpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()); + o2::track::TrackParCovFwd extrap_mfttrack{mfttrack.z(), tmftpars, tmftcovs, mfttrack.chi2()}; + + double propVec[3] = {0.}; + float zPlane = 0.f; + if (mMatchingType == MCH_FIRST_CLUSTER) { + propVec[0] = muontrack.x() - mfttrack.x(); + propVec[1] = muontrack.y() - mfttrack.y(); + propVec[2] = muontrack.z() - mfttrack.z(); + zPlane = muontrack.z(); + } else if (mMatchingType == END_OF_ABSORBER || mMatchingType == BEGINING_OF_ABSORBER) { + auto extrap_muontrack = propagateMUONtoMatchingPlane(); + propVec[0] = extrap_muontrack.getX() - mfttrack.x(); + propVec[1] = extrap_muontrack.getY() - mfttrack.y(); + propVec[2] = extrap_muontrack.getZ() - mfttrack.z(); + zPlane = (mMatchingType == END_OF_ABSORBER) ? -505.f : -90.f; + } else { + zPlane = mfttrack.z(); + } - auto collision = muon.collision(); - - o2::dataformats::GlobalFwdTrack propmuon; - - double chi2 = muon.chi2(); - - SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt()); - std::vector v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(), - muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(), - muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()}; - if (isGoodMUONTrack(muon)) { - SMatrix55 tcovs(v1.begin(), v1.end()); - o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; - - o2::dataformats::GlobalFwdTrack track; - track.setParameters(tpars); - track.setZ(fwdtrack.getZ()); - track.setCovariances(tcovs); - auto mchTrack = mMatching.FwdtoMCH(track); - if (PropType == ProagationPoint::ToVtx) - o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); - else if (PropType == ProagationPoint::ToDCA) - o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, collision.posZ()); - - auto proptrack = mMatching.MCHtoFwd(mchTrack); - propmuon.setParameters(proptrack.getParameters()); - propmuon.setZ(proptrack.getZ()); - propmuon.setCovariances(proptrack.getCovariances()); + double centerZ[3] = {mfttrack.x() + propVec[0] / 2., mfttrack.y() + propVec[1] / 2., mfttrack.z() + propVec[2] / 2.}; + float Bz = fieldB->getBz(centerZ); + extrap_mfttrack.propagateToZ(zPlane, Bz); // z in cm + return extrap_mfttrack; } - v1.clear(); - v1.shrink_to_fit(); + inline o2::dataformats::GlobalFwdTrack propagateMUONtoMatchingPlane() + { + float cov[15] = { + muontrack.cXX(), muontrack.cXY(), muontrack.cYY(), + muontrack.cPhiX(), muontrack.cPhiY(), muontrack.cPhiPhi(), + muontrack.cTglX(), muontrack.cTglY(), muontrack.cTglPhi(), + muontrack.cTglTgl(), muontrack.c1PtX(), muontrack.c1PtY(), + muontrack.c1PtPhi(), muontrack.c1PtTgl(), muontrack.c1Pt21Pt2()}; + + SMatrix5 tpars(muontrack.x(), muontrack.y(), muontrack.phi(), muontrack.tgl(), muontrack.signed1Pt()); + SMatrix55 tcovs(cov, cov + 15); + double chi2 = muontrack.chi2(); + + o2::track::TrackParCovFwd parcovmuontrack{muontrack.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + + auto mchtrack = mMatching.FwdtoMCH(gtrack); + + if (mMatchingType == MFT_LAST_CLUSTR) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchtrack, mfttrack.z()); + } else if (mMatchingType == END_OF_ABSORBER) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchtrack, -505.); + } else if (mMatchingType == BEGINING_OF_ABSORBER) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchtrack, -90.); + } - return propmuon; - } + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); - template - o2::track::TrackParCovFwd PropagateMFT(T const& mfttrack, int PropType) - { - std::vector mftv1; - SMatrix55 mftcovs{mftv1.begin(), mftv1.end()}; - SMatrix5 mftpars = {mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()}; - o2::track::TrackParCovFwd mftpartrack = {mfttrack.z(), mftpars, mftcovs, mfttrack.chi2()}; - if (PropType == ProagationPoint::ToDCA) { - auto collision = mfttrack.collision(); - double propVec[3] = {fabs(mfttrack.x() - collision.posX()), fabs(mfttrack.y() - collision.posY()), fabs(mfttrack.z() - collision.posZ())}; - double centerZ[3] = {mfttrack.x() - propVec[0] / 2., mfttrack.y() - propVec[1] / 2., mfttrack.z() - propVec[2] / 2.}; + o2::dataformats::GlobalFwdTrack extrap_muontrack; + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + return extrap_muontrack; + } + + inline o2::track::TrackParCovFwd propagateMFTtoDCA() + { + double covArr[15]{0.0}; + SMatrix55 tmftcovs(covArr, covArr + 15); + + SMatrix5 tmftpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()); + o2::track::TrackParCovFwd extrap_mfttrack{mfttrack.z(), tmftpars, tmftcovs, mfttrack.chi2()}; + + double propVec[3] = {}; + propVec[0] = collision.posX() - mfttrack.x(); + propVec[1] = collision.posY() - mfttrack.y(); + propVec[2] = collision.posZ() - mfttrack.z(); + + double centerZ[3] = {mfttrack.x() + propVec[0] / 2., mfttrack.y() + propVec[1] / 2., mfttrack.z() + propVec[2] / 2.}; float Bz = fieldB->getBz(centerZ); - mftpartrack.propagateToZ(collision.posZ(), Bz); + extrap_mfttrack.propagateToZ(collision.posZ(), Bz); // z in cm + return extrap_mfttrack; } - return mftpartrack; + + inline o2::dataformats::GlobalFwdTrack propagateMUONtoPV() + { + float cov[15] = { + muontrack.cXX(), muontrack.cXY(), muontrack.cYY(), + muontrack.cPhiX(), muontrack.cPhiY(), muontrack.cPhiPhi(), + muontrack.cTglX(), muontrack.cTglY(), muontrack.cTglPhi(), + muontrack.cTglTgl(), muontrack.c1PtX(), muontrack.c1PtY(), + muontrack.c1PtPhi(), muontrack.c1PtTgl(), muontrack.c1Pt21Pt2()}; + + SMatrix5 tpars(muontrack.x(), muontrack.y(), muontrack.phi(), muontrack.tgl(), muontrack.signed1Pt()); + SMatrix55 tcovs(cov, cov + 15); + double chi2 = muontrack.chi2(); + + o2::track::TrackParCovFwd parcovmuontrack{muontrack.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + + auto mchtrack = mMatching.FwdtoMCH(gtrack); + o2::mch::TrackExtrap::extrapToVertex(mchtrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + o2::dataformats::GlobalFwdTrack extrap_muontrack; + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + + return extrap_muontrack; + } + + public: + enum MATCHING_TYPE { MCH_FIRST_CLUSTER, + MFT_LAST_CLUSTR, + END_OF_ABSORBER, + BEGINING_OF_ABSORBER }; + + MatchingParamsML(MUON const& muon, MFT const& mft, Collision const& coll, int MType, o2::field::MagneticField* field) : muontrack(muon), mfttrack(mft), collision(coll), mDX(0.f), mDY(0.f), mDPt(0.f), mDPhi(0.f), mDEta(0.f), mGlobalMuonPtAtDCA(0.f), mGlobalMuonEtaAtDCA(0.f), mGlobalMuonPhiAtDCA(0.f), mGlobalMuonDCAx(0.f), mGlobalMuonDCAy(0.f), mGlobalMuonQ(0.f), mMatchingType(MType), fieldB(field) {} + void calcMatchingParams() + { + auto mfttrack_on_matchingP = propagateMFTtoMatchingPlane(); + auto muontrack_on_matchingP = propagateMUONtoMatchingPlane(); + + float dphiRaw = mfttrack_on_matchingP.getPhi() - muontrack_on_matchingP.getPhi(); + float dphi = TVector2::Phi_mpi_pi(dphiRaw); + float deta = mfttrack_on_matchingP.getEta() - muontrack_on_matchingP.getEta(); + + mDX = mfttrack_on_matchingP.getX() - muontrack_on_matchingP.getX(); + mDY = mfttrack_on_matchingP.getY() - muontrack_on_matchingP.getY(); + mDPt = mfttrack_on_matchingP.getPt() - muontrack_on_matchingP.getPt(); + mDPhi = dphi; + mDEta = deta; + } + + void calcGlobalMuonParams() + { + auto mfttrack_at_dca = propagateMFTtoDCA(); + auto muontrack_at_pv = propagateMUONtoPV(); + + float momentum = muontrack_at_pv.getP(); + float theta = mfttrack_at_dca.getTheta(); + float phiTrack = mfttrack_at_dca.getPhi(); + float px = momentum * std::sin(theta) * std::cos(phiTrack); + float py = momentum * std::sin(theta) * std::sin(phiTrack); + + mGlobalMuonQ = muontrack.sign() + mfttrack.sign(); + mGlobalMuonPtAtDCA = std::sqrt(px * px + py * py); + mGlobalMuonEtaAtDCA = mfttrack_at_dca.getEta(); + mGlobalMuonPhiAtDCA = mfttrack_at_dca.getPhi(); + mGlobalMuonDCAx = mfttrack_at_dca.getX() - collision.posX(); + mGlobalMuonDCAy = mfttrack_at_dca.getY() - collision.posY(); + } + + inline float getDx() const { return mDX; } + inline float getDy() const { return mDY; } + inline float getDphi() const { return mDPhi; } + inline float getDeta() const { return mDEta; } + inline float getDpt() const { return mDPt; } + inline float getGMPtAtDCA() const { return mGlobalMuonPtAtDCA; } + inline float getGMEtaAtDCA() const { return mGlobalMuonEtaAtDCA; } + inline float getGMPhiAtDCA() const { return mGlobalMuonPhiAtDCA; } + inline float getGMDcaX() const { return mGlobalMuonDCAx; } + inline float getGMDcaY() const { return mGlobalMuonDCAy; } + inline float getGMDcaXY() const { return std::sqrt(mGlobalMuonDCAx * mGlobalMuonDCAx + mGlobalMuonDCAy * mGlobalMuonDCAy); } + inline int16_t getGMQ() const { return static_cast(mGlobalMuonQ); } + + }; // end of class MatchingParamsML + + template + o2::dataformats::GlobalFwdTrack propagateMUONtoPV(MUON const& muontrack, Collisions const& collisions) + { + auto collision = collisions.rawIteratorAt(muontrack.collisionId()); + o2::globaltracking::MatchGlobalFwd mMatching; + o2::dataformats::GlobalFwdTrack extrap_muontrack; + + SMatrix5 tpars(muontrack.x(), muontrack.y(), muontrack.phi(), muontrack.tgl(), muontrack.signed1Pt()); + std::vector v1{muontrack.cXX(), muontrack.cXY(), muontrack.cYY(), + muontrack.cPhiX(), muontrack.cPhiY(), muontrack.cPhiPhi(), + muontrack.cTglX(), muontrack.cTglY(), muontrack.cTglPhi(), + muontrack.cTglTgl(), muontrack.c1PtX(), muontrack.c1PtY(), + muontrack.c1PtPhi(), muontrack.c1PtTgl(), muontrack.c1Pt21Pt2()}; + SMatrix55 tcovs(v1.begin(), v1.end()); + double chi2 = muontrack.chi2(); + o2::track::TrackParCovFwd parcovmuontrack{muontrack.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack gtrack; + gtrack.setParameters(tpars); + gtrack.setZ(parcovmuontrack.getZ()); + gtrack.setCovariances(tcovs); + auto mchtrack = mMatching.FwdtoMCH(gtrack); + + o2::mch::TrackExtrap::extrapToVertex(mchtrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + + auto fwdtrack = mMatching.MCHtoFwd(mchtrack); + extrap_muontrack.setParameters(fwdtrack.getParameters()); + extrap_muontrack.setZ(fwdtrack.getZ()); + extrap_muontrack.setCovariances(fwdtrack.getCovariances()); + + return extrap_muontrack; + } + + inline bool isGoodTagDimuon(float M) + { + return !(M < fTagMassWindowMin || M > fTagMassWindowMax); } - template - o2::track::TrackParCovFwd PropagateMFTtoMatchingPlane(MFT const& mfttrack, FWD const& fwdtrack) + inline bool isGoodTagMatching(float mDX, float mDY, float mDEta, float mDPhi) { - std::vector v1; // Temporary null vector for the computation of the covariance matrix - double propVec[3] = {fwdtrack.x() - mfttrack.x(), fwdtrack.y() - mfttrack.y(), fwdtrack.z() - mfttrack.z()}; - double centerZ[3] = {mfttrack.x() + propVec[0] / 2., mfttrack.y() + propVec[1] / 2., mfttrack.z() + propVec[2] / 2.}; - float Bz = fieldB->getBz(centerZ); // gives error if the propagator is not initFielded - SMatrix55 tmftcovs(v1.begin(), v1.end()); - SMatrix5 tmftpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()); - o2::track::TrackParCovFwd extrap_mfttrack{mfttrack.z(), tmftpars, tmftcovs, mfttrack.chi2()}; - extrap_mfttrack.propagateToZ(fwdtrack.z(), Bz); // z in cm - return extrap_mfttrack; + float dxNorm = (mDX - fMeanXTagMuonCut) / (fSigmaXTagMuonCut * 3); + float dyNorm = (mDY - fMeanYTagMuonCut) / (fSigmaYTagMuonCut * 3); + float detaNorm = (mDEta - fMeanEtaTagMuonCut) / (fSigmaEtaTagMuonCut * 3); + float dphiNorm = (mDPhi - fMeanPhiTagMuonCut) / (fSigmaPhiTagMuonCut * 3); + + float rTagXY = dxNorm * dxNorm + dyNorm * dyNorm; + float rTagEtaPhi = detaNorm * detaNorm + dphiNorm * dphiNorm; + + return (rTagXY < 1.f && rTagEtaPhi > 0.f); } - template - bool isGoodMUONTrack(T track) + template + bool isCorrectMatching(MUON const& muontrack, MFT const& mfttrack) { - if (!track.has_collision()) + + int idmuon = muontrack.mcParticleId(); + int idmft = mfttrack.mcParticleId(); + + if (idmuon == -1 || idmft == -1) return false; - if (track.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) + if (idmuon != idmft) return false; - if (track.chi2() > fTrackChi2MchUp) + else + return true; + }; + + template + bool isGoodMuonQuality(MUON muontrack) + { + if (!muontrack.has_collision()) return false; - if (fRabsLow1 > track.rAtAbsorberEnd() || track.rAtAbsorberEnd() > fRabsUp2) + if (muontrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) return false; - if (track.rAtAbsorberEnd() < fRabsUp1 && fPdcaUp1 < track.pDca()) + if (muontrack.chi2() > fTrackChi2MchUp) return false; - if (track.rAtAbsorberEnd() > fRabsLow2 && fPdcaUp2 < track.pDca()) + if (fRabsLow1 > muontrack.rAtAbsorberEnd() || muontrack.rAtAbsorberEnd() > fRabsUp2) + return false; + if (muontrack.rAtAbsorberEnd() < fRabsUp1 && fPdcaUp1 < muontrack.pDca()) + return false; + if (muontrack.rAtAbsorberEnd() > fRabsLow2 && fPdcaUp2 < muontrack.pDca()) return false; return true; } - template - int selectTagMUON(T track1, T track2) + template + bool isGoodMuonKine(MUON muontrack) { - if (track1.pt() > track2.pt()) { - return track1.globalIndex(); - } else { - return track2.globalIndex(); - } - } - - template - int selectProbeMUONTrack(T track1, T track2) - { - if (track1.pt() < track2.pt()) { - return track1.globalIndex(); - } else { - return track2.globalIndex(); - } - } - - bool isGoodKenematicMUONTrack(o2::dataformats::GlobalFwdTrack track) - { - if (fEtaMchLow > track.getEta() || track.getEta() > fEtaMchUp) + if (fEtaMchLow > muontrack.getEta() || muontrack.getEta() > fEtaMchUp) return false; return true; } - template - bool isGoodMFTTrack(T track) + template + bool isGoodMFTQuality(MFT mfttrack) { - if (!track.has_collision()) + if (!mfttrack.has_collision()) return false; - if (track.chi2() > fTrackChi2MftUp) + if (mfttrack.chi2() > fTrackChi2MftUp) return false; - if (track.nClusters() < fTrackNClustMftLow) + if (mfttrack.nClusters() < fTrackNClustMftLow) return false; return true; } - bool isGoodKenematicMFTTrack(o2::track::TrackParCovFwd track) + template + bool isGoodMFTKine(MFT mfttrack) { - if (fEtaMftLow > track.getEta() || track.getEta() > fEtaMftUp) { + if (fEtaMftLow > mfttrack.getEta() || mfttrack.getEta() > fEtaMftUp) return false; - } return true; } - void process(aod::Collisions const&, ExtBCs const& ebcs, - MyMuons const& fwdtracks, MyMFTs const& mfttracks) + inline bool isPassMatchingPreselection(float Dx, float Dy) { - initCCDB(ebcs.begin()); - - std::unordered_set bcs_mfttrack; - std::unordered_map map_vtxZ; - std::unordered_map nmfttracks; - std::unordered_map> map_mfttraks; - - for (const auto& mfttrack : mfttracks) { + return !(std::abs(Dx) > fPreselectMatchingX || std::abs(Dy) > fPreselectMatchingY); + } - if (!isGoodMFTTrack(mfttrack)) { + template + void setMUONs(MUONs const& muontracks, Collisions const& collisions) + { + for (auto muontrack : muontracks) { + if (!isGoodMuonQuality(muontrack)) continue; - } - - bcs_mfttrack.insert(mfttrack.collisionId()); - std::vector& tracks = map_mfttraks[mfttrack.collisionId()]; - tracks.push_back(mfttrack.globalIndex()); - - o2::track::TrackParCovFwd mftpartrack = PropagateMFT(mfttrack, ProagationPoint::ToDCA); - - if (!isGoodKenematicMFTTrack(mftpartrack)) { + o2::dataformats::GlobalFwdTrack muontrack_at_pv = propagateMUONtoPV(muontrack, collisions); + if (!isGoodMuonKine(muontrack_at_pv)) continue; - } - - auto collision = mfttrack.collision(); - map_vtxZ[mfttrack.collisionId()] = collision.posZ(); + auto collision = collisions.rawIteratorAt(muontrack.collisionId()); - float dx = mftpartrack.getX() - collision.posX(); - float dy = mftpartrack.getY() - collision.posY(); + bool& has = map_has_muontracks_collisions[muontrack.collisionId()]; + has = true; - mftParams(mfttrack.nClusters(), mfttrack.isCA(), mfttrack.chi2(), mfttrack.sign(), mftpartrack.getPt(), mftpartrack.getEta(), mftpartrack.getPhi(), dx, dy); - nmfttracks[mfttrack.collisionId()]++; + vector& arr_muontracks = map_muontracks[collision.globalIndex()]; + arr_muontracks.push_back(muontrack.globalIndex()); } + } - std::unordered_map nfwdtracks; - std::unordered_map> map_fwdtraks; - - for (auto fwdtrack : fwdtracks) { + template + o2::track::TrackParCovFwd PropagateMFTtoDCA(MFT const& mfttrack, Collisions const& collisions, o2::field::MagneticField* field) + { + auto collision = collisions.rawIteratorAt(mfttrack.collisionId()); + std::vector mftv1; + SMatrix55 mftcovs{mftv1.begin(), mftv1.end()}; + SMatrix5 mftpars = {mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()}; + o2::track::TrackParCovFwd mftpartrack = {mfttrack.z(), mftpars, mftcovs, mfttrack.chi2()}; + double propVec[3] = {fabs(mfttrack.x() - collision.posX()), + fabs(mfttrack.y() - collision.posY()), + fabs(mfttrack.z() - collision.posZ())}; + double centerZ[3] = {mfttrack.x() - propVec[0] / 2., + mfttrack.y() - propVec[1] / 2., + mfttrack.z() - propVec[2] / 2.}; + float Bz = field->getBz(centerZ); + mftpartrack.propagateToZ(collision.posZ(), Bz); + return mftpartrack; + } - if (!isGoodMUONTrack(fwdtrack)) { + template + void setMFTs(MFTs const& mfttracks, Collisions const& collisions, o2::field::MagneticField* field) + { + for (auto mfttrack : mfttracks) { + if (!isGoodMFTQuality(mfttrack)) continue; - } - o2::dataformats::GlobalFwdTrack propmuonAtPV = PropagateMUONTrack(fwdtrack, ProagationPoint::ToVtx); - if (!isGoodKenematicMUONTrack(propmuonAtPV)) { + o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFTtoDCA(mfttrack, collisions, field); + if (!isGoodMFTKine(mfttrack_at_dca)) continue; - } - - std::vector& tracks = map_fwdtraks[fwdtrack.collisionId()]; - tracks.push_back(fwdtrack.globalIndex()); - bool hasMFT = false; + auto collision = collisions.rawIteratorAt(mfttrack.collisionId()); - std::vector& mfttracks = map_mfttraks[fwdtrack.collisionId()]; + map_vtxz[mfttrack.collisionId()] = collision.posZ(); + map_nmfttrack[mfttrack.collisionId()] += 1; - if (mfttracks.size() > 0) { - hasMFT = true; - } + bool& has = map_has_mfttracks_collisions[mfttrack.collisionId()]; + has = true; - muonParams(fwdtrack.chi2(), fwdtrack.rAtAbsorberEnd(), fwdtrack.sign(), propmuonAtPV.getPt(), propmuonAtPV.getEta(), propmuonAtPV.getPhi(), hasMFT); - nfwdtracks[fwdtrack.collisionId()]++; + vector& arr_mfttracks = map_mfttracks[collision.globalIndex()]; + arr_mfttracks.push_back(mfttrack.globalIndex()); } + } - for (auto fwdtrack1 : fwdtracks) { - - if (!isGoodMUONTrack(fwdtrack1)) { - continue; - } - - int ibc = fwdtrack1.collisionId(); - auto collision = fwdtrack1.collision(); - - o2::dataformats::GlobalFwdTrack fwdtrackAtPV1 = PropagateMUONTrack(fwdtrack1, ProagationPoint::ToVtx); - if (!isGoodKenematicMUONTrack(fwdtrackAtPV1)) { - continue; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////// MIXED EVENT /////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - for (auto bc_mfttrack : bcs_mfttrack) { - - if (ibc == bc_mfttrack) - continue; - if (fabs(nmfttracks[ibc] - nmfttracks[bc_mfttrack]) > fEventMaxDeltaNMFT) { - continue; - } - if (fabs(map_vtxZ[bc_mfttrack] - collision.posZ()) > fEventMaxDeltaVtxZ) { - continue; - } - - std::vector& mfttrackGlobalIndex = map_mfttraks[bc_mfttrack]; - - for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { - - auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); - o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, fwdtrack1); - - V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); - V2.SetPtEtaPhi(fwdtrack1.pt(), fwdtrack1.eta(), fwdtrack1.phi()); - - double deltaPt = mfttrack_at_matching.getPt() - fwdtrack1.pt(); - double deltaX = mfttrack_at_matching.getX() - fwdtrack1.x(); - double deltaY = mfttrack_at_matching.getY() - fwdtrack1.y(); - double deltaPhi = V1.DeltaPhi(V2); - double deltaEta = mfttrack_at_matching.getEta() - fwdtrack1.eta(); - - if (fabs(deltaX) > fPreselectMatchingX) { - continue; - } - if (fabs(deltaY) > fPreselectMatchingY) { - continue; - } - - o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); + Produces tableMatchingParams; + Produces tableTagMatchingParams; + Produces tableProbeMatchingParams; + Produces tableMixMatchingParams; + Produces tableMuonPair; - mixmatchingParams(deltaPt, deltaEta, deltaPhi, deltaX, deltaY, fwdtrackAtPV1.getPt(), fwdtrackAtPV1.getEta(), fwdtrack1.sign(), mfttrack_at_dca.getEta(), mfttrack1.sign()); - } - } // end of loop bc_mfttrack + Service ccdbManager; - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////// SAME EVENT /////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - std::vector& mfttrackGlobalIndex = map_mfttraks[ibc]; + o2::field::MagneticField* fieldB; + o2::ccdb::CcdbApi ccdbApi; - for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { + template + void initCCDB(BC const& bc) + { + if (mRunNumber == bc.runNumber()) + return; - auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); - o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, fwdtrack1); - V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); - V2.SetPtEtaPhi(fwdtrack1.pt(), fwdtrack1.eta(), fwdtrack1.phi()); + mRunNumber = bc.runNumber(); + std::map metadata; + auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, mRunNumber); + auto ts = soreor.first; + auto grpmag = ccdbApi.retrieveFromTFileAny(grpmagPath, metadata, ts); + o2::base::Propagator::initFieldFromGRP(grpmag); + if (!o2::base::GeometryManager::isGeometryLoaded()) { + ccdbManager->get(geoPath); + } + o2::mch::TrackExtrap::setField(); + fieldB = static_cast(TGeoGlobalMagField::Instance()->GetField()); + } - double deltaPt = mfttrack_at_matching.getPt() - fwdtrack1.pt(); - double deltaX = mfttrack_at_matching.getX() - fwdtrack1.x(); - double deltaY = mfttrack_at_matching.getY() - fwdtrack1.y(); - double deltaPhi = V1.DeltaPhi(V2); - double deltaEta = mfttrack_at_matching.getEta() - fwdtrack1.eta(); + void init(o2::framework::InitContext&) + { + ccdbManager->setURL(ccdburl); + ccdbManager->setCaching(true); + ccdbManager->setLocalObjectValidityChecking(); + ccdbManager->setFatalWhenNull(false); + ccdbApi.init(ccdburl); + mRunNumber = 0; + } - if (fabs(deltaX) > fPreselectMatchingX) { - continue; - } - if (fabs(deltaY) > fPreselectMatchingY) { + void process(MyCollisions const& collisions, + MyBCs const& bcs, + MyMUONs const& muontracks, + MyMFTs const& mfttracks) + { + LOG(info) << "Process() "; + map_muontracks.clear(); + map_mfttracks.clear(); + map_collisions.clear(); + map_has_muontracks_collisions.clear(); + map_has_mfttracks_collisions.clear(); + + initCCDB(bcs.begin()); + setMUONs(muontracks, collisions); + setMFTs(mfttracks, collisions, fieldB); + + for (auto map_has_muontracks_collision : map_has_muontracks_collisions) { + auto idmuontrack_collisions = map_has_muontracks_collision.first; + for (auto map_has_mfttracks_collision : map_has_mfttracks_collisions) { + auto idmfttrack_collisions = map_has_mfttracks_collision.first; + if (idmuontrack_collisions != idmfttrack_collisions) continue; - } - - o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); - - matchingParams(deltaPt, deltaEta, deltaPhi, deltaX, deltaY, - fwdtrackAtPV1.getPt(), fwdtrackAtPV1.getEta(), fwdtrack1.sign(), - mfttrack_at_dca.getEta(), mfttrack1.sign()); - - } // end of loop idmfttrack1 - - std::vector& fwdtrackGlobalIndex = map_fwdtraks[ibc]; + map_collisions[idmfttrack_collisions] = true; + } + } - for (int idfwdtrack2 = 0; idfwdtrack2 < static_cast(fwdtrackGlobalIndex.size()); ++idfwdtrack2) { + for (auto const& map_collision : map_collisions) { + auto const& collision = collisions.rawIteratorAt(map_collision.first); - if (fwdtrack1.globalIndex() == fwdtrackGlobalIndex[idfwdtrack2]) { - continue; - } + for (auto const& imuontrack1 : map_muontracks[map_collision.first]) { + auto const& muontrack1 = muontracks.rawIteratorAt(imuontrack1); - auto fwdtrack2 = fwdtracks.rawIteratorAt(fwdtrackGlobalIndex[idfwdtrack2]); + for (auto const& imfttrack1 : map_mfttracks[map_collision.first]) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); - if (!isGoodMUONTrack(fwdtrack2)) { - continue; - } + MatchingParamsML matching(muontrack1, mfttrack1, collision, fMatchingMethod, fieldB); + matching.calcMatchingParams(); - o2::dataformats::GlobalFwdTrack fwdtrackAtPV2 = PropagateMUONTrack(fwdtrack2, ProagationPoint::ToVtx); - if (!isGoodKenematicMUONTrack(fwdtrackAtPV2)) { - continue; - } + if (!isPassMatchingPreselection(matching.getDx(), matching.getDy())) + continue; - muon1LV.SetPtEtaPhiM(fwdtrackAtPV1.getPt(), fwdtrackAtPV1.getEta(), fwdtrackAtPV1.getPhi(), mMu); - muon2LV.SetPtEtaPhiM(fwdtrackAtPV2.getPt(), fwdtrackAtPV2.getEta(), fwdtrackAtPV2.getPhi(), mMu); - dimuonLV = muon1LV + muon2LV; + matching.calcGlobalMuonParams(); - muonPairs(nmfttracks[ibc], fwdtrack1.sign() + fwdtrack2.sign(), dimuonLV.M(), dimuonLV.Pt(), dimuonLV.Rapidity()); + bool isTrue = false; - if (fabs(fwdtrack1.sign() + fwdtrack2.sign()) > 0) { - continue; - } - if (fTagMassWindowMin > dimuonLV.M() || dimuonLV.M() > fTagMassWindowMax) { - continue; - } - if (nmfttracks[ibc] < 1) { - continue; + tableMatchingParams(matching.getGMPtAtDCA(), + matching.getGMEtaAtDCA(), + static_cast(matching.getGMQ()), + matching.getDpt(), + matching.getDx(), + matching.getDy(), + matching.getDeta(), + matching.getDphi(), + isTrue); } - tagmuonPairs(nmfttracks[ibc], fwdtrack1.sign() + fwdtrack2.sign(), dimuonLV.M(), dimuonLV.Pt(), dimuonLV.Rapidity()); - - bool isGoodTag = false; - int nMFTCandsTagMUON = 0; - - auto tagfwdtrack = fwdtracks.rawIteratorAt(selectTagMUON(fwdtrack1, fwdtrack2)); - o2::dataformats::GlobalFwdTrack tagfwdtrackAtPV = PropagateMUONTrack(tagfwdtrack, ProagationPoint::ToVtx); - - for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { - - auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); - o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, tagfwdtrack); - - V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); - V2.SetPtEtaPhi(tagfwdtrack.pt(), tagfwdtrack.eta(), tagfwdtrack.phi()); - - double deltaPt = mfttrack_at_matching.getPt() - tagfwdtrack.pt(); - double deltaX = mfttrack_at_matching.getX() - tagfwdtrack.x(); - double deltaY = mfttrack_at_matching.getY() - tagfwdtrack.y(); - double deltaPhi = V1.DeltaPhi(V2); - double deltaEta = mfttrack_at_matching.getEta() - tagfwdtrack.eta(); - - if (fabs(deltaX) > fPreselectMatchingX) { + for (auto const& map_mfttrack : map_mfttracks) { + if (map_mfttrack.first == map_collision.first) continue; - } - if (fabs(deltaY) > fPreselectMatchingY) { + if (fabs(map_vtxz[map_mfttrack.first] - map_vtxz[map_collision.first]) > fEventMaxDeltaVtxZ) + continue; + if (fabs(map_nmfttrack[map_mfttrack.first] - map_nmfttrack[map_collision.first]) > fEventMaxDeltaNMFT) continue; - } - - o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); - - bool dummyTag = false; - if (fTagXWindowLow < deltaX && deltaX < fTagXWindowUp && - fTagXWindowLow < deltaY && deltaY < fTagXWindowUp && - fTagPhiWindowLow < deltaPhi && deltaPhi < fTagPhiWindowUp && - fTagEtaWindowLow < deltaEta && deltaEta < fTagEtaWindowUp) { - isGoodTag = true; - dummyTag = true; - nMFTCandsTagMUON++; + for (auto const& imfttrack1 : map_mfttrack.second) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + MatchingParamsML matching(muontrack1, mfttrack1, collision, fMatchingMethod, fieldB); + matching.calcMatchingParams(); + if (!isPassMatchingPreselection(matching.getDx(), matching.getDy())) + continue; + matching.calcGlobalMuonParams(); + + bool isTrue = false; + + tableMixMatchingParams(matching.getGMPtAtDCA(), + matching.getGMEtaAtDCA(), + static_cast(matching.getGMQ()), + matching.getDpt(), + matching.getDx(), + matching.getDy(), + matching.getDeta(), + matching.getDphi(), + isTrue); } - - tagmatchingParams(deltaPt, deltaEta, deltaPhi, deltaX, deltaY, - tagfwdtrackAtPV.getPt(), tagfwdtrackAtPV.getEta(), tagfwdtrack.sign(), mfttrack_at_dca.getEta(), mfttrack1.sign(), dummyTag); } - if (!isGoodTag) { - continue; - } + for (auto const& imuontrack2 : map_muontracks[map_collision.first]) { - auto probefwdtrack = fwdtracks.rawIteratorAt(selectProbeMUONTrack(fwdtrack1, fwdtrack2)); - o2::dataformats::GlobalFwdTrack probefwdtrackAtPV = PropagateMUONTrack(probefwdtrack, ProagationPoint::ToVtx); - - int nMFTCandsProbeMUON = 0; - /// Counting the number of MFT tracks in a probe muon track - for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { + if (imuontrack1 >= imuontrack2) + continue; - auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); - o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, probefwdtrack); - V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); - V2.SetPtEtaPhi(probefwdtrack.pt(), probefwdtrack.eta(), probefwdtrack.phi()); + auto const& muontrack2 = muontracks.rawIteratorAt(imuontrack2); - double deltaX = mfttrack_at_matching.getX() - probefwdtrack.x(); - double deltaY = mfttrack_at_matching.getY() - probefwdtrack.y(); - double deltaPhi = V1.DeltaPhi(V2); - double deltaEta = mfttrack_at_matching.getEta() - probefwdtrack.eta(); + FindTagAndProbe tagdimuon(muontrack1, muontrack2, collision); + tagdimuon.calcMuonPairAtPV(); + tableMuonPair(tagdimuon.getCharge(), tagdimuon.getMass(), tagdimuon.getPt(), tagdimuon.getRap()); - if (fProbeXWindowLow < deltaX && deltaX < fProbeXWindowUp && - fProbeXWindowLow < deltaY && deltaY < fProbeXWindowUp && - fProbePhiWindowLow < deltaPhi && deltaPhi < fProbePhiWindowUp && - fProbeEtaWindowLow < deltaEta && deltaEta < fProbeEtaWindowUp) { - nMFTCandsProbeMUON++; - } - } - - for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { - - auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); - o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, probefwdtrack); + if (!isGoodTagDimuon(tagdimuon.getMass())) + continue; - V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); - V2.SetPtEtaPhi(probefwdtrack.pt(), probefwdtrack.eta(), probefwdtrack.phi()); + auto tagmuontrack = muontrack1; + auto probemuontrack = muontrack2; - double deltaPt = mfttrack_at_matching.getPt() - probefwdtrack.pt(); - double deltaX = mfttrack_at_matching.getX() - probefwdtrack.x(); - double deltaY = mfttrack_at_matching.getY() - probefwdtrack.y(); - double deltaPhi = V1.DeltaPhi(V2); - double deltaEta = mfttrack_at_matching.getEta() - probefwdtrack.eta(); + if (tagdimuon.getTagMuonIndex() == 1) { + tagmuontrack = muontrack2; + probemuontrack = muontrack1; + } - if (fabs(deltaX) > fPreselectMatchingX) { + int nTagMFTCand = 0; + int nProbeMFTCand = 0; + + int IndexTagMFTCand = -1; + float tagGMPtAtDCA = 0; + // float tagGMEtaAtDCA = 0; + + float minimumR = 9999.; + int minimumIndexProbeMFTCand = -1; + + unordered_map> map_tagMatchingParams; + unordered_map> map_probeMatchingParams; + + for (auto const& imfttrack1 : map_mfttracks[map_collision.first]) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + MatchingParamsML matchingTag(tagmuontrack, mfttrack1, collision, fMatchingMethod, fieldB); + matchingTag.calcMatchingParams(); + matchingTag.calcGlobalMuonParams(); + if (isGoodTagMatching(matchingTag.getDx(), matchingTag.getDy(), matchingTag.getDeta(), matchingTag.getDphi()) && + isPassMatchingPreselection(matchingTag.getDx(), matchingTag.getDy())) { + bool isTrue = false; + tableTagMatchingParams(matchingTag.getGMPtAtDCA(), + matchingTag.getGMEtaAtDCA(), + matchingTag.getGMQ(), + matchingTag.getDpt(), + matchingTag.getDx(), + matchingTag.getDy(), + matchingTag.getDeta(), + matchingTag.getDphi(), + isTrue); + IndexTagMFTCand = mfttrack1.globalIndex(); + tagGMPtAtDCA = matchingTag.getGMPtAtDCA(); + // tagGMEtaAtDCA = matchingTag.getGMEtaAtDCA(); + ++nTagMFTCand; + } + } // end of loop imfttrack1 + + if (nTagMFTCand != 1) continue; - } - if (fabs(deltaY) > fPreselectMatchingY) { + for (auto const& imfttrack1 : map_mfttracks[map_collision.first]) { + auto const& mfttrack1 = mfttracks.rawIteratorAt(imfttrack1); + if (mfttrack1.globalIndex() == IndexTagMFTCand) + continue; + MatchingParamsML matchingProbe(probemuontrack, mfttrack1, collision, fMatchingMethod, fieldB); + matchingProbe.calcMatchingParams(); + if (isPassMatchingPreselection(matchingProbe.getDx(), matchingProbe.getDy())) { + float R = sqrt(matchingProbe.getDx() * matchingProbe.getDx() + matchingProbe.getDy() * matchingProbe.getDy()); + bool isTrue = false; + matchingProbe.calcGlobalMuonParams(); + vector& probeMatchingParams = map_probeMatchingParams[nProbeMFTCand]; + probeMatchingParams.push_back(tagGMPtAtDCA); + probeMatchingParams.push_back(matchingProbe.getGMPtAtDCA()); + probeMatchingParams.push_back(matchingProbe.getGMEtaAtDCA()); + probeMatchingParams.push_back(matchingProbe.getGMQ()); + probeMatchingParams.push_back(matchingProbe.getDpt()); + probeMatchingParams.push_back(matchingProbe.getDx()); + probeMatchingParams.push_back(matchingProbe.getDy()); + probeMatchingParams.push_back(matchingProbe.getDeta()); + probeMatchingParams.push_back(matchingProbe.getDphi()); + probeMatchingParams.push_back(isTrue); + if (R < minimumR) { + minimumIndexProbeMFTCand = nProbeMFTCand; + minimumR = R; + } + ++nProbeMFTCand; + } + } // end of loop imfttrack1 + + if (nProbeMFTCand < 1) continue; + + if (minimumIndexProbeMFTCand > -1) { + vector& probeMatchingParams = map_probeMatchingParams[minimumIndexProbeMFTCand]; + tableProbeMatchingParams(probeMatchingParams[0], + probeMatchingParams[1], + probeMatchingParams[2], + static_cast(probeMatchingParams[3]), + probeMatchingParams[4], + probeMatchingParams[5], + probeMatchingParams[6], + probeMatchingParams[7], + probeMatchingParams[8], + static_cast(probeMatchingParams[9])); } - o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); + } // end of loop imuontrack2 + } // end of loop imuontrack1 + } // end of loop map_collision - probematchingParams(nMFTCandsTagMUON, nMFTCandsProbeMUON, tagfwdtrack.p(), deltaPt, deltaEta, deltaPhi, deltaX, deltaY, probefwdtrackAtPV.getPt(), probefwdtrackAtPV.getEta(), probefwdtrack.sign(), mfttrack_at_dca.getEta(), mfttrack1.sign()); - } - } - } - } + } // end of processMC }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; }