From d7813b5ecd47313385cf105d43e0883834b934d9 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Sat, 23 Nov 2024 05:23:18 +0100 Subject: [PATCH] PWGEM/Dilepton: first version of prefilter to reject photon conversion --- PWGEM/Dilepton/Core/DielectronCut.cxx | 15 ++ PWGEM/Dilepton/Core/DielectronCut.h | 73 +++++++- PWGEM/Dilepton/Core/Dilepton.h | 37 +++- PWGEM/Dilepton/Core/DileptonMC.h | 36 +++- PWGEM/Dilepton/Tasks/prefilterDielectron.cxx | 180 +++++++++++++++++-- 5 files changed, 318 insertions(+), 23 deletions(-) diff --git a/PWGEM/Dilepton/Core/DielectronCut.cxx b/PWGEM/Dilepton/Core/DielectronCut.cxx index 3d1987801cc..38e6e9c6103 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.cxx +++ b/PWGEM/Dilepton/Core/DielectronCut.cxx @@ -84,6 +84,21 @@ void DielectronCut::SetRequireDifferentSides(bool flag) mRequireDiffSides = flag; LOG(info) << "Dielectron Cut, require 2 tracks to be from different sides: " << mRequireDiffSides; } +void DielectronCut::SetPrefilterPhiV(float max_mee_uls, float max_phiv_uls, float max_mee_ls, float max_phiv_ls) +{ + mMaxMee_phiv_uls = max_mee_uls; + mMaxPhiV_uls = max_phiv_uls; + mSlope_phiv_ls = max_mee_ls / (M_PI - max_phiv_ls); + mIntercept_phiv_ls = max_mee_ls - mSlope_phiv_ls * M_PI; + LOG(info) << "Dielectron Cut, set phiv prefilter ULS: " << " mMaxMee_phiv_uls: " << mMaxMee_phiv_uls << " mMaxPhiV_uls: " << mMaxPhiV_uls; + LOG(info) << "Dielectron Cut, set phiv prefilter LS: " << " mSlope_phiv_ls: " << mSlope_phiv_ls << " mIntercept_phiv_ls: " << mIntercept_phiv_ls; +} +void DielectronCut::SetPrefilterMee(float min_mee_uls, float max_mee_uls) +{ + mMinMee_uls = min_mee_uls; + mMaxMee_uls = max_mee_uls; + LOG(info) << "Dielectron Cut, set mee prefilter ULS: " << " mMinMee_uls: " << mMinMee_uls << " mMaxMee_uls: " << mMaxMee_uls; +} void DielectronCut::SetTrackPtRange(float minPt, float maxPt) { mMinTrackPt = minPt; diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index ac3b6d2bb5b..f08d8cd3fcb 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -143,7 +143,7 @@ class DielectronCut : public TNamed return false; } - if (opAng < mMinOpAng || mMaxOpAng < opAng) { // in sigma for pair + if (opAng < mMinOpAng || mMaxOpAng < opAng) { return false; } @@ -161,6 +161,70 @@ class DielectronCut : public TNamed return true; } + template + bool IsSelectedPair_PrefilterULS(TTrack1 const& t1, TTrack2 const& t2, const float bz) const + { + // don't move this function into IsSelectedPair. + if (!IsSelectedPair_PrefilterULS_Mee(t1, t2, bz)) { + return false; + } + if (!IsSelectedPair_PrefilterULS_PhiV(t1, t2, bz)) { + return false; + } + return true; + } + + template + bool IsSelectedPair_PrefilterULS_Mee(TTrack1 const& t1, TTrack2 const& t2, const float /*bz*/) const + { + // don't move this function into IsSelectedPair. + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + if (mMinMee_uls < v12.M() && v12.M() < mMaxMee_uls) { + return false; + } + return true; + } + + template + bool IsSelectedPair_PrefilterULS_PhiV(TTrack1 const& t1, TTrack2 const& t2, const float bz) const + { + // don't move this function into IsSelectedPair. + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), bz); + if (v12.M() < mMaxMee_phiv_uls && mMaxPhiV_uls < phiv) { + return false; + } + return true; + } + + template + bool IsSelectedPair_PrefilterLS(TTrack1 const& t1, TTrack2 const& t2, const float bz) const + { + // don't move this function into IsSelectedPair. + if (!IsSelectedPair_PrefilterLS_PhiV(t1, t2, bz)) { + return false; + } + return true; + } + + template + bool IsSelectedPair_PrefilterLS_PhiV(TTrack1 const& t1, TTrack2 const& t2, const float bz) const + { + // don't move this function into IsSelectedPair. + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), bz); + if (v12.M() < phiv * mSlope_phiv_ls + mIntercept_phiv_ls || v12.M() < (M_PI - phiv) * mSlope_phiv_ls + mIntercept_phiv_ls) { + return false; + } + return true; + } + template bool IsSelectedTrack(TTrack const& track, TCollision const& collision = 0) const { @@ -413,6 +477,8 @@ class DielectronCut : public TNamed void SelectPhotonConversion(bool flag); void SetMindEtadPhi(bool flag, float min_deta, float min_dphi); void SetRequireDifferentSides(bool flag); + void SetPrefilterPhiV(float max_mee_uls, float max_phiv_uls, float max_mee_ls, float max_phiv_ls); + void SetPrefilterMee(float min_mee_uls, float max_mee_uls); void SetTrackPtRange(float minPt = 0.f, float maxPt = 1e10f); void SetTrackEtaRange(float minEta = -1e10f, float maxEta = 1e10f); @@ -480,6 +546,11 @@ class DielectronCut : public TNamed float mMinOpAng{0.f}, mMaxOpAng{1e10f}; bool mRequireDiffSides{false}; // flag to require 2 tracks to be from different sides. (A-C combination). If one wants 2 tracks to be in the same side (A-A or C-C), one can simply use track eta cut. + // only for prefilter + float mMinMee_uls{0.f}, mMaxMee_uls{0.f}; + float mMaxMee_phiv_uls{0.f}, mMaxPhiV_uls{0.f}; // rectangle + float mSlope_phiv_ls{0.f}, mIntercept_phiv_ls{0.f}; // mee > phiv * slope + intercept + // kinematic cuts float mMinTrackPt{0.f}, mMaxTrackPt{1e10f}; // range in pT float mMinTrackEta{-1e10f}, mMaxTrackEta{1e10f}; // range in eta diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index 70580bbdc74..2e1ba6659c2 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -75,7 +75,7 @@ using MyCollision = MyCollisions::iterator; using MyCollisionsWithSWT = soa::Join; using MyCollisionWithSWT = MyCollisionsWithSWT::iterator; -using MyElectrons = soa::Join; +using MyElectrons = soa::Join; using MyElectron = MyElectrons::iterator; using FilteredMyElectrons = soa::Filtered; using FilteredMyElectron = FilteredMyElectrons::iterator; @@ -180,7 +180,15 @@ struct Dilepton { Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; Configurable cfg_max_opang{"cfg_max_opang", 6.4, "max opening angle"}; Configurable cfg_require_diff_sides{"cfg_require_diff_sides", false, "flag to require 2 tracks are from different sides."}; - Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; + + Configurable cfg_apply_cuts_from_prefilter{"cfg_apply_cuts_from_prefilter", false, "flag to apply phiv cut inherited from prefilter"}; + Configurable cfg_prefilter_bits{"cfg_prefilter_bits", 0, "prefilter bits [kNone : 0, kMee : 1, kPhiV : 2, kFakeMatchITSTPC : 4] Please consider logical-OR among them."}; // see PairUtilities.h + Configurable cfgMinMee_uls{"cfgMinMee_uls", 0.0, "min mee for prefilter in GeV/c2"}; // only for ULS + Configurable cfgMaxMee_uls{"cfgMaxMee_uls", 0.01, "max mee for prefilter in GeV/c2"}; // only for ULS + Configurable cfgMaxMee_for_phiv_uls{"cfgMaxMee_for_phiv_uls", 0.65, "max mee at phiv = pi for ULS"}; // GeV/c2 + Configurable cfgMaxPhiV_uls{"cfgMaxPhiV_uls", 2.9, "min phiv for in ULS"}; // radian + Configurable cfgMaxMee_for_phiv_ls{"cfgMinMee_for_phiv", 0.25, "max mee at phiv = 0 and pi for LS"}; // GeV/c2 // symmetric + Configurable cfgMaxPhiV_ls{"cfgMaxPhiV_ls", 2.5, "min phiv for LS"}; // radian Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for single track"}; @@ -204,6 +212,7 @@ struct Dilepton { Configurable cfg_max_p_its_cluster_size{"cfg_max_p_its_cluster_size", 0.0, "max p to apply ITS cluster size cut"}; Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5, kTPChadrejORTOFreq_woTOFif : 6]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -525,7 +534,7 @@ struct Dilepton { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC)) { fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca}, true); fRegistry.add("Pair/same/uls/hsDeltaP", "difference of p between 2 tracks;|p_{T,1} - p_{T,2}|/|p_{T,1} + p_{T,2}|;#Delta#eta;#Delta#varphi (rad.);", kTHnSparseD, {{20, 0, 1}, {100, -0.5, +0.5}, {180, -M_PI, M_PI}}, true); - fRegistry.add("Pair/same/uls/hGeomDeltaZRDeltaPhi", Form("difference in z-r#varphi plane between 2 tracks at r = %2.1f cm;r#Delta#varphi (cm);#Deltaz (cm);", dielectroncuts.cfg_x_to_go.value), kTH2D, {{200, -50, 50}, {40, -10, 10}}, true); + fRegistry.add("Pair/same/uls/hGeomDeltaZRDeltaPhi", Form("difference in z-r#varphi plane between 2 tracks at r = %2.1f cm;r#Delta#varphi (cm);#Deltaz (cm);", dielectroncuts.cfg_x_to_go.value), kTH2D, {{200, -20, 20}, {100, -10, 10}}, true); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.add("Pair/same/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2D, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); // phiv is only for dielectron fRegistry.add("Pair/same/uls/hMvsPhiV_prop", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2D, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); // phiv is only for dielectron @@ -652,6 +661,16 @@ struct Dilepton { fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); + // for prefilter + if (dielectroncuts.cfg_apply_cuts_from_prefilter) { + if ((dielectroncuts.cfg_prefilter_bits & (1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee))) > 0) { + fDielectronCut.SetPrefilterMee(dielectroncuts.cfgMinMee_uls, dielectroncuts.cfgMaxMee_uls); + } + if ((dielectroncuts.cfg_prefilter_bits & (1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC))) > 0) { + fDielectronCut.SetPrefilterPhiV(dielectroncuts.cfgMaxMee_for_phiv_uls, dielectroncuts.cfgMaxPhiV_uls, dielectroncuts.cfgMaxMee_for_phiv_ls, dielectroncuts.cfgMaxPhiV_ls); + } + } + // for track fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, 1e+10f); fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, dielectroncuts.cfg_max_eta_track); @@ -858,6 +877,10 @@ struct Dilepton { return false; } + if (!cut.template IsSelectedPair_PrefilterULS(t1, t2, d_bz) || !cut.template IsSelectedPair_PrefilterLS(t1, t2, d_bz)) { + return false; + } + if constexpr (ev_id == 0) { dz_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_z_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_z_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_z_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_z_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_phi_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_phi_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_phi_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_phi_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; @@ -1151,6 +1174,11 @@ struct Dilepton { Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && dielectroncuts.cfg_min_phi_track < o2::aod::track::phi && o2::aod::track::phi < dielectroncuts.cfg_max_phi_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); + Filter prefilter_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter.node() && dielectroncuts.cfg_prefilter_bits.node() >= static_cast(1), + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbpi0 & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC))) > static_cast(0), (o2::aod::emprimaryelectron::pfbpi0 & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC))) <= static_cast(0), true), + o2::aod::emprimaryelectron::pfbpi0 >= static_cast(0)); + Partition positive_electrons = o2::aod::emprimaryelectron::sign > int8_t(0); Partition negative_electrons = o2::aod::emprimaryelectron::sign < int8_t(0); @@ -1400,6 +1428,9 @@ struct Dilepton { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + if (!cut.template IsSelectedPair_PrefilterULS(t1, t2, d_bz) || !cut.template IsSelectedPair_PrefilterLS(t1, t2, d_bz)) { + return false; + } float dz_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_z_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_z_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_z_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_z_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; float dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_phi_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_phi_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_phi_prop[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_phi_prop[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; o2::math_utils::bringToPMPi(dphi_geom); diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 84af68489da..a8b57d937af 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -65,7 +65,7 @@ using namespace o2::aod::pwgem::dilepton::utils::pairutil; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyMCElectrons = soa::Join; +using MyMCElectrons = soa::Join; using MyMCElectron = MyMCElectrons::iterator; using FilteredMyMCElectrons = soa::Filtered; using FilteredMyMCElectron = FilteredMyMCElectrons::iterator; @@ -159,7 +159,15 @@ struct DileptonMC { Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; Configurable cfg_max_opang{"cfg_max_opang", 6.4, "max opening angle"}; Configurable cfg_require_diff_sides{"cfg_require_diff_sides", false, "flag to require 2 tracks are from different sides."}; - Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; + + Configurable cfg_apply_cuts_from_prefilter{"cfg_apply_cuts_from_prefilter", false, "flag to apply phiv cut inherited from prefilter"}; + Configurable cfg_prefilter_bits{"cfg_prefilter_bits", 0, "prefilter bits [kNone : 0, kMee : 1, kPhiV : 2, kFakeMatchITSTPC : 4] Please consider logical-OR among them."}; // see PairUtilities.h + Configurable cfgMinMee_uls{"cfgMinMee_uls", 0.0, "min mee for prefilter in GeV/c2"}; // only for ULS + Configurable cfgMaxMee_uls{"cfgMaxMee_uls", 0.01, "max mee for prefilter in GeV/c2"}; // only for ULS + Configurable cfgMaxMee_for_phiv_uls{"cfgMaxMee_for_phiv_uls", 0.65, "max mee at phiv = pi for ULS"}; // GeV/c2 + Configurable cfgMaxPhiV_uls{"cfgMaxPhiV_uls", 2.9, "min phiv for in ULS"}; // radian + Configurable cfgMaxMee_for_phiv_ls{"cfgMinMee_for_phiv", 0.25, "max mee at phiv = 0 and pi for LS"}; // GeV/c2 // symmetric + Configurable cfgMaxPhiV_ls{"cfgMaxPhiV_ls", 2.5, "min phiv for LS"}; // radian Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "max eta for single track"}; @@ -183,6 +191,7 @@ struct DileptonMC { Configurable cfg_max_p_its_cluster_size{"cfg_max_p_its_cluster_size", 0.0, "max p to apply ITS cluster size cut"}; Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif = 4, kPIDML = 5]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -357,6 +366,7 @@ struct DileptonMC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.add("Pair/sm/Photon/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); + fRegistry.add("Pair/sm/Photon/hMvsRxy", "m_{ee} vs. r_{xy};r_{xy}^{true} (cm);m_{ee} (GeV/c^{2})", kTH2F, {{100, 0, 100}, {100, 0.0f, 1.0f}}, true); fRegistry.add("Pair/sm/Pi0/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); } @@ -556,6 +566,16 @@ struct DileptonMC { fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); + // for prefilter + if (dielectroncuts.cfg_apply_cuts_from_prefilter) { + if ((dielectroncuts.cfg_prefilter_bits & (1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee))) > 0) { + fDielectronCut.SetPrefilterMee(dielectroncuts.cfgMinMee_uls, dielectroncuts.cfgMaxMee_uls); + } + if ((dielectroncuts.cfg_prefilter_bits & (1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC))) > 0) { + fDielectronCut.SetPrefilterPhiV(dielectroncuts.cfgMaxMee_for_phiv_uls, dielectroncuts.cfgMaxPhiV_uls, dielectroncuts.cfgMaxMee_for_phiv_ls, dielectroncuts.cfgMaxPhiV_ls); + } + } + // for track fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, 1e+10f); fDielectronCut.SetTrackEtaRange(-dielectroncuts.cfg_max_eta_track, +dielectroncuts.cfg_max_eta_track); @@ -724,6 +744,9 @@ struct DileptonMC { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + if (!cut.template IsSelectedPair_PrefilterULS(t1, t2, d_bz) || !cut.template IsSelectedPair_PrefilterLS(t1, t2, d_bz)) { + return false; + } if (dielectroncuts.cfg_x_to_go > 0.f) { auto track_par_cov1 = getTrackParCov(t1); @@ -955,6 +978,8 @@ struct DileptonMC { fRegistry.fill(HIST("Pair/sm/Photon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), abs(dphi), deta, abs(cos_thetaCS), abs(phiCS), aco, asym, abs(dphi_e_ee), pair_dca, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/sm/Photon/hMvsPhiV"), phiv, v12.M()); + float rxy_gen = std::sqrt(std::pow(t1mc.vx(), 2) + std::pow(t1mc.vy(), 2)); + fRegistry.fill(HIST("Pair/sm/Photon/hMvsRxy"), rxy_gen, v12.M()); } break; default: @@ -1057,6 +1082,10 @@ struct DileptonMC { Filter trackFilter_electron = dielectroncuts.cfg_min_phi_track < o2::aod::track::phi && o2::aod::track::phi < dielectroncuts.cfg_max_phi_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; Filter pidFilter_electron = (dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl) && (o2::aod::pidtpc::tpcNSigmaPi < dielectroncuts.cfg_min_TPCNsigmaPi || dielectroncuts.cfg_max_TPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi); Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); + Filter prefilter_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter.node() && dielectroncuts.cfg_prefilter_bits.node() >= static_cast(1), + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbpi0 & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC))) > static_cast(0), (o2::aod::emprimaryelectron::pfbpi0 & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC))) <= static_cast(0), true), + o2::aod::emprimaryelectron::pfbpi0 >= static_cast(0)); Preslice perCollision_muon = aod::emprimarymuon::emeventId; Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type && dimuoncuts.cfg_min_phi_track < o2::aod::fwdtrack::phi && o2::aod::fwdtrack::phi < dimuoncuts.cfg_max_phi_track; @@ -1639,6 +1668,9 @@ struct DileptonMC { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + if (!cut.template IsSelectedPair_PrefilterULS(t1, t2, d_bz) || !cut.template IsSelectedPair_PrefilterLS(t1, t2, d_bz)) { + return false; + } if (dielectroncuts.cfg_x_to_go > 0.f) { auto track_par_cov1 = getTrackParCov(t1); track_par_cov1.setPID(o2::track::PID::Electron); diff --git a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx b/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx index 9d908c24de9..e310074c815 100644 --- a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx +++ b/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx @@ -17,6 +17,8 @@ #include #include #include +// #include +// #include #include "TString.h" #include "Math/Vector4D.h" @@ -24,7 +26,9 @@ #include "Framework/AnalysisTask.h" #include "Framework/ASoAHelpers.h" #include "Common/Core/RecoDecay.h" +// #include "Common/Core/trackUtilities.h" +#include "DetectorsBase/Propagator.h" #include "DetectorsBase/GeometryManager.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" @@ -61,15 +65,15 @@ struct prefilterDielectron { Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - // Configurable> cfgMaxMee{"cfgMaxMee", {0.01, 0.02, 0.04, 0.06, 0.08, 0.10}, "max mee steps for prefilter. Don't exceed 15 values!"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; - Configurable cfgMaxMee{"cfgMaxMee", 0.01, "max mee for prefilter in GeV/c2"}; // only for ULS + Configurable cfgMinMee_uls{"cfgMinMee_uls", 0.0, "min mee for prefilter in GeV/c2"}; // only for ULS + Configurable cfgMaxMee_uls{"cfgMaxMee_uls", 0.01, "max mee for prefilter in GeV/c2"}; // only for ULS Configurable cfgMaxMee_for_phiv_uls{"cfgMaxMee_for_phiv_uls", 0.65, "max mee at phiv = pi for ULS"}; // GeV/c2 - Configurable cfgMinPhiV_uls{"cfgMinPhiV_uls", 2.9, "min phiv for in ULS"}; // radian - Configurable cfgMaxMee_for_phiv_ls{"cfgMinMee_for_phiv", 0.25, "max mee at phiv = 0 and pi for LS"}; // GeV/c2 // symmetric - Configurable cfgMinPhiVv_ls{"cfgMinPhiVv_ls", 2.5, "min phiv for LS"}; // radian + Configurable cfgMaxPhiV_uls{"cfgMaxPhiV_uls", 2.9, "min phiv for in ULS"}; // radian + Configurable cfgMaxMee_for_phiv_ls{"cfgMaxMee_for_phiv", 0.25, "max mee at phiv = 0 and pi for LS"}; // GeV/c2 // symmetric + Configurable cfgMaxPhiV_ls{"cfgMaxPhiV_ls", 2.5, "min phiv for LS"}; // radian EMEventCut fEMEventCut; struct : ConfigurableGroup { @@ -112,6 +116,7 @@ struct prefilterDielectron { Configurable cfg_max_p_its_cluster_size{"cfg_max_p_its_cluster_size", 0.0, "max p to apply ITS cluster size cut"}; Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + // Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5, kTPChadrejORTOFreq_woTOFif : 6]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -144,6 +149,7 @@ struct prefilterDielectron { Service ccdb; int mRunNumber; float d_bz; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; @@ -176,6 +182,7 @@ struct prefilterDielectron { if (fabs(d_bz) > 1e-5) { grpmag.setL3Current(30000.f / (d_bz / 5.0f)); } + o2::base::Propagator::initFieldFromGRP(&grpmag); mRunNumber = collision.runNumber(); return; } @@ -186,6 +193,7 @@ struct prefilterDielectron { if (!skipGRPOquery) grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); // Fetch magnetic field from ccdb for current collision d_bz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -194,6 +202,7 @@ struct prefilterDielectron { if (!grpmag) { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; } + o2::base::Propagator::initFieldFromGRP(grpmag); // Fetch magnetic field from ccdb for current collision d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -212,7 +221,10 @@ struct prefilterDielectron { // for pair fRegistry.add("Pair/before/uls/hMvsPt", "m_{ee} vs. p_{T,ee}", kTH2D, {axis_mass, axis_pair_pt}, true); fRegistry.add("Pair/before/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2D, {axis_phiv, {200, 0, 1}}, true); - fRegistry.add("Pair/before/uls/hDeltaEtaDeltaPhi", "d#eta-d#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", kTH2D, {{180, -M_PI, M_PI}, {100, -0.5, +0.5}}, true); + fRegistry.add("Pair/before/uls/hDeltaEtaDeltaPhi", "#Delta#eta-#Delta#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", kTH2D, {{180, -M_PI, M_PI}, {100, -0.5, +0.5}}, true); + // fRegistry.add("Pair/before/uls/hGeomDeltaZRDeltaPhi", Form("difference in z-r#varphi plane between 2 tracks at r = %2.1f cm;r#Delta#varphi (cm);#Deltaz (cm);", dielectroncuts.cfg_x_to_go.value), kTH2D, {{200, -20, 20}, {100, -10, 10}}, true); + // fRegistry.add("Pair/before/uls/hMvsPhiV_prop", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2D, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); + fRegistry.addClone("Pair/before/uls/", "Pair/before/lspp/"); fRegistry.addClone("Pair/before/uls/", "Pair/before/lsmm/"); fRegistry.addClone("Pair/before/", "Pair/after/"); @@ -246,6 +258,10 @@ struct prefilterDielectron { fDielectronCut.SetPairOpAng(0.f, 3.2f); fDielectronCut.SetRequireDifferentSides(false); + // for prefilter + fDielectronCut.SetPrefilterPhiV(cfgMaxMee_for_phiv_uls, cfgMaxPhiV_uls, cfgMaxMee_for_phiv_ls, cfgMaxPhiV_ls); + fDielectronCut.SetPrefilterMee(cfgMinMee_uls, cfgMaxMee_uls); + // for track fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, 1e+10f); fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, dielectroncuts.cfg_max_eta_track); @@ -302,6 +318,40 @@ struct prefilterDielectron { } // end of PID ML } + // std::map, float> map_z_prop; // map -> geometrical z position at propagated point + // std::map, float> map_phi_prop; // map -> geometrical phi position at propagated point + // std::map, float> map_px_prop; // map -> px at propagated point + // std::map, float> map_py_prop; // map -> py at propagated point + // std::map, float> map_pz_prop; // map -> pz at propagated point + + // template + // void propagateElectron(TTracks const& tracks) + // { + // // this has to be called after initCCDB for bz. + // for (auto& track : tracks) { + // auto track_par_cov = getTrackParCov(track); + // track_par_cov.setPID(o2::track::PID::Electron); + // o2::base::Propagator::Instance()->propagateToX(track_par_cov, dielectroncuts.cfg_x_to_go, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); + // auto xyz = track_par_cov.getXYZGlo(); + // // float eta = RecoDecay::eta(std::array{xyz.X(), xyz.Y(), xyz.Z()}); + // float phi = RecoDecay::phi(std::array{xyz.X(), xyz.Y()}); + // o2::math_utils::bringTo02Pi(phi); + // map_z_prop[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = xyz.Z(); + // map_phi_prop[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = phi; + + // std::array pxpypz_prop = {0, 0, 0}; // px, py, pz + // getPxPyPz(track_par_cov, pxpypz_prop); + // map_px_prop[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = pxpypz_prop[0]; + // map_py_prop[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = pxpypz_prop[1]; + // map_pz_prop[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = pxpypz_prop[2]; + + // // float r = sqrt(pow(xyz.X(),2) + pow(xyz.Y(), 2)); + // // float theta = 2.f * std::atan(std::exp(-eta)); + // // float z = r/std::tan(theta); + // // LOGF(info, "r = %f, z = %f , xyz.Z() = %f", r, z, xyz.Z()); + // } + // } + std::unordered_map map_pfb; // map track.globalIndex -> prefilter bit SliceCache cache; @@ -314,6 +364,7 @@ struct prefilterDielectron { Filter collisionFilter_occupancy_ft0c = eventcuts.cfgFT0COccupancyMin < o2::aod::evsel::ft0cOccupancyInTimeRange && o2::aod::evsel::ft0cOccupancyInTimeRange < eventcuts.cfgFT0COccupancyMax; using FilteredMyCollisions = soa::Filtered; + int ndf = 0; void processPFB(FilteredMyCollisions const& collisions, MyTracks const& tracks) { for (auto& track : tracks) { @@ -341,6 +392,11 @@ struct prefilterDielectron { continue; } + // if (dielectroncuts.cfg_x_to_go > 0.f) { + // propagateElectron(posTracks_per_coll); + // propagateElectron(negTracks_per_coll); + // } + // LOGF(info, "centrality = %f , posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", centralities[cfgCentEstimator], posTracks_per_coll.size(), negTracks_per_coll.size()); for (auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS @@ -357,15 +413,30 @@ struct prefilterDielectron { float dphi = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); - fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt()); + // float dz_geom = pos.sign() * pos.pt() > ele.sign() * ele.pt() ? map_z_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())] - map_z_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] : map_z_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] - map_z_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())]; + // float dphi_geom = pos.sign() * pos.pt() > ele.sign() * ele.pt() ? map_phi_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())] - map_phi_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] : map_phi_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] - map_phi_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())]; + // o2::math_utils::bringToPMPi(dphi_geom); + // float rdphi_geom = dielectroncuts.cfg_x_to_go * dphi_geom; + + // ROOT::Math::PxPyPzMVector v1prop(map_px_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_py_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v2prop(map_px_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_py_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v12prop = v1prop + v2prop; + // float mee_prop = v12prop.M(); + // float phiv_prop = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(map_px_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_py_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], + // map_px_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_py_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], + // pos.sign(), ele.sign(), d_bz); + fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV"), phiv, v12.M()); + fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/before/uls/hDeltaEtaDeltaPhi"), dphi, deta); + // fRegistry.fill(HIST("Pair/before/uls/hGeomDeltaZRDeltaPhi"), rdphi_geom, dz_geom); + // fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV_prop"), phiv_prop, mee_prop); - if (v12.M() < cfgMaxMee) { + if (!fDielectronCut.IsSelectedPair_PrefilterULS_Mee(pos, ele, d_bz)) { map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee); map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kMee); } - if (v12.M() < cfgMaxMee_for_phiv_uls && cfgMinPhiV_uls < phiv) { + if (!fDielectronCut.IsSelectedPair_PrefilterULS_PhiV(pos, ele, d_bz)) { map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC); map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC); } @@ -385,13 +456,26 @@ struct prefilterDielectron { float dphi = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); + // float dz_geom = pos1.sign() * pos1.pt() > pos2.sign() * pos2.pt() ? map_z_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())] - map_z_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] : map_z_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] - map_z_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())]; + // float dphi_geom = pos1.sign() * pos1.pt() > pos2.sign() * pos2.pt() ? map_phi_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())] - map_phi_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] : map_phi_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] - map_phi_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())]; + // o2::math_utils::bringToPMPi(dphi_geom); + // float rdphi_geom = dielectroncuts.cfg_x_to_go * dphi_geom; + + // ROOT::Math::PxPyPzMVector v1prop(map_px_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_py_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v2prop(map_px_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_py_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v12prop = v1prop + v2prop; + // float mee_prop = v12prop.M(); + // float phiv_prop = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(map_px_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_py_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], + // map_px_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_py_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], + // pos1.sign(), pos2.sign(), d_bz); + fRegistry.fill(HIST("Pair/before/lspp/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/before/lspp/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/before/lspp/hDeltaEtaDeltaPhi"), dphi, deta); + // fRegistry.fill(HIST("Pair/before/lspp/hGeomDeltaZRDeltaPhi"), rdphi_geom, dz_geom); + // fRegistry.fill(HIST("Pair/before/lspp/hMvsPhiV_prop"), phiv_prop, mee_prop); - float slope = cfgMaxMee_for_phiv_ls / (M_PI - cfgMinPhiVv_ls); - float intercept = cfgMaxMee_for_phiv_ls - slope * M_PI; - if (v12.M() < phiv * slope + intercept || v12.M() < (M_PI - phiv) * slope + intercept) { + if (!fDielectronCut.IsSelectedPair_PrefilterLS_PhiV(pos1, pos2, d_bz)) { map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC); map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC); } @@ -411,12 +495,26 @@ struct prefilterDielectron { float dphi = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); + // float dz_geom = ele1.sign() * ele1.pt() > ele2.sign() * ele2.pt() ? map_z_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())] - map_z_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] : map_z_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] - map_z_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())]; + // float dphi_geom = ele1.sign() * ele1.pt() > ele2.sign() * ele2.pt() ? map_phi_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())] - map_phi_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] : map_phi_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] - map_phi_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())]; + // o2::math_utils::bringToPMPi(dphi_geom); + // float rdphi_geom = dielectroncuts.cfg_x_to_go * dphi_geom; + + // ROOT::Math::PxPyPzMVector v1prop(map_px_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_py_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v2prop(map_px_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_py_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v12prop = v1prop + v2prop; + // float mee_prop = v12prop.M(); + // float phiv_prop = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(map_px_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_py_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], + // map_px_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_py_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], + // ele1.sign(), ele2.sign(), d_bz); + fRegistry.fill(HIST("Pair/before/lsmm/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/before/lsmm/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/before/lsmm/hDeltaEtaDeltaPhi"), dphi, deta); - float slope = cfgMaxMee_for_phiv_ls / (M_PI - cfgMinPhiVv_ls); - float intercept = cfgMaxMee_for_phiv_ls - slope * M_PI; - if (v12.M() < phiv * slope + intercept || v12.M() < (M_PI - phiv) * slope + intercept) { + // fRegistry.fill(HIST("Pair/before/lsmm/hGeomDeltaZRDeltaPhi"), rdphi_geom, dz_geom); + // fRegistry.fill(HIST("Pair/before/lsmm/hMvsPhiV_prop"), phiv_prop, mee_prop); + + if (!fDielectronCut.IsSelectedPair_PrefilterLS_PhiV(ele1, ele2, d_bz)) { map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC); map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kFakeMatchITSTPC); } @@ -458,9 +556,25 @@ struct prefilterDielectron { float deta = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? v1.Eta() - v2.Eta() : v2.Eta() - v1.Eta(); float dphi = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); - fRegistry.fill(HIST("Pair/after/uls/hMvsPt"), v12.M(), v12.Pt()); + + // float dz_geom = pos.sign() * pos.pt() > ele.sign() * ele.pt() ? map_z_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())] - map_z_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] : map_z_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] - map_z_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())]; + // float dphi_geom = pos.sign() * pos.pt() > ele.sign() * ele.pt() ? map_phi_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())] - map_phi_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] : map_phi_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())] - map_phi_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())]; + // o2::math_utils::bringToPMPi(dphi_geom); + // float rdphi_geom = dielectroncuts.cfg_x_to_go * dphi_geom; + + // ROOT::Math::PxPyPzMVector v1prop(map_px_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_py_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v2prop(map_px_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_py_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v12prop = v1prop + v2prop; + // float mee_prop = v12prop.M(); + // float phiv_prop = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(map_px_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_py_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos.emeventId(), pos.globalIndex())], + // map_px_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_py_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele.emeventId(), ele.globalIndex())], + // pos.sign(), ele.sign(), d_bz); + fRegistry.fill(HIST("Pair/after/uls/hMvsPhiV"), phiv, v12.M()); + fRegistry.fill(HIST("Pair/after/uls/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/after/uls/hDeltaEtaDeltaPhi"), dphi, deta); + // fRegistry.fill(HIST("Pair/after/uls/hGeomDeltaZRDeltaPhi"), rdphi_geom, dz_geom); + // fRegistry.fill(HIST("Pair/after/uls/hMvsPhiV_prop"), phiv_prop, mee_prop); } for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ @@ -478,9 +592,25 @@ struct prefilterDielectron { float deta = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? v1.Eta() - v2.Eta() : v2.Eta() - v1.Eta(); float dphi = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); + + // float dz_geom = pos1.sign() * pos1.pt() > pos2.sign() * pos2.pt() ? map_z_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())] - map_z_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] : map_z_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] - map_z_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())]; + // float dphi_geom = pos1.sign() * pos1.pt() > pos2.sign() * pos2.pt() ? map_phi_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())] - map_phi_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] : map_phi_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())] - map_phi_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())]; + // o2::math_utils::bringToPMPi(dphi_geom); + // float rdphi_geom = dielectroncuts.cfg_x_to_go * dphi_geom; + + // ROOT::Math::PxPyPzMVector v1prop(map_px_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_py_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v2prop(map_px_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_py_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v12prop = v1prop + v2prop; + // float mee_prop = v12prop.M(); + // float phiv_prop = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(map_px_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_py_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos1.emeventId(), pos1.globalIndex())], + // map_px_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_py_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], map_pz_prop[std::make_tuple(ndf, pos2.emeventId(), pos2.globalIndex())], + // pos1.sign(), pos2.sign(), d_bz); + fRegistry.fill(HIST("Pair/after/lspp/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/after/lspp/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/after/lspp/hDeltaEtaDeltaPhi"), dphi, deta); + // fRegistry.fill(HIST("Pair/after/lspp/hGeomDeltaZRDeltaPhi"), rdphi_geom, dz_geom); + // fRegistry.fill(HIST("Pair/after/lspp/hMvsPhiV_prop"), phiv_prop, mee_prop); } for (auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- @@ -498,13 +628,29 @@ struct prefilterDielectron { float deta = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? v1.Eta() - v2.Eta() : v2.Eta() - v1.Eta(); float dphi = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); + + // float dz_geom = ele1.sign() * ele1.pt() > ele2.sign() * ele2.pt() ? map_z_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())] - map_z_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] : map_z_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] - map_z_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())]; + // float dphi_geom = ele1.sign() * ele1.pt() > ele2.sign() * ele2.pt() ? map_phi_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())] - map_phi_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] : map_phi_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())] - map_phi_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())]; + // o2::math_utils::bringToPMPi(dphi_geom); + // float rdphi_geom = dielectroncuts.cfg_x_to_go * dphi_geom; + + // ROOT::Math::PxPyPzMVector v1prop(map_px_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_py_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v2prop(map_px_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_py_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], o2::constants::physics::MassElectron); + // ROOT::Math::PxPyPzMVector v12prop = v1prop + v2prop; + // float mee_prop = v12prop.M(); + // float phiv_prop = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(map_px_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_py_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele1.emeventId(), ele1.globalIndex())], + // map_px_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_py_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], map_pz_prop[std::make_tuple(ndf, ele2.emeventId(), ele2.globalIndex())], + // ele1.sign(), ele2.sign(), d_bz); + fRegistry.fill(HIST("Pair/after/lsmm/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/after/lsmm/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/after/lsmm/hDeltaEtaDeltaPhi"), dphi, deta); + // fRegistry.fill(HIST("Pair/after/lsmm/hGeomDeltaZRDeltaPhi"), rdphi_geom, dz_geom); + // fRegistry.fill(HIST("Pair/after/lsmm/hMvsPhiV_prop"), phiv_prop, mee_prop); } } // end of collision loop - + ndf++; map_pfb.clear(); } // end of process PROCESS_SWITCH(prefilterDielectron, processPFB, "produce prefilter bit", false);