From 7e75efce9123982246d8447566a2fd5861896915 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 25 Jul 2025 21:31:41 +0200 Subject: [PATCH] PWGEM/Dilepton: update 2PC --- PWGEM/Dilepton/Core/DileptonHadronMPC.h | 385 +++++++----------- PWGEM/Dilepton/Core/EMTrackCut.cxx | 6 + PWGEM/Dilepton/Core/EMTrackCut.h | 137 ++++--- PWGEM/Dilepton/DataModel/dileptonTables.h | 25 +- .../TableProducer/skimmerPrimaryTrack.cxx | 125 +++--- PWGEM/Dilepton/Utils/EMTrack.h | 32 +- PWGEM/Dilepton/Utils/EMTrackUtilities.h | 14 + PWGEM/Dilepton/Utils/EventHistograms.h | 6 +- PWGEM/Dilepton/Utils/PairUtilities.h | 4 +- PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h | 304 +++++++++----- .../TableProducer/createEMEventPhoton.cxx | 16 +- 11 files changed, 582 insertions(+), 472 deletions(-) diff --git a/PWGEM/Dilepton/Core/DileptonHadronMPC.h b/PWGEM/Dilepton/Core/DileptonHadronMPC.h index 176cfcdb740..fe1c3f7c036 100644 --- a/PWGEM/Dilepton/Core/DileptonHadronMPC.h +++ b/PWGEM/Dilepton/Core/DileptonHadronMPC.h @@ -90,10 +90,8 @@ using FilteredMyMuon = FilteredMyMuons::iterator; using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; -using MyEMH_electron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrackWithCov>; +using MyEMH_electron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; using MyEMH_muon = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMFwdTrack>; -using MyEMH_dielectron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; -using MyEMH_dimuon = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMFwdTrack>; using MyEMH_track = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; // for charged track template @@ -106,16 +104,17 @@ struct DileptonHadronMPC { Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - Configurable cfgAnalysisType{"cfgAnalysisType", static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant), "kCumulant:0, kCorrelationFunction:1"}; + Configurable cfgAnalysisType{"cfgAnalysisType", static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation), "kAzimuthalCorrelation:0, kCumulant:1"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; - Configurable ndepth{"ndepth", 100, "depth for event mixing"}; + Configurable ndepth_lepton{"ndepth_lepton", 100, "depth for event mixing between lepton-lepton"}; + Configurable ndepth_hadron{"ndepth_hadron", 2, "depth for event mixing between hadron-hadron"}; Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; ConfigurableAxis ConfVtxBins{"ConfVtxBins", {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 ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; + ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 0.1, 1, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; Configurable cfg_swt_name{"cfg_swt_name", "fHighTrackMult", "desired software trigger name"}; // 1 trigger name per 1 task. fHighTrackMult, fHighFt0Mult // Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; @@ -280,7 +279,7 @@ struct DileptonHadronMPC { EMTrackCut fEMTrackCut; struct : ConfigurableGroup { std::string prefix = "trackcut_group"; - Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.15, "min pT for ref. track"}; + Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for ref. track"}; Configurable cfg_max_pt_track{"cfg_max_pt_track", 3.0, "max pT for ref. track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -1.2, "min eta for ref. track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", +1.2, "max eta for ref. track"}; @@ -292,8 +291,8 @@ struct DileptonHadronMPC { Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; + Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; + Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; Configurable cfg_require_itsib_any{"cfg_require_itsib_any", true, "flag to require ITS ib any hits"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", false, "flag to require ITS ib 1st hit"}; } trackcuts; @@ -381,8 +380,9 @@ struct DileptonHadronMPC { } } - emh_pos = new TEMH(ndepth); - emh_neg = new TEMH(ndepth); + emh_pos = new TEMH(ndepth_lepton); + emh_neg = new TEMH(ndepth_lepton); + emh_ref = new MyEMH_track(ndepth_hadron); // for reference flow DefineEMEventCut(); DefineEMTrackCut(); @@ -397,7 +397,7 @@ struct DileptonHadronMPC { leptonM2 = o2::constants::physics::MassMuon; } - if (doprocess2PCwithTrigger) { + if (doprocessTriggerAnalysis) { fRegistry.add("Event/hNInspectedTVX", "N inspected TVX;run number;N_{TVX}", kTProfile, {{80000, 520000.5, 600000.5}}, true); } } @@ -456,9 +456,13 @@ struct DileptonHadronMPC { emh_pos = 0x0; delete emh_neg; emh_neg = 0x0; + delete emh_ref; + emh_ref = 0x0; used_trackIds.clear(); used_trackIds.shrink_to_fit(); + used_refTrackIds.clear(); + used_refTrackIds.shrink_to_fit(); } void addhistograms() @@ -506,51 +510,45 @@ struct DileptonHadronMPC { // dilepton-hadron info const AxisSpec axis_pt_ref{ConfPtHadronBins, "p_{T,h}^{ref} (GeV/c)"}; const AxisSpec axis_deta{ConfDEtaBins, deta_axis_title}; - // const AxisSpec axis_dphi{cfgNbinsDPhi, -M_PI/2, 3 * M_PI/2, dphi_axis_title}; - const AxisSpec axis_cos_ndphi{cfgNbinsCosNDPhi, -1, +1, cosndphi_axis_title}; + + // hadron-hadron info + const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{trg} - #eta_{h}^{ref}"}; const AxisSpec axis_pt_trg{ConfPtHadronBins, "p_{T,h} (GeV/c)"}; const AxisSpec axis_eta_trg{40, -2, +2, "#eta_{h}"}; const AxisSpec axis_phi_trg{36, 0, 2 * M_PI, "#varphi_{h} (rad.)"}; - - if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { - fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_trg, axis_eta_trg, axis_phi_trg}, true); - - fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_pt_ref, axis_deta, axis_cos_ndphi}, true); + fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_trg, axis_eta_trg, axis_phi_trg}, true); + fRegistry.add("Dilepton/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); + fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lspp/"); + fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lsmm/"); + fRegistry.addClone("Dilepton/same/", "Dilepton/mix/"); + + if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { + const AxisSpec axis_dphi{cfgNbinsDPhi, -M_PI / 2, 3 * M_PI / 2, dphi_axis_title}; + const AxisSpec axis_dphi_hh{cfgNbinsDPhi, -M_PI / 2, 3 * M_PI / 2, "#Delta#varphi = #varphi_{h}^{trg} - #varphi_{h}^{ref} (rad.)"}; + // dilepton-hadron + fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_pt_ref, axis_deta, axis_dphi}, true); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lspp/"); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lsmm/"); - fRegistry.addClone("DileptonHadron/same/", "DileptonHadron/mix/"); - - fRegistry.add("Dilepton/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); - fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lspp/"); - fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lsmm/"); - fRegistry.addClone("Dilepton/same/", "Dilepton/mix/"); + // fRegistry.addClone("DileptonHadron/same/", "DileptonHadron/mix/"); // hadron-hadron - const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{trg} - #eta_{h}^{ref}"}; - // const AxisSpec axis_dphi_hh{cfgNbinsDPhi, -M_PI/2, 3 * M_PI/2, "#Delta#varphi = #varphi_{h}^{trg} - #varphi_{h}^{ref} (rad.)"}; const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{trg}} - #varphi_{{h}}^{{ref}}))", cfgNmod.value)}; - fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_trg, axis_pt_ref, axis_deta_hh, axis_cosndphi_hh}, true); - // fRegistry.addClone("HadronHadron/same/", "HadronHadron/mix/"); - } else { // same as kCumulant to avoid seg. fault - fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_trg, axis_eta_trg, axis_phi_trg}, true); + fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_trg, axis_pt_ref, axis_deta_hh, axis_dphi_hh}, true); + fRegistry.addClone("HadronHadron/same/", "HadronHadron/mix/"); + fRegistry.add("HadronHadron/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", kTH1D, {{10001, -0.5, 10000.5}}, true); + } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { + const AxisSpec axis_cos_ndphi{cfgNbinsCosNDPhi, -1, +1, cosndphi_axis_title}; + // dilepton-hadron fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_pt_ref, axis_deta, axis_cos_ndphi}, true); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lspp/"); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lsmm/"); fRegistry.addClone("DileptonHadron/same/", "DileptonHadron/mix/"); - fRegistry.add("Dilepton/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); - fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lspp/"); - fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lsmm/"); - fRegistry.addClone("Dilepton/same/", "Dilepton/mix/"); - // hadron-hadron - const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{trg} - #eta_{h}^{ref}"}; - // const AxisSpec axis_dphi_hh{cfgNbinsDPhi, -M_PI/2, 3 * M_PI/2, "#Delta#varphi = #varphi_{h}^{trg} - #varphi_{h}^{ref} (rad.)"}; const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{trg}} - #varphi_{{h}}^{{ref}}))", cfgNmod.value)}; fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_trg, axis_pt_ref, axis_deta_hh, axis_cosndphi_hh}, true); - // fRegistry.addClone("HadronHadron/same/", "HadronHadron/mix/"); } fRegistry.add("Dilepton/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", kTH1D, {{10001, -0.5, 10000.5}}, true); } @@ -777,22 +775,12 @@ struct DileptonHadronMPC { pair_dca = pairDCAQuadSum(fwdDcaXYinSigma(t1), fwdDcaXYinSigma(t2)); } - if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { - if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); - } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); - } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); - } - } else { // same as kCumulant to avoid seg. fault - if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); - } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); - } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); - } + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Dilepton/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); } // store tracks for event mixing without double counting @@ -812,13 +800,9 @@ struct DileptonHadronMPC { used_trackIds.emplace_back(pair_tmp_id1); if (cfgDoMix) { if (t1.sign() > 0) { - emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); + emh_pos->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, t1.cYY(), t1.cZY(), t1.cZZ())); } else { - emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); + emh_neg->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, t1.cYY(), t1.cZY(), t1.cZZ())); } } } @@ -826,13 +810,9 @@ struct DileptonHadronMPC { used_trackIds.emplace_back(pair_tmp_id2); if (cfgDoMix) { if (t2.sign() > 0) { - emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); + emh_pos->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, t2.cYY(), t2.cZY(), t2.cZZ())); } else { - emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); + emh_neg->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, t2.cYY(), t2.cZY(), t2.cZZ())); } } } @@ -865,6 +845,11 @@ struct DileptonHadronMPC { } } } + + // possibleIds1.clear(); + // possibleIds1.shrink_to_fit(); + // possibleIds2.clear(); + // possibleIds2.shrink_to_fit(); } return true; } @@ -872,6 +857,7 @@ struct DileptonHadronMPC { template bool fillDileptonHadron(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const& tracks, TRefTrack const& t3) { + // this function must be called, if dilepton passes the cut. if constexpr (ev_id == 1) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { // bool is_found1 = std::find(t2.ambiguousElectronsIds.begin(), t2.ambiguousElectronsIds.end(), t1.globalIndex()) != t2.ambiguousElectronsIds.end(); // this does not work. @@ -951,9 +937,6 @@ struct DileptonHadronMPC { ROOT::Math::PtEtaPhiMVector v3(t3.pt(), t3.eta(), t3.phi(), 0.139); // mass of hadron does not matter. float deta = v12.Eta() - v3.Eta(); float dphi = v12.Phi() - v3.Phi(); - // dphi = RecoDecay::constrainAngle(dphi, - M_PI/2, 1U); - o2::math_utils::bringTo02Pi(dphi); - float cosndphi = std::cos(cfgNmod * dphi); float pair_dca = 999.f; if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { @@ -967,7 +950,18 @@ struct DileptonHadronMPC { pair_dca = pairDCAQuadSum(fwdDcaXYinSigma(t1), fwdDcaXYinSigma(t2)); } - if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { + if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, dphi, weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, dphi, weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, dphi, weight); + } + } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { + o2::math_utils::bringTo02Pi(dphi); + float cosndphi = std::cos(cfgNmod * dphi); if (t1.sign() * t2.sign() < 0) { // ULS fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, cosndphi, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ @@ -977,175 +971,67 @@ struct DileptonHadronMPC { } } - // // store tracks for event mixing without double counting - // if constexpr (ev_id == 0) { - // std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); - // std::pair pair_tmp_id1 = std::make_pair(ndf, t1.globalIndex()); - // std::pair pair_tmp_id2 = std::make_pair(ndf, t2.globalIndex()); - - // std::vector possibleIds1; - // std::vector possibleIds2; - - // if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - // std::copy(t1.ambiguousElectronsIds().begin(), t1.ambiguousElectronsIds().end(), std::back_inserter(possibleIds1)); - // std::copy(t2.ambiguousElectronsIds().begin(), t2.ambiguousElectronsIds().end(), std::back_inserter(possibleIds2)); - - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id1) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id1); - // if (cfgDoMix) { - // if (t1.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - // t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - // t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - // t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - // t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); - // } - // } - // } - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id2) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id2); - // if (cfgDoMix) { - // if (t2.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - // t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - // t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - // t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - // t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); - // } - // } - // } - // } else if (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - // std::copy(t1.ambiguousMuonsIds().begin(), t1.ambiguousMuonsIds().end(), std::back_inserter(possibleIds1)); - // std::copy(t2.ambiguousMuonsIds().begin(), t2.ambiguousMuonsIds().end(), std::back_inserter(possibleIds2)); - - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id1) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id1); - // if (cfgDoMix) { - // if (t1.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, - // t1.cXXatDCA(), t1.cXYatDCA(), t1.cYYatDCA())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, - // t1.cXXatDCA(), t1.cXYatDCA(), t1.cYYatDCA())); - // } - // } - // } - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id2) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id2); - // if (cfgDoMix) { - // if (t2.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, - // t2.cXXatDCA(), t2.cXYatDCA(), t2.cYYatDCA())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, - // t2.cXXatDCA(), t2.cXYatDCA(), t2.cYYatDCA())); - // } - // } - // } - // } - // } return true; } - template - bool fillHadronHadron(TRefTrack const& t1, TRefTrack const& t2) + template + bool fillHadronHadron(TCollision const& collision, TRefTrack const& t1, TRefTrack const& t2, TLeptons const& posLeptons, TLeptons const& negLeptons) { if constexpr (ev_id == 0) { if (!fEMTrackCut.IsSelected(t1) || !fEMTrackCut.IsSelected(t2)) { // for charged track return false; } - } else { - return false; // mixed event is not necessary for cumulant method. + + // Leptons should not be in reference track sample. + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + for (const auto& pos : posLeptons) { // leptons per collision + if (t1.trackId() == pos.trackId() || t2.trackId() == pos.trackId()) { + return false; + } + } + for (const auto& neg : negLeptons) { // leptons per collision + if (t1.trackId() == neg.trackId() || t2.trackId() == neg.trackId()) { + return false; + } + } + } + } + + if constexpr (ev_id == 1) { + if (t1.dfId() == t2.dfId() && t1.globalIndex() == t2.globalIndex()) { + return false; // this never happens. only for protection. + } } float weight = 1.f; float deta = t1.eta() - t2.eta(); // t1 is trigger, t2 is associated float dphi = t1.phi() - t2.phi(); // t1 is trigger, t2 is associated - // dphi = RecoDecay::constrainAngle(dphi, - M_PI/2, 1U); - o2::math_utils::bringTo02Pi(dphi); - float cosndphi = std::cos(cfgNmod * dphi); - if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { - fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hs"), t1.pt(), t2.pt(), deta, cosndphi, weight); - } else { // same as kCumulant to avoid seg. fault + if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hs"), t1.pt(), t2.pt(), deta, dphi, weight); + } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { + o2::math_utils::bringTo02Pi(dphi); + float cosndphi = std::cos(cfgNmod * dphi); fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hs"), t1.pt(), t2.pt(), deta, cosndphi, weight); } - // // store tracks for event mixing without double counting - // if constexpr (ev_id == 0) { - // std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); - // std::pair pair_tmp_id1 = std::make_pair(ndf, t1.globalIndex()); - // std::pair pair_tmp_id2 = std::make_pair(ndf, t2.globalIndex()); - // - // std::vector possibleIds1; - // std::vector possibleIds2; - // - // if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - // std::copy(t1.ambiguousElectronsIds().begin(), t1.ambiguousElectronsIds().end(), std::back_inserter(possibleIds1)); - // std::copy(t2.ambiguousElectronsIds().begin(), t2.ambiguousElectronsIds().end(), std::back_inserter(possibleIds2)); - // - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id1) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id1); - // if (cfgDoMix) { - // if (t1.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - // t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - // t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - // t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - // t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); - // } - // } - // } - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id2) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id2); - // if (cfgDoMix) { - // if (t2.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - // t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - // t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - // t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - // t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); - // } - // } - // } - // } else if (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - // std::copy(t1.ambiguousMuonsIds().begin(), t1.ambiguousMuonsIds().end(), std::back_inserter(possibleIds1)); - // std::copy(t2.ambiguousMuonsIds().begin(), t2.ambiguousMuonsIds().end(), std::back_inserter(possibleIds2)); - // - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id1) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id1); - // if (cfgDoMix) { - // if (t1.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, - // t1.cXXatDCA(), t1.cXYatDCA(), t1.cYYatDCA())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, - // t1.cXXatDCA(), t1.cXYatDCA(), t1.cYYatDCA())); - // } - // } - // } - // if (std::find(used_trackIds.begin(), used_trackIds.end(), pair_tmp_id2) == used_trackIds.end()) { - // used_trackIds.emplace_back(pair_tmp_id2); - // if (cfgDoMix) { - // if (t2.sign() > 0) { - // emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, - // t2.cXXatDCA(), t2.cXYatDCA(), t2.cYYatDCA())); - // } else { - // emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, - // t2.cXXatDCA(), t2.cXYatDCA(), t2.cYYatDCA())); - // } - // } - // } - // } - // } + // store ref tracks for mixed event in case of kAzimuthalCorrelation + if constexpr (ev_id == 0) { + if (cfgDoMix && cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { + std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); + std::pair pair_tmp_id1 = std::make_pair(ndf, t1.globalIndex()); + std::pair pair_tmp_id2 = std::make_pair(ndf, t2.globalIndex()); + if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_id1) == used_refTrackIds.end()) { + used_refTrackIds.emplace_back(pair_tmp_id1); + emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), 0.139)); + } // store t1 + if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_id2) == used_refTrackIds.end()) { + used_refTrackIds.emplace_back(pair_tmp_id2); + emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), 0.139)); + } // store t2 + } + } return true; } @@ -1188,9 +1074,11 @@ struct DileptonHadronMPC { TEMH* emh_pos = nullptr; TEMH* emh_neg = nullptr; + MyEMH_track* emh_ref = nullptr; // for reference flow std::map, uint64_t> map_mixed_eventId_to_globalBC; std::vector> used_trackIds; + std::vector> used_refTrackIds; int ndf = 0; template @@ -1239,8 +1127,8 @@ struct DileptonHadronMPC { bool is_pair_ok = fillDilepton<0>(collision, pos, neg, cut, tracks); if (is_pair_ok) { nuls++; - for (const auto& reftrack : refTracks_per_coll) { - fillDileptonHadron<0>(collision, pos, neg, cut, tracks, reftrack); + for (const auto& refTrack : refTracks_per_coll) { + fillDileptonHadron<0>(collision, pos, neg, cut, tracks, refTrack); } } } @@ -1248,8 +1136,8 @@ struct DileptonHadronMPC { bool is_pair_ok = fillDilepton<0>(collision, pos1, pos2, cut, tracks); if (is_pair_ok) { nlspp++; - for (const auto& reftrack : refTracks_per_coll) { - fillDileptonHadron<0>(collision, pos1, pos2, cut, tracks, reftrack); + for (const auto& refTrack : refTracks_per_coll) { + fillDileptonHadron<0>(collision, pos1, pos2, cut, tracks, refTrack); } } } @@ -1257,15 +1145,15 @@ struct DileptonHadronMPC { bool is_pair_ok = fillDilepton<0>(collision, neg1, neg2, cut, tracks); if (is_pair_ok) { nlsmm++; - for (const auto& reftrack : refTracks_per_coll) { - fillDileptonHadron<0>(collision, neg1, neg2, cut, tracks, reftrack); + for (const auto& refTrack : refTracks_per_coll) { + fillDileptonHadron<0>(collision, neg1, neg2, cut, tracks, refTrack); } } } if (nuls > 0 || nlspp > 0 || nlsmm > 0) { // at least 1 pair exists. for (const auto& [trg, ref] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_coll, refTracks_per_coll))) { - fillHadronHadron<0>(trg, ref); + fillHadronHadron<0>(collision, trg, ref, posTracks_per_coll, negTracks_per_coll); } } @@ -1356,12 +1244,39 @@ struct DileptonHadronMPC { fillDilepton<1>(collision, neg1, neg2, cut, tracks); } } - } // end of loop over mixed event pool + } // end of loop over mixed event pool for lepton-lepton + + if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { + auto selected_refTracks_in_this_event = emh_ref->GetTracksPerCollision(key_df_collision); + auto collisionIds_in_mixing_pool_hadron = emh_ref->GetCollisionIdsFromEventPool(key_bin); + for (const auto& mix_dfId_collisionId : collisionIds_in_mixing_pool_hadron) { + int mix_dfId = mix_dfId_collisionId.first; + int mix_collisionId = mix_dfId_collisionId.second; + if (collision.globalIndex() == mix_collisionId && ndf == mix_dfId) { // this never happens. only protection. + continue; + } + + auto globalBC_mix = map_mixed_eventId_to_globalBC[mix_dfId_collisionId]; + uint64_t diffBC = std::max(collision.globalBC(), globalBC_mix) - std::min(collision.globalBC(), globalBC_mix); + fRegistry.fill(HIST("HadronHadron/mix/hDiffBC"), diffBC); + if (diffBC < ndiff_bc_mix) { + continue; + } + + auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + for (const auto& ref1 : selected_refTracks_in_this_event) { // ref-ref mix + for (const auto& ref2 : refTracks_from_event_pool) { + fillHadronHadron<1>(collision, ref1, ref2, nullptr, nullptr); + } + } + } // end of loop over mixed event pool for lepton-lepton + } if (nuls > 0 || nlspp > 0 || nlsmm > 0) { map_mixed_eventId_to_globalBC[key_df_collision] = collision.globalBC(); emh_pos->AddCollisionIdAtLast(key_bin, key_df_collision); emh_neg->AddCollisionIdAtLast(key_bin, key_df_collision); + emh_ref->AddCollisionIdAtLast(key_bin, key_df_collision); } } // end of collision loop @@ -1488,7 +1403,7 @@ struct DileptonHadronMPC { passed_pairIds.shrink_to_fit(); } - void process2PC(FilteredMyCollisions const& collisions, MyTracks const& refTracks, Types const&... args) + void processAnalysis(FilteredMyCollisions const& collisions, MyTracks const& refTracks, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); @@ -1506,10 +1421,10 @@ struct DileptonHadronMPC { map_weight.clear(); ndf++; } - PROCESS_SWITCH(DileptonHadronMPC, process2PC, "run dilepton analysis", true); + PROCESS_SWITCH(DileptonHadronMPC, processAnalysis, "run dilepton analysis", true); using FilteredMyCollisionsWithSWT = soa::Filtered; - void process2PCwithTrigger(FilteredMyCollisionsWithSWT const& collisions, MyTracks const& refTracks, Types const&... args) + void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, MyTracks const& refTracks, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); @@ -1527,7 +1442,7 @@ struct DileptonHadronMPC { map_weight.clear(); ndf++; } - PROCESS_SWITCH(DileptonHadronMPC, process2PCwithTrigger, "run dilepton analysis on triggered data", false); + PROCESS_SWITCH(DileptonHadronMPC, processTriggerAnalysis, "run dilepton analysis on triggered data", false); void processDummy(MyCollisions const&) {} PROCESS_SWITCH(DileptonHadronMPC, processDummy, "Dummy function", false); diff --git a/PWGEM/Dilepton/Core/EMTrackCut.cxx b/PWGEM/Dilepton/Core/EMTrackCut.cxx index 9d33efc1fc8..a875a644ce8 100644 --- a/PWGEM/Dilepton/Core/EMTrackCut.cxx +++ b/PWGEM/Dilepton/Core/EMTrackCut.cxx @@ -111,3 +111,9 @@ void EMTrackCut::RequireITSib1st(bool flag) mRequireITSib1st = flag; LOG(info) << "EMTrack Cut, require ITS ib 1st: " << mRequireITSib1st; } + +void EMTrackCut::SetTrackBits(uint16_t bits) +{ + mTrackBits = bits; + LOG(info) << "EMTrack Cut, require track bits: " << mTrackBits; +} diff --git a/PWGEM/Dilepton/Core/EMTrackCut.h b/PWGEM/Dilepton/Core/EMTrackCut.h index 7b15d8871f3..0df094c8ff1 100644 --- a/PWGEM/Dilepton/Core/EMTrackCut.h +++ b/PWGEM/Dilepton/Core/EMTrackCut.h @@ -16,7 +16,7 @@ #ifndef PWGEM_DILEPTON_CORE_EMTRACKCUT_H_ #define PWGEM_DILEPTON_CORE_EMTRACKCUT_H_ -// #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" +#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/DataTypes.h" @@ -31,7 +31,7 @@ #include #include -// using namespace o2::aod::pwgem::dilepton::utils::emtrackutil; +using namespace o2::aod::pwgem::dilepton::utils::emtrackutil; class EMTrackCut : public TNamed { @@ -45,24 +45,25 @@ class EMTrackCut : public TNamed kTrackPtRange, kTrackEtaRange, kTrackPhiRange, + kDCAxy, + kDCAz, kTPCNCls, kTPCCrossedRows, kTPCCrossedRowsOverNCls, kTPCFracSharedClusters, kTPCChi2NDF, - kDCAxy, - kDCAz, kITSNCls, kITSChi2NDF, + kTrackBits, kNCuts }; template bool IsSelected(TTrack const& track) const { - if (!track.hasITS() || !track.hasTPC()) { - return false; - } + // if (!track.hasITS() || !track.hasTPC()) { + // return false; + // } if (!IsSelectedTrack(track, EMTrackCuts::kTrackPtRange)) { return false; @@ -70,55 +71,58 @@ class EMTrackCut : public TNamed if (!IsSelectedTrack(track, EMTrackCuts::kTrackEtaRange)) { return false; } - if (!IsSelectedTrack(track, EMTrackCuts::kTrackPhiRange)) { return false; } + if (!IsSelectedTrack(track, EMTrackCuts::kDCAxy)) { return false; } if (!IsSelectedTrack(track, EMTrackCuts::kDCAz)) { return false; } - - // ITS cuts - if (!IsSelectedTrack(track, EMTrackCuts::kITSNCls)) { + if (!IsSelectedTrack(track, EMTrackCuts::kTrackBits)) { return false; } - if (!IsSelectedTrack(track, EMTrackCuts::kITSChi2NDF)) { - return false; - } - - if (mRequireITSibAny) { - auto hits_ib = std::count_if(its_ib_any_Requirement.second.begin(), its_ib_any_Requirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); - if (hits_ib < its_ib_any_Requirement.first) { - return false; - } - } - if (mRequireITSib1st) { - auto hits_ib = std::count_if(its_ib_1st_Requirement.second.begin(), its_ib_1st_Requirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); - if (hits_ib < its_ib_1st_Requirement.first) { - return false; - } - } - - // TPC cuts - if (!IsSelectedTrack(track, EMTrackCuts::kTPCNCls)) { - return false; - } - if (!IsSelectedTrack(track, EMTrackCuts::kTPCCrossedRows)) { - return false; - } - if (!IsSelectedTrack(track, EMTrackCuts::kTPCCrossedRowsOverNCls)) { - return false; - } - if (!IsSelectedTrack(track, EMTrackCuts::kTPCFracSharedClusters)) { - return false; - } - if (!IsSelectedTrack(track, EMTrackCuts::kTPCChi2NDF)) { - return false; - } + // // ITS cuts + // if (!IsSelectedTrack(track, EMTrackCuts::kITSNCls)) { + // return false; + // } + // if (!IsSelectedTrack(track, EMTrackCuts::kITSChi2NDF)) { + // return false; + // } + // + // if (mRequireITSibAny) { + // auto hits_ib = std::count_if(its_ib_any_Requirement.second.begin(), its_ib_any_Requirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); + // if (hits_ib < its_ib_any_Requirement.first) { + // return false; + // } + // } + // + // if (mRequireITSib1st) { + // auto hits_ib = std::count_if(its_ib_1st_Requirement.second.begin(), its_ib_1st_Requirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); + // if (hits_ib < its_ib_1st_Requirement.first) { + // return false; + // } + // } + // + // // TPC cuts + // if (!IsSelectedTrack(track, EMTrackCuts::kTPCNCls)) { + // return false; + // } + // if (!IsSelectedTrack(track, EMTrackCuts::kTPCCrossedRows)) { + // return false; + // } + // if (!IsSelectedTrack(track, EMTrackCuts::kTPCCrossedRowsOverNCls)) { + // return false; + // } + // if (!IsSelectedTrack(track, EMTrackCuts::kTPCFracSharedClusters)) { + // return false; + // } + // if (!IsSelectedTrack(track, EMTrackCuts::kTPCChi2NDF)) { + // return false; + // } return true; } @@ -136,32 +140,35 @@ class EMTrackCut : public TNamed case EMTrackCuts::kTrackPhiRange: return track.phi() > mMinTrackPhi && track.phi() < mMaxTrackPhi; - case EMTrackCuts::kTPCNCls: - return track.tpcNClsFound() >= mMinNClustersTPC; - - case EMTrackCuts::kTPCCrossedRows: - return track.tpcNClsCrossedRows() >= mMinNCrossedRowsTPC; - - case EMTrackCuts::kTPCCrossedRowsOverNCls: - return track.tpcCrossedRowsOverFindableCls() > mMinNCrossedRowsOverFindableClustersTPC; - - case EMTrackCuts::kTPCFracSharedClusters: - return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; - - case EMTrackCuts::kTPCChi2NDF: - return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; - case EMTrackCuts::kDCAxy: return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); case EMTrackCuts::kDCAz: return std::fabs(track.dcaZ()) < mMaxDcaZ; - case EMTrackCuts::kITSNCls: - return mMinNClustersITS <= track.itsNCls() && track.itsNCls() <= mMaxNClustersITS; - - case EMTrackCuts::kITSChi2NDF: - return mMinChi2PerClusterITS < track.itsChi2NCl() && track.itsChi2NCl() < mMaxChi2PerClusterITS; + case EMTrackCuts::kTrackBits: + return true; + + // case EMTrackCuts::kTPCNCls: + // return track.tpcNClsFound() >= mMinNClustersTPC; + // + // case EMTrackCuts::kTPCCrossedRows: + // return track.tpcNClsCrossedRows() >= mMinNCrossedRowsTPC; + // + // case EMTrackCuts::kTPCCrossedRowsOverNCls: + // return track.tpcCrossedRowsOverFindableCls() > mMinNCrossedRowsOverFindableClustersTPC; + // + // case EMTrackCuts::kTPCFracSharedClusters: + // return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; + // + // case EMTrackCuts::kTPCChi2NDF: + // return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; + // + // case EMTrackCuts::kITSNCls: + // return mMinNClustersITS <= track.itsNCls() && track.itsNCls() <= mMaxNClustersITS; + // + // case EMTrackCuts::kITSChi2NDF: + // return mMinChi2PerClusterITS < track.itsChi2NCl() && track.itsChi2NCl() < mMaxChi2PerClusterITS; default: return false; @@ -186,6 +193,7 @@ class EMTrackCut : public TNamed void SetTrackMaxDcaXYPtDep(std::function ptDepCut); void RequireITSibAny(bool flag); void RequireITSib1st(bool flag); + void SetTrackBits(uint16_t bits); private: static const std::pair> its_ib_any_Requirement; @@ -206,6 +214,7 @@ class EMTrackCut : public TNamed float mMinChi2PerClusterITS{0.f}, mMaxChi2PerClusterITS{1e10f}; // max its fit chi2 per ITS cluster bool mRequireITSibAny{true}; bool mRequireITSib1st{false}; + uint16_t mTrackBits{0}; float mMaxDcaXY{1.0f}; // max dca in xy plane float mMaxDcaZ{1.0f}; // max dca in z direction diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index ad003750ca3..88321541855 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -694,6 +694,7 @@ DECLARE_SOA_INDEX_COLUMN(EMEvent, emevent); //! DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! DECLARE_SOA_COLUMN(TrackId, trackId, int); //! DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! +DECLARE_SOA_COLUMN(TrackBit, trackBit, uint16_t); //! DECLARE_SOA_DYNAMIC_COLUMN(Signed1Pt, signed1Pt, [](float pt, int8_t sign) -> float { return sign * 1. / pt; }); DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float pt, float eta) -> float { return pt * std::cosh(eta); }); DECLARE_SOA_DYNAMIC_COLUMN(Px, px, [](float pt, float phi) -> float { return pt * std::cos(phi); }); @@ -704,18 +705,20 @@ DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, [](float pt, float eta) -> float { return pt DECLARE_SOA_TABLE_VERSIONED(EMPrimaryTracks_000, "AOD", "EMPRIMARYTRACK", 0, //! o2::soa::Index<>, emprimarytrack::CollisionId, emprimarytrack::TrackId, emprimarytrack::Sign, - track::Pt, track::Eta, track::Phi, track::DcaXY, track::DcaZ, - track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, track::TPCChi2NCl, - track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, + track::Pt, track::Eta, track::Phi, track::DcaXY, track::DcaZ, emprimarytrack::TrackBit, - // dynamic column - track::TPCNClsFound, - track::TPCNClsCrossedRows, - track::TPCCrossedRowsOverFindableCls, - track::TPCFoundOverFindableCls, - track::TPCFractionSharedCls, - track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, - track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, + // track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, track::TPCChi2NCl, + // track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, + + // // dynamic column + // track::TPCNClsFound, + // track::TPCNClsCrossedRows, + // track::TPCCrossedRowsOverFindableCls, + // track::TPCFoundOverFindableCls, + // track::TPCFractionSharedCls, + // track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, + + // track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, emprimarytrack::Signed1Pt, emprimarytrack::P, emprimarytrack::Px, diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx index 93cbd031f88..37bde849360 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx @@ -13,7 +13,8 @@ /// \author daiki.sekihata@cern.ch #include "PWGEM/Dilepton/DataModel/dileptonTables.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" +// #include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "Common/Core/TableHelper.h" #include "Common/Core/trackUtilities.h" @@ -44,6 +45,7 @@ using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::constants::physics; +using namespace o2::aod::pwgem::dilepton::utils::emtrackutil; using MyCollisions = soa::Join; using MyCollisionsWithSWT = soa::Join; @@ -69,19 +71,21 @@ struct skimmerPrimaryTrack { // Operation and minimisation criteria Configurable fillQAHistogram{"fillQAHistogram", false, "flag to fill QA histograms"}; Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; - Configurable mincrossedrows{"mincrossedrows", 70, "min. crossed rows"}; - Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable min_ncluster_its{"min_ncluster_its", 4, "min ncluster its"}; - Configurable min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"}; - Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; - Configurable maxchi2its{"maxchi2its", 36.0, "max. chi2/NclsITS"}; + Configurable minpt{"minpt", 0.15, "min pt for ITS-TPC track"}; + Configurable maxpt{"maxpt", 5.0, "max pt for ITS-TPC track"}; Configurable maxeta{"maxeta", 2.0, "eta acceptance"}; Configurable dca_xy_max{"dca_xy_max", 1.0, "max DCAxy in cm"}; Configurable dca_z_max{"dca_z_max", 1.0, "max DCAz in cm"}; - Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1e+10, "max DCA 3D in sigma"}; - Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; + + // Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; + // Configurable mincrossedrows{"mincrossedrows", 70, "min. crossed rows"}; + // Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; + // Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; + // Configurable min_ncluster_its{"min_ncluster_its", 4, "min ncluster its"}; + // Configurable min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"}; + // Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; + // Configurable maxchi2its{"maxchi2its", 36.0, "max. chi2/NclsITS"}; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; @@ -195,35 +199,35 @@ struct skimmerPrimaryTrack { return false; } - if (track.itsChi2NCl() > maxchi2its) { + if (track.itsChi2NCl() > 36.f) { return false; } - if (track.itsNCls() < min_ncluster_its) { + if (track.itsNCls() < 4) { return false; } - if (track.itsNClsInnerBarrel() < min_ncluster_itsib) { + if (track.itsNClsInnerBarrel() < 1) { return false; } - if (track.tpcChi2NCl() > maxchi2tpc) { + if (track.tpcChi2NCl() > 5.f) { return false; } - if (track.tpcNClsFound() < min_ncluster_tpc) { + if (track.tpcNClsFound() < 0) { return false; } - if (track.tpcNClsCrossedRows() < mincrossedrows) { + if (track.tpcNClsCrossedRows() < 50) { return false; } - if (track.tpcCrossedRowsOverFindableCls() < min_tpc_cr_findable_ratio) { + if (track.tpcCrossedRowsOverFindableCls() < 0.8) { return false; } - if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) { - return false; - } + // if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) { + // return false; + // } o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); @@ -239,19 +243,7 @@ struct skimmerPrimaryTrack { return false; } - float dca_3d = 999.f; - float det = trackParCov.getSigmaY2() * trackParCov.getSigmaZ2() - trackParCov.getSigmaZY() * trackParCov.getSigmaZY(); - if (det < 0) { - dca_3d = 999.f; - } else { - float chi2 = (dcaXY * dcaXY * trackParCov.getSigmaZ2() + dcaZ * dcaZ * trackParCov.getSigmaY2() - 2. * dcaXY * dcaZ * trackParCov.getSigmaZY()) / det; - dca_3d = std::sqrt(std::fabs(chi2) / 2.); - } - if (dca_3d > dca_3d_sigma_max) { - return false; - } - - if (std::fabs(trackParCov.getEta()) > maxeta || trackParCov.getPt() < minpt) { + if (std::fabs(trackParCov.getEta()) > maxeta || trackParCov.getPt() < minpt || maxpt < trackParCov.getPt()) { return false; } @@ -272,26 +264,65 @@ struct skimmerPrimaryTrack { float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); - float pt_recalc = trackParCov.getPt(); - float eta_recalc = trackParCov.getEta(); - float phi_recalc = trackParCov.getPhi(); - o2::math_utils::bringTo02Pi(phi_recalc); + float pt = trackParCov.getPt(); + float eta = trackParCov.getEta(); + float phi = trackParCov.getPhi(); + o2::math_utils::bringTo02Pi(phi); + uint16_t trackBit = 0; + + // As minimal cuts, following cuts are applied. The cut values are hardcoded on the purpose for consistent bit operation. + // has info on ITS and TPC + // a hit on ITSib any + // Ncls ITS >= 4 + // chi2/Ncls ITS < 36 + // Ncr TPC >= 50 + // chi2/Ncls TPC < 5 + // Ncr/Nf ratio in TPC > 0.8 + + if (track.itsNCls() >= 5) { + trackBit |= static_cast(RefTrackBit::kNclsITS5); + } + if (track.itsNCls() >= 6) { + trackBit |= static_cast(RefTrackBit::kNclsITS6); + } + + if (track.tpcNClsCrossedRows() >= 70) { + trackBit |= static_cast(RefTrackBit::kNcrTPC70); + } + if (track.tpcNClsCrossedRows() >= 90) { + trackBit |= static_cast(RefTrackBit::kNcrTPC90); + } + if (track.tpcNClsFound() >= 50) { + trackBit |= static_cast(RefTrackBit::kNclsTPC50); + } + if (track.tpcNClsFound() >= 70) { + trackBit |= static_cast(RefTrackBit::kNclsTPC70); + } + if (track.tpcNClsFound() >= 90) { + trackBit |= static_cast(RefTrackBit::kNclsTPC90); + } + if (track.tpcChi2NCl() < 4) { + trackBit |= static_cast(RefTrackBit::kChi2TPC4); + } + if (track.tpcChi2NCl() < 3) { + trackBit |= static_cast(RefTrackBit::kChi2TPC3); + } + if (track.tpcFractionSharedCls() < 0.7) { + trackBit |= static_cast(RefTrackBit::kFracSharedTPC07); + } - emprimarytracks(collision.globalIndex(), track.globalIndex(), track.sign(), - pt_recalc, eta_recalc, phi_recalc, dcaXY, dcaZ, - track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), track.tpcChi2NCl(), - track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap()); + emprimarytracks(collision.globalIndex(), track.globalIndex(), track.sign(), pt, eta, phi, dcaXY, dcaZ, trackBit); stored_trackIds.emplace_back(std::pair{collision.globalIndex(), track.globalIndex()}); if (fillQAHistogram) { - fRegistry.fill(HIST("Track/hPt"), pt_recalc); - fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / pt_recalc); - fRegistry.fill(HIST("Track/hEtaPhi"), phi_recalc, eta_recalc); + fRegistry.fill(HIST("Track/hPt"), pt); + fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / pt); + fRegistry.fill(HIST("Track/hEtaPhi"), phi, eta); fRegistry.fill(HIST("Track/hDCAxyz"), dcaXY, dcaZ); fRegistry.fill(HIST("Track/hDCAxyzSigma"), dcaXY / std::sqrt(trackParCov.getSigmaY2()), dcaZ / std::sqrt(trackParCov.getSigmaZ2())); - fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), pt_recalc, std::sqrt(trackParCov.getSigmaY2()) * 1e+4); // convert cm to um - fRegistry.fill(HIST("Track/hDCAzRes_Pt"), pt_recalc, std::sqrt(trackParCov.getSigmaZ2()) * 1e+4); // convert cm to um + fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), pt, std::sqrt(trackParCov.getSigmaY2()) * 1e+4); // convert cm to um + fRegistry.fill(HIST("Track/hDCAzRes_Pt"), pt, std::sqrt(trackParCov.getSigmaZ2()) * 1e+4); // convert cm to um fRegistry.fill(HIST("Track/hNclsITS"), track.itsNCls()); fRegistry.fill(HIST("Track/hNclsTPC"), track.tpcNClsFound()); fRegistry.fill(HIST("Track/hNcrTPC"), track.tpcNClsCrossedRows()); @@ -308,7 +339,7 @@ struct skimmerPrimaryTrack { Preslice trackIndicesPerCollision = aod::track_association::collisionId; std::vector> stored_trackIds; - Filter trackFilter = o2::aod::track::itsChi2NCl < maxchi2its && o2::aod::track::tpcChi2NCl < maxchi2tpc && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; + Filter trackFilter = o2::aod::track::itsChi2NCl < 36.f && o2::aod::track::tpcChi2NCl < 5.f && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; using MyFilteredTracks = soa::Filtered; // ---------- for data ---------- diff --git a/PWGEM/Dilepton/Utils/EMTrack.h b/PWGEM/Dilepton/Utils/EMTrack.h index 0f894d5b4dc..d7ddae81476 100644 --- a/PWGEM/Dilepton/Utils/EMTrack.h +++ b/PWGEM/Dilepton/Utils/EMTrack.h @@ -15,15 +15,16 @@ #ifndef PWGEM_DILEPTON_UTILS_EMTRACK_H_ #define PWGEM_DILEPTON_UTILS_EMTRACK_H_ -#include #include "Math/Vector4D.h" +#include + namespace o2::aod::pwgem::dilepton::utils { class EMTrack { public: - EMTrack(int dfId, int globalId, int collisionId, int trackId, float pt, float eta, float phi, float mass, int8_t charge = 0, float dcaXY = 0.f, float dcaZ = 0.f, std::vector amb_ele_self_ids = {}) + EMTrack(int dfId, int globalId, int collisionId, int trackId, float pt, float eta, float phi, float mass, int8_t charge = 0, float dcaXY = 0.f, float dcaZ = 0.f, std::vector amb_ele_self_ids = {}, float CYY = 0, float CZY = 0, float CZZ = 0) { fDFId = dfId; fGlobalId = globalId; @@ -36,6 +37,9 @@ class EMTrack fCharge = charge; fDCAxy = dcaXY; fDCAz = dcaZ; + fCYY = CYY; + fCZY = CZY; + fCZZ = CZZ; fPairDCA3DinSigmaOTF = 0; fAmbEleSelfIds = amb_ele_self_ids; @@ -78,6 +82,11 @@ class EMTrack int8_t sign() const { return fCharge; } float dcaXY() const { return fDCAxy; } float dcaZ() const { return fDCAz; } + + float cYY() const { return fCYY; } + float cZY() const { return fCZY; } + float cZZ() const { return fCZZ; } + float p() const { return fPt * std::cosh(fEta); } float px() const { return fPt * std::cos(fPhi); } float py() const { return fPt * std::sin(fPhi); } @@ -130,6 +139,10 @@ class EMTrack std::vector ambiguousPosLegIds() const { return fAmbPosLegSelfIds; } std::vector ambiguousNegLegIds() const { return fAmbNegLegSelfIds; } + void setCYY(float cYY) { fCYY = cYY; } + void setCZY(float cZY) { fCZY = cZY; } + void setCZZ(float cZZ) { fCZZ = cZZ; } + protected: int fDFId; int fGlobalId; @@ -142,6 +155,11 @@ class EMTrack int8_t fCharge; float fDCAxy; float fDCAz; + + float fCYY; + float fCZY; + float fCZZ; + float fPairDCA3DinSigmaOTF; bool fIsAmbiguous; std::vector fAmbEleSelfIds; @@ -199,9 +217,6 @@ class EMTrackWithCov : public EMTrack float snp() const { return fSnp; } float tgl() const { return fTgl; } - float cYY() const { return fCYY; } - float cZY() const { return fCZY; } - float cZZ() const { return fCZZ; } float cSnpY() const { return fCSnpY; } float cSnpZ() const { return fCSnpZ; } float cSnpSnp() const { return fCSnpSnp; } @@ -215,10 +230,6 @@ class EMTrackWithCov : public EMTrack float c1PtTgl() const { return fC1PtTgl; } float c1Pt21Pt2() const { return fC1Pt21Pt2; } - void setCYY(float cYY) { fCYY = cYY; } - void setCZY(float cZY) { fCZY = cZY; } - void setCZZ(float cZZ) { fCZZ = cZZ; } - protected: float fX; float fY; @@ -226,9 +237,6 @@ class EMTrackWithCov : public EMTrack float fAlpha; float fSnp; float fTgl; - float fCYY; - float fCZY; - float fCZZ; float fCSnpY; float fCSnpZ; float fCSnpSnp; diff --git a/PWGEM/Dilepton/Utils/EMTrackUtilities.h b/PWGEM/Dilepton/Utils/EMTrackUtilities.h index d698bdbf68c..087ee38d60b 100644 --- a/PWGEM/Dilepton/Utils/EMTrackUtilities.h +++ b/PWGEM/Dilepton/Utils/EMTrackUtilities.h @@ -26,6 +26,20 @@ //_______________________________________________________________________ namespace o2::aod::pwgem::dilepton::utils::emtrackutil { + +enum class RefTrackBit : uint16_t { // This is not for leptons, but charged particles for ref. flow. + kNclsITS5 = 1, + kNclsITS6 = 2, + kNcrTPC70 = 4, + kNcrTPC90 = 8, + kNclsTPC50 = 16, // (not necessary, if ncr is used.) + kNclsTPC70 = 32, // (not necessary, if ncr is used.) + kNclsTPC90 = 64, // (not necessary, if ncr is used.) + kChi2TPC4 = 128, + kChi2TPC3 = 256, + kFracSharedTPC07 = 512, +}; + //_______________________________________________________________________ template float dca3DinSigma(T const& track) diff --git a/PWGEM/Dilepton/Utils/EventHistograms.h b/PWGEM/Dilepton/Utils/EventHistograms.h index afebfff955b..ab448b1dcc6 100644 --- a/PWGEM/Dilepton/Utils/EventHistograms.h +++ b/PWGEM/Dilepton/Utils/EventHistograms.h @@ -74,9 +74,9 @@ void addEventHistograms(HistogramRegistry* fRegistry) fRegistry->add("Event/before/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); fRegistry->add("Event/before/hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); fRegistry->add("Event/before/hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", kTH2F, {{200, 0, 200000}, {60, 0, 60000}}, false); - fRegistry->add("Event/before/hCentFT0A", "hCentFT0A;centrality FT0A (%)", kTH1F, {{axis_cent_ft0m}}, false); - fRegistry->add("Event/before/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1F, {{axis_cent_ft0a}}, false); - fRegistry->add("Event/before/hCentFT0M", "hCentFT0M;centrality FT0M (%)", kTH1F, {{axis_cent_ft0c}}, false); + fRegistry->add("Event/before/hCentFT0A", "hCentFT0A;centrality FT0A (%)", kTH1F, {{axis_cent_ft0a}}, false); + fRegistry->add("Event/before/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1F, {{axis_cent_ft0c}}, false); + fRegistry->add("Event/before/hCentFT0M", "hCentFT0M;centrality FT0M (%)", kTH1F, {{axis_cent_ft0m}}, false); fRegistry->add("Event/before/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); fRegistry->add("Event/before/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); fRegistry->add("Event/before/hMultFT0CvsOccupancy", "hMultFT0CvsOccupancy;mult. FT0C;N_{track} in time range", kTH2F, {{60, 0, 60000}, {200, 0, 20000}}, false); diff --git a/PWGEM/Dilepton/Utils/PairUtilities.h b/PWGEM/Dilepton/Utils/PairUtilities.h index 73e66a53142..1fcede0e14d 100644 --- a/PWGEM/Dilepton/Utils/PairUtilities.h +++ b/PWGEM/Dilepton/Utils/PairUtilities.h @@ -47,8 +47,8 @@ enum class DileptonAnalysisType : int { }; enum class DileptonHadronAnalysisType : int { - kCumulant = 0, - kCorrelationFunction = 1, + kAzimuthalCorrelation = 0, + kCumulant = 1, }; enum class DileptonPrefilterBit : int { diff --git a/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h b/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h index 499b3fe1184..7ceb009cbd8 100644 --- a/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h +++ b/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h @@ -97,10 +97,11 @@ struct DiphotonHadronMPC { Configurable cfgCentMax{"cfgCentMax", 999, "max. centrality"}; Configurable maxY{"maxY", 0.8, "maximum rapidity for diphoton"}; Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; - Configurable ndepth{"ndepth", 100, "depth for event mixing"}; + Configurable ndepth_photon{"ndepth_photon", 100, "depth for event mixing between photon-photon"}; + Configurable ndepth_hadron{"ndepth_hadron", 2, "depth for event mixing between hadron-hadron"}; Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; ConfigurableAxis ConfVtxBins{"ConfVtxBins", {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 ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; + ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 0.1, 1, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; ConfigurableAxis ConfMggBins{"ConfMggBins", {200, 0.0, 0.8}, "mgg bins for output histograms"}; @@ -109,8 +110,8 @@ struct DiphotonHadronMPC { ConfigurableAxis ConfPtHadronBins{"ConfPtHadronBins", {VARIABLE_WIDTH, 0.00, 0.15, 0.2, 0.3, 0.4, 0.50, 1.00, 2.00, 3.00, 4.00, 5.00}, "pT,h bins for output histograms"}; ConfigurableAxis ConfDEtaBins{"ConfDEtaBins", {60, -3, 3}, "deta bins for output histograms"}; Configurable cfgNbinsDPhi{"cfgNbinsDPhi", 36, "nbins in dphi for output histograms"}; - Configurable cfgNbinsCosNDPhi{"cfgNbinsCosNDPhi", 200, "nbins in cos(n(dphi)) for output histograms"}; - Configurable cfgNmod{"cfgNmod", 2, "n-th harmonics"}; + // Configurable cfgNbinsCosNDPhi{"cfgNbinsCosNDPhi", 100, "nbins in cos(n(dphi)) for output histograms"}; + // Configurable cfgNmod{"cfgNmod", 2, "n-th harmonics"}; EMPhotonEventCut fEMEventCut; struct : ConfigurableGroup { @@ -202,11 +203,11 @@ struct DiphotonHadronMPC { EMTrackCut fEMTrackCut; struct : ConfigurableGroup { std::string prefix = "trackcut_group"; - Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.15, "min pT for ref. track"}; + Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for ref. track"}; Configurable cfg_max_pt_track{"cfg_max_pt_track", 3.0, "max pT for ref. track"}; - Configurable cfg_min_eta_track{"cfg_min_eta_track", -1.2, "min eta for ref. track"}; - Configurable cfg_max_eta_track{"cfg_max_eta_track", +1.2, "max eta for ref. track"}; - Configurable cfg_min_phi_track{"cfg_min_phi_track", 0., "min phi for ref. track"}; + Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for ref. track"}; + Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.8, "max eta for ref. track"}; + Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.0, "min phi for ref. track"}; Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for ref. track"}; Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; @@ -246,8 +247,10 @@ struct DiphotonHadronMPC { occ_bin_edges = std::vector(ConfOccupancyBins.value.begin(), ConfOccupancyBins.value.end()); occ_bin_edges.erase(occ_bin_edges.begin()); - emh1 = new MyEMH(ndepth); - emh2 = new MyEMH(ndepth); + emh1 = new MyEMH(ndepth_photon); + emh2 = new MyEMH(ndepth_photon); + emh_diphoton = new MyEMH_track(ndepth_photon); + emh_ref = new MyEMH_track(ndepth_hadron); o2::aod::pwgem::photonmeson::utils::eventhistogram::addEventHistograms(&fRegistry); addHistograms(); @@ -258,7 +261,7 @@ struct DiphotonHadronMPC { DefineDileptonCut(); fRegistry.add("Diphoton/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", kTH1D, {{10001, -0.5, 10000.5}}, true); - if (doprocess2PCwithTrigger) { + if (doprocessTriggerAnalysis) { fRegistry.add("Event/hNInspectedTVX", "N inspected TVX;run number;N_{TVX}", kTProfile, {{80000, 520000.5, 600000.5}}, true); } @@ -293,8 +296,9 @@ struct DiphotonHadronMPC { auto run3grp_timestamp = collision.timestamp(); o2::parameters::GRPObject* grpo = 0x0; o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) + if (!skipGRPOquery) { grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + } if (grpo) { // Fetch magnetic field from ccdb for current collision d_bz = grpo->getNominalL3Field(); @@ -323,11 +327,18 @@ struct DiphotonHadronMPC { emh1 = 0x0; delete emh2; emh2 = 0x0; + delete emh_diphoton; + emh_diphoton = 0x0; + delete emh_ref; + emh_ref = 0x0; used_photonIds.clear(); used_photonIds.shrink_to_fit(); used_dileptonIds.clear(); used_dileptonIds.shrink_to_fit(); + used_refTrackIds.clear(); + used_refTrackIds.shrink_to_fit(); + map_mixed_eventId_to_globalBC.clear(); } @@ -337,22 +348,23 @@ struct DiphotonHadronMPC { std::string pair_pt_axis_title = "p_{T,#gamma#gamma} (GeV/c)"; std::string deta_axis_title = "#Delta#eta = #eta_{#gamma#gamma} - #eta_{h}"; std::string dphi_axis_title = "#Delta#varphi = #varphi_{#gamma#gamma} - #varphi_{h} (rad.)"; - std::string cosndphi_axis_title = std::format("cos({0:d}(#varphi_{{#gamma#gamma}} - #varphi_{{h}}))", cfgNmod.value); + // std::string cosndphi_axis_title = std::format("cos({0:d}(#varphi_{{#gamma#gamma}} - #varphi_{{h}}))", cfgNmod.value); if constexpr (pairtype == PairType::kPCMDalitzEE) { mass_axis_title = "m_{ee#gamma} (GeV/c^{2})"; pair_pt_axis_title = "p_{T,ee#gamma} (GeV/c)"; deta_axis_title = "#Delta#eta = #eta_{ee#gamma} - #eta_{h}"; dphi_axis_title = "#Delta#varphi = #varphi_{ee#gamma} - #varphi_{h} (rad.)"; - cosndphi_axis_title = std::format("cos({0:d}(#varphi_{{ee#gamma}} - #varphi_{{h}}))", cfgNmod.value); + // cosndphi_axis_title = std::format("cos({0:d}(#varphi_{{ee#gamma}} - #varphi_{{h}}))", cfgNmod.value); } // photon info const AxisSpec axis_pt_single{ConfPtggBins, "p_{T,#gamma} (GeV/c)"}; - const AxisSpec axis_eta_single{40, -2, +2, "#eta_{#gamma}"}; + const AxisSpec axis_eta_single{20, -1, +1, "#eta_{#gamma}"}; const AxisSpec axis_phi_single{36, 0, 2 * M_PI, "#varphi_{#gamma} (rad.)"}; const AxisSpec axis_deta_single{ConfDEtaBins, "#Delta#eta = #eta_{#gamma} - #eta_{h}"}; - const AxisSpec axis_cos_ndphi_single{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{#gamma}} - #varphi_{{h}}))", cfgNmod.value)}; + const AxisSpec axis_dphi_single{cfgNbinsDPhi, -M_PI / 2, +3 * M_PI / 2, "#Delta#varphi = #varphi_{#gamma} - #varphi_{h} (rad.)"}; + // const AxisSpec axis_cos_ndphi_single{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{#gamma}} - #varphi_{{h}}))", cfgNmod.value)}; // diphoton info const AxisSpec axis_mass{ConfMggBins, mass_axis_title}; @@ -361,26 +373,26 @@ struct DiphotonHadronMPC { // diphoton-hadron info const AxisSpec axis_pt_ref{ConfPtHadronBins, "p_{T,h}^{ref} (GeV/c)"}; const AxisSpec axis_deta{ConfDEtaBins, deta_axis_title}; - const AxisSpec axis_cos_ndphi{cfgNbinsCosNDPhi, -1, +1, cosndphi_axis_title}; + const AxisSpec axis_dphi{cfgNbinsDPhi, -M_PI / 2, +3 * M_PI / 2, dphi_axis_title}; - const AxisSpec axis_pt_trg{ConfPtHadronBins, "p_{T,h} (GeV/c)"}; - const AxisSpec axis_eta_trg{40, -2, +2, "#eta_{h}"}; - const AxisSpec axis_phi_trg{36, 0, 2 * M_PI, "#varphi_{h} (rad.)"}; + const AxisSpec axis_pt_hadron{ConfPtHadronBins, "p_{T,h} (GeV/c)"}; + const AxisSpec axis_eta_hadron{40, -2, +2, "#eta_{h}"}; + const AxisSpec axis_phi_hadron{36, 0, 2 * M_PI, "#varphi_{h} (rad.)"}; - fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_trg, axis_eta_trg, axis_phi_trg}, true); - fRegistry.add("Photon/hs", "photon", kTHnSparseD, {axis_pt_single, axis_eta_single, axis_phi_single}, true); + fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_hadron, axis_eta_hadron, axis_phi_hadron}, true); fRegistry.add("Diphoton/same/hs", "diphoton", kTHnSparseD, {axis_mass, axis_pt}, true); fRegistry.addClone("Diphoton/same/", "Diphoton/mix/"); - fRegistry.add("DiphotonHadron/same/hs", "diphoton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_pt_ref, axis_deta, axis_cos_ndphi}, true); - fRegistry.add("PhotonHadron/same/hs", "photon-hadron 2PC", kTHnSparseD, {axis_pt_single, axis_pt_ref, axis_deta_single, axis_cos_ndphi_single}, true); + fRegistry.add("DiphotonHadron/same/hs", "diphoton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_pt_ref, axis_deta, axis_dphi}, true); + fRegistry.addClone("DiphotonHadron/same/", "DiphotonHadron/mix/"); // hadron-hadron - const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{trg} - #eta_{h}^{ref}"}; - const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{trg}} - #varphi_{{h}}^{{ref}}))", cfgNmod.value)}; - fRegistry.add("HadronHadron_for_Diphoton/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_trg, axis_pt_ref, axis_deta_hh, axis_cosndphi_hh}, true); - fRegistry.addClone("HadronHadron_for_Diphoton/same/hs", "HadronHadron_for_Photon/same/hs"); + const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{ref1} - #eta_{h}^{ref2}"}; + const AxisSpec axis_dphi_hh{cfgNbinsDPhi, -M_PI / 2, +3 * M_PI / 2, "#Delta#varphi = #varphi_{h}^{ref1} - #varphi_{h}^{ref2} (rad.)"}; + // const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{ref1}} - #varphi_{{h}}^{{ref2}}))", cfgNmod.value)}; + fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_hadron, axis_pt_ref, axis_deta_hh, axis_dphi_hh}, true); + fRegistry.addClone("HadronHadron/same/", "HadronHadron/mix/"); } void DefineEMEventCut() @@ -490,8 +502,14 @@ struct DiphotonHadronMPC { using MyEMH = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; MyEMH* emh1 = nullptr; MyEMH* emh2 = nullptr; + using MyEMH_track = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; // for charged track + MyEMH_track* emh_diphoton = nullptr; + MyEMH_track* emh_ref = nullptr; + std::vector> used_photonIds; // std::vector> used_dileptonIds; // + std::vector> used_refTrackIds; // + std::vector> used_diphotonIds; // std::map, uint64_t> map_mixed_eventId_to_globalBC; template @@ -502,7 +520,6 @@ struct DiphotonHadronMPC { for (const auto& collision : collisions) { initCCDB(collision); int ndiphoton = 0; - int nphoton = 0; const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { @@ -574,22 +591,6 @@ struct DiphotonHadronMPC { auto photons1_per_collision = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_per_collision = photons2.sliceBy(perCollision2, collision.globalIndex()); - for (const auto& photon : photons1_per_collision) { // single photon - if (cut1.template IsSelected(photon)) { - fRegistry.fill(HIST("Photon/hs"), photon.pt(), photon.eta(), photon.phi()); - nphoton++; - for (const auto& track : refTracks_per_collision) { - if (fEMTrackCut.IsSelected(track)) { - float deta = photon.eta() - track.eta(); - float dphi = photon.phi() - track.phi(); - o2::math_utils::bringTo02Pi(dphi); - - fRegistry.fill(HIST("PhotonHadron/same/hs"), photon.pt(), track.pt(), deta, std::cos(cfgNmod * dphi)); - } - } // end of ref track loop - } - } // end of photon loop - for (const auto& [g1, g2] : combinations(CombinationsStrictlyUpperIndexPolicy(photons1_per_collision, photons2_per_collision))) { if (!cut1.template IsSelected(g1) || !cut2.template IsSelected(g2)) { continue; @@ -601,27 +602,53 @@ struct DiphotonHadronMPC { if (std::fabs(v12.Rapidity()) > maxY) { continue; } - fRegistry.fill(HIST("Diphoton/same/hs"), v12.M(), v12.Pt()); + auto pos1 = g1.template posTrack_as(); + auto ele1 = g1.template negTrack_as(); + auto pos2 = g2.template posTrack_as(); + auto ele2 = g2.template negTrack_as(); + + int npair = 0; for (const auto& track : refTracks_per_collision) { + if (pos1.trackId() == track.trackId() || ele1.trackId() == track.trackId()) { + continue; + } + if (pos2.trackId() == track.trackId() || ele2.trackId() == track.trackId()) { + continue; + } + if (fEMTrackCut.IsSelected(track)) { ROOT::Math::PtEtaPhiMVector v3(track.pt(), track.eta(), track.phi(), 0.139); float deta = v12.Eta() - v3.Eta(); float dphi = v12.Phi() - v3.Phi(); - o2::math_utils::bringTo02Pi(dphi); - fRegistry.fill(HIST("DiphotonHadron/same/hs"), v12.M(), v12.Pt(), v3.Pt(), deta, std::cos(cfgNmod * dphi)); + // o2::math_utils::bringTo02Pi(dphi); + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("DiphotonHadron/same/hs"), v12.M(), v12.Pt(), v3.Pt(), deta, dphi); + npair++; + std::pair pair_tmp_ref = std::make_pair(ndf, track.globalIndex()); + if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_ref) == used_refTrackIds.end()) { // add a ref track in mixing pool + emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, track.globalIndex(), collision.globalIndex(), track.globalIndex(), track.pt(), track.eta(), track.phi(), 0.139)); + used_refTrackIds.emplace_back(pair_tmp_ref); + } } } // end of ref track loop + if (npair > 0) { + std::tuple tuple_tmp_diphoton = std::make_tuple(ndf, g1.globalIndex(), g2.globalIndex(), -1); + if (std::find(used_diphotonIds.begin(), used_diphotonIds.end(), tuple_tmp_diphoton) == used_diphotonIds.end()) { + emh_diphoton->AddTrackToEventPool(key_df_collision, EMTrack(ndf, -1, collision.globalIndex(), -1, v12.Pt(), v12.Eta(), v12.Phi(), v12.M())); + used_diphotonIds.emplace_back(tuple_tmp_diphoton); + } + } + std::pair pair_tmp_id1 = std::make_pair(ndf, g1.globalIndex()); std::pair pair_tmp_id2 = std::make_pair(ndf, g2.globalIndex()); - if (std::find(used_photonIds.begin(), used_photonIds.end(), pair_tmp_id1) == used_photonIds.end()) { - emh1->AddTrackToEventPool(key_df_collision, EMTrack(-1, g1.globalIndex(), collision.globalIndex(), g1.globalIndex(), g1.pt(), g1.eta(), g1.phi(), 0)); + emh1->AddTrackToEventPool(key_df_collision, EMTrack(ndf, g1.globalIndex(), collision.globalIndex(), g1.globalIndex(), g1.pt(), g1.eta(), g1.phi(), 0)); used_photonIds.emplace_back(pair_tmp_id1); } if (std::find(used_photonIds.begin(), used_photonIds.end(), pair_tmp_id2) == used_photonIds.end()) { - emh1->AddTrackToEventPool(key_df_collision, EMTrack(-1, g2.globalIndex(), collision.globalIndex(), g2.globalIndex(), g2.pt(), g2.eta(), g2.phi(), 0)); + emh1->AddTrackToEventPool(key_df_collision, EMTrack(ndf, g2.globalIndex(), collision.globalIndex(), g2.globalIndex(), g2.pt(), g2.eta(), g2.phi(), 0)); used_photonIds.emplace_back(pair_tmp_id2); } ndiphoton++; @@ -631,22 +658,6 @@ struct DiphotonHadronMPC { auto positrons_per_collision = positrons->sliceByCached(o2::aod::emprimaryelectron::emeventId, collision.globalIndex(), cache); auto electrons_per_collision = electrons->sliceByCached(o2::aod::emprimaryelectron::emeventId, collision.globalIndex(), cache); - for (const auto& photon : photons1_per_collision) { // single photon - if (cut1.template IsSelected(photon)) { - fRegistry.fill(HIST("Photon/hs"), photon.pt(), photon.eta(), photon.phi()); - nphoton++; - for (const auto& track : refTracks_per_collision) { - if (fEMTrackCut.IsSelected(track)) { - float deta = photon.eta() - track.eta(); - float dphi = photon.phi() - track.phi(); - o2::math_utils::bringTo02Pi(dphi); - - fRegistry.fill(HIST("PhotonHadron/same/hs"), photon.pt(), track.pt(), deta, std::cos(cfgNmod * dphi)); - } - } // end of ref track loop - } - } // end of photon loop - for (const auto& g1 : photons1_per_collision) { if (!cut1.template IsSelected(g1)) { continue; @@ -679,24 +690,48 @@ struct DiphotonHadronMPC { if (std::fabs(veeg.Rapidity()) > maxY) { continue; } - fRegistry.fill(HIST("Diphoton/same/hs"), veeg.M(), veeg.Pt()); + + int npair = 0; for (const auto& track : refTracks_per_collision) { + if (pos1.trackId() == track.trackId() || ele1.trackId() == track.trackId()) { + continue; + } + if (pos2.trackId() == track.trackId() || ele2.trackId() == track.trackId()) { + continue; + } + ROOT::Math::PtEtaPhiMVector v3(track.pt(), track.eta(), track.phi(), 0.139); float deta = veeg.Eta() - v3.Eta(); float dphi = veeg.Phi() - v3.Phi(); - o2::math_utils::bringTo02Pi(dphi); - fRegistry.fill(HIST("DiphotonHadron/same/hs"), veeg.M(), veeg.Pt(), v3.Pt(), deta, std::cos(cfgNmod * dphi)); + // o2::math_utils::bringTo02Pi(dphi); + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("DiphotonHadron/same/hs"), veeg.M(), veeg.Pt(), v3.Pt(), deta, dphi); + npair++; + + std::pair pair_tmp_ref = std::make_pair(ndf, track.globalIndex()); + if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_ref) == used_refTrackIds.end()) { // add a ref track in mixing pool + emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, track.globalIndex(), collision.globalIndex(), track.globalIndex(), track.pt(), track.eta(), track.phi(), 0.139)); + used_refTrackIds.emplace_back(pair_tmp_ref); + } } // end of ref track loop + if (npair > 0) { + std::tuple tuple_tmp_diphoton = std::make_tuple(ndf, g1.globalIndex(), pos2.trackId(), ele2.trackId()); + if (std::find(used_diphotonIds.begin(), used_diphotonIds.end(), tuple_tmp_diphoton) == used_diphotonIds.end()) { + emh_diphoton->AddTrackToEventPool(key_df_collision, EMTrack(ndf, -1, collision.globalIndex(), -1, veeg.Pt(), veeg.Eta(), veeg.Phi(), veeg.M())); + used_diphotonIds.emplace_back(tuple_tmp_diphoton); + } + } + std::pair pair_tmp_id1 = std::make_pair(ndf, g1.globalIndex()); std::tuple tuple_tmp_id2 = std::make_tuple(ndf, collision.globalIndex(), pos2.trackId(), ele2.trackId()); if (std::find(used_photonIds.begin(), used_photonIds.end(), pair_tmp_id1) == used_photonIds.end()) { - emh1->AddTrackToEventPool(key_df_collision, EMTrack(-1, g1.globalIndex(), collision.globalIndex(), -1, g1.pt(), g1.eta(), g1.phi(), 0)); + emh1->AddTrackToEventPool(key_df_collision, EMTrack(ndf, g1.globalIndex(), collision.globalIndex(), -1, g1.pt(), g1.eta(), g1.phi(), 0)); used_photonIds.emplace_back(pair_tmp_id1); } if (std::find(used_dileptonIds.begin(), used_dileptonIds.end(), tuple_tmp_id2) == used_dileptonIds.end()) { - emh2->AddTrackToEventPool(key_df_collision, EMTrack(-1, -1, collision.globalIndex(), -1, v_ee.Pt(), v_ee.Eta(), v_ee.Phi(), v_ee.M())); + emh2->AddTrackToEventPool(key_df_collision, EMTrack(ndf, -1, collision.globalIndex(), -1, v_ee.Pt(), v_ee.Eta(), v_ee.Phi(), v_ee.M())); used_dileptonIds.emplace_back(tuple_tmp_id2); } ndiphoton++; @@ -704,24 +739,14 @@ struct DiphotonHadronMPC { } // end of g1 loop } // end of pairing in same event - if (nphoton > 0) { - for (const auto& [trg, ref] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_collision, refTracks_per_collision))) { - if (fEMTrackCut.IsSelected(trg) && fEMTrackCut.IsSelected(ref)) { - float deta = trg.eta() - ref.eta(); - float dphi = trg.phi() - ref.phi(); - o2::math_utils::bringTo02Pi(dphi); - fRegistry.fill(HIST("HadronHadron_for_Photon/same/hs"), trg.pt(), ref.pt(), deta, std::cos(cfgNmod * dphi)); - } - } - } - if (ndiphoton > 0) { - for (const auto& [trg, ref] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_collision, refTracks_per_collision))) { - if (fEMTrackCut.IsSelected(trg) && fEMTrackCut.IsSelected(ref)) { - float deta = trg.eta() - ref.eta(); - float dphi = trg.phi() - ref.phi(); - o2::math_utils::bringTo02Pi(dphi); - fRegistry.fill(HIST("HadronHadron_for_Diphoton/same/hs"), trg.pt(), ref.pt(), deta, std::cos(cfgNmod * dphi)); + for (const auto& [ref1, ref2] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_collision, refTracks_per_collision))) { + if (fEMTrackCut.IsSelected(ref1) && fEMTrackCut.IsSelected(ref2)) { + float deta = ref1.eta() - ref2.eta(); + float dphi = ref1.phi() - ref2.phi(); + // o2::math_utils::bringTo02Pi(dphi); + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("HadronHadron/same/hs"), ref1.pt(), ref2.pt(), deta, dphi); } } } @@ -734,9 +759,13 @@ struct DiphotonHadronMPC { // make a vector of selected photons in this collision. auto selected_photons1_in_this_event = emh1->GetTracksPerCollision(key_df_collision); auto selected_photons2_in_this_event = emh2->GetTracksPerCollision(key_df_collision); + auto selected_refTracks_in_this_event = emh_ref->GetTracksPerCollision(key_df_collision); + auto selected_diphotons_in_this_event = emh_diphoton->GetTracksPerCollision(key_df_collision); auto collisionIds1_in_mixing_pool = emh1->GetCollisionIdsFromEventPool(key_bin); auto collisionIds2_in_mixing_pool = emh2->GetCollisionIdsFromEventPool(key_bin); + auto collisionIdsRef_in_mixing_pool = emh_ref->GetCollisionIdsFromEventPool(key_bin); + auto collisionIdsDiphoton_in_mixing_pool = emh_diphoton->GetCollisionIdsFromEventPool(key_bin); if constexpr (pairtype == PairType::kPCMPCM) { // same kinds pairing for (const auto& mix_dfId_collisionId : collisionIds1_in_mixing_pool) { @@ -765,11 +794,36 @@ struct DiphotonHadronMPC { if (std::fabs(v12.Rapidity()) > maxY) { continue; } - fRegistry.fill(HIST("Diphoton/mix/hs"), v12.M(), v12.Pt(), 1.f); } } - } // end of loop over mixed event pool + } // end of loop over mixed event pool between photon-photon + + for (const auto& mix_dfId_collisionId : collisionIdsRef_in_mixing_pool) { + int mix_dfId = mix_dfId_collisionId.first; + int64_t mix_collisionId = mix_dfId_collisionId.second; + + if (collision.globalIndex() == mix_collisionId && ndf == mix_dfId) { // this never happens. only protection. + continue; + } + + auto globalBC_mix = map_mixed_eventId_to_globalBC[mix_dfId_collisionId]; + uint64_t diffBC = std::max(collision.globalBC(), globalBC_mix) - std::min(collision.globalBC(), globalBC_mix); + if (diffBC < ndiff_bc_mix) { + continue; + } + + auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + for (const auto& trg : selected_diphotons_in_this_event) { + for (const auto& ref : refTracks_from_event_pool) { + float deta = trg.eta() - ref.eta(); + float dphi = trg.phi() - ref.phi(); + // o2::math_utils::bringTo02Pi(dphi); + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("DiphotonHadron/mix/hs"), trg.mass(), trg.pt(), ref.pt(), deta, dphi); + } + } + } // end of loop over mixed event pool between diphoton-hadron } else { // [photon1 from event1, photon2 from event2] and [photon1 from event2, photon2 from event1] for (const auto& mix_dfId_collisionId : collisionIds2_in_mixing_pool) { @@ -804,7 +858,8 @@ struct DiphotonHadronMPC { fRegistry.fill(HIST("Diphoton/mix/hs"), v12.M(), v12.Pt(), 1.f); } } - } // end of loop over mixed event pool + } // end of loop over mixed event pool between photon-photon + for (const auto& mix_dfId_collisionId : collisionIds1_in_mixing_pool) { int mix_dfId = mix_dfId_collisionId.first; int64_t mix_collisionId = mix_dfId_collisionId.second; @@ -837,12 +892,67 @@ struct DiphotonHadronMPC { fRegistry.fill(HIST("Diphoton/mix/hs"), v12.M(), v12.Pt(), 1.f); } } - } // end of loop over mixed event pool + } // end of loop over mixed event pool between photon-photon + + for (const auto& mix_dfId_collisionId : collisionIdsRef_in_mixing_pool) { + int mix_dfId = mix_dfId_collisionId.first; + int64_t mix_collisionId = mix_dfId_collisionId.second; + + if (collision.globalIndex() == mix_collisionId && ndf == mix_dfId) { // this never happens. only protection. + continue; + } + + auto globalBC_mix = map_mixed_eventId_to_globalBC[mix_dfId_collisionId]; + uint64_t diffBC = std::max(collision.globalBC(), globalBC_mix) - std::min(collision.globalBC(), globalBC_mix); + if (diffBC < ndiff_bc_mix) { + continue; + } + + auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + for (const auto& trg : selected_diphotons_in_this_event) { + for (const auto& ref : refTracks_from_event_pool) { + float deta = trg.eta() - ref.eta(); + float dphi = trg.phi() - ref.phi(); + // o2::math_utils::bringTo02Pi(dphi); + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("DiphotonHadron/mix/hs"), trg.mass(), trg.pt(), ref.pt(), deta, dphi); + } + } + } // end of loop over mixed event pool between diphoton-hadron } + // hadron-hadron mixed event + for (const auto& mix_dfId_collisionId : collisionIdsRef_in_mixing_pool) { + int mix_dfId = mix_dfId_collisionId.first; + int64_t mix_collisionId = mix_dfId_collisionId.second; + + if (collision.globalIndex() == mix_collisionId && ndf == mix_dfId) { // this never happens. only protection. + continue; + } + + auto globalBC_mix = map_mixed_eventId_to_globalBC[mix_dfId_collisionId]; + uint64_t diffBC = std::max(collision.globalBC(), globalBC_mix) - std::min(collision.globalBC(), globalBC_mix); + if (diffBC < ndiff_bc_mix) { + continue; + } + + auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + for (const auto& ref1 : selected_refTracks_in_this_event) { + for (const auto& ref2 : refTracks_from_event_pool) { + float deta = ref1.eta() - ref2.eta(); + float dphi = ref1.phi() - ref2.phi(); + // o2::math_utils::bringTo02Pi(dphi); + dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); + fRegistry.fill(HIST("HadronHadron/mix/hs"), ref1.pt(), ref2.pt(), deta, dphi); + } + } + } // end of loop over mixed event pool between hadron-hadron + if (ndiphoton > 0) { emh1->AddCollisionIdAtLast(key_bin, key_df_collision); emh2->AddCollisionIdAtLast(key_bin, key_df_collision); + emh_diphoton->AddCollisionIdAtLast(key_bin, key_df_collision); + emh_ref->AddCollisionIdAtLast(key_bin, key_df_collision); map_mixed_eventId_to_globalBC[key_df_collision] = collision.globalBC(); } @@ -858,7 +968,7 @@ struct DiphotonHadronMPC { Filter prefilter_primaryelectron = ifnode(dileptoncuts.cfg_apply_cuts_from_prefilter_derived.node(), o2::aod::emprimaryelectron::pfbderived == static_cast(0), true); int ndf = 0; - void process2PC(FilteredMyCollisions const& collisions, MyTracks const& refTracks, Types const&... args) + void processAnalysis(FilteredMyCollisions const& collisions, MyTracks const& refTracks, Types const&... args) { // LOGF(info, "ndf = %d", ndf); if constexpr (pairtype == PairType::kPCMPCM) { @@ -874,10 +984,10 @@ struct DiphotonHadronMPC { } ndf++; } - PROCESS_SWITCH(DiphotonHadronMPC, process2PC, "process pair analysis", true); + PROCESS_SWITCH(DiphotonHadronMPC, processAnalysis, "process pair analysis", true); using FilteredMyCollisionsWithSWT = soa::Filtered; - void process2PCwithTrigger(FilteredMyCollisionsWithSWT const& collisions, MyTracks const& refTracks, Types const&... args) + void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, MyTracks const& refTracks, Types const&... args) { // LOGF(info, "ndf = %d", ndf); if constexpr (pairtype == PairType::kPCMPCM) { @@ -893,7 +1003,7 @@ struct DiphotonHadronMPC { } ndf++; } - PROCESS_SWITCH(DiphotonHadronMPC, process2PCwithTrigger, "process pair analysis", false); + PROCESS_SWITCH(DiphotonHadronMPC, processTriggerAnalysis, "process pair analysis with software trigger", false); void processDummy(MyCollisions const&) {} PROCESS_SWITCH(DiphotonHadronMPC, processDummy, "Dummy function", false); diff --git a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx index e1438f423ad..9a6d3be2734 100644 --- a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx @@ -52,6 +52,7 @@ using MyCollisionsMCCent = soa::Join; struct CreateEMEventPhoton { + Produces embc; Produces event; // Produces eventCov; Produces eventMult; @@ -135,8 +136,14 @@ struct CreateEMEventPhoton { } template - void skimEvent(TCollisions const& collisions, TBCs const&) + void skimEvent(TCollisions const& collisions, TBCs const& bcs) { + for (const auto& bc : bcs) { + if (bc.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + embc(bc.alias_raw(), bc.selection_raw(), bc.rct_raw()); // TVX is fired. + } + } // end of bc loop + for (const auto& collision : collisions) { if constexpr (isMC) { if (!collision.has_mcCollision()) { @@ -328,11 +335,13 @@ struct AssociatePhotonToEMEvent { Produces prmeleventid; Produces phoseventid; Produces emceventid; + Produces prmtrackeventid; Preslice perCollisionPCM = aod::v0photonkf::collisionId; PresliceUnsorted perCollisionEl = aod::emprimaryelectron::collisionId; Preslice perCollisionPHOS = aod::skimmedcluster::collisionId; Preslice perCollisionEMC = aod::skimmedcluster::collisionId; + PresliceUnsorted perCollisionTrack = aod::emprimarytrack::collisionId; void init(o2::framework::InitContext&) {} @@ -361,6 +370,11 @@ struct AssociatePhotonToEMEvent { fillEventId(collisions, tracks, prmeleventid, perCollisionEl); } + void processChargedTrack(aod::EMEvents const& collisions, aod::EMPrimaryTracks const& tracks) + { + fillEventId(collisions, tracks, prmtrackeventid, perCollisionTrack); + } + void processPHOS(aod::EMEvents const& collisions, aod::PHOSClusters const& photons) { fillEventId(collisions, photons, phoseventid, perCollisionPHOS);