From e5e20c34208252725b0b1af148a8c47011425e4b Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Thu, 7 Dec 2023 18:14:11 +0100 Subject: [PATCH 001/156] Add histogram and modification in histogram variables (#4105) --- PWGLF/Tasks/f1protoncorrelation.cxx | 40 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/PWGLF/Tasks/f1protoncorrelation.cxx b/PWGLF/Tasks/f1protoncorrelation.cxx index 6048b7dccf1..a42c879ca50 100644 --- a/PWGLF/Tasks/f1protoncorrelation.cxx +++ b/PWGLF/Tasks/f1protoncorrelation.cxx @@ -57,8 +57,8 @@ struct f1protoncorrelation { void init(o2::framework::InitContext&) { // register histograms - histos.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 10.0f}}); - histos.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 10.0f}}); + histos.add("hNsigmaProtonTPCSE", "Nsigma Proton TPC distribution same event", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 1.0f}}); + histos.add("hNsigmaProtonTPCME", "Nsigma Proton TPC distribution mixed event", kTH2F, {{200, -10.0f, 10.0f}, {100, 0.0f, 1.0f}}); histos.add("h2SameEventPtCorrelation", "Pt correlation of F1 and proton", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {100, 0.0, 10.0}}); histos.add("h2SameEventInvariantMassUnlike_mass104", "Unlike Sign Invariant mass of f1 same event", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {800, 1.0, 1.8}}); histos.add("h2MixEventInvariantMassUnlike_mass104", "Unlike Sign Invariant mass of f1 mix event", kTH3F, {{100, 0.0f, 1.0f}, {100, 0.0, 10.0}, {800, 1.0, 1.8}}); @@ -133,37 +133,38 @@ struct f1protoncorrelation { continue; } auto relative_momentum = getkstar(F1, Proton); - histos.fill(HIST("h2SameEventPtCorrelation"), relative_momentum, Pion.P() / Kaon.P(), Proton.Pt()); + histos.fill(HIST("h2SameEventPtCorrelation"), relative_momentum, F1.Pt(), Proton.Pt()); if (f1track.f1MassKaonKshort() < 1.04) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass104"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("hNsigmaProtonTPCSE"), protontrack.protonNsigmaTPC(), relative_momentum); } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass104"), relative_momentum, F1.Pt(), F1.M()); } } if (f1track.f1MassKaonKshort() < 1.03) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass103"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass103"), relative_momentum, F1.Pt(), F1.M()); } } if (f1track.f1MassKaonKshort() < 1.02) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass102"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass102"), relative_momentum, F1.Pt(), F1.M()); } } if (f1track.f1MassKaonKshort() < 1.01) { if (f1track.f1SignalStat() == 1) { - histos.fill(HIST("h2SameEventInvariantMassUnlike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2SameEventInvariantMassUnlike_mass101"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (f1track.f1SignalStat() == -1) { - histos.fill(HIST("h2SameEventInvariantMassLike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2SameEventInvariantMassLike_mass101"), relative_momentum, F1.Pt(), F1.M()); } } } @@ -224,34 +225,35 @@ struct f1protoncorrelation { auto relative_momentum = getkstar(F1, Proton); if (t1.f1MassKaonKshort() < 1.04) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass104"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("hNsigmaProtonTPCME"), t2.protonNsigmaTPC(), relative_momentum); } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass104"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass104"), relative_momentum, F1.Pt(), F1.M()); } } if (t1.f1MassKaonKshort() < 1.03) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass103"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass103"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass103"), relative_momentum, F1.Pt(), F1.M()); } } if (t1.f1MassKaonKshort() < 1.02) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass102"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass102"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass102"), relative_momentum, F1.Pt(), F1.M()); } } if (t1.f1MassKaonKshort() < 1.01) { if (t1.f1SignalStat() == 1) { - histos.fill(HIST("h2MixEventInvariantMassUnlike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like + histos.fill(HIST("h2MixEventInvariantMassUnlike_mass101"), relative_momentum, F1.Pt(), F1.M()); // F1 sign = 1 unlike, F1 sign = -1 like } if (t1.f1SignalStat() == -1) { - histos.fill(HIST("h2MixEventInvariantMassLike_mass101"), relative_momentum, Pion.P() / Kaon.P(), F1.M()); + histos.fill(HIST("h2MixEventInvariantMassLike_mass101"), relative_momentum, F1.Pt(), F1.M()); } } } From 9052156248fe4ff6e38fd34611bfdab9507f94db Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Thu, 7 Dec 2023 18:35:41 +0100 Subject: [PATCH 002/156] modified UE calculation + small improvements (#4106) --- PWGLF/Tasks/nuclei_in_jets.cxx | 111 ++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 44 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 820f95c6b5f..3e7df1a8cd2 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -104,13 +104,14 @@ struct nuclei_in_jets { void init(InitContext const&) { // Global Properties and QC - registryQC.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{5, 0, 5, "1 = all events, 2 = selected events, 3 = events with pt>pt_threshold, 4 = events with pt>pt_threshold and particle of interest"}}); - registryQC.add("jet_plus_ue_multiplicity", "jet + underlying-event multiplicity", HistType::kTH1F, {{300, 0, 300, "#it{N}_{ch}"}}); - registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{300, 0, 300, "#it{N}_{ch}"}}); - registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{300, 0, 300, "#it{N}_{ch}"}}); + registryQC.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{10, 0, 10, "counter"}}); + registryQC.add("jet_plus_ue_multiplicity", "jet + underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); + registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); + registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("pt_leading", "pt leading", HistType::kTH1F, {{500, 0, 50, "#it{p}_{T} (GeV/#it{c})"}}); registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{500, -0.5, 0.5, "#Delta#eta"}, {500, 0.0, TMath::Pi(), "#Delta#phi"}}); registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{500, -0.5, 0.5, "#Delta#eta"}, {500, 0.0, TMath::Pi(), "#Delta#phi"}}); + registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}_{max}"}}); registryQC.add("r_jet", "R jet", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}"}}); registryQC.add("r_ue", "R ue", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}"}}); @@ -249,6 +250,10 @@ struct nuclei_in_jets { // Process Data void processData(SelectedCollisions::iterator const& collision, FullTracks const& tracks) { + + // Seed + gRandom->SetSeed(0); + // Event Counter (before event selection) registryQC.fill(HIST("number_of_events_data"), 0.5); @@ -299,6 +304,7 @@ struct nuclei_in_jets { // Skip Events with no trigger Particle if (pt_max == 0) return; + registryQC.fill(HIST("number_of_events_data"), 2.5); // Histogram with pt_leading registryQC.fill(HIST("pt_leading"), pt_max); @@ -309,26 +315,25 @@ struct nuclei_in_jets { // Selection of Events with pt > pt_leading if (nParticles < 2) return; + registryQC.fill(HIST("number_of_events_data"), 3.5); + if (pt_max < min_pt_leading) return; // Event Counter (after pt > pt_max selection) - registryQC.fill(HIST("number_of_events_data"), 2.5); + registryQC.fill(HIST("number_of_events_data"), 4.5); // Skip Events with no Particle of Interest if (!containsParticleOfInterest) return; // Event Counter (events with pt > pt_max that contain particle of interest) - registryQC.fill(HIST("number_of_events_data"), 3.5); + registryQC.fill(HIST("number_of_events_data"), 5.5); // Momentum of the Leading Particle auto const& leading_track = tracks.iteratorAt(leading_ID); TVector3 p_leading(leading_track.px(), leading_track.py(), leading_track.pz()); - // Instruction to be removed - registryQC.fill(HIST("number_of_events_data"), 4.5); - // Array of Particles inside Jet std::vector jet_particle_ID; jet_particle_ID.push_back(leading_ID); @@ -405,16 +410,49 @@ struct nuclei_in_jets { // Multiplicity inside Jet + UE int nParticlesJetUE = static_cast(jet_particle_ID.size()); + // Find Maximum Distance from Jet Axis + float Rmax(0); + + for (int i = 0; i < nParticlesJetUE; i++) { + + const auto& jet_track = tracks.iteratorAt(jet_particle_ID[i]); + TVector3 p_i(jet_track.px(), jet_track.py(), jet_track.pz()); + + // Track Selection + if (!passedTrackSelection(jet_track)) + continue; + if (require_primVtx_contributor && !(jet_track.isPVContributor())) + continue; + + float deltaEta = p_i.Eta() - p_leading.Eta(); + float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); + float R = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); + if (R > Rmax) + Rmax = R; + } + + registryQC.fill(HIST("r_max_jet"), Rmax); + + // Cut on eta jet + float eta_jet_axis = p_leading.Eta(); + if ((TMath::Abs(eta_jet_axis) + Rmax) > max_eta) + return; + registryQC.fill(HIST("number_of_events_data"), 6.5); + // Fill Jet Multiplicity - registryQC.fill(HIST("jet_plus_ue_multiplicity"), static_cast(jet_particle_ID.size())); + registryQC.fill(HIST("jet_plus_ue_multiplicity"), nParticlesJetUE); // Perpendicular Cones for UE Estimate - TVector3 z_positive(0.0, 0.0, 1.0); - TVector3 z_negative(0.0, 0.0, -1.0); - TVector3 v1 = (z_positive.Cross(p_leading)).Unit(); - TVector3 v2 = (z_negative.Cross(p_leading)).Unit(); - TVector3 v3 = (p_leading.Cross(v1)).Unit(); - TVector3 v4 = (p_leading.Cross(v2)).Unit(); + TVector3 z(0.0, 0.0, p_leading.Mag()); + TVector3 ue_axis = z.Cross(p_leading); + + double dEta(200); + do { + double angle = gRandom->Uniform(0.0, TMath::TwoPi()); + ue_axis.Rotate(angle, p_leading); + double eta_ue_axis = ue_axis.Eta(); + dEta = (TMath::Abs(eta_ue_axis) + Rmax); + } while (dEta > max_eta); // Store UE std::vector ue_particle_ID; @@ -429,32 +467,15 @@ struct nuclei_in_jets { const auto& ue_track = tracks.iteratorAt(particle_ID[i]); // Variables - float deltaEta1 = ue_track.eta() - v1.Eta(); - float deltaEta2 = ue_track.eta() - v2.Eta(); - float deltaEta3 = ue_track.eta() - v3.Eta(); - float deltaEta4 = ue_track.eta() - v4.Eta(); - - float deltaPhi1 = TVector2::Phi_0_2pi(ue_track.phi() - v1.Phi()); - float deltaPhi2 = TVector2::Phi_0_2pi(ue_track.phi() - v2.Phi()); - float deltaPhi3 = TVector2::Phi_0_2pi(ue_track.phi() - v3.Phi()); - float deltaPhi4 = TVector2::Phi_0_2pi(ue_track.phi() - v4.Phi()); - - float dr1 = TMath::Sqrt(deltaEta1 * deltaEta1 + deltaPhi1 * deltaPhi1); - float dr2 = TMath::Sqrt(deltaEta2 * deltaEta2 + deltaPhi2 * deltaPhi2); - float dr3 = TMath::Sqrt(deltaEta3 * deltaEta3 + deltaPhi3 * deltaPhi3); - float dr4 = TMath::Sqrt(deltaEta4 * deltaEta4 + deltaPhi4 * deltaPhi4); - - registryQC.fill(HIST("eta_phi_ue"), deltaEta1, deltaPhi1); - registryQC.fill(HIST("eta_phi_ue"), deltaEta2, deltaPhi2); - registryQC.fill(HIST("eta_phi_ue"), deltaEta3, deltaPhi3); - registryQC.fill(HIST("eta_phi_ue"), deltaEta4, deltaPhi4); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta1 * deltaEta1 + deltaPhi1 * deltaPhi1)); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta2 * deltaEta2 + deltaPhi2 * deltaPhi2)); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta3 * deltaEta3 + deltaPhi3 * deltaPhi3)); - registryQC.fill(HIST("r_ue"), TMath::Sqrt(deltaEta4 * deltaEta4 + deltaPhi4 * deltaPhi4)); + float deltaEta = ue_track.eta() - ue_axis.Eta(); + float deltaPhi = TVector2::Phi_0_2pi(ue_track.phi() - ue_axis.Phi()); + float dr = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); + + registryQC.fill(HIST("eta_phi_ue"), deltaEta, deltaPhi); + registryQC.fill(HIST("r_ue"), dr); // Store Particles in the UE - if (dr1 < max_jet_radius || dr2 < max_jet_radius || dr3 < max_jet_radius || dr4 < max_jet_radius) { + if (dr < Rmax) { ue_particle_ID.push_back(particle_ID[i]); } } @@ -462,10 +483,10 @@ struct nuclei_in_jets { // UE Multiplicity int nParticlesUE = static_cast(ue_particle_ID.size()); - registryQC.fill(HIST("ue_multiplicity"), static_cast(ue_particle_ID.size()) / 4.0); + registryQC.fill(HIST("ue_multiplicity"), nParticlesUE); // Jet Multiplicity - float jet_Nch = static_cast(jet_particle_ID.size()) - static_cast(ue_particle_ID.size()) / 4.0; + int jet_Nch = nParticlesJetUE - nParticlesUE; registryQC.fill(HIST("jet_multiplicity"), jet_Nch); // Loop over particles inside Jet @@ -476,8 +497,10 @@ struct nuclei_in_jets { float deltaEta = p_i.Eta() - p_leading.Eta(); float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); - registryQC.fill(HIST("eta_phi_jet"), deltaEta, deltaPhi); - registryQC.fill(HIST("r_jet"), TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi)); + if (deltaEta != 0 && deltaPhi != 0) { + registryQC.fill(HIST("eta_phi_jet"), deltaEta, deltaPhi); + registryQC.fill(HIST("r_jet"), TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi)); + } // Track Selection if (!passedTrackSelection(jet_track)) From 1e084f694a4e42919eade02fccf98c9a7d76c4fb Mon Sep 17 00:00:00 2001 From: Nicolas Strangmann <77485327+nstrangm@users.noreply.github.com> Date: Thu, 7 Dec 2023 18:57:01 +0100 Subject: [PATCH 003/156] PWGEM/PhotonMeson: Update EMCalQCTask (#4107) * PWGEM/PhotonMeson: Update EMCalQCTask - Introduce configurable axis for invmass-pT histograms - Change required trigger from INT7 to kTVXinEMC - Introduce option to differentiate between gamma-gamma pairs from EMCal and DCal * PWGEM/PhotonMeson: Fixed clang issue --- PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx | 56 +++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx index 0295fe909b2..4a00e8f3953 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx @@ -62,6 +62,7 @@ struct Photon { { eta = eta_tmp; phi = phi_tmp; + onDCal = (phi < 6 && phi > 4); energy = energy_tmp; theta = 2 * std::atan2(std::exp(-eta), 1); px = energy * std::sin(theta) * std::cos(phi); @@ -79,6 +80,7 @@ struct Photon { float pz; float eta; float phi; + bool onDCal; // Checks whether photon is in phi region of the DCal, otherwise: EMCal float energy; float theta; int id; @@ -141,9 +143,13 @@ struct Pi0QCTask { Configurable mMinNCellsCut{"MinNCellsCut", 1, "apply min cluster number of cell cut"}; Configurable mMinOpenAngleCut{"OpeningAngleCut", 0.0202, "apply min opening angle cut"}; Configurable mClusterDefinition{"clusterDefinition", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; + Configurable mSplitEMCalDCal{"SplitEMCalDCal", 0, "Create and fill inv mass histograms for photons on EMCal and DCal individually"}; std::vector mVetoBCIDs; std::vector mSelectBCIDs; + ConfigurableAxis pTBinning{"pTBinning", {500, 0.0f, 50.0f}, "Binning used along pT axis for inv mass histograms"}; + ConfigurableAxis invmassBinning{"invmassBinning", {400, 0.0f, 0.8f}, "Binning used for inv mass axis in inv mass - pT histograms"}; + // define cluster filter. It selects only those clusters which are of the type // specified in the string mClusterDefinition,e.g. kV3Default, which is V3 clusterizer with default // clusterization parameters @@ -194,9 +200,18 @@ struct Pi0QCTask { mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100}}); // meson related histograms - mHistManager.add("invMassVsPt", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {{400, 0, 0.8}, {energyAxis}}); - mHistManager.add("invMassVsPtBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH2F, {{400, 0, 0.8}, {energyAxis}}); - mHistManager.add("invMassVsPtMixedBackground", "invariant mass and pT of mixed background meson candidates", o2HistType::kTH2F, {{400, 0, 0.8}, {energyAxis}}); + mHistManager.add("invMassVsPt", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtMixedBackground", "invariant mass and pT of mixed background meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + + if (mSplitEMCalDCal) { + mHistManager.add("invMassVsPt_EMCal", "invariant mass and pT of meson candidates with both clusters on EMCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground_EMCal", "invariant mass and pT of background meson candidates with both clusters on EMCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtMixedBackground_EMCal", "invariant mass and pT of mixed background meson candidates with both clusters on EMCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPt_DCal", "invariant mass and pT of meson candidates with both clusters on DCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground_DCal", "invariant mass and pT of background meson candidates with both clusters on DCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtMixedBackground_DCal", "invariant mass and pT of mixed background meson candidates with both clusters on DCal", o2HistType::kTH2F, {invmassBinning, pTBinning}); + } if (mVetoBCID->length()) { std::stringstream parser(mVetoBCID.value); @@ -228,10 +243,10 @@ struct Pi0QCTask { mHistManager.fill(HIST("eventsAll"), 1); LOG(debug) << "processCollisions"; // do event selection if mDoEventSel is specified - // currently the event selection is hard coded to kINT7 + // currently the event selection is hard coded to kTVXinEMC // but other selections are possible that are defined in TriggerAliases.h - if (mDoEventSel && (!collision.alias_bit(kINT7))) { - LOG(debug) << "Event not selected becaus it is not kINT7, skipping"; + if (mDoEventSel && (!collision.alias_bit(kTVXinEMC))) { + LOG(debug) << "Event not selected becaus it is not kTVXinEMC, skipping"; return; } mHistManager.fill(HIST("eventVertexZAll"), collision.posZ()); @@ -407,6 +422,14 @@ struct Pi0QCTask { Meson meson(mPhotons[ig1], mPhotons[ig2]); if (meson.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPt"), meson.getMass(), meson.getPt()); + + if (mSplitEMCalDCal) { + if (!mPhotons[ig1].onDCal && !mPhotons[ig2].onDCal) { + mHistManager.fill(HIST("invMassVsPt_EMCal"), meson.getMass(), meson.getPt()); + } else if (mPhotons[ig1].onDCal && mPhotons[ig2].onDCal) { + mHistManager.fill(HIST("invMassVsPt_DCal"), meson.getMass(), meson.getPt()); + } + } } // calculate background candidates (rotation background) @@ -457,9 +480,23 @@ struct Pi0QCTask { // Fill histograms if (mesonRotated1.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPtBackground"), mesonRotated1.getMass(), mesonRotated1.getPt()); + if (mSplitEMCalDCal) { + if (!mPhotons[ig1].onDCal && !mPhotons[ig2].onDCal && !mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_EMCal"), mesonRotated1.getMass(), mesonRotated1.getPt()); + } else if (mPhotons[ig1].onDCal && mPhotons[ig2].onDCal && mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_DCal"), mesonRotated1.getMass(), mesonRotated1.getPt()); + } + } } if (mesonRotated2.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPtBackground"), mesonRotated2.getMass(), mesonRotated2.getPt()); + if (mSplitEMCalDCal) { + if (!mPhotons[ig1].onDCal && !mPhotons[ig2].onDCal && !mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_EMCal"), mesonRotated2.getMass(), mesonRotated2.getPt()); + } else if (mPhotons[ig1].onDCal && mPhotons[ig2].onDCal && mPhotons[ig3].onDCal) { + mHistManager.fill(HIST("invMassVsPtBackground_DCal"), mesonRotated2.getMass(), mesonRotated2.getPt()); + } + } } } } @@ -471,6 +508,13 @@ struct Pi0QCTask { Meson meson(gamma, evtMix.vecEvtMix[i][ig1]); if (meson.getOpeningAngle() > mMinOpenAngleCut) { mHistManager.fill(HIST("invMassVsPtMixedBackground"), meson.getMass(), meson.getPt()); + if (mSplitEMCalDCal) { + if (!gamma.onDCal && !evtMix.vecEvtMix[i][ig1].onDCal) { + mHistManager.fill(HIST("invMassVsPtMixedBackground_EMCal"), meson.getMass(), meson.getPt()); + } else if (gamma.onDCal && evtMix.vecEvtMix[i][ig1].onDCal) { + mHistManager.fill(HIST("invMassVsPtMixedBackground_DCal"), meson.getMass(), meson.getPt()); + } + } } } } From 52d0e1dc486c45fe411389ea454b30d6cf4a1e96 Mon Sep 17 00:00:00 2001 From: Giovanni Malfattore <89481844+giovannimalfattore@users.noreply.github.com> Date: Thu, 7 Dec 2023 19:01:55 +0100 Subject: [PATCH 004/156] [PWFLG] LightNucleiTask - Add rapidity plots (#4093) * [PWFLG] LightNucleiTask - Add rapidity plots * [PWFLG] LightNucleiTask - Add rapidity plots * [PWFLG] LightNucleiTask - Add MC matching efficiency plots --- PWGLF/Tasks/LFNucleiBATask.cxx | 63 ++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/LFNucleiBATask.cxx index 8d81ef2794f..5361d582e4d 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/LFNucleiBATask.cxx @@ -367,10 +367,20 @@ struct LFNucleiBATask { if (enablePr) { histos.add("tracks/proton/h1ProtonSpectra", "#it{p}_{T} (p)", HistType::kTH1F, {ptAxis}); histos.add("tracks/proton/h1antiProtonSpectra", "#it{p}_{T} (#bar{p})", HistType::kTH1F, {ptAxis}); + + histos.add("tracks/proton/h2ProtonYvsPt", "#it{y} vs #it{p}_{T} (p)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/proton/h2antiProtonYvsPt", "#it{y} vs #it{p}_{T} (#bar{p})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/proton/h2ProtonEtavsPt", "#it{#eta} vs #it{p}_{T} (p)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/proton/h2antiProtonEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{p})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableDe) { histos.add("tracks/deuteron/h1DeuteronSpectra", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectra", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); + + histos.add("tracks/deuteron/h2DeuteronYvsPt", "#it{y} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2antiDeuteronYvsPt", "#it{y} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2DeuteronEtavsPt", "it{#eta} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2antiDeuteronEtavsPt", "it{#eta} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableTr) { histos.add("tracks/triton/h1TritonSpectra", "#it{p}_{T} (t)", HistType::kTH1F, {ptAxis}); @@ -380,8 +390,18 @@ struct LFNucleiBATask { histos.add("tracks/helium/h1HeliumSpectra", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectra", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); + histos.add("tracks/helium/h2HeliumYvsPt", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt", "it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h1HeliumSpectra_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectra_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); + + histos.add("tracks/helium/h2antiHeliumYvsPt", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt", "it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectra", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -450,6 +470,14 @@ struct LFNucleiBATask { histos.add("tracks/helium/h1antiHeliumSpectraTruePrim_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectraTrueSec_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectraTrueTransport_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); + if (enablePtSpectra) { + histos.add("tracks/eff/helium/hPtHeTrue", "Track #it{p}_{T} (He); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + histos.add("tracks/eff/helium/hPtantiHeTrue", "Track #it{p}_{T} (#bar{He}); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + if (doTOFplots) { + histos.add("tracks/eff/helium/hPtHeTOFTrue", "Track #it{p}_{T} (He); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + histos.add("tracks/eff/helium/hPtantiHeTOFTrue", "Track #it{p}_{T} (#bar{He}); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); + } + } } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectraTrue", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -2361,6 +2389,9 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/proton/h2pVsTPCmomentumPr"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/proton/h1ProtonSpectra"), track.pt()); + histos.fill(HIST("tracks/proton/h2ProtonYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton)), track.pt()); + histos.fill(HIST("tracks/proton/h2ProtonEtavsPt"), track.eta(), track.pt()); + if (enablePIDplot) histos.fill(HIST("tracks/proton/h2TPCsignVsTPCmomentumProton"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaDe()) > 2)) { @@ -2373,6 +2404,9 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/proton/h2pVsTPCmomentumantiPr"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/proton/h1antiProtonSpectra"), track.pt()); + histos.fill(HIST("tracks/proton/h2antiProtonYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton)), track.pt()); + histos.fill(HIST("tracks/proton/h2antiProtonEtavsPt"), track.eta(), track.pt()); + if (enablePIDplot) histos.fill(HIST("tracks/proton/h2TPCsignVsTPCmomentumantiProton"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaDe()) > 2)) { @@ -2383,7 +2417,6 @@ struct LFNucleiBATask { } if (enableDe) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron))) < yCut)) { if ((std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) && deRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { @@ -2391,6 +2424,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/deuteron/h2pVsTPCmomentumDe"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/deuteron/h1DeuteronSpectra"), track.pt()); + histos.fill(HIST("tracks/deuteron/h2DeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), track.pt()); if (enablePIDplot) histos.fill(HIST("tracks/deuteron/h2TPCsignVsTPCmomentumDeuteron"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 1) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCStrongCut)) { @@ -2402,6 +2436,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/eff/deuteron/h2pVsTPCmomentumantiDe"), track.tpcInnerParam(), track.p()); } histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectra"), track.pt()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), track.pt()); if (enablePIDplot) histos.fill(HIST("tracks/deuteron/h2TPCsignVsTPCmomentumantiDeuteron"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 1) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCStrongCut)) { @@ -2412,7 +2447,6 @@ struct LFNucleiBATask { } if (enableTr) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaTr()) < nsigmaTPCTr)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if ((isTriton) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if (track.sign() > 0) { if (enablePtSpectra) { @@ -2440,7 +2474,6 @@ struct LFNucleiBATask { } } if (enableHe) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3))) < yCut)) { if ((std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) && heRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { @@ -2449,6 +2482,11 @@ struct LFNucleiBATask { } histos.fill(HIST("tracks/helium/h1HeliumSpectra"), hePt); histos.fill(HIST("tracks/helium/h1HeliumSpectra_Z2"), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumEtavsPt"), track.eta(), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumEtavsPt_Z2"), track.eta(), 2 * hePt); + if (enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumHelium"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCStrongCut)) { @@ -2461,6 +2499,10 @@ struct LFNucleiBATask { } histos.fill(HIST("tracks/helium/h1antiHeliumSpectra"), antihePt); histos.fill(HIST("tracks/helium/h1antiHeliumSpectra_Z2"), 2 * antihePt); + histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt"), track.eta(), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumantiHelium"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCStrongCut)) { @@ -2470,7 +2512,6 @@ struct LFNucleiBATask { } } if (enableAl) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaAl()) < nsigmaTPCAl)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { if ((std::abs(track.tpcNSigmaAl()) < nsigmaTPCAl) && TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/h1AlphaSpectra"), track.pt()); @@ -2716,7 +2757,6 @@ struct LFNucleiBATask { } } if (enableDe) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron))) < yCut)) { if ((std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) && deRapCut) { if (track.sign() > 0) { if (enablePtSpectra) @@ -2788,7 +2828,6 @@ struct LFNucleiBATask { } if (enableTr) { - // if ((((!enableStrongCut) && (std::abs(track.tpcNSigmaTr()) < nsigmaTPCTr)) || ((enableStrongCut) && (std::abs(track.tpcNSigmaPr()) >= nsigmaTPCStrongCut))) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if ((isTriton) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut)) { if (track.sign() > 0) { if (enablePtSpectra) @@ -3028,6 +3067,12 @@ struct LFNucleiBATask { if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID"), hePt); histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID_Z2"), 2 * hePt); + if (enablePtSpectra) { + histos.fill(HIST("tracks/eff/helium/hPtHeTrue"), 2 * hePt); + if (track.hasTOF() & doTOFplots) { + histos.fill(HIST("tracks/eff/helium/hPtHeTOFTrue"), 2 * hePt); + } + } } if (isPhysPrim) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTruePrim"), hePt); @@ -3062,6 +3107,12 @@ struct LFNucleiBATask { if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID"), antihePt); histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2"), 2 * antihePt); + if (enablePtSpectra) { + histos.fill(HIST("tracks/eff/helium/hPtantiHeTrue"), 2 * hePt); + if (track.hasTOF() & doTOFplots) { + histos.fill(HIST("tracks/eff/helium/hPtantiHeTOFTrue"), 2 * hePt); + } + } } if (isPhysPrim) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTruePrim"), antihePt); From f0b5f3b2bf7392e11b40cbeed58f54eca829d6df Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Thu, 7 Dec 2023 19:02:32 +0100 Subject: [PATCH 005/156] Bugfix in link builders (#4102) --- PWGLF/TableProducer/cascadebuilder.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PWGLF/TableProducer/cascadebuilder.cxx b/PWGLF/TableProducer/cascadebuilder.cxx index 4534975f6a1..29c49498842 100644 --- a/PWGLF/TableProducer/cascadebuilder.cxx +++ b/PWGLF/TableProducer/cascadebuilder.cxx @@ -2018,5 +2018,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } From 6178aeabcf02a9792c856e2e1339e6d6c5b780e5 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Thu, 7 Dec 2023 19:03:36 +0100 Subject: [PATCH 006/156] Add typecast (#4101) --- PWGLF/TableProducer/cascademcbuilder.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/TableProducer/cascademcbuilder.cxx b/PWGLF/TableProducer/cascademcbuilder.cxx index 9eb313cb25c..c8be4b0f994 100644 --- a/PWGLF/TableProducer/cascademcbuilder.cxx +++ b/PWGLF/TableProducer/cascademcbuilder.cxx @@ -165,7 +165,7 @@ struct cascademcbuilder { { for (auto& casc : casctable) { // Loop over those that actually have the corresponding V0 associated to them - auto v0 = casc.v0(); + auto v0 = casc.v0_as(); int lLabel = -1; // Acquire all three daughter tracks, please From ad8d833548d575c1f3bd16095db044c9d52bc009 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Thu, 7 Dec 2023 20:36:35 +0100 Subject: [PATCH 007/156] PWGEM/PhotonMeson: remove unnecessary PHOS/EMC dep. in MaterialBudget.cxx (#4109) --- PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx index fc3b36d835a..75fc2b7c28c 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx @@ -43,7 +43,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; From ab0403f71b74811f771ac2504ace577d1a10dd7e Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Fri, 8 Dec 2023 02:42:34 +0100 Subject: [PATCH 008/156] PWGEM/PhotonMeson: quick fix for TPConly tracks (#4111) --- PWGEM/PhotonMeson/Core/V0PhotonCut.h | 6 +++--- .../PhotonMeson/TableProducer/photonconversionbuilder.cxx | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index 0cc7fc34bca..149e871a977 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -390,9 +390,9 @@ class V0PhotonCut : public TNamed // return false; // } - // if (track.x() > 82.9 && abs(track.y()) > abs(track.x() * TMath::Tan(10.f * TMath::DegToRad())) + 5.f) { - // return false; - // } + if (track.x() > 82.9 && abs(track.y()) > abs(track.x() * TMath::Tan(10.f * TMath::DegToRad())) + 5.f) { + return false; + } const float slope = TMath::Tan(2 * TMath::ATan(TMath::Exp(-0.5))); return !(track.x() > 82.9 && abs(track.y()) < 15.f && abs(abs(track.z()) - track.x() / slope) < 7.f && 15.f < abs(track.dcaXY())); diff --git a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx index 1cd2cd685a5..5eecb2d8a2a 100644 --- a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx +++ b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx @@ -274,7 +274,8 @@ struct PhotonConversionBuilder { auto track_par_cov = getTrackParCov(track); o2::base::Propagator::Instance()->propagateToX(track_par_cov, 83.f, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); trackiu_x = track_par_cov.getX(); - trackiu_y = track_par_cov.getY(); + // trackiu_y = track_par_cov.getY(); + trackiu_y = track.y(); trackiu_z = track_par_cov.getZ(); } else { trackiu_x = track.x(); @@ -323,13 +324,13 @@ struct PhotonConversionBuilder { gpu::gpustd::array dcaInfo; auto pTrack = getTrackPar(pos); - pTrack.setPID(o2::track::PID::Electron); + // pTrack.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, pTrack, 2.f, matCorr, &dcaInfo); auto posdcaXY = dcaInfo[0]; auto posdcaZ = dcaInfo[1]; auto nTrack = getTrackPar(ele); - nTrack.setPID(o2::track::PID::Electron); + // nTrack.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, nTrack, 2.f, matCorr, &dcaInfo); auto eledcaXY = dcaInfo[0]; auto eledcaZ = dcaInfo[1]; From b6a5e460f7f82d7aa229e9a1e61aecd91e4b08cc Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Fri, 8 Dec 2023 09:51:30 +0100 Subject: [PATCH 009/156] Update onTheFlyTOFPID.cxx (#4036) --- ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx b/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx index ed1913420d5..5d63cc48434 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx @@ -276,10 +276,10 @@ struct OnTheFlyTOFPID { if (scalarProduct1 > scalarProduct2) { modulus = std::hypot(point1[0] - trcCircle.xC, point1[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[0] - trcCircle.yC); + cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); } else { modulus = std::hypot(point2[0] - trcCircle.xC, point2[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[0] - trcCircle.yC); + cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); } cosAngle /= modulus; length = trcCircle.rC * TMath::ACos(cosAngle); From 1736f52dc855bde0bafbf8f84f30b43f03977e07 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:56:21 +0100 Subject: [PATCH 010/156] added more QA histograms (#4113) --- PWGLF/Tasks/nuclei_in_jets.cxx | 43 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 3e7df1a8cd2..95cd2b31e25 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -254,14 +254,14 @@ struct nuclei_in_jets { // Seed gRandom->SetSeed(0); - // Event Counter (before event selection) + // Event Counter: before event selection registryQC.fill(HIST("number_of_events_data"), 0.5); // Event Selection if (!collision.sel8()) return; - // Event Counter (after event selection) + // Event Counter: after event selection registryQC.fill(HIST("number_of_events_data"), 1.5); // Reduced Event @@ -301,7 +301,7 @@ struct nuclei_in_jets { particle_ID.push_back(i); } - // Skip Events with no trigger Particle + // Event Counter: Skip Events with no trigger Particle (pmax=0) if (pt_max == 0) return; registryQC.fill(HIST("number_of_events_data"), 2.5); @@ -312,22 +312,19 @@ struct nuclei_in_jets { // Number of Stored Particles int nParticles = static_cast(particle_ID.size()); - // Selection of Events with pt > pt_leading - if (nParticles < 2) + // Event Counter: Skip Events with less than 2 Particles + if (nParticles < 3) return; registryQC.fill(HIST("number_of_events_data"), 3.5); + // Event Counter: Skip Events with pt pt_max selection) registryQC.fill(HIST("number_of_events_data"), 4.5); - // Skip Events with no Particle of Interest + // Event Counter: Skip Events with no Particle of Interest if (!containsParticleOfInterest) return; - - // Event Counter (events with pt > pt_max that contain particle of interest) registryQC.fill(HIST("number_of_events_data"), 5.5); // Momentum of the Leading Particle @@ -410,6 +407,11 @@ struct nuclei_in_jets { // Multiplicity inside Jet + UE int nParticlesJetUE = static_cast(jet_particle_ID.size()); + // Event Counter: Skip Events with only 1 Particle inside jet cone + if (nParticlesJetUE < 2) + return; + registryQC.fill(HIST("number_of_events_data"), 6.5); + // Find Maximum Distance from Jet Axis float Rmax(0); @@ -418,12 +420,6 @@ struct nuclei_in_jets { const auto& jet_track = tracks.iteratorAt(jet_particle_ID[i]); TVector3 p_i(jet_track.px(), jet_track.py(), jet_track.pz()); - // Track Selection - if (!passedTrackSelection(jet_track)) - continue; - if (require_primVtx_contributor && !(jet_track.isPVContributor())) - continue; - float deltaEta = p_i.Eta() - p_leading.Eta(); float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); float R = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); @@ -431,13 +427,18 @@ struct nuclei_in_jets { Rmax = R; } + // Event Counter: Skip Events with Rmax=0 + if (Rmax == 0) + return; + registryQC.fill(HIST("number_of_events_data"), 7.5); + registryQC.fill(HIST("r_max_jet"), Rmax); - // Cut on eta jet + // Event Counter: Skip Events with jet not fully inside acceptance float eta_jet_axis = p_leading.Eta(); if ((TMath::Abs(eta_jet_axis) + Rmax) > max_eta) return; - registryQC.fill(HIST("number_of_events_data"), 6.5); + registryQC.fill(HIST("number_of_events_data"), 8.5); // Fill Jet Multiplicity registryQC.fill(HIST("jet_plus_ue_multiplicity"), nParticlesJetUE); @@ -471,18 +472,16 @@ struct nuclei_in_jets { float deltaPhi = TVector2::Phi_0_2pi(ue_track.phi() - ue_axis.Phi()); float dr = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); - registryQC.fill(HIST("eta_phi_ue"), deltaEta, deltaPhi); - registryQC.fill(HIST("r_ue"), dr); - // Store Particles in the UE if (dr < Rmax) { + registryQC.fill(HIST("eta_phi_ue"), deltaEta, deltaPhi); + registryQC.fill(HIST("r_ue"), dr); ue_particle_ID.push_back(particle_ID[i]); } } // UE Multiplicity int nParticlesUE = static_cast(ue_particle_ID.size()); - registryQC.fill(HIST("ue_multiplicity"), nParticlesUE); // Jet Multiplicity From 4f84708f798ef90d9f46940a1d7fdca1808a7b4d Mon Sep 17 00:00:00 2001 From: rbailhac Date: Fri, 8 Dec 2023 16:22:40 +0100 Subject: [PATCH 011/156] Fix to avoid double histo definition (#4114) --- PWGDQ/Core/HistogramsLibrary.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index df2a4d02a60..8183ace5dd9 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -93,7 +93,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MultTPC_MultFT0C", "MultTPC vs MultFT0C", false, 400, 0, 800.0, VarManager::kMultTPC, 100, 0, 1000.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 1000.0, VarManager::kMultFT0A, 100, 0, 1000.0, VarManager::kMultFT0C); } - if (subGroupStr.Contains("multFTOPbPbRun3")) { + if (subGroupStr.Contains("ftmulpbpb")) { hm->AddHistogram(histClass, "MultTPC", "MultTPC", false, 100, 0.0, 50000.0, VarManager::kMultTPC); hm->AddHistogram(histClass, "MultFT0C", "MultFT0C", false, 100, 0.0, 60000.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "MultFT0A", "MultFT0A", false, 100, 0.0, 180000.0, VarManager::kMultFT0A); From f49c6d9bc64c59496e3af39b725d9ef88fb39f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johanna=20L=C3=B6mker?= Date: Sat, 9 Dec 2023 09:52:35 +0100 Subject: [PATCH 012/156] PWGJE: fix track table production and isEventSelected() (#4116) * fix isEventSelected, add collisionRejectionId * clang formatting --- PWGJE/TableProducer/jettrackderived.cxx | 97 +++++++++++++------------ PWGJE/Tasks/trackJetqa.cxx | 59 +++++++++------ 2 files changed, 88 insertions(+), 68 deletions(-) diff --git a/PWGJE/TableProducer/jettrackderived.cxx b/PWGJE/TableProducer/jettrackderived.cxx index 5fff4fcec48..923881c963b 100644 --- a/PWGJE/TableProducer/jettrackderived.cxx +++ b/PWGJE/TableProducer/jettrackderived.cxx @@ -109,6 +109,7 @@ struct jetspectraDerivedMaker { histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z with event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/sampledvertexz", "Sampled collsion Vertex Z with event (sel8) selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/NumContrib", "Number of contributors to vertex of collision; number of contributors to vtx; number of entries", HistType::kTH1F, {{nBins, 0, 600}}); + histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); const AxisSpec axisPercentileFT0A{binsPercentile, "Centrality FT0A"}; const AxisSpec axisPercentileFT0C{binsPercentile, "Centrality FT0C"}; @@ -128,80 +129,82 @@ struct jetspectraDerivedMaker { { // here we already fill some event histos for cross checks if (!collision.sel8()) { + histos.fill(HIST("EventProp/rejectedCollId"), 2); return false; } if (abs(collision.posZ()) > ValVtx) { + histos.fill(HIST("EventProp/rejectedCollId"), 3); return false; } histos.fill(HIST("EventProp/collisionVtxZ"), collision.posZ()); // test fill // Last thing, check the sampling if (fractionOfEvents < 1.f && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > fractionOfEvents) { // Skip events that are not sampled + histos.fill(HIST("EventProp/rejectedCollId"), 4); return false; } histos.fill(HIST("EventProp/sampledvertexz"), collision.posZ()); histos.fill(HIST("EventProp/NumContrib"), collision.numContrib()); - return true; - - if (fillMultiplicity) { - histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); + if (fillMultiplicity == true) { histos.fill(HIST("Centrality/FT0A"), collision.centFT0A()); - histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); + histos.fill(HIST("Centrality/FT0C"), collision.centFT0C()); + histos.fill(HIST("Mult/FT0C"), collision.multFT0C()); histos.fill(HIST("Mult/FT0A"), collision.multFT0A()); histos.fill(HIST("Mult/NTracksPV"), collision.multNTracksPV()); } + return true; } Produces tableTrack; using CollisionCandidate = soa::Join; using TrackCandidates = soa::Join; unsigned int randomSeed = 0; - void processData(CollisionCandidate::iterator const& collision, - TrackCandidates const& tracks, - aod::BCs const&) + void processData(CollisionCandidate const& collisions, + TrackCandidates const& tracks) { - if (!isEventSelected(collision)) { - return; + for (const auto& collision : collisions) { + if (!isEventSelected(collision)) { + histos.fill(HIST("EventProp/rejectedCollId"), 1); + } } + tableTrack.reserve(tracks.size()); for (const auto& trk : tracks) { - if (!trk.has_collision() || !(collision.globalIndex() == trk.collisionId())) { - return; - } - if (!customTrackCuts.IsSelected(trk)) { - return; + if (!customTrackCuts.IsSelected(trk)) { // we fill all tracks that have a collision(rejected or not) and pass this check ! + continue; + } else { + tableTrack(trk.collisionId(), + trk.trackTime(), + trk.signed1Pt(), trk.eta(), trk.phi(), trk.pt(), + trk.sigma1Pt(), + trk.alpha(), + trk.x(), trk.y(), trk.z(), + trk.snp(), + trk.tgl(), + trk.isPVContributor(), + trk.hasTRD(), + trk.hasITS(), + trk.hasTPC(), + trk.isGlobalTrack(), + trk.isGlobalTrackWoDCA(), + trk.isGlobalTrackWoPtEta(), + trk.flags(), + trk.trackType(), + trk.length(), + trk.tpcChi2NCl(), trk.itsChi2NCl(), trk.tofChi2(), + trk.tpcNClsShared(), + trk.tpcNClsFindable(), + trk.tpcNClsFindableMinusFound(), + trk.tpcNClsFindableMinusCrossedRows(), + trk.itsClusterMap(), + trk.itsNCls(), + trk.tpcFractionSharedCls(), + trk.tpcNClsFound(), + trk.tpcNClsCrossedRows(), + trk.tpcCrossedRowsOverFindableCls(), + trk.tpcFoundOverFindableCls(), + trk.dcaXY(), + trk.dcaZ()); } - tableTrack(trk.collisionId(), - trk.trackTime(), - trk.signed1Pt(), trk.eta(), trk.phi(), trk.pt(), - trk.sigma1Pt(), - trk.alpha(), - trk.x(), trk.y(), trk.z(), - trk.snp(), - trk.tgl(), - trk.isPVContributor(), - trk.hasTRD(), - trk.hasITS(), - trk.hasTPC(), - trk.isGlobalTrack(), - trk.isGlobalTrackWoDCA(), - trk.isGlobalTrackWoPtEta(), - trk.flags(), - trk.trackType(), - trk.length(), - trk.tpcChi2NCl(), trk.itsChi2NCl(), trk.tofChi2(), - trk.tpcNClsShared(), - trk.tpcNClsFindable(), - trk.tpcNClsFindableMinusFound(), - trk.tpcNClsFindableMinusCrossedRows(), - trk.itsClusterMap(), - trk.itsNCls(), - trk.tpcFractionSharedCls(), - trk.tpcNClsFound(), - trk.tpcNClsCrossedRows(), - trk.tpcCrossedRowsOverFindableCls(), - trk.tpcFoundOverFindableCls(), - trk.dcaXY(), - trk.dcaZ()); } } diff --git a/PWGJE/Tasks/trackJetqa.cxx b/PWGJE/Tasks/trackJetqa.cxx index 64aed5deb96..f13a87dd4a9 100644 --- a/PWGJE/Tasks/trackJetqa.cxx +++ b/PWGJE/Tasks/trackJetqa.cxx @@ -144,6 +144,8 @@ struct TrackJetQa { histos.add("EventProp/collisionVtxZ", "Collsion Vertex Z;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/collisionVtxZnoSel", "Collsion Vertex Z without event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z with event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); + histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); + // Common axes const AxisSpec axisPercentileFT0M{binsPercentile, "Centrality FT0M"}; const AxisSpec axisPercentileFT0A{binsPercentile, "Centrality FT0A"}; @@ -187,16 +189,18 @@ struct TrackJetQa { } template - void fillEventQa(eventInfo const& collision) + bool fillEventQa(eventInfo const& collision) { // fill event property variables histos.fill(HIST("EventProp/collisionVtxZnoSel"), collision.posZ()); if (!collision.sel8()) { - return; + histos.fill(HIST("EventProp/rejectedCollId"), 2); + return false; } histos.fill(HIST("EventProp/collisionVtxZSel8"), collision.posZ()); if (fabs(collision.posZ()) > ValVtx) { - return; + histos.fill(HIST("EventProp/rejectedCollId"), 3); + return false; } histos.fill(HIST("EventProp/collisionVtxZ"), collision.posZ()); if (fillMultiplicity) { @@ -206,23 +210,24 @@ struct TrackJetQa { histos.fill(HIST("Mult/FT0A"), collision.multFT0A()); histos.fill(HIST("Mult/FT0C"), collision.multFT0C()); } + return true; } template - void fillTrackQa(Tracks const& track) + bool fillTrackQa(Tracks const& track) { // check track selection if ((globalTrack == true) && (!track.isGlobalTrack())) { - return; + return false; } if ((globalTrackWoDCA == true) && (!track.isGlobalTrackWoDCA())) { - return; + return false; } if ((globalTrackWoPtEta == true) && (!track.isGlobalTrackWoPtEta())) { - return; + return false; } if ((customTrack == true) && (!customTrackCuts.IsSelected(track))) { - return; + return false; } // fill kinematic variables histos.fill(HIST("Kine/pt"), track.pt()); @@ -306,29 +311,41 @@ struct TrackJetQa { histos.fill(HIST("TPC/tpcCrossedRowsOverFindableCls"), track.pt(), track.tpcCrossedRowsOverFindableCls()); histos.fill(HIST("TPC/tpcFractionSharedCls"), track.pt(), track.tpcFractionSharedCls()); histos.fill(HIST("TPC/tpcChi2NCl"), track.pt(), track.tpcChi2NCl()); + + return true; } // Preslice> trackPerColl = aod::track::collisionId; Preslice trackPerColl = aod::track::collisionId; // SliceCache cacheTrk; - void processFull(soa::Join const& collisions, - soa::Join const& tracks) + using CollisionCandidate = soa::Join; + using TrackCandidates = soa::Join; + + void processFull(CollisionCandidate const& collisions, + TrackCandidates const& tracks) { for (const auto& collision : collisions) { - fillEventQa(collision); - if (fillMultiplicity) { - histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); - histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); - histos.fill(HIST("Mult/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); - } - auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); + if (fillEventQa(collision)) { - for (const auto& track : tracksInCollision) { - fillTrackQa(track); if (fillMultiplicity) { - histos.fill(HIST("TrackEventPar/Sigma1PtFT0Mcent"), collision.centFT0M(), track.pt(), track.sigma1Pt()); - histos.fill(HIST("TrackEventPar/MultCorrelations"), track.sigma1Pt(), track.pt(), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); + histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); + histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); + histos.fill(HIST("Mult/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); + } + auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); + + for (const auto& track : tracksInCollision) { + if (track.has_collision() && (collision.globalIndex() == track.collisionId())) { // double check + if (fillTrackQa(track)) { + if (fillMultiplicity) { + histos.fill(HIST("TrackEventPar/Sigma1PtFT0Mcent"), collision.centFT0M(), track.pt(), track.sigma1Pt()); + histos.fill(HIST("TrackEventPar/MultCorrelations"), track.sigma1Pt(), track.pt(), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); + } + } + } } + } else { + histos.fill(HIST("EventProp/rejectedCollId"), 1); } } } From 6ab169700d700d8f1756fccea2793dcdc724fd0f Mon Sep 17 00:00:00 2001 From: eloviyo <38348689+Eloviyo@users.noreply.github.com> Date: Sat, 9 Dec 2023 15:16:24 +0100 Subject: [PATCH 013/156] fixed bug (#4119) Co-authored-by: Shirajum Monira --- .../FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 8a58c7ebf63..d4cd080b9ee 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -288,10 +288,10 @@ struct femtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); From 915a6220b3ef7f1149c89dbe3a0548f7231ae4ac Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Sat, 9 Dec 2023 15:30:54 +0100 Subject: [PATCH 014/156] added y cut and MC for efficiency (#4122) --- PWGLF/Tasks/nuclei_in_jets.cxx | 126 ++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 95cd2b31e25..c7cfcf02636 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -88,12 +89,16 @@ struct nuclei_in_jets { Configurable max_chi2_TPC{"max_chi2_TPC", 4.0f, "maximum TPC chi^2/Ncls"}; Configurable max_chi2_ITS{"max_chi2_ITS", 36.0f, "maximum ITS chi^2/Ncls"}; Configurable min_pt{"min_pt", 0.2f, "minimum pt of the tracks"}; - Configurable min_eta{"min_eta", -0.8f, "minimum_eta"}; - Configurable max_eta{"max_eta", +0.8f, "maximum_eta"}; + Configurable min_eta{"min_eta", -0.8f, "minimum eta"}; + Configurable max_eta{"max_eta", +0.8f, "maximum eta"}; + Configurable min_y{"min_y", -0.5f, "minimum y"}; + Configurable max_y{"max_y", +0.5f, "maximum y"}; Configurable max_dcaxy{"max_dcaxy", 0.1f, "Maximum DCAxy"}; Configurable max_dcaz{"max_dcaz", 0.1f, "Maximum DCAz"}; Configurable min_nsigmaTPC{"min_nsigmaTPC", -3.0f, "Minimum nsigma TPC"}; Configurable max_nsigmaTPC{"max_nsigmaTPC", +3.0f, "Maximum nsigma TPC"}; + Configurable min_nsigmaTOF{"min_nsigmaTOF", -3.0f, "Minimum nsigma TOF"}; + Configurable max_nsigmaTOF{"max_nsigmaTOF", +3.5f, "Maximum nsigma TOF"}; Configurable require_primVtx_contributor{"require_primVtx_contributor", true, "require that the track is a PV contributor"}; // List of Particles @@ -105,6 +110,7 @@ struct nuclei_in_jets { { // Global Properties and QC registryQC.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{10, 0, 10, "counter"}}); + registryQC.add("number_of_events_mc", "number of events in mc", HistType::kTH1F, {{10, 0, 10, "counter"}}); registryQC.add("jet_plus_ue_multiplicity", "jet + underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); @@ -130,6 +136,20 @@ struct nuclei_in_jets { // Antihelium-3 registryData.add("antihelium3_jet_tpc", "antihelium3_jet_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); registryData.add("antihelium3_ue_tpc", "antihelium3_ue_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); + + // Generated + registryMC.add("antiproton_gen", "antiproton_gen", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_gen", "antideuteron_gen", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_gen", "antihelium3_gen", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed TPC + registryMC.add("antiproton_rec_tpc", "antiproton_rec_tpc", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tpc", "antideuteron_rec_tpc", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_rec_tpc", "antihelium3_rec_tpc", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed TOF + registryMC.add("antiproton_rec_tof", "antiproton_rec_tof", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof", "antideuteron_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); } // Single-Track Selection for the Particle of Interest @@ -159,6 +179,20 @@ struct nuclei_in_jets { if (TMath::Abs(track.dcaZ()) > max_dcaz) return false; + // Rapidity Cut + double mass(0); + if (particle_of_interest == 0) + mass = 0.93827208816; // Proton + if (particle_of_interest == 1) + mass = 1.87561294257; // Deuteron + if (particle_of_interest == 2) + mass = 2.80839160743; // Helium-3 + + TLorentzVector lorentzVect; + lorentzVect.SetXYZM(track.px(), track.py(), track.pz(), mass); + if (lorentzVect.Rapidity() < min_y || lorentzVect.Rapidity() > max_y) + return false; + return true; } @@ -580,6 +614,94 @@ struct nuclei_in_jets { } // end processData PROCESS_SWITCH(nuclei_in_jets, processData, "Process data", true); + + // MC + void processMC(soa::Join::iterator const& collision, MCTracks const& mcTracks, aod::McParticles& mcParticles, aod::McCollisions const& mcCollisions) + { + + // Event Counter (before event sel) + registryQC.fill(HIST("number_of_events_mc"), 0.5); + + // Event Selection + if (!collision.sel8()) + return; + + // Event Counter (after event sel) + registryQC.fill(HIST("number_of_events_mc"), 1.5); + + for (auto& particle : mcParticles) { + + if (!particle.isPhysicalPrimary()) + continue; + if ((particle.pdgCode() != -2212) && (particle.pdgCode() != -1000010020) && (particle.pdgCode() != -1000020030)) + continue; + if (particle.y() < min_y || particle.y() > max_y) + continue; + + // Fill Histograms + if (particle.pdgCode() == -2212) + registryMC.fill(HIST("antiproton_gen"), particle.pt()); + if (particle.pdgCode() == -1000010020) + registryMC.fill(HIST("antideuteron_gen"), particle.pt()); + if (particle.pdgCode() == -1000020030) + registryMC.fill(HIST("antihelium3_gen"), particle.pt()); + } + + for (auto track : mcTracks) { + + // Get MC Particle + if (!track.has_mcParticle()) + continue; + + const auto particle = track.mcParticle(); + if (!particle.isPhysicalPrimary()) + continue; + if ((particle.pdgCode() != -2212) && (particle.pdgCode() != -1000010020) && (particle.pdgCode() != -1000020030)) + continue; + + if (!track.passedITSRefit()) + continue; + if (!track.passedTPCRefit()) + continue; + + // Track Selection + if (!passedTrackSelection(track)) + continue; + if (require_primVtx_contributor && !(track.isPVContributor())) + continue; + + // Variables + float nsigmaTPCPr = track.tpcNSigmaPr(); + float nsigmaTOFPr = track.tofNSigmaPr(); + float nsigmaTPCDe = track.tpcNSigmaDe(); + float nsigmaTOFDe = track.tofNSigmaDe(); + float nsigmaTPCHe = track.tpcNSigmaHe(); + float pt = track.pt(); + + // Antiproton + if (particle.pdgCode() != -2212) { + if (pt < 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC) + registryMC.fill(HIST("antiproton_rec_tpc"), pt); + if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && track.hasTOF() && nsigmaTOFPr > min_nsigmaTOF && nsigmaTOFPr < max_nsigmaTOF) + registryMC.fill(HIST("antiproton_rec_tof"), pt); + } + + // Antideuteron + if (particle.pdgCode() != -1000010020) { + if (pt < 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC) + registryMC.fill(HIST("antideuteron_rec_tpc"), pt); + if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && track.hasTOF() && nsigmaTOFDe > min_nsigmaTOF && nsigmaTOFDe < max_nsigmaTOF) + registryMC.fill(HIST("antideuteron_rec_tof"), pt); + } + + // Antihelium-3 + if (particle.pdgCode() != -1000020030) { + if (nsigmaTPCHe > min_nsigmaTPC && nsigmaTPCHe < max_nsigmaTPC) + registryMC.fill(HIST("antihelium3_rec_tpc"), 2.0 * pt); + } + } + } + PROCESS_SWITCH(nuclei_in_jets, processMC, "process MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From b33c173b778c8cbdf2def146ef4ede9240127f7c Mon Sep 17 00:00:00 2001 From: Yash Patley <52608802+yashpatley@users.noreply.github.com> Date: Sat, 9 Dec 2023 20:40:34 +0530 Subject: [PATCH 015/156] PWGLF: Update lambda1520SpherocityAnalysis.cxx (#4120) * PWGLF: Update lambda1520SpherocityAnalysis.cxx * PWGLF: Update lambda1520SpherocityAnalysis.cxx --- PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx | 29 +++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx index c99a606df83..4535d908a24 100644 --- a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx +++ b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx @@ -88,7 +88,7 @@ struct lambdaAnalysis { // Define Axis. const AxisSpec axisSp(nBinsSp, 0., 1., "S_{0}"); const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); - const AxisSpec axisPtQA(40, 0., 2., "p_{T} (GeV/c)"); + const AxisSpec axisPtQA(100, 0., 2., "p_{T} (GeV/c)"); const AxisSpec axisPt(nBinsPt, 0., 10., "p_{T} (GeV/c)"); const AxisSpec axisEta(40, -1, 1, "#eta"); const AxisSpec axisDCAz(500, -0.5, 0.5, {"DCA_{z} (cm)"}); @@ -96,7 +96,7 @@ struct lambdaAnalysis { const AxisSpec axisTPCNCls(200, 0, 200, {"TPCNCls"}); const AxisSpec axisTPCNsigma(120, -6, 6, {"n#sigma^{TPC}"}); const AxisSpec axisTOFNsigma(120, -6, 6, {"n#sigma^{TOF}"}); - const AxisSpec axisInvM(nBinsInvM, 1.44, 2.04, {"M_{inv} (GeV/c^{2})"}); + const AxisSpec axisInvM(nBinsInvM, 1.44, 2.44, {"M_{inv} (GeV/c^{2})"}); // Create Histograms. // Event @@ -116,17 +116,19 @@ struct lambdaAnalysis { histos.add("QAafter/Proton/hPt", "p_{T}-spectra Protons", kTH1F, {axisPt}); histos.add("QAafter/Proton/hDcaZ", "dca_{z} Protons", kTH2F, {axisPtQA, axisDCAz}); histos.add("QAafter/Proton/hDcaXY", "dca_{xy} Protons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAafter/Proton/hTPCNsigma", "n#sigma^{TPC} only Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma^{TPC} Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTOFNsigma", "n#sigma^{TOF} Protons", kTH2F, {axisPtQA, axisTOFNsigma}); - histos.add("QAafter/Proton/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Proton/hTPCNsigmaFull", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Proton/hTPCNsigma", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Proton/hTOFNsigma", "n#sigma(TOF) Protons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAafter/Proton/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); histos.add("QAafter/Kaon/hPt", "p_{T}-spectra Kaons", kTH1F, {axisPt}); histos.add("QAafter/Kaon/hDcaZ", "dca_{z} Kaons", kTH2F, {axisPtQA, axisDCAz}); histos.add("QAafter/Kaon/hDcaXY", "dca_{xy} Kaons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma^{TPC} only Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma^{TPC} Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma^{TOF} Kaons", kTH2F, {axisPtQA, axisTOFNsigma}); - histos.add("QAafter/Kaon/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Kaon/hTPCNsigmaFull", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma(TOF) Kaons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAafter/Kaon/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // Analysis // Lambda Invariant Mass @@ -135,11 +137,13 @@ struct lambdaAnalysis { histos.add("Analysis/hInvMassLS2", "Like Signs M_{inv} #bar{p} K^{-}", kTH1D, {axisInvM}); histos.add("Analysis/hInvMassR", "Rotated Spectra", kTH1D, {axisInvM}); histos.add("Analysis/hInvMassMix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/hInvMassMixLS", "Mixed Events M_{inv}", kTH1D, {axisInvM}); histos.add("Analysis/h4InvMass", "THn #Lambda(1520)", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassLS1", "THn Like Signs p K^{+}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassLS2", "THn Like Signs #bar{p} K^{-}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassR", "THn Rotated", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); histos.add("Analysis/h4InvMassMix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4InvMassMixLS", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); // MC if (doprocessMC) { @@ -321,6 +325,7 @@ struct lambdaAnalysis { histos.fill(HIST("QAafter/Proton/hPt"), trkPr.pt()); histos.fill(HIST("QAafter/Proton/hDcaZ"), trkPr.pt(), trkPr.dcaZ()); histos.fill(HIST("QAafter/Proton/hDcaXY"), trkPr.pt(), trkPr.dcaXY()); + histos.fill(HIST("QAafter/Proton/hTPCNsigmaFull"), trkPr.pt(), trkPr.tpcNSigmaPr()); if (!cUseTpcOnly && trkPr.hasTOF()) { histos.fill(HIST("QAafter/Proton/hTPCNsigmaTOF"), trkPr.pt(), trkPr.tpcNSigmaPr()); histos.fill(HIST("QAafter/Proton/hTOFNsigma"), trkPr.pt(), trkPr.tofNSigmaPr()); @@ -331,6 +336,7 @@ struct lambdaAnalysis { histos.fill(HIST("QAafter/Kaon/hPt"), trkKa.pt()); histos.fill(HIST("QAafter/Kaon/hDcaZ"), trkKa.pt(), trkKa.dcaZ()); histos.fill(HIST("QAafter/Kaon/hDcaXY"), trkKa.pt(), trkKa.dcaXY()); + histos.fill(HIST("QAafter/Kaon/hTPCNsigmaFull"), trkKa.pt(), trkKa.tpcNSigmaKa()); if (!cUseTpcOnly && trkKa.hasTOF()) { histos.fill(HIST("QAafter/Kaon/hTPCNsigmaTOF"), trkKa.pt(), trkKa.tpcNSigmaKa()); histos.fill(HIST("QAafter/Kaon/hTOFNsigma"), trkKa.pt(), trkKa.tofNSigmaKa()); @@ -414,6 +420,9 @@ struct lambdaAnalysis { if (trkPr.sign() * trkKa.sign() < 0) { histos.fill(HIST("Analysis/hInvMassMix"), p.M()); histos.fill(HIST("Analysis/h4InvMassMix"), p.M(), p.Pt(), sph, mult); + } else { + histos.fill(HIST("Analysis/hInvMassMixLS"), p.M()); + histos.fill(HIST("Analysis/h4InvMassMixLS"), p.M(), p.Pt(), sph, mult); } } } From e8a8a67fa4872eeafea0eae0f1bce380c6712e57 Mon Sep 17 00:00:00 2001 From: Federica Zanone <94552525+ZFederica@users.noreply.github.com> Date: Sat, 9 Dec 2023 17:53:26 +0100 Subject: [PATCH 016/156] PWGHF: implement track selections for bachelor in lfCascade+bachelor decays (#4076) * Implement track selections for bachelor in casc+bach decays * Update comment * Change histogram axis --- .../TableProducer/candidateCreatorToXiPi.cxx | 4 +- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 82 +++++++++++++++++-- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx index eca0dc9d5d0..dcf300d35a4 100644 --- a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx @@ -246,8 +246,8 @@ struct HfCandidateCreatorToXiPi { auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); for (const auto& trackIndexPion : groupedTrackIndices) { - // use bachelor selections from HfTrackIndexSkimCreatorTagSelTracks --> bit =2 is CandidateType::CandV0bachelor - if (!TESTBIT(trackIndexPion.isSelProng(), 2)) { + // use bachelor selections from HfTrackIndexSkimCreatorTagSelTracks --> bit = 4 is CandidateType::CandCascadeBachelor + if (!TESTBIT(trackIndexPion.isSelProng(), 4)) { continue; } diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 0f431da044a..dcc68082aa1 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -63,6 +63,7 @@ enum CandidateType { Cand3Prong, CandV0bachelor, CandDstar, + CandCascadeBachelor, NCandidateTypes }; @@ -364,11 +365,19 @@ struct HfTrackIndexSkimCreatorTagSelTracks { Configurable> cutsTrack3Prong{"cutsTrack3Prong", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for 3-prong candidates"}; Configurable etaMinTrack3Prong{"etaMinTrack3Prong", -99999., "min. pseudorapidity for 3 prong candidate"}; Configurable etaMaxTrack3Prong{"etaMaxTrack3Prong", 4., "max. pseudorapidity for 3 prong candidate"}; - // bachelor cuts (when using cascades) + // bachelor cuts (V0 + bachelor decays) Configurable ptMinTrackBach{"ptMinTrackBach", 0.3, "min. track pT for bachelor in cascade candidate"}; // 0.5 for PbPb 2015? Configurable> cutsTrackBach{"cutsTrackBach", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for the bachelor of V0-bachelor candidates"}; Configurable etaMinTrackBach{"etaMinTrackBach", -99999., "min. pseudorapidity for bachelor in cascade candidate"}; Configurable etaMaxTrackBach{"etaMaxTrackBach", 0.8, "max. pseudorapidity for bachelor in cascade candidate"}; + // bachelor cuts (cascade + bachelor decays) + Configurable ptMinTrackBachLfCasc{"ptMinTrackBachLfCasc", 0.1, "min. track pT for bachelor in cascade + bachelor decays"}; // 0.5 for PbPb 2015? + Configurable> cutsTrackBachLfCasc{"cutsTrackBachLfCasc", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for the bachelor in cascade + bachelor decays"}; + Configurable etaMinTrackBachLfCasc{"etaMinTrackBachLfCasc", -99999., "min. pseudorapidity for bachelor in cascade + bachelor decays"}; + Configurable etaMaxTrackBachLfCasc{"etaMaxTrackBachLfCasc", 1.1, "max. pseudorapidity for bachelor in cascade + bachelor decays"}; + Configurable useIsGlobalTrackForBachLfCasc{"useIsGlobalTrackForBachLfCasc", false, "check isGlobalTrack status for bachelor in cascade + bachelor decays"}; + Configurable useIsGlobalTrackWoDCAForBachLfCasc{"useIsGlobalTrackWoDCAForBachLfCasc", false, "check isGlobalTrackWoDCA status for bachelor in cascade + bachelor decays"}; + Configurable useIsQualityTrackITSForBachLfCasc{"useIsQualityTrackITSForBachLfCasc", true, "check isQualityTrackITS status for bachelor in cascade + bachelor decays"}; // soft pion cuts for D* Configurable ptMinSoftPionForDstar{"ptMinSoftPionForDstar", 0.05, "min. track pT for soft pion in D* candidate"}; Configurable ptMaxSoftPionForDstar{"ptMaxSoftPionForDstar", 2., "max. track pT for soft pion in D* candidate"}; @@ -413,7 +422,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { LOGP(fatal, "One and only one process function for the different PID selection strategies can be enabled at a time!"); } - cutsSingleTrack = {cutsTrack2Prong, cutsTrack3Prong, cutsTrackBach, cutsTrackDstar}; + cutsSingleTrack = {cutsTrack2Prong, cutsTrack3Prong, cutsTrackBach, cutsTrackDstar, cutsTrackBachLfCasc}; if (etaMinTrack2Prong == -99999.) { etaMinTrack2Prong.value = -etaMaxTrack2Prong; @@ -427,10 +436,13 @@ struct HfTrackIndexSkimCreatorTagSelTracks { if (etaMinSoftPionForDstar == -99999.) { etaMinSoftPionForDstar.value = -etaMaxSoftPionForDstar; } + if (etaMinTrackBachLfCasc == -99999.) { + etaMinTrackBachLfCasc.value = -etaMaxTrackBachLfCasc; + } if (fillHistograms) { // general tracks - registry.add("hRejTracks", "Tracks;;entries", {HistType::kTH1F, {{20, 0.5, 20.5}}}); + registry.add("hRejTracks", "Tracks;;entries", {HistType::kTH1F, {{25, 0.5, 25.5}}}); registry.add("hPtNoCuts", "all tracks;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); // 2-prong histograms @@ -441,7 +453,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.add("hPtCuts3Prong", "tracks selected for 3-prong vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); registry.add("hDCAToPrimXYVsPtCuts3Prong", "tracks selected for 3-prong vertexing;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); registry.add("hEtaCuts3Prong", "tracks selected for 3-prong vertexing;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxTrack3Prong - etaMinTrack3Prong) * 100), -1.2 * etaMinTrack3Prong, 1.2 * etaMaxTrack3Prong}}}); - // bachelor (for cascades) histograms + // bachelor (for V0 + bachelor decays) histograms registry.add("hPtCutsV0bachelor", "tracks selected for V0-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); registry.add("hDCAToPrimXYVsPtCutsV0bachelor", "tracks selected for V0-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); registry.add("hEtaCutsV0bachelor", "tracks selected for V0-bachelor vertexing;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxTrackBach - etaMinTrackBach) * 100), -1.2 * etaMinTrackBach, 1.2 * etaMaxTrackBach}}}); @@ -449,9 +461,13 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.add("hPtCutsSoftPionForDstar", "tracks selected for D* soft pion;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); registry.add("hDCAToPrimXYVsPtCutsSoftPionForDstar", "tracks selected for D* soft pion;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); registry.add("hEtaCutsSoftPionForDstar", "tracks selected for D* soft pion;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxSoftPionForDstar - etaMinSoftPionForDstar) * 100), -1.2 * etaMinSoftPionForDstar, 1.2 * etaMaxSoftPionForDstar}}}); + // bachelor (for cascade + bachelor decays) histograms + registry.add("hPtCutsCascadeBachelor", "tracks selected for cascade-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("hDCAToPrimXYVsPtCutsCascadeBachelor", "tracks selected for cascade-bachelor vertexing;#it{p}_{T}^{track} (GeV/#it{c});DCAxy to prim. vtx. (cm);entries", {HistType::kTH2F, {{360, 0., 36.}, {400, -2., 2.}}}); + registry.add("hEtaCutsCascadeBachelor", "tracks selected for cascade-bachelor vertexing;#it{#eta};entries", {HistType::kTH1F, {{static_cast(0.6 * (etaMaxTrackBachLfCasc - etaMinTrackBachLfCasc) * 100), -1.2 * etaMinTrackBachLfCasc, 1.2 * etaMaxTrackBachLfCasc}}}); std::string cutNames[nCuts + 1] = {"selected", "rej pT", "rej eta", "rej track quality", "rej dca"}; - std::string candNames[CandidateType::NCandidateTypes] = {"2-prong", "3-prong", "bachelor", "dstar"}; + std::string candNames[CandidateType::NCandidateTypes] = {"2-prong", "3-prong", "bachelor", "dstar", "lfCascBachelor"}; for (int iCandType = 0; iCandType < CandidateType::NCandidateTypes; iCandType++) { for (int iCut = 0; iCut < nCuts + 1; iCut++) { registry.get(HIST("hRejTracks"))->GetXaxis()->SetBinLabel((nCuts + 1) * iCandType + iCut + 1, Form("%s %s", candNames[iCandType].data(), cutNames[iCut].data())); @@ -548,10 +564,10 @@ struct HfTrackIndexSkimCreatorTagSelTracks { return flag; } - /// Single-track cuts for 2-prongs, 3-prongs, or cascades + /// Single-track cuts for 2-prongs, 3-prongs, bachelor+V0, bachelor+cascade decays /// \param trackPt is the track pt /// \param dca is a 2-element array with dca in transverse and longitudinal directions - /// \param candType is the flag to decide which cuts to be applied (either for 2-prong, 3-prong, or cascade decays) + /// \param candType is the flag to decide which cuts to be applied (either for 2-prong, 3-prong, bachelor+V0 or bachelor+cascade decays) /// \return true if track passes all cuts bool isSelectedTrackDCA(const float& trackPt, const std::array& dca, const int candType) { @@ -609,6 +625,12 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandDstar + iCut); } } + if (trackPt < ptMinTrackBachLfCasc) { + CLRBIT(statusProng, CandidateType::CandCascadeBachelor); + if (fillHistograms) { + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } + } iCut = 3; // eta cut @@ -639,6 +661,13 @@ struct HfTrackIndexSkimCreatorTagSelTracks { } } + if (TESTBIT(statusProng, CandidateType::CandCascadeBachelor) && (trackEta > etaMaxTrackBachLfCasc || trackEta < etaMinTrackBachLfCasc)) { + CLRBIT(statusProng, CandidateType::CandCascadeBachelor); + if (fillHistograms) { + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } + } + // quality cut iCut = 4; bool hasGoodQuality = true; @@ -701,6 +730,35 @@ struct HfTrackIndexSkimCreatorTagSelTracks { } } + // quality cut for bachelor in cascade + bachelor decays + hasGoodQuality = true; + if (doCutQuality.value && TESTBIT(statusProng, CandidateType::CandCascadeBachelor)) { + if (useIsGlobalTrackForBachLfCasc) { + if (!hfTrack.isGlobalTrack()) { + hasGoodQuality = false; + } + } else if (useIsGlobalTrackWoDCAForBachLfCasc) { + if (!hfTrack.isGlobalTrackWoDCA()) { + hasGoodQuality = false; + } + } else if (useIsQualityTrackITSForBachLfCasc) { + if (!hfTrack.isQualityTrackITS()) { + hasGoodQuality = false; + } + } else { // selections for Run2 converted data + UChar_t clustermap = hfTrack.itsClusterMap(); + if (!(TESTBIT(hfTrack.flags(), o2::aod::track::ITSrefit) && (TESTBIT(clustermap, 0) || TESTBIT(clustermap, 1)))) { + hasGoodQuality = false; + } + } + if (!hasGoodQuality) { + CLRBIT(statusProng, CandidateType::CandCascadeBachelor); + if (fillHistograms) { + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } + } + } + // DCA cut iCut = 5; if (statusProng > 0) { @@ -741,6 +799,12 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.fill(HIST("hDCAToPrimXYVsPtCutsSoftPionForDstar"), trackPt, dca[0]); registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandDstar + iCut); } + if (TESTBIT(statusProng, CandidateType::CandCascadeBachelor)) { + registry.fill(HIST("hPtCutsCascadeBachelor"), trackPt); + registry.fill(HIST("hEtaCutsCascadeBachelor"), trackEta); + registry.fill(HIST("hDCAToPrimXYVsPtCutsCascadeBachelor"), trackPt, dca[0]); + registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandCascadeBachelor + iCut); + } } } @@ -3433,7 +3497,7 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag = 0; - if (!TESTBIT(trackIdPion1.isSelProng(), CandidateType::CandV0bachelor)) { + if (!TESTBIT(trackIdPion1.isSelProng(), CandidateType::CandCascadeBachelor)) { continue; } @@ -3529,7 +3593,7 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag = 0; - if (!TESTBIT(trackIdPion2.isSelProng(), CandidateType::CandV0bachelor)) { + if (!TESTBIT(trackIdPion2.isSelProng(), CandidateType::CandCascadeBachelor)) { continue; } From 586b3d126dd4b68cf808ac9e5f10eb3fc9c18886 Mon Sep 17 00:00:00 2001 From: Zhiyong <71517277+Luzhiyongg@users.noreply.github.com> Date: Sun, 10 Dec 2023 03:59:58 +0800 Subject: [PATCH 017/156] PWGCF: upload PbPb flow analysis for hyperloop (#4088) * upload PbPb flow analysis for hyperloop * format source file with git-clang-format * fix the error informed by MegaLinter * add a new line at the end of file according to MegaLinter * remove commented lines * Use TList to store Bootstrap samples * move up according to MegaLinter * simplify code with return pointers of registry.add --- PWGCF/Flow/Tasks/CMakeLists.txt | 6 + PWGCF/Flow/Tasks/FlowPbPbTask.cxx | 381 ++++++++++++++++++++++++++++++ 2 files changed, 387 insertions(+) create mode 100644 PWGCF/Flow/Tasks/FlowPbPbTask.cxx diff --git a/PWGCF/Flow/Tasks/CMakeLists.txt b/PWGCF/Flow/Tasks/CMakeLists.txt index 997f5024e29..b6e1291b1f2 100644 --- a/PWGCF/Flow/Tasks/CMakeLists.txt +++ b/PWGCF/Flow/Tasks/CMakeLists.txt @@ -13,3 +13,9 @@ o2physics_add_dpl_workflow(flow-pt-efficiency SOURCES flowPtEfficiency.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flow-pbpb-task + SOURCES FlowPbPbTask.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) + diff --git a/PWGCF/Flow/Tasks/FlowPbPbTask.cxx b/PWGCF/Flow/Tasks/FlowPbPbTask.cxx new file mode 100644 index 00000000000..e5114c20774 --- /dev/null +++ b/PWGCF/Flow/Tasks/FlowPbPbTask.cxx @@ -0,0 +1,381 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/DataModel/EventSelection.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" + +#include "GFWPowerArray.h" +#include "GFW.h" +#include "GFWCumulant.h" +#include "FlowContainer.h" +#include "TList.h" +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +struct FlowPbPbTask { + + O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMin, float, 0.2f, "Minimal pT for poi tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMax, float, 10.0f, "Maximal pT for poi tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "Minimal pT for ref tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 3.0f, "Maximal pT for ref tracks") + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5, "Chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Use Nch for flow observables") + O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") + + ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; + ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; + ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; + ConfigurableAxis axisPtHist{"axisPtHist", {100, 0., 10.}, "pt axis for histograms"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.25, 0.30, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.20, 2.40, 2.60, 2.80, 3.00}, "pt axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "centrality axis for histograms"}; + + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); + + // Connect to ccdb + Service ccdb; + Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable url{"ccdb-url", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + + // Define output + OutputObj fFC{FlowContainer("FlowContainer")}; + HistogramRegistry registry{"registry"}; + + // define global variables + GFW* fGFW = new GFW(); + std::vector corrconfigs; + TAxis* fPtAxis; + TRandom3* fRndm = new TRandom3(0); + std::vector>> BootstrapArray; + + using aodCollisions = soa::Filtered>; + using aodTracks = soa::Filtered>; + + void init(InitContext const&) + { + ccdb->setURL(url.value); + ccdb->setCaching(true); + ccdb->setCreatedNotAfter(nolaterthan.value); + + // Add some output objects to the histogram registry + registry.add("hPhi", "", {HistType::kTH1D, {axisPhi}}); + registry.add("hEta", "", {HistType::kTH1D, {axisEta}}); + registry.add("hPt", "", {HistType::kTH1D, {axisPtHist}}); + registry.add("hVtxZ", "", {HistType::kTH1D, {axisVertex}}); + registry.add("hMult", "", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); + registry.add("hCent", "", {HistType::kTH1D, {{90, 0, 90}}}); + registry.add("hMeanPt", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("hMeanPtWithinGap08", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("c22_gap08_Weff", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("c22_gap08_trackMeanPt", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("PtVariance_partA_WithinGap08", "", {HistType::kTProfile, {axisMultiplicity}}); + registry.add("PtVariance_partB_WithinGap08", "", {HistType::kTProfile, {axisMultiplicity}}); + + // initial array + BootstrapArray.resize(cfgNbootstrap); + for (int i = 0; i < cfgNbootstrap; i++) { + // currently we have 5 TProfiles in each sub dir + BootstrapArray[i].resize(5); + } + for (int i = 0; i < cfgNbootstrap; i++) { + BootstrapArray[i][0] = std::get>(registry.add(Form("BootstrapContainer_%d/hMeanPtWithinGap08", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][1] = std::get>(registry.add(Form("BootstrapContainer_%d/c22_gap08_Weff", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][2] = std::get>(registry.add(Form("BootstrapContainer_%d/c22_gap08_trackMeanPt", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][3] = std::get>(registry.add(Form("BootstrapContainer_%d/PtVariance_partA_WithinGap08", i), "", {HistType::kTProfile, {axisMultiplicity}})); + BootstrapArray[i][4] = std::get>(registry.add(Form("BootstrapContainer_%d/PtVariance_partB_WithinGap08", i), "", {HistType::kTProfile, {axisMultiplicity}})); + } + + o2::framework::AxisSpec axis = axisPt; + int nPtBins = axis.binEdges.size() - 1; + double* PtBins = &(axis.binEdges)[0]; + fPtAxis = new TAxis(nPtBins, PtBins); + + // add in FlowContainer to Get boostrap sample automatically + TObjArray* oba = new TObjArray(); + oba->Add(new TNamed("ChGap22", "ChGap22")); + for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("ChGap22_pt_%i", i + 1), "ChGap22_pTDiff")); + oba->Add(new TNamed("ChFull22", "ChFull22")); + oba->Add(new TNamed("ChFull32", "ChFull32")); + oba->Add(new TNamed("ChFull42", "ChFull42")); + oba->Add(new TNamed("ChFull24", "ChFull24")); + oba->Add(new TNamed("ChFull26", "ChFull26")); + oba->Add(new TNamed("Ch04Gap22", "Ch04Gap22")); + oba->Add(new TNamed("Ch06Gap22", "Ch06Gap22")); + oba->Add(new TNamed("Ch08Gap22", "Ch08Gap22")); + oba->Add(new TNamed("Ch10Gap22", "Ch10Gap22")); + oba->Add(new TNamed("Ch04Gap32", "Ch04Gap32")); + oba->Add(new TNamed("Ch06Gap32", "Ch06Gap32")); + oba->Add(new TNamed("Ch08Gap32", "Ch08Gap32")); + oba->Add(new TNamed("Ch10Gap32", "Ch10Gap32")); + oba->Add(new TNamed("Ch04Gap42", "Ch04Gap42")); + oba->Add(new TNamed("Ch06Gap42", "Ch06Gap42")); + oba->Add(new TNamed("Ch08Gap42", "Ch08Gap42")); + oba->Add(new TNamed("Ch10Gap42", "Ch10Gap42")); + oba->Add(new TNamed("ChFull422", "ChFull422")); + oba->Add(new TNamed("Ch04GapA422", "Ch04GapA422")); + oba->Add(new TNamed("Ch04GapB422", "Ch04GapB422")); + oba->Add(new TNamed("Ch10GapA422", "Ch10GapA422")); + oba->Add(new TNamed("Ch10GapB422", "Ch10GapB422")); + oba->Add(new TNamed("ChFull3232", "ChFull3232")); + oba->Add(new TNamed("ChFull4242", "ChFull4242")); + oba->Add(new TNamed("Ch04Gap3232", "Ch04Gap3232")); + oba->Add(new TNamed("Ch04Gap4242", "Ch04Gap4242")); + oba->Add(new TNamed("Ch04Gap24", "Ch04Gap24")); + oba->Add(new TNamed("Ch10Gap3232", "Ch10Gap3232")); + oba->Add(new TNamed("Ch10Gap4242", "Ch10Gap4242")); + oba->Add(new TNamed("Ch10Gap24", "Ch10Gap24")); + fFC->SetName("FlowContainer"); + fFC->SetXAxis(fPtAxis); + fFC->Initialize(oba, axisMultiplicity, cfgNbootstrap); + delete oba; + + // eta region + fGFW->AddRegion("full", -0.8, 0.8, 1, 1); + fGFW->AddRegion("refN04", -0.8, -0.2, 1, 1); // gap4 negative region + fGFW->AddRegion("refP04", 0.2, 0.8, 1, 1); // gap4 positve region + fGFW->AddRegion("refN06", -0.8, -0.3, 1, 1); // gap6 negative region + fGFW->AddRegion("refP06", 0.3, 0.8, 1, 1); // gap6 positve region + fGFW->AddRegion("refN08", -0.8, -0.4, 1, 1); + fGFW->AddRegion("refP08", 0.4, 0.8, 1, 1); + fGFW->AddRegion("refN10", -0.8, -0.5, 1, 1); + fGFW->AddRegion("refP10", 0.5, 0.8, 1, 1); + fGFW->AddRegion("refP", 0.4, 0.8, 1, 1); + fGFW->AddRegion("refN", -0.8, -0.4, 1, 1); + fGFW->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); + fGFW->AddRegion("olN", -0.8, -0.4, 1, 4); + + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {3 -3}", "ChFull32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 -4}", "ChFull42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 -2 -2}", "ChFull24", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 2 -2 -2 -2}", "ChFull26", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {2} refP04 {-2}", "Ch04Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN06 {2} refP06 {-2}", "Ch06Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ch08Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {2} refP10 {-2}", "Ch10Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {3} refP04 {-3}", "Ch04Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN06 {3} refP06 {-3}", "Ch06Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {3} refP08 {-3}", "Ch08Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {3} refP10 {-3}", "Ch10Gap32", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {4} refP04 {-4}", "Ch04Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN06 {4} refP06 {-4}", "Ch06Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {4} refP08 {-4}", "Ch08Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4} refP10 {-4}", "Ch10Gap42", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN {2} refP {-2}", "ChGap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN | olN {2} refP {-2}", "ChGap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 -2 -2}", "ChFull422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {-2 -2} refP04 {4}", "Ch04GapA422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {4} refP04 {-2 -2}", "Ch04GapB422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {-2 -2} refP10 {4}", "Ch10GapA422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4} refP10 {-2 -2}", "Ch10GapB422", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {3 2 -3 -2}", "ChFull3232", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {4 2 -4 -2}", "ChFull4242", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {3 2} refP04 {-3 -2}", "Ch04Gap3232", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {4 2} refP04 {-4 -2}", "Ch04Gap4242", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN04 {2 2} refP04 {-2 -2}", "Ch04Gap24", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {3 2} refP10 {-3 -2}", "Ch10Gap3232", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4 2} refP10 {-4 -2}", "Ch10Gap4242", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {2 2} refP10 {-2 -2}", "Ch10Gap24", kFALSE)); + fGFW->CreateRegions(); + } + + template + void FillProfile(const GFW::CorrConfig& corrconf, const ConstStr& tarName, const double& cent) + { + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + registry.fill(tarName, cent, val, dnx); + return; + } + return; + } + + template + void FillpTvnProfile(const GFW::CorrConfig& corrconf, const double& sum_pt, const double& WeffEvent, const ConstStr& vnWeff, const ConstStr& vnpT, const double& cent) + { + double meanPt = sum_pt / WeffEvent; + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) { + registry.fill(vnWeff, cent, val, dnx * WeffEvent); + registry.fill(vnpT, cent, val * meanPt, dnx * WeffEvent); + } + return; + } + return; + } + + void FillpTvnProfile(const GFW::CorrConfig& corrconf, const double& sum_pt, const double& WeffEvent, std::shared_ptr vnWeff, std::shared_ptr vnpT, const double& cent) + { + double meanPt = sum_pt / WeffEvent; + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) { + vnWeff->Fill(cent, val, dnx * WeffEvent); + vnpT->Fill(cent, val * meanPt, dnx * WeffEvent); + } + return; + } + return; + } + + void FillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) + { + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + return; + } + for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { + dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); + if (dnx == 0) + continue; + val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + } + return; + } + + void process(aodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, aodTracks const& tracks) + { + int Ntot = tracks.size(); + if (Ntot < 1) + return; + float l_Random = fRndm->Rndm(); + float vtxz = collision.posZ(); + registry.fill(HIST("hVtxZ"), vtxz); + registry.fill(HIST("hMult"), Ntot); + registry.fill(HIST("hCent"), collision.centFT0C()); + fGFW->Clear(); + const auto cent = collision.centFT0C(); + float weff = 1, wacc = 1; + double weffEvent = 0, waccEvent = 0; + int TrackNum = 0; + double ptSum = 0., ptSum_Gap08 = 0.; + double weffEvent_WithinGap08 = 0., weffEventSquare_WithinGap08 = 0.; + double sum_ptSquare_wSquare_WithinGap08 = 0., sum_pt_wSquare_WithinGap08 = 0.; + + for (auto& track : tracks) { + double pt = track.pt(); + double eta = track.eta(); + bool WithinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range + bool WithinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range + bool WithinEtaGap08 = (eta >= -0.4) && (eta <= 0.4); + if (WithinPtRef) { + registry.fill(HIST("hPhi"), track.phi()); + registry.fill(HIST("hEta"), track.eta()); + registry.fill(HIST("hPt"), pt); + weffEvent += weff; + waccEvent += wacc; + ptSum += weff * pt; + TrackNum++; + if (WithinEtaGap08) { + ptSum_Gap08 += weff * pt; + sum_pt_wSquare_WithinGap08 += weff * weff * pt; + sum_ptSquare_wSquare_WithinGap08 += weff * weff * pt * pt; + weffEvent_WithinGap08 += weff; + weffEventSquare_WithinGap08 += weff * weff; + } + } + if (WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 1); + if (WithinPtPOI) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 2); + if (WithinPtPOI && WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 4); + } + + double WeffEvent_diff_WithGap08 = weffEvent_WithinGap08 * weffEvent_WithinGap08 - weffEventSquare_WithinGap08; + // Filling TProfile + // MeanPt + registry.fill(HIST("hMeanPt"), cent, ptSum / weffEvent, weffEvent); + if (weffEvent_WithinGap08 > 1e-6) + registry.fill(HIST("hMeanPtWithinGap08"), cent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); + // v22-Pt + // c22_gap8 * pt_withGap8 + if (weffEvent_WithinGap08 > 1e-6) + FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, HIST("c22_gap08_Weff"), HIST("c22_gap08_trackMeanPt"), cent); + // PtVariance + if (WeffEvent_diff_WithGap08 > 1e-6) { + registry.fill(HIST("PtVariance_partA_WithinGap08"), cent, + (ptSum_Gap08 * ptSum_Gap08 - sum_ptSquare_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + registry.fill(HIST("PtVariance_partB_WithinGap08"), cent, + (weffEvent_WithinGap08 * ptSum_Gap08 - sum_pt_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + } + + // Filling Bootstrap Samples + int SampleIndex = static_cast(cfgNbootstrap * l_Random); + if (weffEvent_WithinGap08 > 1e-6) + BootstrapArray[SampleIndex][0]->Fill(cent, ptSum_Gap08 / weffEvent_WithinGap08, weffEvent_WithinGap08); + if (weffEvent_WithinGap08 > 1e-6) + FillpTvnProfile(corrconfigs.at(7), ptSum_Gap08, weffEvent_WithinGap08, BootstrapArray[SampleIndex][1], BootstrapArray[SampleIndex][2], cent); + if (WeffEvent_diff_WithGap08 > 1e-6) { + BootstrapArray[SampleIndex][3]->Fill(cent, + (ptSum_Gap08 * ptSum_Gap08 - sum_ptSquare_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + BootstrapArray[SampleIndex][4]->Fill(cent, + (weffEvent_WithinGap08 * ptSum_Gap08 - sum_pt_wSquare_WithinGap08) / WeffEvent_diff_WithGap08, + WeffEvent_diff_WithGap08); + } + + // Filling Flow Container + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + FillFC(corrconfigs.at(l_ind), cent, l_Random); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} From dcecb3d2a01a6981a064eeec0ddf7b39c0aebfd7 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Sun, 10 Dec 2023 15:37:02 +0900 Subject: [PATCH 018/156] PWGEM/PhotonMeson: replace collisionId with globalIndex (#4124) --- PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx | 16 ++++++++-------- PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx | 6 +++--- PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx | 14 +++++++------- PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx | 6 +++--- PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx | 14 +++++++------- PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx | 6 +++--- PWGEM/PhotonMeson/Tasks/gammaConversions.cxx | 8 ++++---- PWGEM/PhotonMeson/Tasks/pcmQC.cxx | 2 +- PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx | 2 +- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx index 75fc2b7c28c..0d1cf34a0c4 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx @@ -223,7 +223,7 @@ struct MaterialBudget { continue; } - auto photons_coll = photons.sliceBy(perCollision, collision.collisionId()); + auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { for (auto& photon : photons_coll) { @@ -272,8 +272,8 @@ struct MaterialBudget { o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); double value[9] = {0.f}; float phi_cp1 = 0.f, eta_cp1 = 0.f; @@ -337,11 +337,11 @@ struct MaterialBudget { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); - auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.collisionId()); - auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.collisionId()); + auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); + auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); @@ -361,7 +361,7 @@ struct MaterialBudget { if (!IsSelectedPair(g1, g2, cut1, cut2)) { continue; } - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); for (auto& paircut : paircuts) { diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx index e00e2b6a655..50f50a861d1 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx @@ -230,7 +230,7 @@ struct MaterialBudgetMC { continue; } - auto photons_coll = photons.sliceBy(perCollision, collision.collisionId()); + auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { for (auto& photon : photons_coll) { @@ -298,8 +298,8 @@ struct MaterialBudgetMC { o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); double value[9] = {0.f}; float phi_cp1 = 0.f, eta_cp1 = 0.f; diff --git a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx index 5fb510613e5..05ea3174187 100644 --- a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx +++ b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx @@ -241,8 +241,8 @@ struct PhotonHBT { reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); if constexpr (pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) { for (auto& cut : cuts1) { @@ -324,11 +324,11 @@ struct PhotonHBT { THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); - auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.collisionId()); - auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.collisionId()); + auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); + auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); @@ -336,7 +336,7 @@ struct PhotonHBT { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx index faf20554f33..bf6a17708bf 100644 --- a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx +++ b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx @@ -513,8 +513,8 @@ struct Pi0EtaToGammaGamma { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); @@ -525,7 +525,7 @@ struct Pi0EtaToGammaGamma { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx index a411c4c1dc0..fc22b3a3283 100644 --- a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx +++ b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx @@ -256,8 +256,8 @@ struct TagAndProbe { reinterpret_cast(list_ev_pair->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.collisionId()); - auto photons2_coll = photons2.sliceBy(perCollision2, collision.collisionId()); + auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); + auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); for (auto& g1 : photons1_coll) { @@ -334,11 +334,11 @@ struct TagAndProbe { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); - auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.collisionId()); - auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.collisionId()); + auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); + auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); @@ -357,7 +357,7 @@ struct TagAndProbe { } } for (auto& g2 : photons_coll2) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); for (auto& paircut : paircuts) { if (!paircut.IsSelected(g1, g2)) { diff --git a/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx b/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx index 6646f303633..ad7ed63220d 100644 --- a/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx +++ b/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx @@ -401,8 +401,8 @@ struct TaggingPi0 { // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - // LOGF(info, "Mixed event collisionId: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", - // collision1.collisionId(), collision2.collisionId(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); + // LOGF(info, "Mixed event globalIndex: (%d, %d) , counter = %d, ngpcm: (%d, %d), ngphos: (%d, %d), ngemc: (%d, %d)", + // collision1.globalIndex(), collision2.globalIndex(), nev, collision1.ngpcm(), collision2.ngpcm(), collision1.ngphos(), collision2.ngphos(), collision1.ngemc(), collision2.ngemc()); auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); @@ -413,7 +413,7 @@ struct TaggingPi0 { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { - // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.collisionId(), g2.collisionId()); + // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx b/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx index b3e68613763..8c773a63d6e 100644 --- a/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx +++ b/PWGEM/PhotonMeson/Tasks/gammaConversions.cxx @@ -35,7 +35,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using V0DatasAdditional = soa::Join; +using V0DatasAdditional = soa::Join; using V0LegsWithMC = soa::Join; // using collisionEvSelIt = soa::Join::iterator; @@ -608,7 +608,7 @@ struct GammaConversions { } } - Preslice perCollision = aod::v0photonkf::collisionId; + Preslice perCollision = aod::v0photonkf::emreducedeventId; void processRec(aod::EMReducedEvents::iterator const& theCollision, V0DatasAdditional const& theV0s, aod::V0Legs const& theAllTracks) @@ -617,7 +617,7 @@ struct GammaConversions { "hCollisionZ", theCollision.posZ()); - auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.collisionId()); + auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.globalIndex()); for (auto& lV0 : theV0s_per_coll) { float lV0CosinePA = lV0.cospa(); @@ -644,7 +644,7 @@ struct GammaConversions { "hCollisionZ", theCollision.posZ()); - auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.collisionId()); + auto theV0s_per_coll = theV0s.sliceBy(perCollision, theCollision.globalIndex()); for (auto& lV0 : theV0s) { float lV0CosinePA = lV0.cospa(); diff --git a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx index bebbcf202ee..2f43896b1de 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx @@ -154,7 +154,7 @@ struct PCMQC { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_after"))->Fill(collision.posZ()); o2::aod::emphotonhistograms::FillHistClass(list_ev, "", collision); - auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.collisionId()); + auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.globalIndex()); for (const auto& cut : fPCMCuts) { THashList* list_v0_cut = static_cast(list_v0->FindObject(cut.GetName())); THashList* list_v0leg_cut = static_cast(list_v0leg->FindObject(cut.GetName())); diff --git a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx index deacc5a0af1..c34d0d1bb30 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx @@ -160,7 +160,7 @@ struct PCMQCMC { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hCollisionCounter"))->Fill(4.0); reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_after"))->Fill(collision.posZ()); o2::aod::emphotonhistograms::FillHistClass(list_ev, "", collision); - auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.collisionId()); + auto V0Photons_coll = v0photons.sliceBy(perCollision, collision.globalIndex()); for (const auto& cut : fPCMCuts) { THashList* list_v0_cut = static_cast(list_v0->FindObject(cut.GetName())); From e27a5ff882b2c24a05135e8b752472bf3bb27fa4 Mon Sep 17 00:00:00 2001 From: Jochen Klein Date: Sun, 10 Dec 2023 14:47:36 +0100 Subject: [PATCH 019/156] Add track cuts for pions associated to ST cascades (#4117) --- PWGHF/TableProducer/treeCreatorOmegacSt.cxx | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index 67732cea60e..efc542f76cc 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -34,6 +34,7 @@ #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelection.h" #include "Common/DataModel/TrackSelectionTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGHF/Core/SelectorCuts.h" @@ -172,6 +173,7 @@ struct HfTreeCreatorOmegacSt { Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; Configurable minNoClsTrackedCascade{"minNoClsTrackedCascade", 70, "Minimum number of clusters required for daughters of tracked cascades"}; + Configurable minNoClsTrackedPion{"minNoClsTrackedPion", 70, "Minimum number of clusters required for associated pions"}; Configurable massWindowTrackedOmega{"massWindowTrackedOmega", 0.05, "Inv. mass window for tracked Omega"}; Configurable massWindowXiExclTrackedOmega{"massWindowXiExclTrackedOmega", 0.005, "Inv. mass window for exclusion of Xi for tracked Omega-"}; Configurable massWindowTrackedXi{"massWindowTrackedXi", 0., "Inv. mass window for tracked Xi"}; @@ -190,11 +192,13 @@ struct HfTreeCreatorOmegacSt { Service ccdb; o2::vertexing::DCAFitterN<2> df2; + TrackSelection trackSelector; + bool bzOnly = true; float bz = 0.; int runNumber{0}; - using TracksExt = soa::Join; + using TracksExt = soa::Join; using TracksExtMc = soa::Join; HistogramRegistry registry{ @@ -235,6 +239,19 @@ struct HfTreeCreatorOmegacSt { o2::base::Propagator::Instance(true)->setMatLUT(lut); } + trackSelector.SetTrackType(o2::aod::track::TrackTypeEnum::Track); + trackSelector.SetEtaRange(-.9, .9); + trackSelector.SetRequireITSRefit(true); + trackSelector.SetRequireTPCRefit(true); + trackSelector.SetRequireGoldenChi2(false); + trackSelector.SetMinNCrossedRowsTPC(minNoClsTrackedPion); + trackSelector.SetMinNCrossedRowsOverFindableClustersTPC(0.8f); + trackSelector.SetMaxChi2PerClusterTPC(4.f); + trackSelector.SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any of the first three layers of IB + trackSelector.SetMaxChi2PerClusterITS(36.f); + trackSelector.SetMaxDcaXY(1.f); + trackSelector.SetMaxDcaZ(2.f); + df2.setPropagateToPCA(propToDCA); df2.setMaxR(maxR); df2.setMaxDZIni(maxDZIni); @@ -392,7 +409,8 @@ struct HfTreeCreatorOmegacSt { trackId == bachelor.globalIndex()) { continue; } - if (std::abs(track.tpcNSigmaPi()) < maxNSigmaPion) { + if (trackSelector.IsSelected(track) && + (std::abs(track.tpcNSigmaPi()) < maxNSigmaPion)) { LOGF(debug, " .. combining with pion candidate %d", track.globalIndex()); auto trackParCovCasc = getTrackParCov(trackCasc); auto trackParCovPion = getTrackParCov(track); From 4a5bf2814fe522c0483475d37c6bdd0a5d9b81c1 Mon Sep 17 00:00:00 2001 From: sofiatomassini <122356048+sofiatomassini@users.noreply.github.com> Date: Sun, 10 Dec 2023 17:45:23 +0100 Subject: [PATCH 020/156] adding new column and filters (#4104) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adding new column and filters * Update singletrackselector.h fixing formatting * Update singletrackselector.h new formatting for singletrackselector.h * Update singletrackselector.h formatting * Update singletrackselector.h formatting again * Update singletrackselector.h * Update singletrackselector.h * Update singletrackselector.h * Update singletrackselector.h * Update singletrackselector.h * Update singletrackselector.h * Update singleTrackSelector.cxx * Update singleTrackSelector.cxx --------- Co-authored-by: Nicolò Jacazio --- PWGCF/Femto3D/DataModel/singletrackselector.h | 104 ++++++++++-------- .../TableProducer/singleTrackSelector.cxx | 15 ++- 2 files changed, 68 insertions(+), 51 deletions(-) mode change 100644 => 100755 PWGCF/Femto3D/DataModel/singletrackselector.h mode change 100644 => 100755 PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx diff --git a/PWGCF/Femto3D/DataModel/singletrackselector.h b/PWGCF/Femto3D/DataModel/singletrackselector.h old mode 100644 new mode 100755 index 4a7f8b50251..91dfb63e856 --- a/PWGCF/Femto3D/DataModel/singletrackselector.h +++ b/PWGCF/Femto3D/DataModel/singletrackselector.h @@ -30,8 +30,9 @@ namespace o2::aod { namespace singletrackselector { + template -typename binningType::binned_t packInTable(const float& valueToBin) +inline typename binningType::binned_t packInTable(const float& valueToBin) { if (valueToBin <= binningType::binned_min) { return binningType::underflowBin; @@ -39,16 +40,13 @@ typename binningType::binned_t packInTable(const float& valueToBin) return binningType::overflowBin; } else { return static_cast(valueToBin / binningType::bin_width); - // return static_cast(((valueToBin - (binningType::binned_max - binningType::binned_min) * 0.5) / binningType::bin_width)); } } template -float unPack(const typename binningType::binned_t& b) +inline float unPack(const typename binningType::binned_t& b) { return static_cast(binningType::bin_width * b); - - // return static_cast((binningType::binned_max - binningType::binned_min) * 0.5 + binningType::bin_width * b); } namespace nsigma @@ -65,15 +63,17 @@ struct binning { }; } // namespace nsigma -DECLARE_SOA_COLUMN(Mult, mult, int); // Multiplicity of the collision -DECLARE_SOA_COLUMN(PosZ, posZ, float); // Vertex of the collision -DECLARE_SOA_COLUMN(MagField, magField, float); // Magnetic field corresponding to a collision (in T) +DECLARE_SOA_COLUMN(Mult, mult, int); // Multiplicity of the collision +DECLARE_SOA_COLUMN(MultPercentile, multPerc, float); // Percentiles of multiplicity of the collision +DECLARE_SOA_COLUMN(PosZ, posZ, float); // Vertex of the collision +DECLARE_SOA_COLUMN(MagField, magField, float); // Magnetic field corresponding to a collision (in T) } // namespace singletrackselector DECLARE_SOA_TABLE(SingleCollSels, "AOD", "SINGLECOLLSEL", // Table of the variables for single track selection. o2::soa::Index<>, singletrackselector::Mult, + singletrackselector::MultPercentile, singletrackselector::PosZ, singletrackselector::MagField); @@ -101,37 +101,40 @@ DECLARE_SOA_COLUMN(StoredTPCNSigmaPr, storedTpcNSigmaPr, nsigma::binning::binned DECLARE_SOA_COLUMN(StoredTOFNSigmaDe, storedTofNSigmaDe, nsigma::binning::binned_t); DECLARE_SOA_COLUMN(StoredTPCNSigmaDe, storedTpcNSigmaDe, nsigma::binning::binned_t); -DECLARE_SOA_DYNAMIC_COLUMN(Energy, energy, - [](float p, float mass) -> float { return sqrt(p * p + mass * mass); }); -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, - [](float p, float eta) -> float { return p / std::cosh(eta); }); -DECLARE_SOA_DYNAMIC_COLUMN(Px, px, - [](float p, float eta, float phi) -> float { return (p / std::cosh(eta)) * std::sin(phi); }); -DECLARE_SOA_DYNAMIC_COLUMN(Py, py, - [](float p, float eta, float phi) -> float { return (p / std::cosh(eta)) * std::cos(phi); }); -DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, - [](float p, float eta) -> float { return p * std::tanh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(Energy, energy, [](float p, float mass) -> float { return sqrt(p * p + mass * mass); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float p, float eta) -> float { return p / std::cosh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, [](float p, float eta, float phi) -> float { return (p / std::cosh(eta)) * std::sin(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, [](float p, float eta, float phi) -> float { return (p / std::cosh(eta)) * std::cos(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, [](float p, float eta) -> float { return p * std::tanh(eta); }); DECLARE_SOA_DYNAMIC_COLUMN(PhiStar, phiStar, [](float p, float eta, float sign, float phi, float magfield = 0.0, float radius = 1.6) -> float { if (magfield == 0.0) { - return -1000.0f; + return -1000.0; } else { return phi + std::asin(-0.3 * magfield * sign * radius / (2.0 * p / std::cosh(eta))); } }); DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaPr, tofNSigmaPr, - [](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); + [](nsigma::binning::binned_t nsigma_binned) -> float { + return singletrackselector::unPack(nsigma_binned); + }); DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaPr, tpcNSigmaPr, - [](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); + [](nsigma::binning::binned_t nsigma_binned) -> float { + return singletrackselector::unPack(nsigma_binned); + }); DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaDe, tofNSigmaDe, - [](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); + [](nsigma::binning::binned_t nsigma_binned) -> float { + return singletrackselector::unPack(nsigma_binned); + }); DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaDe, tpcNSigmaDe, - [](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); + [](nsigma::binning::binned_t nsigma_binned) -> float { + return singletrackselector::unPack(nsigma_binned); + }); } // namespace singletrackselector -DECLARE_SOA_TABLE_FULL(SingleTrackSels, "SingleTrackSels", "AOD", "SINGLETRACKSEL", // Table of the variables for single track selection. +DECLARE_SOA_TABLE_FULL(SingleTrackSels, "SelTracks", "AOD", "SINGLETRACKSEL", // Table of the variables for single track selection. o2::soa::Index<>, singletrackselector::SingleCollSelId, singletrackselector::P, @@ -173,48 +176,53 @@ namespace o2::aod::singletrackselector template inline bool TPCselection(TrackType const& track, std::pair> const& PIDcuts) { - // add check for the size of the vector and order of the values??? must be 2 valies in order => [down, up] - float Nsigma = -1000; - if (PIDcuts.first == 2212) { - Nsigma = track.tpcNSigmaPr(); - } - if (PIDcuts.first == 1000010020) { - Nsigma = track.tpcNSigmaDe(); + switch (PIDcuts.first) { + case 2212: + Nsigma = track.tpcNSigmaPr(); + break; + case 1000010020: + Nsigma = track.tpcNSigmaDe(); + break; + default: + LOG(fatal) << "Cannot interpret PDG for TPC selection: " << PIDcuts.first; } if (Nsigma > PIDcuts.second[0] && Nsigma < PIDcuts.second[1]) { return true; - } else { - return false; } + return false; } template inline bool TOFselection(TrackType const& track, std::pair> const& PIDcuts) { - // add check for the size of the vector and order of the values??? must be 2 valies in order => [down, up] - float Nsigma = -1000; - if (PIDcuts.first == 2212) { - Nsigma = track.tofNSigmaPr(); - } else if (PIDcuts.first == 1000010020) { - Nsigma = track.tofNSigmaDe(); - } else if (PIDcuts.first == 211) { - if constexpr (std::experimental::is_detected::value) - Nsigma = track.tofNSigmaPi(); - } else if (PIDcuts.first == 321) { - if constexpr (std::experimental::is_detected::value) { - Nsigma = track.tofNSigmaKa(); - } + switch (PIDcuts.first) { + case 2212: + Nsigma = track.tofNSigmaPr(); + break; + case 1000010020: + Nsigma = track.tofNSigmaDe(); + break; + case 211: + if constexpr (std::experimental::is_detected::value) { + Nsigma = track.tofNSigmaPi(); + } + case 321: + if constexpr (std::experimental::is_detected::value) { + Nsigma = track.tofNSigmaKa(); + } + default: + LOG(fatal) << "Cannot interpret PDG for TOF selection: " << PIDcuts.first; } if (Nsigma > PIDcuts.second[0] && Nsigma < PIDcuts.second[1]) { return true; - } else { - return false; } + return false; } + } // namespace o2::aod::singletrackselector diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx old mode 100644 new mode 100755 index 4f324909019..4ebc3723246 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -26,7 +26,7 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" +#include "Common/DataModel/Centrality.h" #include "DetectorsBase/Propagator.h" #include "DataFormatsParameters/GRPObject.h" @@ -55,12 +55,18 @@ struct singleTrackSelector { Configurable> _particlesToReject{"particlesToRejectPDGs", std::vector{}, "PDG codes of perticles that will be rejected with TOF (only pion, kaon, proton and deurton are supported now)"}; Configurable> rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-5.0f, 5.0f}, "TOF rejection Nsigma range for particles specified with PDG to be rejected"}; + Configurable _tpcNClsFound{"tpcNClsFound", 70, "Minimun number of cluster found in TPC"}; + Configurable _itsNCls{"itsNCls", 0, "Minimun number of cluster found in ITS"}; + Configurable _tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0.f, "Minimun number of crossed rows over findable clusters"}; + Configurable _dcaXY{"dcaXY", 1000.f, "Maximum dca of track in xy"}; + Configurable _dcaZ{"dcaZ", 1000.f, "Maximum dca of track in xy"}; + using Trks = soa::Join; - using Coll = soa::Join; + using Coll = soa::Join; Produces tableRow; Produces tableRowColl; @@ -70,6 +76,9 @@ struct singleTrackSelector { ((applyEvSel.node() == 2) && (aod::evsel::sel8 == true)); Filter vertexFilter = ((o2::aod::collision::posZ < 15.f) && (o2::aod::collision::posZ > -15.f)); Filter trackFilter = ((o2::aod::track::itsChi2NCl <= 36.f) && (o2::aod::track::itsChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl <= 4.f)); + Filter tpcFilter = ((o2::aod::singletrackselector::tpcNClsFound >= _tpcNClsFound) && (o2::aod::singletrackselector::tpcCrossedRowsOverFindableCls >= _tpcCrossedRowsOverFindableCls)); + Filter itsFilter = (o2::aod::singletrackselector::itsNCls >= _itsNCls); + Filter dcaFilter = (o2::aod::track::dcaXY <= _dcaXY) && (o2::aod::track::dcaZ <= _dcaZ); int mRunNumber = 0; float d_bz = 0.f; @@ -122,13 +131,13 @@ struct singleTrackSelector { { bool skip_track = false; // flag used for track rejection - tableRow.reserve(tracks.size()); auto bc = collision.bc_as(); initCCDB(bc); tableRowColl(collision.multTPC(), + collision.centFT0M(), collision.posZ(), d_bz); From ade492490f600064fecc5332c22fd095a586f7c5 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Sun, 10 Dec 2023 22:45:55 +0100 Subject: [PATCH 021/156] added reweighting for efficiency (#4126) --- PWGLF/Tasks/nuclei_in_jets.cxx | 179 ++++++++++++++++++++++++++------- 1 file changed, 140 insertions(+), 39 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index c7cfcf02636..5a882f3b3cf 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -100,11 +100,20 @@ struct nuclei_in_jets { Configurable min_nsigmaTOF{"min_nsigmaTOF", -3.0f, "Minimum nsigma TOF"}; Configurable max_nsigmaTOF{"max_nsigmaTOF", +3.5f, "Maximum nsigma TOF"}; Configurable require_primVtx_contributor{"require_primVtx_contributor", true, "require that the track is a PV contributor"}; + Configurable> param_proton_jet{"param_proton_jet", {0.93827208816, 0.18, 0.5, 1}, "Parameters for reweighting protons in jets"}; + Configurable> param_deuteron_jet{"param_deuteron_jet", {1.87561294257, 0.18, 0.5, 1}, "Parameters for reweighting deuterons in jets"}; + Configurable> param_helium3_jet{"param_helium3_jet", {2.80839160743, 0.18, 0.5, 1}, "Parameters for reweighting helium3 in jets"}; + Configurable> param_proton_ue{"param_proton_ue", {0.93827208816, 0.18, 0.5, 1}, "Parameters for reweighting protons in ue"}; + Configurable> param_deuteron_ue{"param_deuteron_ue", {1.87561294257, 0.18, 0.5, 1}, "Parameters for reweighting deuterons in ue"}; + Configurable> param_helium3_ue{"param_helium3_ue", {2.80839160743, 0.18, 0.5, 1}, "Parameters for reweighting helium3 in ue"}; // List of Particles - enum particle { proton, - deuteron, - helium }; + enum nucleus { proton, + deuteron, + helium }; + + enum region { jet, + underlying_event }; void init(InitContext const&) { @@ -138,18 +147,26 @@ struct nuclei_in_jets { registryData.add("antihelium3_ue_tpc", "antihelium3_ue_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); // Generated - registryMC.add("antiproton_gen", "antiproton_gen", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_gen", "antideuteron_gen", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antihelium3_gen", "antihelium3_gen", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_jet_gen", "antiproton_jet_gen", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_jet_gen", "antideuteron_jet_gen", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_jet_gen", "antihelium3_jet_gen", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_ue_gen", "antiproton_ue_gen", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_ue_gen", "antideuteron_ue_gen", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_ue_gen", "antihelium3_ue_gen", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); // Reconstructed TPC - registryMC.add("antiproton_rec_tpc", "antiproton_rec_tpc", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_rec_tpc", "antideuteron_rec_tpc", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antihelium3_rec_tpc", "antihelium3_rec_tpc", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_jet_rec_tpc", "antiproton_jet_rec_tpc", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_jet_rec_tpc", "antideuteron_jet_rec_tpc", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_jet_rec_tpc", "antihelium3_jet_rec_tpc", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_ue_rec_tpc", "antiproton_ue_rec_tpc", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_ue_rec_tpc", "antideuteron_ue_rec_tpc", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_ue_rec_tpc", "antihelium3_ue_rec_tpc", HistType::kTH1F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}}); // Reconstructed TOF - registryMC.add("antiproton_rec_tof", "antiproton_rec_tof", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_rec_tof", "antideuteron_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_jet_rec_tof", "antiproton_jet_rec_tof", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_jet_rec_tof", "antideuteron_jet_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_ue_rec_tof", "antiproton_ue_rec_tof", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_ue_rec_tof", "antideuteron_ue_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); } // Single-Track Selection for the Particle of Interest @@ -181,11 +198,11 @@ struct nuclei_in_jets { // Rapidity Cut double mass(0); - if (particle_of_interest == 0) + if (particle_of_interest == nucleus::proton) mass = 0.93827208816; // Proton - if (particle_of_interest == 1) + if (particle_of_interest == nucleus::deuteron) mass = 1.87561294257; // Deuteron - if (particle_of_interest == 2) + if (particle_of_interest == nucleus::helium) mass = 2.80839160743; // Helium-3 TLorentzVector lorentzVect; @@ -242,7 +259,7 @@ struct nuclei_in_jets { return false; // Proton ID - if (particle_of_interest == particle::proton) { + if (particle_of_interest == nucleus::proton) { if (pt < 1.0 && TMath::Abs(nsigmaTPCPr) < 8.0) return true; if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && track.hasTOF() && TMath::Abs(nsigmaTOFPr) < 10.0) @@ -251,7 +268,7 @@ struct nuclei_in_jets { } // Deuteron ID - if (particle_of_interest == particle::deuteron) { + if (particle_of_interest == nucleus::deuteron) { if (pt < 1.0 && TMath::Abs(nsigmaTPCDe) < 8.0) return true; if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && track.hasTOF() && TMath::Abs(nsigmaTOFDe) < 10.0) @@ -260,7 +277,7 @@ struct nuclei_in_jets { } // Helium-3 ID - if (particle_of_interest == particle::helium) { + if (particle_of_interest == nucleus::helium) { if ((0.5 * pt) >= 1.0 && TMath::Abs(nsigmaTPCHe) < 8.0) return true; return false; @@ -281,6 +298,58 @@ struct nuclei_in_jets { return x_min; } + float Weight(float pt, int event_region, int nucleus_of_interest) + { + + auto par_proton_jet = static_cast>(param_proton_jet); + auto par_deuteron_jet = static_cast>(param_deuteron_jet); + auto par_helium3_jet = static_cast>(param_helium3_jet); + auto par_proton_ue = static_cast>(param_proton_ue); + auto par_deuteron_ue = static_cast>(param_deuteron_ue); + auto par_helium3_ue = static_cast>(param_helium3_ue); + + float dNdpt_proton_jet = GetTsallis(par_proton_jet[0], par_proton_jet[1], par_proton_jet[2], par_proton_jet[3], pt); + float dNdpt_proton_ue = GetTsallis(par_proton_ue[0], par_proton_ue[1], par_proton_ue[2], par_proton_ue[3], pt); + float dNdpt_deuteron_jet = GetTsallis(par_deuteron_jet[0], par_deuteron_jet[1], par_deuteron_jet[2], par_deuteron_jet[3], pt); + float dNdpt_deuteron_ue = GetTsallis(par_deuteron_ue[0], par_deuteron_ue[1], par_deuteron_ue[2], par_deuteron_ue[3], pt); + float dNdpt_helium3_jet = GetTsallis(par_helium3_jet[0], par_helium3_jet[1], par_helium3_jet[2], par_helium3_jet[3], pt); + float dNdpt_helium3_ue = GetTsallis(par_helium3_ue[0], par_helium3_ue[1], par_helium3_ue[2], par_helium3_ue[3], pt); + + if (nucleus_of_interest == nucleus::proton && event_region == region::jet) + return dNdpt_proton_jet; + if (nucleus_of_interest == nucleus::proton && event_region == region::underlying_event) + return dNdpt_proton_ue; + if (nucleus_of_interest == nucleus::deuteron && event_region == region::jet) + return dNdpt_deuteron_jet; + if (nucleus_of_interest == nucleus::deuteron && event_region == region::underlying_event) + return dNdpt_deuteron_ue; + if (nucleus_of_interest == nucleus::helium && event_region == region::jet) + return dNdpt_helium3_jet; + if (nucleus_of_interest == nucleus::helium && event_region == region::underlying_event) + return dNdpt_helium3_ue; + + return 1; + } + + float GetLevi(float mass, float temp, float n, float norm, float pt) + { + + float p0 = norm; + float p1 = n; + float p2 = temp; + float p3 = mass; + + float dNdpt = (pt * p0 * (p1 - 1) * (p1 - 2)) / (p1 * p2 * (p1 * p2 + p3 * (p1 - 2))) * TMath::Power((1 + (TMath::Sqrt(p3 * p3 + pt * pt) - p3) / (p1 * p2)), -p1); + + return dNdpt; + } + + float GetTsallis(float mass, float temp, float q, float norm, float pt) + { + + return GetLevi(mass, temp, 1 / (q - 1), norm, pt); + } + // Process Data void processData(SelectedCollisions::iterator const& collision, FullTracks const& tracks) { @@ -550,7 +619,7 @@ struct nuclei_in_jets { float pt = jet_track.pt(); // Antiproton - if (particle_of_interest == particle::proton) { + if (particle_of_interest == nucleus::proton) { if (pt < 1.0) registryData.fill(HIST("antiproton_jet_tpc"), pt, nsigmaTPCPr, jet_Nch); if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && jet_track.hasTOF()) @@ -558,7 +627,7 @@ struct nuclei_in_jets { } // Antideuteron - if (particle_of_interest == particle::deuteron) { + if (particle_of_interest == nucleus::deuteron) { if (pt < 1.0) registryData.fill(HIST("antideuteron_jet_tpc"), pt, nsigmaTPCDe, jet_Nch); if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && jet_track.hasTOF()) @@ -566,7 +635,7 @@ struct nuclei_in_jets { } // Antihelium3 - if (particle_of_interest == particle::helium) { + if (particle_of_interest == nucleus::helium) { registryData.fill(HIST("antihelium3_jet_tpc"), 2.0 * pt, nsigmaTPCHe, jet_Nch); } } @@ -591,7 +660,7 @@ struct nuclei_in_jets { float pt = ue_track.pt(); // Antiproton - if (particle_of_interest == particle::proton) { + if (particle_of_interest == nucleus::proton) { if (pt < 1.0) registryData.fill(HIST("antiproton_ue_tpc"), pt, nsigmaTPCPr, jet_Nch); if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && ue_track.hasTOF()) @@ -599,7 +668,7 @@ struct nuclei_in_jets { } // Antideuteron - if (particle_of_interest == particle::deuteron) { + if (particle_of_interest == nucleus::deuteron) { if (pt < 1.0) registryData.fill(HIST("antideuteron_ue_tpc"), pt, nsigmaTPCDe, jet_Nch); if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && ue_track.hasTOF()) @@ -607,7 +676,7 @@ struct nuclei_in_jets { } // Antihelium3 - if (particle_of_interest == particle::helium) { + if (particle_of_interest == nucleus::helium) { registryData.fill(HIST("antihelium3_ue_tpc"), 2.0 * pt, nsigmaTPCHe, jet_Nch); } } @@ -638,13 +707,27 @@ struct nuclei_in_jets { if (particle.y() < min_y || particle.y() > max_y) continue; + // Reweighting + float wpr_jet = Weight(particle.pt(), region::jet, nucleus::proton); + float wpr_ue = Weight(particle.pt(), region::underlying_event, nucleus::proton); + float wde_jet = Weight(particle.pt(), region::jet, nucleus::deuteron); + float wde_ue = Weight(particle.pt(), region::underlying_event, nucleus::deuteron); + float whe_jet = Weight(particle.pt(), region::jet, nucleus::helium); + float whe_ue = Weight(particle.pt(), region::underlying_event, nucleus::helium); + // Fill Histograms - if (particle.pdgCode() == -2212) - registryMC.fill(HIST("antiproton_gen"), particle.pt()); - if (particle.pdgCode() == -1000010020) - registryMC.fill(HIST("antideuteron_gen"), particle.pt()); - if (particle.pdgCode() == -1000020030) - registryMC.fill(HIST("antihelium3_gen"), particle.pt()); + if (particle.pdgCode() == -2212) { + registryMC.fill(HIST("antiproton_jet_gen"), particle.pt(), wpr_jet); + registryMC.fill(HIST("antiproton_ue_gen"), particle.pt(), wpr_ue); + } + if (particle.pdgCode() == -1000010020) { + registryMC.fill(HIST("antideuteron_jet_gen"), particle.pt(), wde_jet); + registryMC.fill(HIST("antideuteron_ue_gen"), particle.pt(), wde_ue); + } + if (particle.pdgCode() == -1000020030) { + registryMC.fill(HIST("antihelium3_jet_gen"), particle.pt(), whe_jet); + registryMC.fill(HIST("antihelium3_ue_gen"), particle.pt(), whe_ue); + } } for (auto track : mcTracks) { @@ -670,6 +753,14 @@ struct nuclei_in_jets { if (require_primVtx_contributor && !(track.isPVContributor())) continue; + // Reweighting + float wpr_jet = Weight(particle.pt(), region::jet, nucleus::proton); + float wpr_ue = Weight(particle.pt(), region::underlying_event, nucleus::proton); + float wde_jet = Weight(particle.pt(), region::jet, nucleus::deuteron); + float wde_ue = Weight(particle.pt(), region::underlying_event, nucleus::deuteron); + float whe_jet = Weight(particle.pt(), region::jet, nucleus::helium); + float whe_ue = Weight(particle.pt(), region::underlying_event, nucleus::helium); + // Variables float nsigmaTPCPr = track.tpcNSigmaPr(); float nsigmaTOFPr = track.tofNSigmaPr(); @@ -680,24 +771,34 @@ struct nuclei_in_jets { // Antiproton if (particle.pdgCode() != -2212) { - if (pt < 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC) - registryMC.fill(HIST("antiproton_rec_tpc"), pt); - if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && track.hasTOF() && nsigmaTOFPr > min_nsigmaTOF && nsigmaTOFPr < max_nsigmaTOF) - registryMC.fill(HIST("antiproton_rec_tof"), pt); + if (pt < 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC) { + registryMC.fill(HIST("antiproton_jet_rec_tpc"), pt, wpr_jet); + registryMC.fill(HIST("antiproton_ue_rec_tpc"), pt, wpr_ue); + } + if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && track.hasTOF() && nsigmaTOFPr > min_nsigmaTOF && nsigmaTOFPr < max_nsigmaTOF) { + registryMC.fill(HIST("antiproton_jet_rec_tof"), pt, wpr_jet); + registryMC.fill(HIST("antiproton_ue_rec_tof"), pt, wpr_ue); + } } // Antideuteron if (particle.pdgCode() != -1000010020) { - if (pt < 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC) - registryMC.fill(HIST("antideuteron_rec_tpc"), pt); - if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && track.hasTOF() && nsigmaTOFDe > min_nsigmaTOF && nsigmaTOFDe < max_nsigmaTOF) - registryMC.fill(HIST("antideuteron_rec_tof"), pt); + if (pt < 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC) { + registryMC.fill(HIST("antideuteron_jet_rec_tpc"), pt, wde_jet); + registryMC.fill(HIST("antideuteron_ue_rec_tpc"), pt, wde_ue); + } + if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && track.hasTOF() && nsigmaTOFDe > min_nsigmaTOF && nsigmaTOFDe < max_nsigmaTOF) { + registryMC.fill(HIST("antideuteron_jet_rec_tof"), pt, wde_jet); + registryMC.fill(HIST("antideuteron_ue_rec_tof"), pt, wde_ue); + } } // Antihelium-3 if (particle.pdgCode() != -1000020030) { - if (nsigmaTPCHe > min_nsigmaTPC && nsigmaTPCHe < max_nsigmaTPC) - registryMC.fill(HIST("antihelium3_rec_tpc"), 2.0 * pt); + if (nsigmaTPCHe > min_nsigmaTPC && nsigmaTPCHe < max_nsigmaTPC) { + registryMC.fill(HIST("antihelium3_jet_rec_tpc"), 2.0 * pt, whe_jet); + registryMC.fill(HIST("antihelium3_ue_rec_tpc"), 2.0 * pt, whe_ue); + } } } } From 9c1b332a13cfddd7a93aab79582c0a9f9d9dd088 Mon Sep 17 00:00:00 2001 From: Marvin Hemmer <53471402+mhemmer-cern@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:01:30 +0100 Subject: [PATCH 022/156] [EMC-1108] TrackMatching: Changed dEta and dPhi histograms to have SM as 3rd axix (#4125) - dEta and dPhi histograms now have as 3rd axis the SM index. Was the number of matched tracks per cluster previously. This also means, they are now only filled for the first, so the closested found matched track. This change is to help understand difference we see in mean dEta and dPhi from 0, e.g. is it coming from misalignment or from somewhere else. Ruben asked for these plots, to help with this. --- PWGJE/Tasks/emctmmonitor.cxx | 79 ++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/PWGJE/Tasks/emctmmonitor.cxx b/PWGJE/Tasks/emctmmonitor.cxx index af3891a8622..2fa9f597690 100644 --- a/PWGJE/Tasks/emctmmonitor.cxx +++ b/PWGJE/Tasks/emctmmonitor.cxx @@ -116,6 +116,7 @@ struct TrackMatchingMonitor { const o2Axis clusterptAxis{makePtBinning(), "#it{p}_{T}"}; const o2Axis etaAxis{160, -0.8, 0.8, "#eta"}; const o2Axis phiAxis{72, 0, 2 * 3.14159, "#varphi (rad)"}; + const o2Axis smAxis{20, -0.5, 19.5, "SM"}; o2Axis timeAxis{mClusterTimeBinning, "t_{cl} (ns)"}; int MaxMatched = 20; // maximum number of matched tracks, hardcoded in emcalCorrectionTask.cxx! @@ -138,20 +139,20 @@ struct TrackMatchingMonitor { mHistManager.add("MatchedTrackEtaPhi", "#eta vs #varphi of all selected matched tracks", o2HistType::kTH2F, {etaAxis, phiAxis}); // eta vs phi of all selected matched tracks mHistManager.add("MatchedTrackEtaPhi_Neg", "#eta vs #varphi of all selected negative matched tracks", o2HistType::kTH2F, {etaAxis, phiAxis}); // eta vs phi of all selected negative matched tracks mHistManager.add("MatchedTrackEtaPhi_Pos", "#eta vs #varphi of all selected positive matched tracks", o2HistType::kTH2F, {etaAxis, phiAxis}); // eta vs phi of all selected positive matched tracks - mHistManager.add("clusterTM_dEtadPhi", "cluster trackmatching dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest track - mHistManager.add("clusterTM_dEtadPhi_ASide", "cluster trackmatching in A-Side dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest track in A-Aside - mHistManager.add("clusterTM_dEtadPhi_CSide", "cluster trackmatching in C-Side tracks dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest track in C-Side - mHistManager.add("clusterTM_PosdEtadPhi", "cluster trackmatching positive tracks dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest positive track - mHistManager.add("clusterTM_NegdEtadPhi", "cluster trackmatching negative tracks dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest negative track - mHistManager.add("clusterTM_PosdEtadPhi_Pl0_75", "cluster trackmatching positive tracks, p < 0.75 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest positive track with p < 0.75 GeV/c - mHistManager.add("clusterTM_NegdEtadPhi_Pl0_75", "cluster trackmatching negative tracks, p < 0.75 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest negative track with p < 0.75 GeV/c - mHistManager.add("clusterTM_PosdEtadPhi_0_75leqPl1_25", "cluster trackmatching positive tracks, 0.75 <= p < 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest positive track with 0.75 <= p < 1.25 GeV/c - mHistManager.add("clusterTM_NegdEtadPhi_0_75leqPl1_25", "cluster trackmatching negative tracks, 0.75 <= p < 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest negative track with 0.75 <= p < 1.25 GeV/c - mHistManager.add("clusterTM_PosdEtadPhi_Pgeq1_25", "cluster trackmatching positive tracks, p >= 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest positive track with p >= 1.25 GeV/c - mHistManager.add("clusterTM_NegdEtadPhi_Pgeq1_25", "cluster trackmatching negative tracks, p >= 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, nmatchedtrack}); // dEta dPhi of the Nth clostest negative track with p >= 1.25 GeV/c - mHistManager.add("clusterTM_dEtaPt", "cluster trackmatching dEta/#it{p}_{T};d#it{#eta};#it{p}_{T} (GeV/#it{c})", o2HistType::kTH3F, {dEtaAxis, clusterptAxis, nmatchedtrack}); // dEta vs pT of the Nth clostest track - mHistManager.add("clusterTM_PosdPhiPt", "cluster trackmatching positive tracks dPhi/#it{p}_{T}", o2HistType::kTH3F, {dPhiAxis, clusterptAxis, nmatchedtrack}); // dPhi vs pT of the Nth clostest positive track - mHistManager.add("clusterTM_NegdPhiPt", "cluster trackmatching negative tracks dPh/#it{p}_{T}", o2HistType::kTH3F, {dPhiAxis, clusterptAxis, nmatchedtrack}); // dPhi vs pT of the Nth clostest negative track + mHistManager.add("clusterTM_dEtadPhi", "cluster trackmatching dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM + mHistManager.add("clusterTM_dEtadPhi_ASide", "cluster trackmatching in A-Side dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM in A-Aside + mHistManager.add("clusterTM_dEtadPhi_CSide", "cluster trackmatching in C-Side tracks dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM in C-Side + mHistManager.add("clusterTM_PosdEtadPhi", "cluster trackmatching positive tracks dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM positive track + mHistManager.add("clusterTM_NegdEtadPhi", "cluster trackmatching negative tracks dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM negative track + mHistManager.add("clusterTM_PosdEtadPhi_Pl0_75", "cluster trackmatching positive tracks, p < 0.75 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM positive track with p < 0.75 GeV/c + mHistManager.add("clusterTM_NegdEtadPhi_Pl0_75", "cluster trackmatching negative tracks, p < 0.75 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM negative track with p < 0.75 GeV/c + mHistManager.add("clusterTM_PosdEtadPhi_0_75leqPl1_25", "cluster trackmatching positive tracks, 0.75 <= p < 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM positive track with 0.75 <= p < 1.25 GeV/c + mHistManager.add("clusterTM_NegdEtadPhi_0_75leqPl1_25", "cluster trackmatching negative tracks, 0.75 <= p < 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM negative track with 0.75 <= p < 1.25 GeV/c + mHistManager.add("clusterTM_PosdEtadPhi_Pgeq1_25", "cluster trackmatching positive tracks, p >= 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM positive track with p >= 1.25 GeV/c + mHistManager.add("clusterTM_NegdEtadPhi_Pgeq1_25", "cluster trackmatching negative tracks, p >= 1.25 dEta/dPhi", o2HistType::kTH3F, {dEtaAxis, dPhiAxis, smAxis}); // dEta dPhi per SM negative track with p >= 1.25 GeV/c + mHistManager.add("clusterTM_dEtaPt", "cluster trackmatching dEta/#it{p}_{T};d#it{#eta};#it{p}_{T} (GeV/#it{c})", o2HistType::kTH3F, {dEtaAxis, clusterptAxis, smAxis}); // dEta vs pT per SM + mHistManager.add("clusterTM_PosdPhiPt", "cluster trackmatching positive tracks dPhi/#it{p}_{T}", o2HistType::kTH3F, {dPhiAxis, clusterptAxis, smAxis}); // dPhi vs pT per SM positive track + mHistManager.add("clusterTM_NegdPhiPt", "cluster trackmatching negative tracks dPh/#it{p}_{T}", o2HistType::kTH3F, {dPhiAxis, clusterptAxis, smAxis}); // dPhi vs pT per SM negative track mHistManager.add("clusterTM_dEtaTN", "cluster trackmatching dEta/TN;d#it{#eta};#it{N}_{matched tracks}", o2HistType::kTH2F, {dEtaAxis, nmatchedtrack}); // dEta compared to the Nth closest track mHistManager.add("clusterTM_dPhiTN", "cluster trackmatching dPhi/TN;d#it{#varphi} (rad);#it{N}_{matched tracks}", o2HistType::kTH2F, {dPhiAxis, nmatchedtrack}); // dPhi compared to the Nth closest track mHistManager.add("clusterTM_dRTN", "cluster trackmatching dR/TN;d#it{R};#it{N}_{matched tracks}", o2HistType::kTH2F, {dRAxis, nmatchedtrack}); // dR compared to the Nth closest track @@ -291,6 +292,7 @@ struct TrackMatchingMonitor { // using globTracks = o2::soa::Join; // In this example the counter t is just used to only look at the closest match double dEta, dPhi, pT, abs_p, trackEta, trackPhi, NSigmaEl; + auto supermoduleID = mGeometry->SuperModuleNumberFromEtaPhi(cluster.eta(), cluster.phi()); pT = cluster.energy() / cosh(cluster.eta()); if (M02highPt > 0. && cluster.m02() >= maxM02HighPt && pT >= M02highPt) { // high pT M02 cut continue; @@ -327,6 +329,11 @@ struct TrackMatchingMonitor { if (hasTRD && !(match.track_as().hasTRD())) { // request TRD hit cut continue; } + // only fill these for the first matched track: + if (t == 0) { + mHistManager.fill(HIST("clusterTM_dEtadPhi"), dEta, dPhi, supermoduleID); + mHistManager.fill(HIST("clusterTM_dEtaPt"), dEta, pT, supermoduleID); + } double eOverP = cluster.energy() / abs_p; mHistManager.fill(HIST("clusterTM_dEtaTN"), dEta, t); mHistManager.fill(HIST("clusterTM_dPhiTN"), dPhi, t); @@ -343,35 +350,39 @@ struct TrackMatchingMonitor { mHistManager.fill(HIST("clusterTM_NSigma_cut"), NSigmaEl, match.track_as().pt(), t); } // A- and C-side - if (match.track_as().eta() > 0.0) { - mHistManager.fill(HIST("clusterTM_dEtadPhi_ASide"), dEta, dPhi, t); - } else if (match.track_as().eta() < 0.0) { - mHistManager.fill(HIST("clusterTM_dEtadPhi_CSide"), dEta, dPhi, t); + if (match.track_as().eta() > 0.0 && t == 0) { + mHistManager.fill(HIST("clusterTM_dEtadPhi_ASide"), dEta, dPhi, supermoduleID); + } else if (match.track_as().eta() < 0.0 && t == 0) { + mHistManager.fill(HIST("clusterTM_dEtadPhi_CSide"), dEta, dPhi, supermoduleID); } // positive and negative tracks seperate, with three different track momentum ranges if (match.track_as().sign() == 1) { - mHistManager.fill(HIST("clusterTM_PosdEtadPhi"), dEta, dPhi, t); - mHistManager.fill(HIST("clusterTM_PosdPhiPt"), dPhi, pT, t); mHistManager.fill(HIST("clusterTM_NSigma_pos"), NSigmaEl, match.track_as().pt(), t); mHistManager.fill(HIST("MatchedTrackEtaPhi_Pos"), trackEta, trackPhi); - if (abs_p < 0.75) { - mHistManager.fill(HIST("clusterTM_PosdEtadPhi_Pl0_75"), dEta, dPhi, t); - } else if (abs_p >= 1.25) { - mHistManager.fill(HIST("clusterTM_PosdEtadPhi_Pgeq1_25"), dEta, dPhi, t); - } else { - mHistManager.fill(HIST("clusterTM_PosdEtadPhi_0_75leqPl1_25"), dEta, dPhi, t); + if (t == 0) { + mHistManager.fill(HIST("clusterTM_PosdPhiPt"), dPhi, pT, supermoduleID); + mHistManager.fill(HIST("clusterTM_PosdEtadPhi"), dEta, dPhi, supermoduleID); + if (abs_p < 0.75) { + mHistManager.fill(HIST("clusterTM_PosdEtadPhi_Pl0_75"), dEta, dPhi, supermoduleID); + } else if (abs_p >= 1.25) { + mHistManager.fill(HIST("clusterTM_PosdEtadPhi_Pgeq1_25"), dEta, dPhi, supermoduleID); + } else { + mHistManager.fill(HIST("clusterTM_PosdEtadPhi_0_75leqPl1_25"), dEta, dPhi, supermoduleID); + } } } else if (match.track_as().sign() == -1) { - mHistManager.fill(HIST("clusterTM_NegdEtadPhi"), dEta, dPhi, t); - mHistManager.fill(HIST("clusterTM_NegdPhiPt"), dPhi, pT, t); mHistManager.fill(HIST("clusterTM_NSigma_neg"), NSigmaEl, match.track_as().pt(), t); mHistManager.fill(HIST("MatchedTrackEtaPhi_Neg"), trackEta, trackPhi); - if (abs_p < 0.75) { - mHistManager.fill(HIST("clusterTM_NegdEtadPhi_Pl0_75"), dEta, dPhi, t); - } else if (abs_p >= 1.25) { - mHistManager.fill(HIST("clusterTM_NegdEtadPhi_Pgeq1_25"), dEta, dPhi, t); - } else { - mHistManager.fill(HIST("clusterTM_NegdEtadPhi_0_75leqPl1_25"), dEta, dPhi, t); + if (t == 0) { + mHistManager.fill(HIST("clusterTM_NegdPhiPt"), dPhi, pT, supermoduleID); + mHistManager.fill(HIST("clusterTM_NegdEtadPhi"), dEta, dPhi, supermoduleID); + if (abs_p < 0.75) { + mHistManager.fill(HIST("clusterTM_NegdEtadPhi_Pl0_75"), dEta, dPhi, supermoduleID); + } else if (abs_p >= 1.25) { + mHistManager.fill(HIST("clusterTM_NegdEtadPhi_Pgeq1_25"), dEta, dPhi, supermoduleID); + } else { + mHistManager.fill(HIST("clusterTM_NegdEtadPhi_0_75leqPl1_25"), dEta, dPhi, supermoduleID); + } } } if (tpcNsigmaElectron->at(0) <= NSigmaEl && NSigmaEl <= tpcNsigmaElectron->at(1)) { // E/p for e+/e- From d49fb70cf60879d23300b542028c3f9e00678686 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:44:31 +0100 Subject: [PATCH 023/156] added histogram for proton reweighting (#4129) --- PWGLF/Tasks/nuclei_in_jets.cxx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 5a882f3b3cf..1608c60c32c 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -146,6 +146,11 @@ struct nuclei_in_jets { registryData.add("antihelium3_jet_tpc", "antihelium3_jet_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); registryData.add("antihelium3_ue_tpc", "antihelium3_ue_tpc", HistType::kTH3F, {{40, 1.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); + // Input Antiproton Distribution + registryMC.add("antiproton_input", "antiproton_input", HistType::kTH1F, {{1000, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_weighted_jet", "antiproton_weighted_jet", HistType::kTH1F, {{1000, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_weighted_ue", "antiproton_weighted_ue", HistType::kTH1F, {{1000, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}}); + // Generated registryMC.add("antiproton_jet_gen", "antiproton_jet_gen", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antideuteron_jet_gen", "antideuteron_jet_gen", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); @@ -331,25 +336,19 @@ struct nuclei_in_jets { return 1; } - float GetLevi(float mass, float temp, float n, float norm, float pt) + float GetTsallis(float mass, float temp, float q, float norm, float pt) { float p0 = norm; - float p1 = n; + float p1 = 1.0 / (q - 1.0); float p2 = temp; float p3 = mass; - float dNdpt = (pt * p0 * (p1 - 1) * (p1 - 2)) / (p1 * p2 * (p1 * p2 + p3 * (p1 - 2))) * TMath::Power((1 + (TMath::Sqrt(p3 * p3 + pt * pt) - p3) / (p1 * p2)), -p1); + float dNdpt = (pt * p0 * (p1 - 1.0) * (p1 - 2.0)) / (p1 * p2 * (p1 * p2 + p3 * (p1 - 2.0))) * TMath::Power((1.0 + (TMath::Sqrt(p3 * p3 + pt * pt) - p3) / (p1 * p2)), -p1); return dNdpt; } - float GetTsallis(float mass, float temp, float q, float norm, float pt) - { - - return GetLevi(mass, temp, 1 / (q - 1), norm, pt); - } - // Process Data void processData(SelectedCollisions::iterator const& collision, FullTracks const& tracks) { @@ -717,6 +716,9 @@ struct nuclei_in_jets { // Fill Histograms if (particle.pdgCode() == -2212) { + registryMC.fill(HIST("antiproton_input"), particle.pt()); + registryMC.fill(HIST("antiproton_weighted_jet"), particle.pt(), wpr_jet); + registryMC.fill(HIST("antiproton_weighted_ue"), particle.pt(), wpr_ue); registryMC.fill(HIST("antiproton_jet_gen"), particle.pt(), wpr_jet); registryMC.fill(HIST("antiproton_ue_gen"), particle.pt(), wpr_ue); } From 109d661d1b2158cf1f59c1ee2da628896da19631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Mon, 11 Dec 2023 11:44:00 +0100 Subject: [PATCH 024/156] Extend V0 eff. QA to cover mor PDGs (#4127) * for now example with k0s --- DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx | 136 ++++++++++++------------- 1 file changed, 63 insertions(+), 73 deletions(-) diff --git a/DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx b/DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx index ab77a8b121a..0476d724b22 100644 --- a/DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx +++ b/DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx @@ -36,45 +36,53 @@ #include "THashList.h" using namespace o2::framework; +static constexpr int nSpecies = 2; // One per PDG +// static constexpr const char* particleTitle[nSpecies] = {"K0s", "-K0s"}; +static constexpr int PDGs[nSpecies] = {kK0Short, -kK0Short}; +int pdgToIndex(int pdg) +{ + for (int i = 0; i < nSpecies; i++) { + if (pdg == PDGs[i]) { + return i; + } + } + return -1; +} +static constexpr int kHistoPtNum = 0; +static constexpr int kHistoPtDen = 1; +static constexpr int kHistoTot = 2; + +std::shared_ptr histograms[nSpecies][kHistoTot] = {{nullptr}}; +std::shared_ptr histogramsPrm[nSpecies][kHistoTot] = {{nullptr}}; +std::shared_ptr histogramsPrmRap[nSpecies][kHistoTot] = {{nullptr}}; struct QaEfficiencyV0s { // Particle information - static constexpr int nSpecies = 1; // One per PDG - static constexpr const char* particleTitle[nSpecies] = {"K0s"}; - static constexpr int PDGs[nSpecies] = {kK0Short}; - // Particle only selection - Configurable doK0s{"do-k0s", false, "Flag to run with the PDG code of k0s"}; Configurable rapidityCut{"rapidityCut", 0.5, "Rapidity cut"}; ConfigurableAxis ptBins{"ptBins", {200, 0.f, 5.f}, "Pt binning"}; OutputObj listEfficiencyMC{"EfficiencyMC"}; - // Histograms - HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) { const AxisSpec axisPt{ptBins, "#it{p}_{T} GeV/#it{c}"}; - auto h = registry.add("Pos/PtNum_310", "Pos/Num_310", kTH1F, {axisPt}); - registry.add("Pos/PtDen_310", "Pos/Den_310", kTH1F, {axisPt}); - registry.add("Neg/PtNum_310", "Neg/Num_310", kTH1F, {axisPt}); - registry.add("Neg/PtDen_310", "Neg/Den_310", kTH1F, {axisPt}); - registry.add("Prm/Pos/PtNum_310", "Prm/Pos/Num_310", kTH1F, {axisPt}); - registry.add("Prm/Pos/PtDen_310", "Prm/Pos/Den_310", kTH1F, {axisPt}); - registry.add("Prm/Neg/PtNum_310", "Prm/Neg/Num_310", kTH1F, {axisPt}); - registry.add("Prm/Neg/PtDen_310", "Prm/Neg/Den_310", kTH1F, {axisPt}); - registry.add("PrmRap/Pos/PtNum_310", "PrmRap/Pos/Num_310", kTH1F, {axisPt}); - registry.add("PrmRap/Pos/PtDen_310", "PrmRap/Pos/Den_310", kTH1F, {axisPt}); - registry.add("PrmRap/Neg/PtNum_310", "PrmRap/Neg/Num_310", kTH1F, {axisPt}); - registry.add("PrmRap/Neg/PtDen_310", "PrmRap/Neg/Den_310", kTH1F, {axisPt}); - - TAxis* axis = h->GetXaxis(); listEfficiencyMC.setObject(new THashList); - listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPt_pdg%d", PDGs[0]), Form("efficiencyPt_pdg%d", PDGs[0]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); - listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPt_pdg-%d", PDGs[0]), Form("efficiencyPt_pdg-%d", PDGs[0]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); - listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPtPrm_pdg%d", PDGs[0]), Form("efficiencyPtPrm_pdg%d", PDGs[0]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); - listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPtPrm_pdg-%d", PDGs[0]), Form("efficiencyPtPrm_pdg-%d", PDGs[0]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); - listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPtPrmRap_pdg%d", PDGs[0]), Form("efficiencyPtPrmRap_pdg%d", PDGs[0]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); - listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPtPrmRap_pdg-%d", PDGs[0]), Form("efficiencyPtPrmRap_pdg-%d", PDGs[0]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); + + for (int i = 0; i < nSpecies; i++) { + // MC efficiency (PDG code + histograms[i][kHistoPtNum] = registry.add(Form("Pt/Num_%i", PDGs[i]), Form("Num %i", PDGs[i]), kTH1F, {axisPt}); + histograms[i][kHistoPtDen] = registry.add(Form("Pt/Den_%i", PDGs[i]), Form("Den %i", PDGs[i]), kTH1F, {axisPt}); + + histogramsPrm[i][kHistoPtNum] = registry.add(Form("Pt/Prm/Num_%i", PDGs[i]), Form("Pt Prm Num %i", PDGs[i]), kTH1F, {axisPt}); + histogramsPrm[i][kHistoPtDen] = registry.add(Form("Pt/Prm/Den_%i", PDGs[i]), Form("Pt Prm Den %i", PDGs[i]), kTH1F, {axisPt}); + + histogramsPrmRap[i][kHistoPtNum] = registry.add(Form("Pt/Prm/Rap/PtNum_%i", PDGs[i]), Form("Pt Prm Rap Num %i", PDGs[i]), kTH1F, {axisPt}); + histogramsPrmRap[i][kHistoPtDen] = registry.add(Form("Pt/Prm/Rap/PtDen_%i", PDGs[i]), Form("Pt Prm Rap Den %i", PDGs[i]), kTH1F, {axisPt}); + + TAxis* axis = histograms[i][0]->GetXaxis(); + listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPt_pdg%d", PDGs[i]), Form("efficiencyPt_pdg%d", PDGs[i]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); + listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPtPrm_pdg%d", PDGs[i]), Form("efficiencyPtPrm_pdg%d", PDGs[i]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); + listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPtPrmRap_pdg%d", PDGs[i]), Form("efficiencyPtPrmRap_pdg%d", PDGs[i]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); + } } // MC process @@ -83,62 +91,44 @@ struct QaEfficiencyV0s { void process(o2::aod::McV0Labels const& V0s, o2::aod::McParticles const& mcParticles) { - for (auto const& v0 : V0s) { + for (auto const& v0 : V0s) { // Numerator if (v0.has_mcParticle()) { auto mcparticle = v0.mcParticle(); - if (mcparticle.pdgCode() == PDGs[0]) { - registry.fill(HIST("Pos/PtNum_310"), mcparticle.pt()); - if (mcparticle.isPhysicalPrimary()) { - registry.fill(HIST("Prm/Pos/PtNum_310"), mcparticle.pt()); - if (TMath::Abs(mcparticle.y()) < rapidityCut) { - registry.fill(HIST("PrmRap/Pos/PtNum_310"), mcparticle.pt()); - } - } - } else if (mcparticle.pdgCode() == -PDGs[0]) { - registry.fill(HIST("Neg/PtNum_310"), mcparticle.pt()); - if (mcparticle.isPhysicalPrimary()) { - registry.fill(HIST("Prm/Neg/PtNum_310"), mcparticle.pt()); - if (TMath::Abs(mcparticle.y()) < rapidityCut) { - registry.fill(HIST("PrmRap/Neg/PtNum_310"), mcparticle.pt()); - } - } + const auto index = pdgToIndex(mcparticle.pdgCode()); + if (index < 0) { + continue; } - } - } - for (auto const& mcparticle : mcParticles) { - if (mcparticle.pdgCode() == PDGs[0]) { - registry.fill(HIST("Pos/PtDen_310"), mcparticle.pt()); + histograms[index][kHistoPtNum]->Fill(mcparticle.pt()); if (mcparticle.isPhysicalPrimary()) { - registry.fill(HIST("Prm/Pos/PtDen_310"), mcparticle.pt()); + histogramsPrm[index][kHistoPtNum]->Fill(mcparticle.pt()); if (TMath::Abs(mcparticle.y()) < rapidityCut) { - registry.fill(HIST("PrmRap/Pos/PtDen_310"), mcparticle.pt()); + histogramsPrmRap[index][kHistoPtNum]->Fill(mcparticle.pt()); } } - } else if (mcparticle.pdgCode() == -PDGs[0]) { - registry.fill(HIST("Neg/PtDen_310"), mcparticle.pt()); - if (mcparticle.isPhysicalPrimary()) { - registry.fill(HIST("Prm/Neg/PtDen_310"), mcparticle.pt()); - if (TMath::Abs(mcparticle.y()) < rapidityCut) { - registry.fill(HIST("PrmRap/Neg/PtDen_310"), mcparticle.pt()); - } + } + } + for (auto const& mcparticle : mcParticles) { // Denominator + const auto index = pdgToIndex(mcparticle.pdgCode()); + if (index < 0) { + continue; + } + histograms[index][kHistoPtDen]->Fill(mcparticle.pt()); + if (mcparticle.isPhysicalPrimary()) { + histogramsPrm[index][kHistoPtDen]->Fill(mcparticle.pt()); + if (TMath::Abs(mcparticle.y()) < rapidityCut) { + histogramsPrmRap[index][kHistoPtDen]->Fill(mcparticle.pt()); } } } - static_cast(listEfficiencyMC->At(0))->SetPassedHistogram(*registry.get(HIST("Pos/PtNum_310")), "f"); - static_cast(listEfficiencyMC->At(0))->SetTotalHistogram(*registry.get(HIST("Pos/PtDen_310")), "f"); - static_cast(listEfficiencyMC->At(1))->SetPassedHistogram(*registry.get(HIST("Neg/PtNum_310")), "f"); - static_cast(listEfficiencyMC->At(1))->SetTotalHistogram(*registry.get(HIST("Neg/PtDen_310")), "f"); - - static_cast(listEfficiencyMC->At(2))->SetPassedHistogram(*registry.get(HIST("Prm/Pos/PtNum_310")), "f"); - static_cast(listEfficiencyMC->At(2))->SetTotalHistogram(*registry.get(HIST("Prm/Pos/PtDen_310")), "f"); - static_cast(listEfficiencyMC->At(3))->SetPassedHistogram(*registry.get(HIST("Prm/Neg/PtNum_310")), "f"); - static_cast(listEfficiencyMC->At(3))->SetTotalHistogram(*registry.get(HIST("Prm/Neg/PtDen_310")), "f"); - - static_cast(listEfficiencyMC->At(4))->SetPassedHistogram(*registry.get(HIST("PrmRap/Pos/PtNum_310")), "f"); - static_cast(listEfficiencyMC->At(4))->SetTotalHistogram(*registry.get(HIST("PrmRap/Pos/PtDen_310")), "f"); - static_cast(listEfficiencyMC->At(5))->SetPassedHistogram(*registry.get(HIST("PrmRap/Neg/PtNum_310")), "f"); - static_cast(listEfficiencyMC->At(5))->SetTotalHistogram(*registry.get(HIST("PrmRap/Neg/PtDen_310")), "f"); + for (int i = 0; i < nSpecies; i++) { + static_cast(listEfficiencyMC->At(i * nSpecies))->SetPassedHistogram(*histograms[i][kHistoPtNum].get(), "f"); + static_cast(listEfficiencyMC->At(i * nSpecies))->SetTotalHistogram(*histograms[i][kHistoPtDen].get(), "f"); + static_cast(listEfficiencyMC->At(i * nSpecies + 1))->SetPassedHistogram(*histogramsPrm[i][kHistoPtNum].get(), "f"); + static_cast(listEfficiencyMC->At(i * nSpecies + 1))->SetTotalHistogram(*histogramsPrm[i][kHistoPtDen].get(), "f"); + static_cast(listEfficiencyMC->At(i * nSpecies + 2))->SetPassedHistogram(*histogramsPrmRap[i][kHistoPtNum].get(), "f"); + static_cast(listEfficiencyMC->At(i * nSpecies + 2))->SetTotalHistogram(*histogramsPrmRap[i][kHistoPtDen].get(), "f"); + } } }; From 035cce5c033c2aeb530baac12c67bd497f47cbcf Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Mon, 11 Dec 2023 16:01:18 +0100 Subject: [PATCH 025/156] [PWGDQ] Adding flow variables to dilepton flat tables and propagation of MCH-MID tracks in table-maker (#4091) * Add function to propagate muon tracks through absorber to PV * Format * Fix * Fix * Fix typo * Fixing libraries * Clang format * Missing array definition * Retrieving geometry from ccdb * Clang format * Fixing retrieving of ccdb object * Calng format * Fixing covariance name * PWGDQ: Adding propagation for MCH-MID tracks and filling flow variables in dilepton flat table * Clang format * Bug fixes * Clang format --- PWGDQ/Core/VarManager.h | 42 ++++++++++++++++++++++++----- PWGDQ/DataModel/ReducedInfoTables.h | 6 ++++- PWGDQ/Tasks/dqEfficiency.cxx | 2 +- PWGDQ/Tasks/tableReader.cxx | 17 ++++++------ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 9d4fc0e4f04..9e78af9ed48 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -38,6 +38,8 @@ #include "Framework/DataTypes.h" // #include "MCHTracking/TrackExtrap.h" +#include "TGeoGlobalMagField.h" +#include "Field/MagneticField.h" #include "ReconstructionDataFormats/Track.h" #include "ReconstructionDataFormats/Vertex.h" #include "DCAFitter/DCAFitterN.h" @@ -802,7 +804,6 @@ void VarManager::FillPropagateMuon(const T& muon, const C& collision, float* val values = fgValues; } if constexpr ((fillMap & MuonCov) > 0) { - o2::mch::TrackExtrap::setField(); double chi2 = muon.chi2(); SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt()); std::vector v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(), @@ -810,11 +811,31 @@ void VarManager::FillPropagateMuon(const T& muon, const C& collision, float* val muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()}; SMatrix55 tcovs(v1.begin(), v1.end()); o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; - o2::dataformats::GlobalFwdTrack track(fwdtrack); - auto mchTrack = mMatching.FwdtoMCH(track); - o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); - auto propmuon = mMatching.MCHtoFwd(mchTrack); - + o2::dataformats::GlobalFwdTrack propmuon; + if (static_cast(muon.trackType()) > 2) { + o2::mch::TrackExtrap::setField(); + o2::dataformats::GlobalFwdTrack track; + track.setParameters(tpars); + track.setZ(fwdtrack.getZ()); + track.setCovariances(tcovs); + auto mchTrack = mMatching.FwdtoMCH(track); + o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + auto proptrack = mMatching.MCHtoFwd(mchTrack); + propmuon.setParameters(proptrack.getParameters()); + propmuon.setZ(proptrack.getZ()); + propmuon.setCovariances(proptrack.getCovariances()); + + } else if (static_cast(muon.trackType()) < 2) { + double centerMFT[3] = {0, 0, -61.4}; + o2::field::MagneticField* field = static_cast(TGeoGlobalMagField::Instance()->GetField()); + auto Bz = field->getBz(centerMFT); // Get field at centre of MFT + auto geoMan = o2::base::GeometryManager::meanMaterialBudget(muon.x(), muon.y(), muon.z(), collision.posX(), collision.posY(), collision.posZ()); + auto x2x0 = static_cast(geoMan.meanX2X0); + fwdtrack.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, Bz, x2x0); + propmuon.setParameters(fwdtrack.getParameters()); + propmuon.setZ(fwdtrack.getZ()); + propmuon.setCovariances(fwdtrack.getCovariances()); + } values[kPt] = propmuon.getPt(); values[kX] = propmuon.getX(); values[kY] = propmuon.getY(); @@ -2022,6 +2043,15 @@ void VarManager::FillPairVertexing(C const& collision, T const& t1, T const& t2, v1 = {pars1.getPt(), pars1.getEta(), pars1.getPhi(), m1}; v2 = {pars2.getPt(), pars2.getEta(), pars2.getPhi(), m2}; v12 = v1 + v2; + values[kMass] = v12.M(); + values[kPt] = v12.Pt(); + values[kEta] = v12.Eta(); + values[kPhi] = v12.Phi(); + values[kRap] = -v12.Rapidity(); + values[kVertexingTauxy] = KFGeoTwoProng.GetPseudoProperDecayTime(KFPV, v12.M()) / (o2::constants::physics::LightSpeedCm2NS); + values[kVertexingTauz] = dzPair2PV * v12.M() / (TMath::Abs(v12.Pz()) * o2::constants::physics::LightSpeedCm2NS); + values[kVertexingTauxyErr] = values[kVertexingLxyErr] * v12.M() / (v12.Pt() * o2::constants::physics::LightSpeedCm2NS); + values[kVertexingTauzErr] = values[kVertexingLzErr] * v12.M() / (TMath::Abs(v12.Pz()) * o2::constants::physics::LightSpeedCm2NS); values[kPt1] = pars1.getPt(); values[kEta1] = pars1.getEta(); diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index 7146ed9810c..613aff6e800 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -514,7 +514,11 @@ DECLARE_SOA_TABLE(DimuonsAll, "AOD", "RTDIMUONALL", //! dilepton_track_index::PtMC2, dilepton_track_index::EtaMC2, dilepton_track_index::PhiMC2, dilepton_track_index::EMC2, dilepton_track_index::Vx1, dilepton_track_index::Vy1, dilepton_track_index::Vz1, dilepton_track_index::Vt1, dilepton_track_index::Vx2, dilepton_track_index::Vy2, dilepton_track_index::Vz2, dilepton_track_index::Vt2, - dilepton_track_index::IsAmbig1, dilepton_track_index::IsAmbig2); + dilepton_track_index::IsAmbig1, dilepton_track_index::IsAmbig2, + reducedpair::U2Q2, + reducedpair::U3Q3, + reducedpair::Cos2DeltaPhi, + reducedpair::Cos3DeltaPhi); using Dilepton = Dileptons::iterator; using DileptonExtra = DileptonsExtra::iterator; diff --git a/PWGDQ/Tasks/dqEfficiency.cxx b/PWGDQ/Tasks/dqEfficiency.cxx index 00d9a08cb5c..61eae0a79b1 100644 --- a/PWGDQ/Tasks/dqEfficiency.cxx +++ b/PWGDQ/Tasks/dqEfficiency.cxx @@ -797,7 +797,7 @@ struct AnalysisSameEventPairing { t2.reducedMCTrack().pt(), t2.reducedMCTrack().eta(), t2.reducedMCTrack().phi(), t2.reducedMCTrack().e(), t1.reducedMCTrack().vx(), t1.reducedMCTrack().vy(), t1.reducedMCTrack().vz(), t1.reducedMCTrack().vt(), t2.reducedMCTrack().vx(), t2.reducedMCTrack().vy(), t2.reducedMCTrack().vz(), t2.reducedMCTrack().vt(), - t1.isAmbiguous(), t2.isAmbiguous()); + t1.isAmbiguous(), t2.isAmbiguous(), -999., -999., -999., -999.); } } diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index c939c1ac66f..0ed46426cfd 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -796,7 +796,7 @@ struct AnalysisSameEventPairing { if (fNoCorr) { VarManager::SetupFwdDCAFitterNoCorr(); - } else if (fCorrFullGeo) { + } else if (fCorrFullGeo || (fConfigUseKFVertexing && fPropToPCA)) { if (!o2::base::GeometryManager::isGeometryLoaded()) { ccdb->get(geoPath); } @@ -944,15 +944,15 @@ struct AnalysisSameEventPairing { if (fConfigUseKFVertexing.value) { VarManager::SetupTwoProngKFParticle(mMagField); } else { - VarManager::SetupTwoProngDCAFitter(mMagField, fPropToPCA.value, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables - VarManager::SetupTwoProngFwdDCAFitter(mMagField, fPropToPCA.value, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); + VarManager::SetupTwoProngDCAFitter(mMagField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables + VarManager::SetupTwoProngFwdDCAFitter(mMagField, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); } } else { if (fConfigUseKFVertexing.value) { VarManager::SetupTwoProngKFParticle(fConfigMagField.value); } else { - VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, fPropToPCA.value, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables - VarManager::SetupTwoProngFwdDCAFitter(fConfigMagField.value, fPropToPCA.value, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); + VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables + VarManager::SetupTwoProngFwdDCAFitter(fConfigMagField.value, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); } } fCurrentRun = event.runNumber(); @@ -1016,8 +1016,7 @@ struct AnalysisSameEventPairing { if constexpr ((TPairType == pairTypeEE) && trackHasCov) { dileptonExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauz], VarManager::fgValues[VarManager::kVertexingLz], VarManager::fgValues[VarManager::kVertexingLxy]); } - constexpr bool muonHasCov = ((TTrackFillMap & VarManager::ObjTypes::MuonCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedMuonCov) > 0); - if constexpr ((TPairType == pairTypeMuMu) && muonHasCov) { + if constexpr (TPairType == pairTypeMuMu) { // LOGP(info, "mu1 collId = {}, mu2 collId = {}", t1.collisionId(), t2.collisionId()); dileptonExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauz], VarManager::fgValues[VarManager::kVertexingLz], VarManager::fgValues[VarManager::kVertexingLxy]); if (fConfigFlatTables.value) { @@ -1040,7 +1039,9 @@ struct AnalysisSameEventPairing { -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., - t1.isAmbiguous(), t2.isAmbiguous()); + t1.isAmbiguous(), t2.isAmbiguous(), + VarManager::fgValues[VarManager::kU2Q2], VarManager::fgValues[VarManager::kU3Q3], + VarManager::fgValues[VarManager::kCos2DeltaPhi], VarManager::fgValues[VarManager::kCos3DeltaPhi]); } } From 4c439a91b282cab1bcb282df9184e03a2a3423df Mon Sep 17 00:00:00 2001 From: vfeuilla <71069003+vfeuilla@users.noreply.github.com> Date: Mon, 11 Dec 2023 16:21:39 +0100 Subject: [PATCH 026/156] Small changes to some cuts (ren-labelling, adjustement of variables...) (#4128) Cleanup of unused cuts --- PWGDQ/Core/CutsLibrary.cxx | 179 +++++++++++++++---------------------- 1 file changed, 74 insertions(+), 105 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 3a32a1127f7..2188aa916f7 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -28,27 +28,53 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // These are the Cuts used in the CEFP Task // // to select tracks in the event selection // // /////////////////////////////////////////////// - if (!nameStr.compare("Electron")) { + if (!nameStr.compare("Electron2022")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5")); return cut; } - if (!nameStr.compare("ElectronTight")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine3")); + if (!nameStr.compare("Electron2023")) { + cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug1")); + cut->AddCut(GetAnalysisCut("pidCut_lowP_Corr")); + + AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP_Corr")); + pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP_Corr")); + cut->AddCut(pidCut_highP); + return cut; + } + if (!nameStr.compare("Electron2023_Tight")) { + cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); + cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); + cut->AddCut(GetAnalysisCut("pidCut_lowP_Corr")); + + AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP2_Corr")); + pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP_Corr")); + cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("MuonLow")) { + if (!nameStr.compare("MuonLow2022")) { + cut->AddCut(GetAnalysisCut("muonLowPt2")); + cut->AddCut(GetAnalysisCut("muonQualityCuts")); + return cut; + } + if (!nameStr.compare("MuonLow2023")) { cut->AddCut(GetAnalysisCut("muonLowPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("MuonHigh")) { + if (!nameStr.compare("MuonHigh2022")) { cut->AddCut(GetAnalysisCut("muonHighPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); + return cut; + } + if (!nameStr.compare("MuonHigh2023")) { + cut->AddCut(GetAnalysisCut("muonHighPt6")); + cut->AddCut(GetAnalysisCut("muonQualityCuts")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } @@ -214,95 +240,53 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryLoose")); // with 3 sigma El TOF return cut; } - // - // New cuts to test for jpsi2ee electron selection (potentially not useful) - // - // With pT > 1.0 GeV/c as primary cut - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_1")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_1")); // Loose pion rejection at high p with no correction maps - - return cut; - } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_1_Corr")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_1_Corr")); // Loose pion rejection at high p with correction maps - - return cut; - } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_2")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_2")); // No pion rejection at high p and asymmetrical e selection with no correction maps - - return cut; - } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_2_Corr")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_2_Corr")); // No pion rejection at high p and asymmetrical e selection with correction maps - return cut; - } - - // With p > 1.5 GeV/c as primary cut - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_3")) { + if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent_Corr")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_1")); // Loose pion rejection at high p with no correction maps + cut->AddCut(GetAnalysisCut("pidCut_lowP_Corr")); + AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP_Corr")); + pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP_Corr")); + cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_3_Corr")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_1_Corr")); // Loose pion rejection at high p with correction maps - return cut; - } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_4")) { + if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_2")); // No pion rejection at high p and asymmetrical e selection with no correction maps + cut->AddCut(GetAnalysisCut("pidCut_lowP")); + AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP")); + pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP")); + cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_4_Corr")) { + if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent2_Corr")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TEST_2_Corr")); // No pion rejection at high p and asymmetrical e selection with correction maps - - return cut; - } - - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_6_Corr")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); - cut->AddCut(GetAnalysisCut("pidCut_lowP")); + cut->AddCut(GetAnalysisCut("pidCut_lowP_Corr")); AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); - pidCut_highP->AddCut(GetAnalysisCut("MySpecial_EleInclusion")); - pidCut_highP->AddCut(GetAnalysisCut("MySpecial_PionExclusion")); + pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP2_Corr")); + pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP_Corr")); cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_TEST_5_Corr")) { + if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent2")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("pidCut_lowP")); AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); - pidCut_highP->AddCut(GetAnalysisCut("MySpecial_EleInclusion")); - pidCut_highP->AddCut(GetAnalysisCut("MySpecial_PionExclusion")); + pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP2")); + pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP")); cut->AddCut(pidCut_highP); return cut; } - // - // end new test cuts - // if (!nameStr.compare("JpsiPWGSkimmedCuts1")) { // please do not remove or modify, this is used for the common Skimmed tree production, (Xiaozhi Bai) cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); @@ -2921,60 +2905,45 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 999); return cut; } - // - // New test for jpsi2ee PID selection - // - if (!nameStr.compare("jpsi_TPCPID_TEST_1_Corr")) { - cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0); - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.0, 999, false, VarManager::kP, 4.0, 999); - cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 2.0, 999, false, VarManager::kP, 4.0, 999); + + if (!nameStr.compare("pidCut_lowP_Corr")) { + cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0, false, VarManager::kP, 0.0, 5.0); + cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kP, 0.0, 5.0); + cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 2.5, 999, false, VarManager::kP, 0.0, 5.0); return cut; } - if (!nameStr.compare("jpsi_TPCPID_TEST_1")) { - cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); - cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPi, 2.0, 999, false, VarManager::kP, 4.0, 999); - cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPr, 2.0, 999, false, VarManager::kP, 4.0, 999); + + if (!nameStr.compare("EleInclusion_highP_Corr")) { + cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -1.0, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("jpsi_TPCPID_TEST_2_Corr")) { - cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -1.0, 4.0, false, VarManager::kP, 4.0, 999); - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.0, 999, false, VarManager::kP, 4.0, 999); - cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 2.0, 999, false, VarManager::kP, 4.0, 999); + if (!nameStr.compare("EleInclusion_highP2_Corr")) { + cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -0.5, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("jpsi_TPCPID_TEST_2")) { - cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kP, 4.0, 999.0); - cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPi, 0, 999, false, VarManager::kP, 4.0, 999); - cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPr, 0, 999, false, VarManager::kP, 4.0, 999); + if (!nameStr.compare("PionExclusion_highP_Corr")) { + cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.0, 999, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("pidCut_lowP")) { - cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 3.0, 999, false, VarManager::kP, 0.0, 4.0); + cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0, false, VarManager::kP, 0.0, 5.0); + cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999, false, VarManager::kP, 0.0, 5.0); + cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 999, false, VarManager::kP, 0.0, 5.0); return cut; } - if (!nameStr.compare("MySpecial_EleInclusion")) { - cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -1.0, 4.0, false, VarManager::kP, 4.0, 999.0); + if (!nameStr.compare("EleInclusion_highP")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kP, 5.0, 999.0); + return cut; + } + if (!nameStr.compare("EleInclusion_highP2")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -0.5, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("MySpecial_PionExclusion")) { - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.0, 999, false, VarManager::kP, 4.0, 999.0); + if (!nameStr.compare("PionExclusion_highP")) { + cut->AddCut(VarManager::kTPCnSigmaPi, 2.0, 999, false, VarManager::kP, 5.0, 999.0); return cut; } - // end of new tests cuts if (!nameStr.compare("lmee_TPCPID_debug1")) { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -5.0, 5.0); From 22133ad98e7fa757a7515971a1bd457ac28f51b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Mon, 11 Dec 2023 18:53:44 +0100 Subject: [PATCH 027/156] Update CMake for LF (#4130) --- PWGLF/Tasks/CMakeLists.txt | 149 +++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 72 deletions(-) diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 79f7074cbd7..ddd2aa5cf32 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(QC) +# Nuclei o2physics_add_dpl_workflow(hyperon-reco-test SOURCES hyperon-reco-test.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -21,6 +22,48 @@ o2physics_add_dpl_workflow(nuclei-batask PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(hypertritonanalysis + SOURCES hypertritonAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(nuclei-hist + SOURCES NucleiHistTask.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hypertriton3bodyanalysis + SOURCES hypertriton3bodyanalysis.cxx + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hypertriton3bodymcqa + SOURCES hypertriton3bodyMCQA.cxx + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(nuclei-in-jets + SOURCES nuclei_in_jets.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(helium-flow + SOURCES helium_flow.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + + +o2physics_add_dpl_workflow(antimatter-abs-hmpid + SOURCES AntimatterAbsorptionHMPID.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::ReconstructionDataFormats O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hyhefour-analysis + SOURCES hyhe4analysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +# Spectra o2physics_add_dpl_workflow(mc-spectra-efficiency SOURCES mcspectraefficiency.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -56,6 +99,17 @@ o2physics_add_dpl_workflow(spectra-tpc-tiny-pikapr PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(spectra-charged + SOURCES spectraCharged.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(id-raa + SOURCES identifiedraa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +# Strangeness o2physics_add_dpl_workflow(lambdakzeroanalysis SOURCES lambdakzeroanalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -76,21 +130,37 @@ o2physics_add_dpl_workflow(cascadeanalysismc PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(hypertritonanalysis - SOURCES hypertritonAnalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore +o2physics_add_dpl_workflow(v0postprocessing + SOURCES v0postprocessing.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(spectra-charged - SOURCES spectraCharged.cxx +o2physics_add_dpl_workflow(stqa + SOURCES stqa.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascadecorrelations + SOURCES cascadecorrelations.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(id-raa - SOURCES identifiedraa.cxx +o2physics_add_dpl_workflow(non-prompt-cascade + SOURCES nonPromptCascade.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore O2::DetectorsBase + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(kinkanalysis + SOURCES kinkAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(vzero-cascade-absorption + SOURCES vzero_cascade_absorption.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +# Resonance o2physics_add_dpl_workflow(rsnanalysis SOURCES rsnanalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -111,11 +181,6 @@ o2physics_add_dpl_workflow(lambda1520analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(nuclei-hist - SOURCES NucleiHistTask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(qa-hist SOURCES QAHistTask.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -131,21 +196,6 @@ o2physics_add_dpl_workflow(hstrangecorrelation PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(stqa - SOURCES stqa.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(non-prompt-cascade - SOURCES nonPromptCascade.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore O2::DetectorsBase - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hyhefour-analysis - SOURCES hyhe4analysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(k1analysis SOURCES k1analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -161,46 +211,11 @@ o2physics_add_dpl_workflow(f0980analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(v0postprocessing - SOURCES v0postprocessing.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(antimatter-abs-hmpid - SOURCES AntimatterAbsorptionHMPID.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::ReconstructionDataFormats O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(cascadecorrelations - SOURCES cascadecorrelations.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(kinkanalysis - SOURCES kinkAnalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(lambda1520spherocityanalysis SOURCES lambda1520SpherocityAnalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(hypertriton3bodyanalysis - SOURCES hypertriton3bodyanalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hypertriton3bodymcqa - SOURCES hypertriton3bodyMCQA.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(vzero-cascade-absorption - SOURCES vzero_cascade_absorption.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(delta-analysis SOURCES deltaanalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -216,16 +231,6 @@ o2physics_add_dpl_workflow(phi-analysis-thnsparse PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(nuclei-in-jets - SOURCES nuclei_in_jets.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(helium-flow - SOURCES helium_flow.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(f1protoncorrelation SOURCES f1protoncorrelation.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore From f3c73c5a07c97b7927dc0a4fe9ee3d4e4ee8d91b Mon Sep 17 00:00:00 2001 From: Giovanni Malfattore <89481844+giovannimalfattore@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:14:40 +0100 Subject: [PATCH 028/156] [PWFLG] LightNucleiTask - Fix typo (#4133) * [PWFLG] LightNucleiTask - Fix typo --- PWGLF/Tasks/LFNucleiBATask.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/LFNucleiBATask.cxx index 5361d582e4d..b7948be8b05 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/LFNucleiBATask.cxx @@ -3069,7 +3069,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID_Z2"), 2 * hePt); if (enablePtSpectra) { histos.fill(HIST("tracks/eff/helium/hPtHeTrue"), 2 * hePt); - if (track.hasTOF() & doTOFplots) { + if (track.hasTOF() && doTOFplots) { histos.fill(HIST("tracks/eff/helium/hPtHeTOFTrue"), 2 * hePt); } } @@ -3109,7 +3109,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2"), 2 * antihePt); if (enablePtSpectra) { histos.fill(HIST("tracks/eff/helium/hPtantiHeTrue"), 2 * hePt); - if (track.hasTOF() & doTOFplots) { + if (track.hasTOF() && doTOFplots) { histos.fill(HIST("tracks/eff/helium/hPtantiHeTOFTrue"), 2 * hePt); } } From f1b4f8eb3c8aec04323e41464e8736ee0f7e9809 Mon Sep 17 00:00:00 2001 From: Nicolas Strangmann <77485327+nstrangm@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:35:41 +0100 Subject: [PATCH 029/156] PWGEM/PhotonMeson: Update EMCalQCTask (#4134) * PWGEM/PhotonMeson: Update EMCalQCTask - Introduce configurable axis for invmass-pT histograms - Change required trigger from INT7 to kTVXinEMC - Introduce option to differentiate between gamma-gamma pairs from EMCal and DCal * PWGEM/PhotonMeson: Fixed clang issue * PWGEM/PhotonMeson: Update EMCalQCTask - Outsource cluster QA histogram filling in dedicated function - Add QA histograms after application of cuts --- PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx | 168 ++++++++++++------------- 1 file changed, 80 insertions(+), 88 deletions(-) diff --git a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx index 4a00e8f3953..a4e4492d9fe 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx @@ -177,7 +177,7 @@ struct Pi0QCTask { // create common axes LOG(info) << "Creating histograms"; const o2Axis bcAxis{3501, -0.5, 3500.5}; - const o2Axis energyAxis{makeClusterBinning(), "#it{p}_{T} (GeV)"}; + const o2Axis energyAxis{makeClusterBinning(), "#it{E} (GeV)"}; // event properties mHistManager.add("eventsAll", "Number of events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); @@ -189,15 +189,18 @@ struct Pi0QCTask { mHistManager.add("eventVertexZSelected", "z-vertex of event (selected events)", o2HistType::kTH1F, {{200, -20, 20}}); // cluster properties - mHistManager.add("clusterE", "Energy of cluster", o2HistType::kTH1F, {energyAxis}); - mHistManager.add("clusterE_SimpleBinning", "Energy of cluster", o2HistType::kTH1F, {{400, 0, 100}}); - mHistManager.add("clusterTime", "Time of cluster", o2HistType::kTH1F, {{500, -250, 250}}); - mHistManager.add("clusterEtaPhi", "Eta and phi of cluster", o2HistType::kTH2F, {{100, -1, 1}, {100, 0, 2 * TMath::Pi()}}); - mHistManager.add("clusterM02", "M02 of cluster", o2HistType::kTH1F, {{400, 0, 5}}); - mHistManager.add("clusterM20", "M20 of cluster", o2HistType::kTH1F, {{400, 0, 2.5}}); - mHistManager.add("clusterNLM", "Number of local maxima of cluster", o2HistType::kTH1I, {{10, 0, 10}}); - mHistManager.add("clusterNCells", "Number of cells in cluster", o2HistType::kTH1I, {{50, 0, 50}}); - mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100}}); + for (bool iBeforeCuts : {false, true}) { + const char* ClusterDirectory = iBeforeCuts ? "ClustersBeforeCuts" : "ClustersAfterCuts"; + mHistManager.add(Form("%s/clusterE", ClusterDirectory), "Energy of cluster", o2HistType::kTH1F, {energyAxis}); + mHistManager.add(Form("%s/clusterE_SimpleBinning", ClusterDirectory), "Energy of cluster", o2HistType::kTH1F, {{400, 0, 100, "#it{E} (GeV)"}}); + mHistManager.add(Form("%s/clusterTime", ClusterDirectory), "Time of cluster", o2HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}); + mHistManager.add(Form("%s/clusterEtaPhi", ClusterDirectory), "Eta and phi of cluster", o2HistType::kTH2F, {{100, -1, 1, "#eta"}, {100, 0, 2 * TMath::Pi(), "#phi"}}); + mHistManager.add(Form("%s/clusterM02", ClusterDirectory), "M02 of cluster", o2HistType::kTH1F, {{400, 0, 5, "#it{M}_{02}"}}); + mHistManager.add(Form("%s/clusterM20", ClusterDirectory), "M20 of cluster", o2HistType::kTH1F, {{400, 0, 2.5, "#it{M}_{20}"}}); + mHistManager.add(Form("%s/clusterNLM", ClusterDirectory), "Number of local maxima of cluster", o2HistType::kTH1I, {{10, 0, 10, "#it{N}_{local maxima}"}}); + mHistManager.add(Form("%s/clusterNCells", ClusterDirectory), "Number of cells in cluster", o2HistType::kTH1I, {{50, 0, 50, "#it{N}_{cells}"}}); + mHistManager.add(Form("%s/clusterDistanceToBadChannel", ClusterDirectory), "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100, "#it{d}"}}); + } // meson related histograms mHistManager.add("invMassVsPt", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); @@ -234,9 +237,8 @@ struct Pi0QCTask { } } } - /// \brief Process EMCAL clusters that are matched to a collisions - // void processCollisions(collisionEvSelIt const& collision, selectedClusters const& clusters) + /// \brief Process EMCAL clusters that are matched to a collisions void processCollisions(o2::soa::Join::iterator const& collision, selectedClusters const& clusters) { // for(const auto & collision : theCollisions){ @@ -258,7 +260,7 @@ struct Pi0QCTask { mHistManager.fill(HIST("eventVertexZSelected"), collision.posZ()); ProcessClusters(clusters); - ProcessMesons(clusters); + ProcessMesons(); } PROCESS_SWITCH(Pi0QCTask, processCollisions, "Process clusters from collision", false); @@ -280,8 +282,8 @@ struct Pi0QCTask { } mHistManager.fill(HIST("eventBCSelected"), eventIR.bc); - ProcessAmbigousClusters(clusters); - ProcessMesons(clusters); + ProcessAmbiguousClusters(clusters); + ProcessMesons(); } PROCESS_SWITCH(Pi0QCTask, processAmbiguous, "Process Ambiguous clusters", false); @@ -309,50 +311,21 @@ struct Pi0QCTask { LOG(info) << "Something went wrong with the collision ID"; } - // fill histograms of cluster properties - // in this implementation the cluster properties are directly - // loaded from the flat table, in the future one should - // consider using the AnalysisCluster object to work with - // after loading. - LOG(debug) << "Cluster energy: " << cluster.energy(); - LOG(debug) << "Cluster time: " << cluster.time(); - LOG(debug) << "Cluster M02: " << cluster.m02(); - mHistManager.fill(HIST("clusterE"), cluster.energy()); - mHistManager.fill(HIST("clusterTime"), cluster.time()); - mHistManager.fill(HIST("clusterE_SimpleBinning"), cluster.energy()); - mHistManager.fill(HIST("clusterEtaPhi"), cluster.eta(), cluster.phi()); - mHistManager.fill(HIST("clusterM02"), cluster.m02()); - mHistManager.fill(HIST("clusterM20"), cluster.m20()); - mHistManager.fill(HIST("clusterNLM"), cluster.nlm()); - mHistManager.fill(HIST("clusterNCells"), cluster.nCells()); - mHistManager.fill(HIST("clusterDistanceToBadChannel"), cluster.distanceToBadChannel()); - - // apply basic cluster cuts - if (cluster.energy() < mMinEnergyCut) { - LOG(debug) << "Cluster rejected because of energy cut"; - continue; - } - if (cluster.nCells() <= mMinNCellsCut) { - LOG(debug) << "Cluster rejected because of nCells cut"; - continue; - } - if (cluster.m02() < mClusterMinM02Cut || cluster.m02() > mClusterMaxM02Cut) { - LOG(debug) << "Cluster rejected because of m02 cut"; - continue; - } - if (cluster.time() < mTimeMin || cluster.time() > mTimeMax) { - LOG(debug) << "Cluster rejected because of time cut"; + FillClusterQAHistos(cluster); + + if (ClusterRejectedByCut(cluster)) continue; - } + + FillClusterQAHistos(cluster); // put clusters in photon vector mPhotons.push_back(Photon(cluster.eta(), cluster.phi(), cluster.energy(), cluster.id())); } } - /// \brief Process EMCAL clusters that are matched to a collisions + /// \brief Process EMCAL clusters that are not matched to a collisions template - void ProcessAmbigousClusters(Clusters const& clusters) + void ProcessAmbiguousClusters(Clusters const& clusters) { LOG(debug) << "ProcessClusters"; // clear photon vector @@ -361,50 +334,70 @@ struct Pi0QCTask { // loop over all clusters from accepted collision for (const auto& cluster : clusters) { - // fill histograms of cluster properties - // in this implementation the cluster properties are directly - // loaded from the flat table, in the future one should - // consider using the AnalysisCluster object to work with - // after loading. - LOG(debug) << "Cluster energy: " << cluster.energy(); - LOG(debug) << "Cluster time: " << cluster.time(); - LOG(debug) << "Cluster M02: " << cluster.m02(); - mHistManager.fill(HIST("clusterE"), cluster.energy()); - mHistManager.fill(HIST("clusterTime"), cluster.time()); - mHistManager.fill(HIST("clusterE_SimpleBinning"), cluster.energy()); - mHistManager.fill(HIST("clusterEtaPhi"), cluster.eta(), cluster.phi()); - mHistManager.fill(HIST("clusterM02"), cluster.m02()); - mHistManager.fill(HIST("clusterM20"), cluster.m20()); - mHistManager.fill(HIST("clusterNLM"), cluster.nlm()); - mHistManager.fill(HIST("clusterNCells"), cluster.nCells()); - mHistManager.fill(HIST("clusterDistanceToBadChannel"), cluster.distanceToBadChannel()); - - // apply basic cluster cuts - if (cluster.energy() < mMinEnergyCut) { - LOG(debug) << "Cluster rejected because of energy cut"; - continue; - } - if (cluster.nCells() <= mMinNCellsCut) { - LOG(debug) << "Cluster rejected because of nCells cut"; - continue; - } - if (cluster.m02() < mClusterMinM02Cut || cluster.m02() > mClusterMaxM02Cut) { - LOG(debug) << "Cluster rejected because of m02 cut"; - continue; - } - if (cluster.time() < mTimeMin || cluster.time() > mTimeMax) { - LOG(debug) << "Cluster rejected because of time cut"; + FillClusterQAHistos(cluster); + + if (ClusterRejectedByCut(cluster)) continue; - } + + FillClusterQAHistos(cluster); // put clusters in photon vector mPhotons.push_back(Photon(cluster.eta(), cluster.phi(), cluster.energy(), cluster.id())); } } + /// \brief Fills the standard QA histograms for a given cluster + template + void FillClusterQAHistos(Cluster const& cluster) + { + // In this implementation the cluster properties are directly loaded from the flat table, + // in the future one should consider using the AnalysisCluster object to work with after loading. + static constexpr std::string_view clusterQAHistEnergy[2] = {"ClustersBeforeCuts/clusterE", "ClustersAfterCuts/clusterE"}; + static constexpr std::string_view clusterQAHistEnergySimpleBinning[2] = {"ClustersBeforeCuts/clusterE_SimpleBinning", "ClustersAfterCuts/clusterE_SimpleBinning"}; + static constexpr std::string_view clusterQAHistTime[2] = {"ClustersBeforeCuts/clusterTime", "ClustersAfterCuts/clusterTime"}; + static constexpr std::string_view clusterQAHistEtaPhi[2] = {"ClustersBeforeCuts/clusterEtaPhi", "ClustersAfterCuts/clusterEtaPhi"}; + static constexpr std::string_view clusterQAHistM02[2] = {"ClustersBeforeCuts/clusterM02", "ClustersAfterCuts/clusterM02"}; + static constexpr std::string_view clusterQAHistM20[2] = {"ClustersBeforeCuts/clusterM20", "ClustersAfterCuts/clusterM20"}; + static constexpr std::string_view clusterQAHistNLM[2] = {"ClustersBeforeCuts/clusterNLM", "ClustersAfterCuts/clusterNLM"}; + static constexpr std::string_view clusterQAHistNCells[2] = {"ClustersBeforeCuts/clusterNCells", "ClustersAfterCuts/clusterNCells"}; + static constexpr std::string_view clusterQAHistDistanceToBadChannel[2] = {"ClustersBeforeCuts/clusterDistanceToBadChannel", "ClustersAfterCuts/clusterDistanceToBadChannel"}; + mHistManager.fill(HIST(clusterQAHistEnergy[BeforeCuts]), cluster.energy()); + mHistManager.fill(HIST(clusterQAHistEnergySimpleBinning[BeforeCuts]), cluster.energy()); + mHistManager.fill(HIST(clusterQAHistTime[BeforeCuts]), cluster.time()); + mHistManager.fill(HIST(clusterQAHistEtaPhi[BeforeCuts]), cluster.eta(), cluster.phi()); + mHistManager.fill(HIST(clusterQAHistM02[BeforeCuts]), cluster.m02()); + mHistManager.fill(HIST(clusterQAHistM20[BeforeCuts]), cluster.m20()); + mHistManager.fill(HIST(clusterQAHistNLM[BeforeCuts]), cluster.nlm()); + mHistManager.fill(HIST(clusterQAHistNCells[BeforeCuts]), cluster.nCells()); + mHistManager.fill(HIST(clusterQAHistDistanceToBadChannel[BeforeCuts]), cluster.distanceToBadChannel()); + } + + /// \brief Return a boolean that states, whether a cluster should be rejected by the applied cluster cuts + template + bool ClusterRejectedByCut(Cluster const& cluster) + { + // apply basic cluster cuts + if (cluster.energy() < mMinEnergyCut) { + LOG(debug) << "Cluster rejected because of energy cut"; + return true; + } + if (cluster.nCells() <= mMinNCellsCut) { + LOG(debug) << "Cluster rejected because of nCells cut"; + return true; + } + if (cluster.m02() < mClusterMinM02Cut || cluster.m02() > mClusterMaxM02Cut) { + LOG(debug) << "Cluster rejected because of m02 cut"; + return true; + } + if (cluster.time() < mTimeMin || cluster.time() > mTimeMax) { + LOG(debug) << "Cluster rejected because of time cut"; + return true; + } + return false; + } + /// \brief Process meson candidates, calculate invariant mass and pT and fill histograms - template - void ProcessMesons(Clusters const& clusters) + void ProcessMesons() { LOG(debug) << "ProcessMesons " << mPhotons.size(); @@ -525,7 +518,6 @@ struct Pi0QCTask { /// \return vector with bin limits std::vector makeClusterBinning() const { - std::vector result; int nBinsPt = 179; double maxPt = 60; From f216f64113082d78f327edecfa7d5febf4191f9a Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Mon, 11 Dec 2023 19:36:46 +0100 Subject: [PATCH 030/156] PWGHF: add possibility to use ML scores of D- mesons and improve B0 task (#4098) * PWGHF: add possibility to use ML scores of D- mesons and improve B0 task * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot --- PWGHF/Core/HfHelper.h | 29 + PWGHF/D2H/DataModel/ReducedDataModel.h | 11 +- .../candidateCreatorB0Reduced.cxx | 261 ++++---- .../candidateSelectorB0ToDPiReduced.cxx | 70 ++- PWGHF/D2H/Tasks/taskB0Reduced.cxx | 556 ++++++++++++------ 5 files changed, 636 insertions(+), 291 deletions(-) diff --git a/PWGHF/Core/HfHelper.h b/PWGHF/Core/HfHelper.h index 4b258566417..8bbca1fa659 100644 --- a/PWGHF/Core/HfHelper.h +++ b/PWGHF/Core/HfHelper.h @@ -890,6 +890,35 @@ class HfHelper return true; } + /// Apply selection on ML scores for charm-hadron daughter in b-hadron decays (common for all the beauty channels) + /// \param candB b-hadron candidates + /// \param cuts ML score selection per bin of charm-hadron pT + /// \param binsPtC pT bin limits of charm hadron + /// \return true if b-hadron candidate passes all selections + template + bool selectionDmesMlScoresForB(const T1& candB, const T2& cuts, const T3& binsPtC) + { + auto ptC = RecoDecay::pt(candB.pxProng0(), candB.pyProng0()); // the first daughter is the charm hadron + int pTBin = o2::analysis::findBin(binsPtC, ptC); + if (pTBin == -1) { + return false; + } + + if (candB.prong0MlScoreBkg() > cuts->get(pTBin, "ML score charm bkg")) { + return false; + } + + if (candB.prong0MlScorePrompt() > cuts->get(pTBin, "ML score charm prompt")) { // we want non-prompt for beauty + return false; + } + + if (candB.prong0MlScoreNonprompt() < cuts->get(pTBin, "ML score charm nonprompt")) { // we want non-prompt for beauty + return false; + } + + return true; + } + private: }; diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 35a58606074..fd0a9f3b1f1 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -207,11 +207,20 @@ namespace hf_cand_b0_reduced { DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfRed3Prongs, "_0"); //! Prong0 index DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, HfRedTrackBases, "_1"); //! Prong1 index +DECLARE_SOA_COLUMN(Prong0MlScoreBkg, prong0MlScoreBkg, float); //! Bkg ML score of the D daughter +DECLARE_SOA_COLUMN(Prong0MlScorePrompt, prong0MlScorePrompt, float); //! Prompt ML score of the D daughter +DECLARE_SOA_COLUMN(Prong0MlScoreNonprompt, prong0MlScoreNonprompt, float); //! Nonprompt ML score of the D daughter } // namespace hf_cand_b0_reduced -DECLARE_SOA_TABLE(HfRedB0Prongs, "AOD", "HFREDB0PRONG", +DECLARE_SOA_TABLE(HfRedB0Prongs, "AOD", "HFREDB0PRONG", //! Table with B0 daughter indices hf_cand_b0_reduced::Prong0Id, hf_cand_b0_reduced::Prong1Id); +DECLARE_SOA_TABLE(HfRedB0DpMls, "AOD", "HFREDB0DPML", //! Table with ML scores for the D+ daughter + hf_cand_b0_reduced::Prong0MlScoreBkg, + hf_cand_b0_reduced::Prong0MlScorePrompt, + hf_cand_b0_reduced::Prong0MlScoreNonprompt, + o2::soa::Marker<1>); + using HfRedCandB0 = soa::Join; namespace hf_cand_bplus_reduced diff --git a/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx index fb5c9184f40..844945d399d 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx @@ -13,6 +13,7 @@ /// \brief Reconstruction of B0 candidates /// /// \author Alexandre Bigot , IPHC Strasbourg +/// \author Fabrizio Grosa , CERN #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" @@ -34,37 +35,44 @@ using namespace o2::framework::expressions; /// Reconstruction of B0 candidates struct HfCandidateCreatorB0Reduced { - Produces rowCandidateBase; // table defined in CandidateReconstructionTables.h - Produces rowCandidateProngs; // table defined in ReducedDataModel.h + Produces rowCandidateBase; // table defined in CandidateReconstructionTables.h + Produces rowCandidateProngs; // table defined in ReducedDataModel.h + Produces rowCandidateDmesMlScores; // table defined in ReducedDataModel.h // vertexing Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; - Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; - Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; - Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any B0 is smaller than this"}; - Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations is chi2/chi2old > this"}; + Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any B0 is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations is chi2/chi2old > this"}; // selection - Configurable invMassWindowDPiTolerance{"invMassWindowDPiTolerance", 0.01, "invariant-mass window tolerance for DPi pair preselections (GeV/c2)"}; + Configurable invMassWindowDPiTolerance{"invMassWindowDPiTolerance", 0.01, "invariant-mass window tolerance for DPi pair preselections (GeV/c2)"}; // variable that will store the value of invMassWindowDPi (defined in dataCreatorDplusPiReduced.cxx) float myInvMassWindowDPi{1.}; - double massPi{0.}; - double massD{0.}; - double massB0{0.}; - double bz{0.}; + float massPi{0.}; + float massD{0.}; + float massB0{0.}; + float bz{0.}; // Fitter for B vertex (2-prong vertex filter) o2::vertexing::DCAFitterN<2> df2; Preslice> candsDPerCollision = hf_track_index_reduced::hfRedCollisionId; + Preslice> candsDWithMlPerCollision = hf_track_index_reduced::hfRedCollisionId; Preslice> tracksPionPerCollision = hf_track_index_reduced::hfRedCollisionId; HistogramRegistry registry{"registry"}; void init(InitContext const&) { + std::array doprocess{doprocessData, doprocessDataWithDmesMl}; + if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { + LOGP(fatal, "Only one process function for data should be enabled at a time."); + } + // histograms registry.add("hMassB0ToDPi", "2-prong candidates;inv. mass (B^{0} #rightarrow D^{#minus}#pi^{#plus} #rightarrow #pi^{#minus}K^{#plus}#pi^{#minus}#pi^{#plus}) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 3., 8.}}}); registry.add("hCovPVXX", "2-prong candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}); @@ -86,11 +94,106 @@ struct HfCandidateCreatorB0Reduced { df2.setWeightedFinalPCA(useWeightedFinalPCA); } - void process(aod::HfRedCollisions const& collisions, - soa::Join const& candsD, - soa::Join const& tracksPion, - aod::HfOrigColCounts const& collisionsCounter, - aod::HfCandB0Configs const& configs) + /// Main function to perform B0 candidate creation + /// \param withDmesMl is the flag to use the table with ML scores for the D- daughter (only possible if present in the derived data) + /// \param collision the collision + /// \param candsDThisColl B0 candidates in this collision + /// \param tracksPionThisCollision pion tracks in this collision + /// \param invMass2DPiMin minimum B0 invariant-mass + /// \param invMass2DPiMax maximum B0 invariant-mass + template + void runCandidateCreation(aod::HfRedCollisions::iterator const& collision, + Cands const& candsDThisColl, + Pions const& tracksPionThisCollision, + const float& invMass2DPiMin, + const float& invMass2DPiMax) + { + auto primaryVertex = getPrimaryVertex(collision); + auto covMatrixPV = primaryVertex.getCov(); + + // Set the magnetic field from ccdb + bz = collision.bz(); + df2.setBz(bz); + + for (const auto& candD : candsDThisColl) { + auto trackParCovD = getTrackParCov(candD); + std::array pVecD = {candD.px(), candD.py(), candD.pz()}; + + for (const auto& trackPion : tracksPionThisCollision) { + // this track is among daughters + if (trackPion.trackId() == candD.prong0Id() || trackPion.trackId() == candD.prong1Id() || trackPion.trackId() == candD.prong2Id()) { + continue; + } + + auto trackParCovPi = getTrackParCov(trackPion); + std::array pVecPion = {trackPion.px(), trackPion.py(), trackPion.pz()}; + + // compute invariant mass square and apply selection + auto invMass2DPi = RecoDecay::m2(std::array{pVecD, pVecPion}, std::array{massD, massPi}); + if ((invMass2DPi < invMass2DPiMin) || (invMass2DPi > invMass2DPiMax)) { + continue; + } + // --------------------------------- + // reconstruct the 2-prong B0 vertex + if (df2.process(trackParCovD, trackParCovPi) == 0) { + continue; + } + // DPi passed B0 reconstruction + + // calculate relevant properties + const auto& secondaryVertexB0 = df2.getPCACandidate(); + auto chi2PCA = df2.getChi2AtPCACandidate(); + auto covMatrixPCA = df2.calcPCACovMatrixFlat(); + registry.fill(HIST("hCovSVXX"), covMatrixPCA[0]); + registry.fill(HIST("hCovPVXX"), covMatrixPV[0]); + + // propagate D and Pi to the B0 vertex + df2.propagateTracksToVertex(); + // track.getPxPyPzGlo(pVec) modifies pVec of track + df2.getTrack(0).getPxPyPzGlo(pVecD); // momentum of D at the B0 vertex + df2.getTrack(1).getPxPyPzGlo(pVecPion); // momentum of Pi at the B0 vertex + + registry.fill(HIST("hMassB0ToDPi"), std::sqrt(invMass2DPi)); + + // compute impact parameters of D and Pi + o2::dataformats::DCA dcaD; + o2::dataformats::DCA dcaPion; + trackParCovD.propagateToDCA(primaryVertex, bz, &dcaD); + trackParCovPi.propagateToDCA(primaryVertex, bz, &dcaPion); + + // get uncertainty of the decay length + float phi, theta; + // getPointDirection modifies phi and theta + getPointDirection(std::array{collision.posX(), collision.posY(), collision.posZ()}, secondaryVertexB0, phi, theta); + auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixPCA, phi, theta)); + auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.)); + + // fill the candidate table for the B0 here: + rowCandidateBase(collision.globalIndex(), + collision.posX(), collision.posY(), collision.posZ(), + secondaryVertexB0[0], secondaryVertexB0[1], secondaryVertexB0[2], + errorDecayLength, errorDecayLengthXY, + chi2PCA, + pVecD[0], pVecD[1], pVecD[2], + pVecPion[0], pVecPion[1], pVecPion[2], + dcaD.getY(), dcaPion.getY(), + std::sqrt(dcaD.getSigmaY2()), std::sqrt(dcaPion.getSigmaY2()), + BIT(hf_cand_b0::DecayType::B0ToDPi)); + + rowCandidateProngs(candD.globalIndex(), trackPion.globalIndex()); + + if constexpr (withDmesMl) { + rowCandidateDmesMlScores(candD.mlScoreBkg(), candD.mlScorePrompt(), candD.mlScoreNonprompt()); + } + } // pi loop + } // D loop + } + + void processData(aod::HfRedCollisions const& collisions, + soa::Join const& candsD, + soa::Join const& tracksPion, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCandB0Configs const& configs) { // DPi invariant-mass window cut for (const auto& config : configs) { @@ -98,104 +201,62 @@ struct HfCandidateCreatorB0Reduced { } // invMassWindowDPiTolerance is used to apply a slightly tighter cut than in DPi pair preselection // to avoid accepting DPi pairs that were not formed in DPi pair creator - double invMass2DPiMin = (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); - double invMass2DPiMax = (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); + float invMass2DPiMin = (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); + float invMass2DPiMax = (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); for (const auto& collisionCounter : collisionsCounter) { registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); } static int ncol = 0; - for (const auto& collision : collisions) { auto thisCollId = collision.globalIndex(); - auto primaryVertex = getPrimaryVertex(collision); - auto covMatrixPV = primaryVertex.getCov(); - + auto candsDThisColl = candsD.sliceBy(candsDPerCollision, thisCollId); + auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); + runCandidateCreation(collision, candsDThisColl, tracksPionThisCollision, invMass2DPiMin, invMass2DPiMax); if (ncol % 10000 == 0) { - LOG(debug) << ncol << " collisions parsed"; + LOGP(debug, "collisions parsed {}", ncol); } ncol++; + } + } // processData - // Set the magnetic field from ccdb - bz = collision.bz(); - df2.setBz(bz); + PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processData, "Process data without any ML score", true); + void processDataWithDmesMl(aod::HfRedCollisions const& collisions, + soa::Join const& candsD, + soa::Join const& tracksPion, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCandB0Configs const& configs) + { + // DPi invariant-mass window cut + for (const auto& config : configs) { + myInvMassWindowDPi = config.myInvMassWindowDPi(); + } + // invMassWindowDPiTolerance is used to apply a slightly tighter cut than in DPi pair preselection + // to avoid accepting DPi pairs that were not formed in DPi pair creator + float invMass2DPiMin = (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); + float invMass2DPiMax = (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); + + for (const auto& collisionCounter : collisionsCounter) { + registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); + } + + static int ncol = 0; + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD.sliceBy(candsDPerCollision, thisCollId); - for (const auto& candD : candsDThisColl) { - auto trackParCovD = getTrackParCov(candD); - std::array pVecD = {candD.px(), candD.py(), candD.pz()}; - - auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); - for (const auto& trackPion : tracksPionThisCollision) { - // this track is among daughters - if (trackPion.trackId() == candD.prong0Id() || trackPion.trackId() == candD.prong1Id() || trackPion.trackId() == candD.prong2Id()) { - continue; - } - - auto trackParCovPi = getTrackParCov(trackPion); - std::array pVecPion = {trackPion.px(), trackPion.py(), trackPion.pz()}; - - // compute invariant mass square and apply selection - auto invMass2DPi = RecoDecay::m2(std::array{pVecD, pVecPion}, std::array{massD, massPi}); - if ((invMass2DPi < invMass2DPiMin) || (invMass2DPi > invMass2DPiMax)) { - continue; - } - // --------------------------------- - // reconstruct the 2-prong B0 vertex - if (df2.process(trackParCovD, trackParCovPi) == 0) { - continue; - } - // DPi passed B0 reconstruction - - // calculate relevant properties - const auto& secondaryVertexB0 = df2.getPCACandidate(); - auto chi2PCA = df2.getChi2AtPCACandidate(); - auto covMatrixPCA = df2.calcPCACovMatrixFlat(); - registry.fill(HIST("hCovSVXX"), covMatrixPCA[0]); - registry.fill(HIST("hCovPVXX"), covMatrixPV[0]); - - // propagate D and Pi to the B0 vertex - df2.propagateTracksToVertex(); - // track.getPxPyPzGlo(pVec) modifies pVec of track - df2.getTrack(0).getPxPyPzGlo(pVecD); // momentum of D at the B0 vertex - df2.getTrack(1).getPxPyPzGlo(pVecPion); // momentum of Pi at the B0 vertex - - registry.fill(HIST("hMassB0ToDPi"), std::sqrt(invMass2DPi)); - - // compute impact parameters of D and Pi - o2::dataformats::DCA dcaD; - o2::dataformats::DCA dcaPion; - trackParCovD.propagateToDCA(primaryVertex, bz, &dcaD); - trackParCovPi.propagateToDCA(primaryVertex, bz, &dcaPion); - - // get uncertainty of the decay length - double phi, theta; - // getPointDirection modifies phi and theta - getPointDirection(std::array{collision.posX(), collision.posY(), collision.posZ()}, secondaryVertexB0, phi, theta); - auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixPCA, phi, theta)); - auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.)); - - int hfFlag = BIT(hf_cand_b0::DecayType::B0ToDPi); - - // fill the candidate table for the B0 here: - rowCandidateBase(thisCollId, - collision.posX(), collision.posY(), collision.posZ(), - secondaryVertexB0[0], secondaryVertexB0[1], secondaryVertexB0[2], - errorDecayLength, errorDecayLengthXY, - chi2PCA, - pVecD[0], pVecD[1], pVecD[2], - pVecPion[0], pVecPion[1], pVecPion[2], - dcaD.getY(), dcaPion.getY(), - std::sqrt(dcaD.getSigmaY2()), std::sqrt(dcaPion.getSigmaY2()), - hfFlag); - - rowCandidateProngs(candD.globalIndex(), trackPion.globalIndex()); - } // pi loop - } // D loop - } // collision loop - } // process -}; // struct + auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); + runCandidateCreation(collision, candsDThisColl, tracksPionThisCollision, invMass2DPiMin, invMass2DPiMax); + if (ncol % 10000 == 0) { + LOGP(debug, "collisions parsed {}", ncol); + } + ncol++; + } + } // processDataWithDmesMl + + PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processDataWithDmesMl, "Process data with ML scores of D mesons", false); +}; // struct /// Extends the table base with expression columns and performs MC matching. struct HfCandidateCreatorB0ReducedExpressions { diff --git a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx index 4b88fcdaa98..262ef26aca5 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx @@ -13,6 +13,7 @@ /// \brief B0 → D- π+ candidate selector /// /// \author Alexandre Bigot , IPHC Strasbourg +/// \author Fabrizio Grosa , CERN #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -33,24 +34,27 @@ using namespace o2::analysis; struct HfCandidateSelectorB0ToDPiReduced { Produces hfSelB0ToDPiCandidate; // table defined in CandidateSelectionTables.h - Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; - Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; + Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; + Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; // Enable PID Configurable usePid{"usePid", true, "Switch for PID selection at track level"}; Configurable acceptPIDNotApplicable{"acceptPIDNotApplicable", true, "Switch to accept Status::NotApplicable [(NotApplicable for one detector) and (NotApplicable or Conditional for the other)] in PID selection"}; // TPC PID - Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Lower bound of track pT for TPC PID"}; - Configurable ptPidTpcMax{"ptPidTpcMax", 20., "Upper bound of track pT for TPC PID"}; - Configurable nSigmaTpcMax{"nSigmaTpcMax", 5., "Nsigma cut on TPC only"}; - Configurable nSigmaTpcCombinedMax{"nSigmaTpcCombinedMax", 5., "Nsigma cut on TPC combined with TOF"}; + Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Lower bound of track pT for TPC PID"}; + Configurable ptPidTpcMax{"ptPidTpcMax", 20., "Upper bound of track pT for TPC PID"}; + Configurable nSigmaTpcMax{"nSigmaTpcMax", 5., "Nsigma cut on TPC only"}; + Configurable nSigmaTpcCombinedMax{"nSigmaTpcCombinedMax", 5., "Nsigma cut on TPC combined with TOF"}; // TOF PID - Configurable ptPidTofMin{"ptPidTofMin", 0.15, "Lower bound of track pT for TOF PID"}; - Configurable ptPidTofMax{"ptPidTofMax", 20., "Upper bound of track pT for TOF PID"}; - Configurable nSigmaTofMax{"nSigmaTofMax", 5., "Nsigma cut on TOF only"}; - Configurable nSigmaTofCombinedMax{"nSigmaTofCombinedMax", 5., "Nsigma cut on TOF combined with TPC"}; + Configurable ptPidTofMin{"ptPidTofMin", 0.15, "Lower bound of track pT for TOF PID"}; + Configurable ptPidTofMax{"ptPidTofMax", 20., "Upper bound of track pT for TOF PID"}; + Configurable nSigmaTofMax{"nSigmaTofMax", 5., "Nsigma cut on TOF only"}; + Configurable nSigmaTofCombinedMax{"nSigmaTofCombinedMax", 5., "Nsigma cut on TOF combined with TPC"}; // topological cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_b0_to_d_pi::vecBinsPt}, "pT bin limits"}; Configurable> cuts{"cuts", {hf_cuts_b0_to_d_pi::cuts[0], hf_cuts_b0_to_d_pi::nBinsPt, hf_cuts_b0_to_d_pi::nCutVars, hf_cuts_b0_to_d_pi::labelsPt, hf_cuts_b0_to_d_pi::labelsCutVar}, "B0 candidate selection per pT bin"}; + // D-meson ML cuts + Configurable> binsPtDmesMl{"binsPtDmesMl", std::vector{hf_cuts_ml::vecBinsPt}, "D-meson pT bin limits for ML cuts"}; + Configurable> cutsDmesMl{"cutsDmesMl", {hf_cuts_ml::cuts[0], hf_cuts_ml::nBinsPt, hf_cuts_ml::nCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "D-meson ML cuts per pT bin"}; // QA switch Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; @@ -68,6 +72,11 @@ struct HfCandidateSelectorB0ToDPiReduced { void init(InitContext const& initContext) { + std::array doprocess{doprocessSelection, doprocessSelectionWithDmesMl}; + if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { + LOGP(fatal, "Only one process function for data should be enabled at a time."); + } + if (usePid) { selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); selectorPion.setRangeNSigmaTpc(-nSigmaTpcMax, nSigmaTpcMax); @@ -92,9 +101,15 @@ struct HfCandidateSelectorB0ToDPiReduced { } } - void process(HfRedCandB0 const& hfCandsB0, - TracksPion const&, - HfCandB0Configs const& configs) + /// Main function to perform B0 candidate creation + /// \param withDmesMl is the flag to use the table with ML scores for the D- daughter (only possible if present in the derived data) + /// \param hfCandsB0 B0 candidates + /// \param pionTracks pion tracks + /// \param configs config inherited from the Dpi data creator + template + void runSelection(Cands const& hfCandsB0, + TracksPion const& pionTracks, + HfCandB0Configs const& configs) { // get DplusPi creator configurable for (const auto& config : configs) { @@ -134,6 +149,15 @@ struct HfCandidateSelectorB0ToDPiReduced { // LOGF(info, "B0 candidate selection failed at topology selection"); continue; } + + if constexpr (withDmesMl) { // we include it in the topological selections + if (!hfHelper.selectionDmesMlScoresForB(hfCandB0, cutsDmesMl, binsPtDmesMl)) { + hfSelB0ToDPiCandidate(statusB0ToDPi); + // LOGF(info, "B0 candidate selection failed at D-meson ML selection"); + continue; + } + } + SETBIT(statusB0ToDPi, SelectionStep::RecoTopol); // RecoTopol = 1 --> statusB0ToDPi = 3 if (activateQA) { registry.fill(HIST("hSelections"), 2 + SelectionStep::RecoTopol, ptCandB0); @@ -146,7 +170,7 @@ struct HfCandidateSelectorB0ToDPiReduced { } // track-level PID selection if (usePid) { - auto trackPi = hfCandB0.prong1_as(); + auto trackPi = hfCandB0.template prong1_as(); int pidTrackPi = selectorPion.statusTpcAndTof(trackPi); if (!hfHelper.selectionB0ToDPiPid(pidTrackPi, acceptPIDNotApplicable.value)) { // LOGF(info, "B0 candidate selection failed at PID selection"); @@ -162,6 +186,24 @@ struct HfCandidateSelectorB0ToDPiReduced { // LOGF(info, "B0 candidate selection passed all selections"); } } + + void processSelection(HfRedCandB0 const& hfCandsB0, + TracksPion const& pionTracks, + HfCandB0Configs const& configs) + { + runSelection(hfCandsB0, pionTracks, configs); + } // processSelection + + PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelection, "Process selection without ML scores of D mesons", true); + + void processSelectionWithDmesMl(soa::Join const& hfCandsB0, + TracksPion const& pionTracks, + HfCandB0Configs const& configs) + { + runSelection(hfCandsB0, pionTracks, configs); + } // processSelectionWithDmesMl + + PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelectionWithDmesMl, "Process selection with ML scores of D mesons", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index d316b0c0ca4..d1c69d61b33 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -13,6 +13,7 @@ /// \brief B0 → D- π+ → (π- K+ π-) π+ analysis task /// /// \author Alexandre Bigot , IPHC Strasbourg +/// \author Fabrizio Grosa , CERN #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" @@ -34,89 +35,168 @@ using namespace o2::framework::expressions; /// B0 analysis task struct HfTaskB0Reduced { Configurable selectionFlagB0{"selectionFlagB0", 1, "Selection Flag for B0"}; - Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; - Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; + Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; + Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; Configurable etaTrackMax{"etaTrackMax", 0.8, "max. track pseudo-rapidity"}; Configurable ptTrackMin{"ptTrackMin", 0.1, "min. track transverse momentum"}; - Configurable> binsPt{"binsPt", std::vector{hf_cuts_b0_to_d_pi::vecBinsPt}, "pT bin limits"}; + Configurable fillHistograms{"fillHistograms", true, "Flag to enable histogram filling"}; + Configurable fillSparses{"fillSparses", false, "Flag to enable sparse filling"}; + Configurable fillBackground{"fillBackground", false, "Flag to enable filling of background histograms/sparses (only MC)"}; HfHelper hfHelper; Filter filterSelectCandidates = (aod::hf_sel_candidate_b0::isSelB0ToDPi >= selectionFlagB0); - HistogramRegistry registry{ - "registry", - {{"hPtProng0", "B0 candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0., 50.}}}}, - {"hPtProng1", "B0 candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 10.}}}}, - {"hPtCand", "B0 candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0., 50.}}}}}}; + HistogramRegistry registry{"registry"}; void init(InitContext&) { - registry.add("hMass", "B^{0} candidates;inv. mass D^{#minus}#pi^{#plus} (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{300, 4.5, 6.0}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLength", "B^{0} candidates;decay length (cm);entries", {HistType::kTH2F, {{200, 0., 0.4}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthXY", "B^{0} candidates;decay length xy (cm);entries", {HistType::kTH2F, {{200, 0., 0.4}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong0", "B^{0} candidates;prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -0.05, 0.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong1", "B^{0} candidates;prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -0.05, 0.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPA", "B^{0} candidates;B^{0} candidate cosine of pointing angle;entries", {HistType::kTH2F, {{110, -1.1, 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEta", "B^{0} candidates;B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hRapidity", "B^{0} candidates;B^{0} candidate #it{y};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hImpParErr", "B^{0} candidates;B^{0} candidate impact parameter error (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLenErr", "B^{0} candidates;B^{0} candidate decay length error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLenXYErr", "B^{0} candidates;B^{0} candidate decay length xy error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hIPProd", "B^{0} candidates;B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {{100, -0.5, 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hInvMassD", "B^{0} candidates;prong0, D^{#minus} inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{350, 1.7, 2.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - - registry.add("hEtaGen", "MC particles (generated);B^{0} candidate #it{#eta}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hYGen", "MC particles (generated);B^{0} candidate #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEtaGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);B^{0} candidate #it{#eta}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hYGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);B^{0} candidate #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtProng0Gen", "MC particles (generated);prong 0 (D^{#minus}) #it{p}_{T}^{gen} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtProng1Gen", "MC particles (generated);prong 1 (#pi^{-}) #it{p}_{T}^{gen} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hYProng0Gen", "MC particles (generated);prong 0 (D^{#minus}) #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2, 2}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hYProng1Gen", "MC particles (generated);prong 1 (#pi^{-}) #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2, 2}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEtaProng0Gen", "MC particles (generated);prong 0 (B^{0}) #it{#eta}^{gen};entries", {HistType::kTH2F, {{100, -2, 2}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEtaProng1Gen", "MC particles (generated);prong 1 (#pi^{-}) #it{#eta}^{gen};entries", {HistType::kTH2F, {{100, -2, 2}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPARecSig", "B^{0} candidates (matched);B^{0} candidate cosine of pointing angle;entries", {HistType::kTH2F, {{220, 0., 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPARecBg", "B^{0} candidates (unmatched);B^{0} candidate cosine of pointing angle;entries", {HistType::kTH2F, {{220, 0., 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPAxyRecSig", "B^{0} candidates (matched);B^{0} candidate CPAxy;entries", {HistType::kTH2F, {{220, 0., 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPAxyRecBg", "B^{0} candidates (unmatched);B^{0} candidate CPAxy;entries", {HistType::kTH2F, {{220, 0., 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPADRecSig", "B^{0} candidates (matched);prong 0 (D^{#minus}) cosine of pointing angle;entries", {HistType::kTH2F, {{220, 0., 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPADRecBg", "B^{0} candidates (unmatched);prong 0 (D^{#minus}) cosine of pointing angle;entries", {HistType::kTH2F, {{220, 0., 1.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEtaRecSig", "B^{0} candidates (matched);B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEtaRecBg", "B^{0} candidates (unmatched);B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hRapidityRecSig", "B^{0} candidates (matched);B^{0} candidate #it{y};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hRapidityRecBg", "B^{0} candidates (unmatched);B^{0} candidate #it{#y};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - - registry.add("hPtProng0RecSig", "B^{0} candidates (matched);prong 0 (D^{#minus}) #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtProng1RecSig", "B^{0} candidates (matched);prong 1 (#pi^{#minus}) #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtProng0RecBg", "B^{0} candidates (unmatched);prong 0 (D^{#minus}) #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtProng1RecBg", "B^{0} candidates (unmatched);prong 1 (#pi^{#minus}) #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassRecSig", "B^{0} candidates (matched);inv. mass D^{#minus}#pi^{+} (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{300, 4.0, 7.00}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMassRecBg", "B^{0} candidates (unmatched);inv. mass D^{#minus}#pi^{+} (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{300, 4.0, 7.0}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong0RecSig", "B^{0} candidates (matched);prong 0 (D^{#minus}}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{200, -0.05, 0.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong1RecSig", "B^{0} candidates (matched);prong 1 (#pi^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{200, -0.05, 0.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong0RecBg", "B^{0} candidates (unmatched);prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{200, -0.05, 0.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong1RecBg", "B^{0} candidates (unmatched);prong 1 (#pi^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{200, -0.05, 0.05}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthRecSig", "B^{0} candidates (matched);B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthXYRecSig", "B^{0} candidates (matched);B^{0} candidate decay length xy (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthRecBg", "B^{0} candidates (unmatched);B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthXYRecBg", "B^{0} candidates (unmatched);B^{0} candidate decay length xy(cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthDRecSig", "B^{0} candidates (matched);B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthDRecBg", "B^{0} candidates (unmatched);B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthNormRecSig", "B^{0} candidates (matched);B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecLengthNormRecBg", "B^{0} candidates (unmatched);B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hImpParProdB0RecSig", "B^{0} candidates (matched);B^{0} candidate impact parameter product ;entries", {HistType::kTH2F, {{100, -0.01, 0.01}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hImpParProdB0RecBg", "B^{0} candidates (unmatched);B^{0} candidate impact parameter product ;entries", {HistType::kTH2F, {{100, -0.01, 0.01}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - - registry.add("hChi2PCARecSig", "B^{0} candidates (matched);sum of distances of the secondary vertex to its prongs;entries", {HistType::kTH2F, {{240, -0.01, 0.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hChi2PCARecBg", "B^{0} candidates (unmatched);sum of distances of the secondary vertex to its prongs;entries", {HistType::kTH2F, {{240, -0.01, 0.1}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - - registry.add("hPtRecSig", "B0 candidates (matched);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); - registry.add("hPtRecBg", "B0 candidates (unmatched);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); - registry.add("hPtGenSig", "B0 candidates (gen+rec);candidate #it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 10.}}}); - registry.add("hPtGen", "MC particles (generated);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); - registry.add("hPtGenWithRapidityBelowHalf", "MC particles (generated - |#it{y}^{gen}|<0.5);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); - registry.add("hPtGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); + std::array processFuncData{doprocessData, doprocessDataWithDmesMl}; + if ((std::accumulate(processFuncData.begin(), processFuncData.end(), 0)) > 1) { + LOGP(fatal, "Only one process function for data can be enabled at a time."); + } + std::array processFuncMc{doprocessMc, doprocessMcWithDmesMl}; + if ((std::accumulate(processFuncMc.begin(), processFuncMc.end(), 0)) > 1) { + LOGP(fatal, "Only one process function for MC can be enabled at a time."); + } + + const AxisSpec axisMlScore{100, 0.f, 1.f}; + const AxisSpec axisMassB0{300, 4.5f, 6.0f}; + const AxisSpec axisMassDminus{300, 1.75f, 2.05f}; + const AxisSpec axisDecayLength{200, 0.f, 0.4f}; + const AxisSpec axisNormDecayLength{100, 0.f, 50.f}; + const AxisSpec axisDca{100, -0.05f, 0.05f}; + const AxisSpec axisCosp{110, 0.f, 1.1f}; + const AxisSpec axisEta{30, -1.5f, 1.5f}; + const AxisSpec axisError{100, 0.f, 1.f}; + const AxisSpec axisImpParProd{100, -1.e-3, 1.e-3}; + const AxisSpec axisPtB0{100, 0.f, 50.f}; + const AxisSpec axisPtDminus{100, 0.f, 50.f}; + const AxisSpec axisPtPi{100, 0.f, 10.f}; + + if (doprocessData || doprocessDataWithDmesMl) { + if (fillHistograms) { + registry.add("hMass", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{M} (D#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtB0, axisMassB0}}); + registry.add("hDecLength", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); + registry.add("hDecLengthXy", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); + registry.add("hNormDecLengthXy", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate norm. decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisNormDecayLength}}); + registry.add("hDcaProng0", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hDcaProng1", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hPtProng0", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hCosp", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); + registry.add("hCospXy", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); + registry.add("hEta", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hRapidity", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{y};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hImpParProd", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); + registry.add("hInvMassD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtDminus, axisMassDminus}}); + registry.add("hDecLengthD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hDecLengthXyD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hCospD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hCospXyD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + + // ML scores of D- daughter + if (doprocessDataWithDmesMl) { + registry.add("hMlScoreBkgD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML background score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScorePromptD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML prompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreNonPromptD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML nonprompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + } + } + if (fillSparses) { + if (!doprocessDataWithDmesMl) { + registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);D^{#minus} candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisDecayLength, axisCosp}}); + } else { + registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate ML score bkg;D^{#minus} candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisMlScore, axisMlScore}}); + } + } + } + + if (doprocessMc || doprocessMcWithDmesMl) { + if (fillHistograms) { + // gen histos + registry.add("hEtaGen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(B^{0});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hYGen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(B^{0});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hYGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(B^{0});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hPtProng0Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{p}_{T}^{gen}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{p}_{T}^{gen}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hYProng0Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(D^{#minus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hYProng1Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(#pi^{#plus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hEtaProng0Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(D^{#minus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hEtaProng1Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(#pi^{#plus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + + // reco histos + // signal + registry.add("hMassRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{M} (D#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtB0, axisMassB0}}); + registry.add("hDecLengthRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); + registry.add("hDecLengthXyRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); + registry.add("hNormDecLengthXyRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate norm. decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisNormDecayLength}}); + registry.add("hDcaProng0RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hDcaProng1RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hPtProng0RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hCospRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); + registry.add("hCospXyRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); + registry.add("hEtaRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hRapidityRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{y};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hImpParProdRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); + registry.add("hInvMassDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtDminus, axisMassDminus}}); + registry.add("hDecLengthDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hDecLengthXyDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hCospDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hCospXyDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + // background + if (fillBackground) { + registry.add("hMassRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{M} (D#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtB0, axisMassB0}}); + registry.add("hDecLengthRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); + registry.add("hDecLengthXyRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); + registry.add("hNormDecLengthXyRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate norm. decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisNormDecayLength}}); + registry.add("hDcaProng0RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hDcaProng1RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hPtProng0RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hCospRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); + registry.add("hCospXyRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); + registry.add("hEtaRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hRapidityRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{y};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hImpParProdRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); + registry.add("hInvMassDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtDminus, axisMassDminus}}); + registry.add("hDecLengthDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hDecLengthXyDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hCospDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hCospXyDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + } + + // ML scores of D- daughter + if (doprocessMcWithDmesMl) { + // signal + registry.add("hMlScoreBkgDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML background score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScorePromptDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML prompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreNonPromptDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML nonprompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + // background + registry.add("hMlScoreBkgDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML background score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScorePromptDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML prompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreNonPromptDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML nonprompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + } + } + if (fillSparses) { + // gen sparses + registry.add("hPtYGenSig", "B^{0} particles (generated);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{y}(B^{0})", {HistType::kTHnSparseF, {axisPtB0, axisEta}}); + registry.add("hPtYWithProngsInAccepanceGenSig", "B^{0} particles (generated-daughters in acceptance);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{y}(B^{0})", {HistType::kTHnSparseF, {axisPtB0, axisEta}}); + + // reco sparses + if (!doprocessDataWithDmesMl) { + registry.add("hMassPtCutVarsRecSig", "B^{0} candidates (matched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);D^{#minus} candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisDecayLength, axisCosp}}); + if (fillBackground) { + registry.add("hMassPtCutVarsRecBg", "B^{0} candidates (unmatched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);D^{#minus} candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisDecayLength, axisCosp}}); + } + } else { + registry.add("hMassPtCutVarsRecSig", "B^{0} candidates (matched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate ML score bkg;D^{#minus} candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisMlScore, axisMlScore}}); + if (fillBackground) { + registry.add("hMassPtCutVarsRecBg", "B^{0} candidates (unmatched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate ML score bkg;D^{#minus} candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisMlScore, axisMlScore}}); + } + } + } + } } /// Selection of B0 daughter in geometrical acceptance @@ -129,8 +209,191 @@ struct HfTaskB0Reduced { return std::abs(etaProng) <= etaTrackMax && ptProng >= ptTrackMin; } - void process(soa::Filtered> const& candidates, - aod::HfRed3Prongs const&) + /// Fill candidate histograms (reco no MC truth) + /// \param withDmesMl is the flag to enable the filling of hisgorams with ML scores for the D- daughter + /// \param candidate is the B0 candidate + /// \param candidatesD is the table with D- candidates + template + void fillCand(Cand const& candidate, + aod::HfRed3Prongs const& candidatesD) + { + auto ptCandB0 = candidate.pt(); + auto invMassB0 = hfHelper.invMassB0ToDPi(candidate); + auto candD = candidate.template prong0_as(); + auto ptD = RecoDecay::pt(candD.px(), candD.py()); + std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; + std::array posSvD{candD.xSecondaryVertex(), candD.ySecondaryVertex(), candD.zSecondaryVertex()}; + std::array momD{candD.px(), candD.py(), candD.pz()}; + auto cospD = RecoDecay::cpa(posPv, posSvD, momD); + auto cospXyD = RecoDecay::cpaXY(posPv, posSvD, momD); + auto decLenD = RecoDecay::distance(posPv, posSvD); + auto decLenXyD = RecoDecay::distanceXY(posPv, posSvD); + + if (fillHistograms) { + registry.fill(HIST("hMass"), ptCandB0, invMassB0); + registry.fill(HIST("hPtProng0"), ptCandB0, candidate.ptProng0()); + registry.fill(HIST("hPtProng1"), ptCandB0, candidate.ptProng1()); + registry.fill(HIST("hImpParProd"), ptCandB0, candidate.impactParameterProduct()); + registry.fill(HIST("hDecLength"), ptCandB0, candidate.decayLength()); + registry.fill(HIST("hDecLengthXy"), ptCandB0, candidate.decayLengthXY()); + registry.fill(HIST("hNormDecLengthXy"), ptCandB0, candidate.decayLengthXY() / candidate.errorDecayLengthXY()); + registry.fill(HIST("hDcaProng0"), ptCandB0, candidate.impactParameter0()); + registry.fill(HIST("hDcaProng1"), ptCandB0, candidate.impactParameter1()); + registry.fill(HIST("hCosp"), ptCandB0, candidate.cpa()); + registry.fill(HIST("hCospXy"), ptCandB0, candidate.cpaXY()); + registry.fill(HIST("hEta"), ptCandB0, candidate.eta()); + registry.fill(HIST("hRapidity"), ptCandB0, hfHelper.yB0(candidate)); + registry.fill(HIST("hInvMassD"), ptD, candD.invMass()); + registry.fill(HIST("hDecLengthD"), ptD, decLenD); + registry.fill(HIST("hDecLengthXyD"), ptD, decLenXyD); + registry.fill(HIST("hCospD"), ptD, cospD); + registry.fill(HIST("hCospXyD"), ptD, cospXyD); + + if constexpr (withDmesMl) { + registry.fill(HIST("hMlScoreBkgD"), ptD, candidate.prong0MlScoreBkg()); + registry.fill(HIST("hMlScorePromptD"), ptD, candidate.prong0MlScorePrompt()); + registry.fill(HIST("hMlScoreNonPromptD"), ptD, candidate.prong0MlScoreNonprompt()); + } + } + if (fillSparses) { + if constexpr (withDmesMl) { + registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + } else { + registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); + } + } + } + + /// Fill candidate histograms (reco MC truth) + /// \param withDmesMl is the flag to enable the filling of hisgorams with ML scores for the D- daughter + /// \param candidate is the B0 candidate + /// \param candidatesD is the table with D- candidates + template + void fillCandMcReco(Cand const& candidate, + aod::HfRed3Prongs const& candidatesD) + { + auto ptCandB0 = candidate.pt(); + auto invMassB0 = hfHelper.invMassB0ToDPi(candidate); + auto candD = candidate.template prong0_as(); + auto ptD = RecoDecay::pt(candD.px(), candD.py()); + std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; + std::array posSvD{candD.xSecondaryVertex(), candD.ySecondaryVertex(), candD.zSecondaryVertex()}; + std::array momD{candD.px(), candD.py(), candD.pz()}; + auto cospD = RecoDecay::cpa(posPv, posSvD, momD); + auto cospXyD = RecoDecay::cpaXY(posPv, posSvD, momD); + auto decLenD = RecoDecay::distance(posPv, posSvD); + auto decLenXyD = RecoDecay::distanceXY(posPv, posSvD); + + bool isSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), hf_cand_b0::DecayType::B0ToDPi); + if (fillHistograms) { + if (isSignal) { + registry.fill(HIST("hMassRecSig"), ptCandB0, hfHelper.invMassB0ToDPi(candidate)); + registry.fill(HIST("hPtProng0RecSig"), ptCandB0, candidate.ptProng0()); + registry.fill(HIST("hPtProng1RecSig"), ptCandB0, candidate.ptProng1()); + registry.fill(HIST("hImpParProdRecSig"), ptCandB0, candidate.impactParameterProduct()); + registry.fill(HIST("hDecLengthRecSig"), ptCandB0, candidate.decayLength()); + registry.fill(HIST("hDecLengthXyRecSig"), ptCandB0, candidate.decayLengthXY()); + registry.fill(HIST("hNormDecLengthXyRecSig"), ptCandB0, candidate.decayLengthXY() / candidate.errorDecayLengthXY()); + registry.fill(HIST("hDcaProng0RecSig"), ptCandB0, candidate.impactParameter0()); + registry.fill(HIST("hDcaProng1RecSig"), ptCandB0, candidate.impactParameter1()); + registry.fill(HIST("hCospRecSig"), ptCandB0, candidate.cpa()); + registry.fill(HIST("hCospXyRecSig"), ptCandB0, candidate.cpaXY()); + registry.fill(HIST("hEtaRecSig"), ptCandB0, candidate.eta()); + registry.fill(HIST("hRapidityRecSig"), ptCandB0, hfHelper.yB0(candidate)); + registry.fill(HIST("hInvMassDRecSig"), ptD, candD.invMass()); + registry.fill(HIST("hDecLengthDRecSig"), ptD, decLenD); + registry.fill(HIST("hDecLengthXyDRecSig"), ptD, decLenXyD); + registry.fill(HIST("hCospDRecSig"), ptD, cospD); + registry.fill(HIST("hCospXyDRecSig"), ptD, cospXyD); + if constexpr (withDmesMl) { + registry.fill(HIST("hMlScoreBkgDRecSig"), ptD, candidate.prong0MlScoreBkg()); + registry.fill(HIST("hMlScorePromptDRecSig"), ptD, candidate.prong0MlScorePrompt()); + registry.fill(HIST("hMlScoreNonPromptDRecSig"), ptD, candidate.prong0MlScoreNonprompt()); + } + } else if (fillBackground) { + registry.fill(HIST("hMassRecBg"), ptCandB0, hfHelper.invMassB0ToDPi(candidate)); + registry.fill(HIST("hPtProng0RecBg"), ptCandB0, candidate.ptProng0()); + registry.fill(HIST("hPtProng1RecBg"), ptCandB0, candidate.ptProng1()); + registry.fill(HIST("hImpParProdRecBg"), ptCandB0, candidate.impactParameterProduct()); + registry.fill(HIST("hDecLengthRecBg"), ptCandB0, candidate.decayLength()); + registry.fill(HIST("hDecLengthXyRecBg"), ptCandB0, candidate.decayLengthXY()); + registry.fill(HIST("hNormDecLengthXyRecBg"), ptCandB0, candidate.decayLengthXY() / candidate.errorDecayLengthXY()); + registry.fill(HIST("hDcaProng0RecBg"), ptCandB0, candidate.impactParameter0()); + registry.fill(HIST("hDcaProng1RecBg"), ptCandB0, candidate.impactParameter1()); + registry.fill(HIST("hCospRecBg"), ptCandB0, candidate.cpa()); + registry.fill(HIST("hCospXyRecBg"), ptCandB0, candidate.cpaXY()); + registry.fill(HIST("hEtaRecBg"), ptCandB0, candidate.eta()); + registry.fill(HIST("hRapidityRecBg"), ptCandB0, hfHelper.yB0(candidate)); + registry.fill(HIST("hInvMassDRecBg"), ptD, candD.invMass()); + registry.fill(HIST("hDecLengthDRecBg"), ptD, decLenD); + registry.fill(HIST("hDecLengthXyDRecBg"), ptD, decLenXyD); + registry.fill(HIST("hCospDRecBg"), ptD, cospD); + registry.fill(HIST("hCospXyDRecBg"), ptD, cospXyD); + if constexpr (withDmesMl) { + registry.fill(HIST("hMlScoreBkgDRecBg"), ptD, candidate.prong0MlScoreBkg()); + registry.fill(HIST("hMlScorePromptDRecBg"), ptD, candidate.prong0MlScorePrompt()); + registry.fill(HIST("hMlScoreNonPromptDRecBg"), ptD, candidate.prong0MlScoreNonprompt()); + } + } + } + if (fillSparses) { + if (isSignal) { + if constexpr (withDmesMl) { + registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + } else { + registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); + } + } else if (fillBackground) { + if constexpr (withDmesMl) { + registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + } else { + registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); + } + } + } + } + + /// Fill particle histograms (gen MC truth) + void fillCandMcGen(aod::HfMcGenRedB0s::iterator const& particle) + { + auto ptParticle = particle.ptTrack(); + auto yParticle = particle.yTrack(); + auto etaParticle = particle.etaTrack(); + if (yCandGenMax >= 0. && std::abs(yParticle) > yCandGenMax) { + return; + } + std::array ptProngs = {particle.ptProng0(), particle.ptProng1()}; + std::array yProngs = {particle.yProng0(), particle.yProng1()}; + std::array etaProngs = {particle.etaProng0(), particle.etaProng1()}; + bool prongsInAcc = isProngInAcceptance(etaProngs[0], ptProngs[0]) && isProngInAcceptance(etaProngs[1], ptProngs[1]); + + if (fillHistograms) { + registry.fill(HIST("hPtProng0Gen"), ptParticle, ptProngs[0]); + registry.fill(HIST("hPtProng1Gen"), ptParticle, ptProngs[1]); + registry.fill(HIST("hYProng0Gen"), ptParticle, yProngs[0]); + registry.fill(HIST("hYProng1Gen"), ptParticle, yProngs[1]); + registry.fill(HIST("hEtaProng0Gen"), ptParticle, etaProngs[0]); + registry.fill(HIST("hEtaProng1Gen"), ptParticle, etaProngs[1]); + + registry.fill(HIST("hYGen"), ptParticle, yParticle); + registry.fill(HIST("hEtaGen"), ptParticle, etaParticle); + + // generated B0 with daughters in geometrical acceptance + if (prongsInAcc) { + registry.fill(HIST("hYGenWithProngsInAcceptance"), ptParticle, yParticle); + } + } + if (fillSparses) { + registry.fill(HIST("hPtYGenSig"), ptParticle, yParticle); + if (prongsInAcc) { + registry.fill(HIST("hPtYWithProngsInAccepanceGenSig"), ptParticle, yParticle); + } + } + } + + // Process functions + void processData(soa::Filtered> const& candidates, + aod::HfRed3Prongs const& candidatesD) { for (const auto& candidate : candidates) { if (!TESTBIT(candidate.hfflag(), hf_cand_b0::DecayType::B0ToDPi)) { @@ -139,34 +402,31 @@ struct HfTaskB0Reduced { if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { continue; } + fillCand(candidate, candidatesD); + } // candidate loop + } // processData - auto ptCandB0 = candidate.pt(); - auto candD = candidate.prong0_as(); - - registry.fill(HIST("hMass"), hfHelper.invMassB0ToDPi(candidate), ptCandB0); - registry.fill(HIST("hPtCand"), ptCandB0); - registry.fill(HIST("hPtProng0"), candidate.ptProng0()); - registry.fill(HIST("hPtProng1"), candidate.ptProng1()); - registry.fill(HIST("hIPProd"), candidate.impactParameterProduct(), ptCandB0); - registry.fill(HIST("hDecLength"), candidate.decayLength(), ptCandB0); - registry.fill(HIST("hDecLengthXY"), candidate.decayLengthXY(), ptCandB0); - registry.fill(HIST("hd0Prong0"), candidate.impactParameter0(), ptCandB0); - registry.fill(HIST("hd0Prong1"), candidate.impactParameter1(), ptCandB0); - registry.fill(HIST("hCPA"), candidate.cpa(), ptCandB0); - registry.fill(HIST("hEta"), candidate.eta(), ptCandB0); - registry.fill(HIST("hRapidity"), hfHelper.yB0(candidate), ptCandB0); - registry.fill(HIST("hImpParErr"), candidate.errorImpactParameter0(), ptCandB0); - registry.fill(HIST("hImpParErr"), candidate.errorImpactParameter1(), ptCandB0); - registry.fill(HIST("hDecLenErr"), candidate.errorDecayLength(), ptCandB0); - registry.fill(HIST("hDecLenXYErr"), candidate.errorDecayLengthXY(), ptCandB0); - registry.fill(HIST("hInvMassD"), candD.invMass(), ptCandB0); + PROCESS_SWITCH(HfTaskB0Reduced, processData, "Process data without ML scores for D daughter", true); + + void processDataWithDmesMl(soa::Filtered> const& candidates, + aod::HfRed3Prongs const& candidatesD) + { + for (const auto& candidate : candidates) { + if (!TESTBIT(candidate.hfflag(), hf_cand_b0::DecayType::B0ToDPi)) { + continue; + } + if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCand(candidate, candidatesD); } // candidate loop - } // process + } // processDataWithDmesMl + + PROCESS_SWITCH(HfTaskB0Reduced, processDataWithDmesMl, "Process data with ML scores for D daughter", false); - /// B0 MC analysis and fill histograms void processMc(soa::Join const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const&) + aod::HfRed3Prongs const& candidatesD) { // MC rec for (const auto& candidate : candidates) { @@ -176,93 +436,37 @@ struct HfTaskB0Reduced { if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { continue; } - - auto ptCandB0 = candidate.pt(); - auto candD = candidate.prong0_as(); - std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; - std::array posSvD{candD.xSecondaryVertex(), candD.ySecondaryVertex(), candD.zSecondaryVertex()}; - std::array momD{candD.px(), candD.py(), candD.pz()}; - auto cospD = RecoDecay::cpa(posPv, posSvD, momD); - auto decLenD = RecoDecay::distance(posPv, posSvD); - - if (TESTBIT(std::abs(candidate.flagMcMatchRec()), hf_cand_b0::DecayType::B0ToDPi)) { - registry.fill(HIST("hPtGenSig"), candidate.ptMother()); - registry.fill(HIST("hPtRecSig"), ptCandB0); - registry.fill(HIST("hCPARecSig"), candidate.cpa(), ptCandB0); - registry.fill(HIST("hCPAxyRecSig"), candidate.cpaXY(), ptCandB0); - registry.fill(HIST("hEtaRecSig"), candidate.eta(), ptCandB0); - registry.fill(HIST("hRapidityRecSig"), hfHelper.yB0(candidate), ptCandB0); - registry.fill(HIST("hDecLengthRecSig"), candidate.decayLength(), ptCandB0); - registry.fill(HIST("hDecLengthXYRecSig"), candidate.decayLengthXY(), ptCandB0); - registry.fill(HIST("hMassRecSig"), hfHelper.invMassB0ToDPi(candidate), ptCandB0); - registry.fill(HIST("hd0Prong0RecSig"), candidate.impactParameter0(), ptCandB0); - registry.fill(HIST("hd0Prong1RecSig"), candidate.impactParameter1(), ptCandB0); - registry.fill(HIST("hPtProng0RecSig"), candidate.ptProng0(), ptCandB0); - registry.fill(HIST("hPtProng1RecSig"), candidate.ptProng1(), ptCandB0); - registry.fill(HIST("hImpParProdB0RecSig"), candidate.impactParameterProduct(), ptCandB0); - registry.fill(HIST("hDecLengthNormRecSig"), candidate.decayLengthXYNormalised(), ptCandB0); - registry.fill(HIST("hCPADRecSig"), cospD, ptCandB0); - registry.fill(HIST("hDecLengthDRecSig"), decLenD, ptCandB0); - registry.fill(HIST("hChi2PCARecSig"), candidate.chi2PCA(), ptCandB0); - } else { - registry.fill(HIST("hPtRecBg"), ptCandB0); - registry.fill(HIST("hCPARecBg"), candidate.cpa(), ptCandB0); - registry.fill(HIST("hCPAxyRecBg"), candidate.cpaXY(), ptCandB0); - registry.fill(HIST("hEtaRecBg"), candidate.eta(), ptCandB0); - registry.fill(HIST("hRapidityRecBg"), hfHelper.yB0(candidate), ptCandB0); - registry.fill(HIST("hDecLengthRecBg"), candidate.decayLength(), ptCandB0); - registry.fill(HIST("hDecLengthXYRecBg"), candidate.decayLengthXY(), ptCandB0); - registry.fill(HIST("hMassRecBg"), hfHelper.invMassB0ToDPi(candidate), ptCandB0); - registry.fill(HIST("hd0Prong0RecBg"), candidate.impactParameter0(), ptCandB0); - registry.fill(HIST("hd0Prong1RecBg"), candidate.impactParameter1(), ptCandB0); - registry.fill(HIST("hPtProng0RecBg"), candidate.ptProng0(), ptCandB0); - registry.fill(HIST("hPtProng1RecBg"), candidate.ptProng1(), ptCandB0); - registry.fill(HIST("hImpParProdB0RecBg"), candidate.impactParameterProduct(), ptCandB0); - registry.fill(HIST("hDecLengthNormRecBg"), candidate.decayLengthXYNormalised(), ptCandB0); - registry.fill(HIST("hCPADRecBg"), cospD, ptCandB0); - registry.fill(HIST("hDecLengthDRecBg"), decLenD, ptCandB0); - registry.fill(HIST("hChi2PCARecBg"), candidate.chi2PCA(), ptCandB0); - } + fillCandMcReco(candidate, candidatesD); } // rec // MC gen. level for (const auto& particle : mcParticles) { - auto ptParticle = particle.ptTrack(); - auto yParticle = particle.yTrack(); - auto etaParticle = particle.etaTrack(); - if (yCandGenMax >= 0. && std::abs(yParticle) > yCandGenMax) { + fillCandMcGen(particle); + } // gen + } // processMc + PROCESS_SWITCH(HfTaskB0Reduced, processMc, "Process MC without ML scores for D daughter", false); + + void processMcWithDmesMl(soa::Join const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + aod::HfRed3Prongs const& candidatesD) + { + // MC rec + for (const auto& candidate : candidates) { + if (!TESTBIT(candidate.hfflag(), hf_cand_b0::DecayType::B0ToDPi)) { continue; } - - std::array ptProngs = {particle.ptProng0(), particle.ptProng1()}; - std::array yProngs = {particle.yProng0(), particle.yProng1()}; - std::array etaProngs = {particle.etaProng0(), particle.etaProng1()}; - - registry.fill(HIST("hPtProng0Gen"), ptProngs[0], ptParticle); - registry.fill(HIST("hPtProng1Gen"), ptProngs[1], ptParticle); - registry.fill(HIST("hYProng0Gen"), yProngs[0], ptParticle); - registry.fill(HIST("hYProng1Gen"), yProngs[1], ptParticle); - registry.fill(HIST("hEtaProng0Gen"), etaProngs[0], ptParticle); - registry.fill(HIST("hEtaProng1Gen"), etaProngs[1], ptParticle); - - registry.fill(HIST("hPtGen"), ptParticle); - registry.fill(HIST("hYGen"), yParticle, ptParticle); - registry.fill(HIST("hEtaGen"), etaParticle, ptParticle); - - // generated B0 with |y|<0.5 - if (std::abs(yParticle) < 0.5) { - registry.fill(HIST("hPtGenWithRapidityBelowHalf"), ptParticle); + if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { + continue; } + fillCandMcReco(candidate, candidatesD); + } // rec - // generated B0 with daughters in geometrical acceptance - if (isProngInAcceptance(etaProngs[0], ptProngs[0]) && isProngInAcceptance(etaProngs[1], ptProngs[1])) { - registry.fill(HIST("hPtGenWithProngsInAcceptance"), ptParticle); - registry.fill(HIST("hYGenWithProngsInAcceptance"), yParticle, ptParticle); - registry.fill(HIST("hEtaGenWithProngsInAcceptance"), etaParticle, ptParticle); - } + // MC gen. level + for (const auto& particle : mcParticles) { + fillCandMcGen(particle); } // gen - } // process - PROCESS_SWITCH(HfTaskB0Reduced, processMc, "Process MC", false); + } // processMcWithDmesMl + PROCESS_SWITCH(HfTaskB0Reduced, processMcWithDmesMl, "Process MC with ML scores for D daughter", false); }; // struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 57eeac04318f5d146114dbd335a82ea2288539ea Mon Sep 17 00:00:00 2001 From: Rosario Turrisi Date: Tue, 12 Dec 2023 08:35:17 +0100 Subject: [PATCH 031/156] Added analysis of TPC cluster number (#4123) * Added analysis of TPC cluster number * Added TPC nclust histos w/pt condition * Modified list of MC histos * Corrected tab inserted by mistake --- DPG/Tasks/AOTTrack/qaMatchEff.cxx | 773 +++++++++++++++++++++++++++++- 1 file changed, 767 insertions(+), 6 deletions(-) diff --git a/DPG/Tasks/AOTTrack/qaMatchEff.cxx b/DPG/Tasks/AOTTrack/qaMatchEff.cxx index a71df23d38e..363fa496718 100644 --- a/DPG/Tasks/AOTTrack/qaMatchEff.cxx +++ b/DPG/Tasks/AOTTrack/qaMatchEff.cxx @@ -264,6 +264,33 @@ struct qaMatchEff { histos.add("data/control/zDCA_tpcits", "DCA along z TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("data/control/xyDCA_tpcits", "DCA in x-y plane TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); + // TPC found/findable clusters and crossed rows distributions - no conditions + histos.add("data/TPCclust/tpcNClsFound", "Number of TPC found clusters", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable", "Number of TPC findable clusters", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows", "Number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows", "Number of TPC findable clusters minus crossed rows", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_tpc", "Number of TPC found clusters - TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_tpc", "Number of TPC findable clusters - TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_tpc", "Number of TPC crossed rows - TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_tpc", "Number of TPC findable clusters minus crossed rows - TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_tpcits", "Number of TPC found clusters - TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_tpcits", "Number of TPC findable clusters - TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_tpcits", "Number of TPC crossed rows - TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_tpcits", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + // + // in [1,2] GeV pt interval + histos.add("data/TPCclust/tpcNClsFound_tpc_1g", "Number of TPC found clusters - TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_tpc_1g", "Number of TPC findable clusters - TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_tpc_1g", "Number of TPC crossed rows - TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_tpc_1g", "Number of TPC findable clusters minus crossed rows - TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_tpcits_1g", "Number of TPC found clusters - TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_tpcits_1g", "Number of TPC findable clusters - TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_tpcits_1g", "Number of TPC crossed rows - TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_tpcits_1g", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + /// compare pt's (tracking and innerParamTPC) if (makept2d) { histos.add("data/control/ptptconfTPCall", "Tracking pt vs TPC inner wall pt - TPC tag", kTH2D, {{100, 0.0, 10.0, "tracking #it{p}_{T}"}, {100, 0.0, 10.0, "TPC #it{p}_{T}"}}); @@ -354,6 +381,34 @@ struct qaMatchEff { histos.add("data/PID/pthist_tpc_piminus_PIDTPC_O", "#it{p}_{T} distribution - data TPC tag - pions- PID TPC only", kTH1D, {axisPt}, true); histos.add("data/PID/pthist_tpc_piminus_PIDTOF_O", "#it{p}_{T} distribution - data TPC tag - pions- PID TOF only", kTH1D, {axisPt}, true); + // TPC found clusters distribution + histos.add("data/TPCclust/tpcNClsFound_pi", "Number of TPC found clusters - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pi", "Number of TPC findable clusters - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pi", "Number of TPC crossed rows - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pi", "Number of TPC findable clusters minus crossed rows - pions", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_pi_tpc", "Number of TPC found clusters - TPC tag - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pi_tpc", "Number of TPC findable clusters - TPC tag - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pi_tpc", "Number of TPC crossed rows - TPC tag - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc", "Number of TPC findable clusters minus crossed rows - TPC tag - pions", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_pi_tpcits", "Number of TPC found clusters - TPC+ITS tag - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pi_tpcits", "Number of TPC findable clusters - TPC+ITS tag - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pi_tpcits", "Number of TPC crossed rows - TPC+ITS tag - pions", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag - pions", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // in [1,2] GeV pt interval + histos.add("data/TPCclust/tpcNClsFound_pi_tpc_1g", "Number of TPC found clusters pions TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pi_tpc_1g", "Number of TPC findable clusters pions TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pi_tpc_1g", "Number of TPC crossed rows pions TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc_1g", "Number of TPC findable clusters minus crossed rows pions TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_pi_tpcits_1g", "Number of TPC found clusters pions TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pi_tpcits_1g", "Number of TPC findable clusters pions TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pi_tpcits_1g", "Number of TPC crossed rows pions TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits_1g", "Number of TPC findable clusters minus crossed rows pions TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + // plus histos.add("data/PID/pthist_tpc_piplus", "#it{p}_{T} distribution - data TPC tag - pos. pions", kTH1D, {axisPt}, true); histos.add("data/PID/etahist_tpc_piplus", "#eta distribution - data TPC tag - pos. pions", kTH1D, {axisEta}, true); @@ -374,6 +429,34 @@ struct qaMatchEff { // // if you want just kaons if (isPIDKaonRequired) { + // + // in [1,2] GeV pt interval + histos.add("data/TPCclust/tpcNClsFound_ka_tpc_1g", "Number of TPC found clusters kaons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_ka_tpc_1g", "Number of TPC findable clusters kaons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_ka_tpc_1g", "Number of TPC crossed rows kaons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc_1g", "Number of TPC findable clusters minus crossed rows kaons TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_ka_tpcits_1g", "Number of TPC found clusters kaons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_ka_tpcits_1g", "Number of TPC findable clusters kaons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_ka_tpcits_1g", "Number of TPC crossed rows kaons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits_1g", "Number of TPC findable clusters minus crossed rows kaons TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // TPC found clusters distribution + histos.add("data/TPCclust/tpcNClsFound_ka", "Number of TPC found clusters - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_ka", "Number of TPC findable clusters - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_ka", "Number of TPC crossed rows - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_ka", "Number of TPC findable clusters minus crossed rows - kaons", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_ka_tpc", "Number of TPC found clusters - TPC tag - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_ka_tpc", "Number of TPC findable clusters - TPC tag - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_ka_tpc", "Number of TPC crossed rows - TPC tag - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc", "Number of TPC findable clusters minus crossed rows - TPC tag - kaons", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_ka_tpcits", "Number of TPC found clusters - TPC+ITS tag - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_ka_tpcits", "Number of TPC findable clusters - TPC+ITS tag - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_ka_tpcits", "Number of TPC crossed rows - TPC+ITS tag - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag - kaons", kTH1F, {{200, -200.0, 200.0}}, true); + histos.add("data/PID/zDCA_tpc_ka", "DCA along z - kaons TPC tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("data/PID/xyDCA_tpc_ka", "DCA in x-y plane - kaons TPC tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("data/PID/zDCA_tpcits_ka", "DCA along z - kaons TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); @@ -450,6 +533,34 @@ struct qaMatchEff { // if you want just protons if (isPIDProtonRequired) { // + // in [1,2] GeV pt interval + histos.add("data/TPCclust/tpcNClsFound_pr_tpc_1g", "Number of TPC found clusters protons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pr_tpc_1g", "Number of TPC findable clusters protons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pr_tpc_1g", "Number of TPC crossed rows protons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc_1g", "Number of TPC findable clusters minus crossed rows protons TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_pr_tpcits_1g", "Number of TPC found clusters protons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pr_tpcits_1g", "Number of TPC findable clusters protons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pr_tpcits_1g", "Number of TPC crossed rows protons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits_1g", "Number of TPC findable clusters minus crossed rows protons TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // TPC found clusters distribution + histos.add("data/TPCclust/tpcNClsFound_pr", "Number of TPC found clusters - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pr", "Number of TPC findable clusters - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pr", "Number of TPC crossed rows - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pr", "Number of TPC findable clusters minus crossed rows - protons", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_pr_tpc", "Number of TPC found clusters - TPC tag - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pr_tpc", "Number of TPC findable clusters - TPC tag - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pr_tpc", "Number of TPC crossed rows - TPC tag - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc", "Number of TPC findable clusters minus crossed rows - TPC tag - protons", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("data/TPCclust/tpcNClsFound_pr_tpcits", "Number of TPC found clusters - TPC+ITS tag - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcNClsFindable_pr_tpcits", "Number of TPC findable clusters - TPC+ITS tag - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcCrossedRows_pr_tpcits", "Number of TPC crossed rows - TPC+ITS tag - protons", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag - protons", kTH1F, {{200, -200.0, 200.0}}, true); + histos.add("data/PID/zDCA_tpc_pr", "DCA along z - protons TPC tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("data/PID/xyDCA_tpc_pr", "DCA in x-y plane - protons TPC tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("data/PID/zDCA_tpcits_pr", "DCA along z - protons TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); @@ -611,6 +722,33 @@ struct qaMatchEff { histos.add("MC/control/zDCA_tpcits", "DCA along z TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("MC/control/xyDCA_tpcits", "DCA in x-y plane TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); + // TPC found/findable clusters and crossed rows distributions - no conditions + histos.add("MC/TPCclust/tpcNClsFound", "Number of TPC found clusters", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable", "Number of TPC findable clusters", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows", "Number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows", "Number of TPC findable clusters minus crossed rows", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_tpc", "Number of TPC found clusters - TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_tpc", "Number of TPC findable clusters - TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_tpc", "Number of TPC crossed rows - TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_tpc", "Number of TPC findable clusters minus crossed rows - TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_tpcits", "Number of TPC found clusters - TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_tpcits", "Number of TPC findable clusters - TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_tpcits", "Number of TPC crossed rows - TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_tpcits", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + // + // pt in [1,2] GeV + histos.add("MC/TPCclust/tpcNClsFound_tpc_1g", "Number of TPC found clusters - TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_tpc_1g", "Number of TPC findable clusters - TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_tpc_1g", "Number of TPC crossed rows - TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_tpc_1g", "Number of TPC findable clusters minus crossed rows - TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_tpcits_1g", "Number of TPC found clusters - TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_tpcits_1g", "Number of TPC findable clusters - TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_tpcits_1g", "Number of TPC crossed rows - TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_tpcits_1g", "Number of TPC findable clusters minus crossed rows - TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + /// compare pt's (tracking and innerParamTPC) if (makept2d) { histos.add("MC/control/ptptconfTPCall", "Tracking pt vs TPC inner wall pt - TPC tag", kTH2D, {{100, 0.0, 10.0, "tracking #it{p}_{T}"}, {100, 0.0, 10.0, "TPC #it{p}_{T}"}}); @@ -716,9 +854,11 @@ struct qaMatchEff { histos.add("MC/primsec/pthist_tpcits_secm", "#it{p}_{T} distribution - MC mat.sec. TPC+ITS tag", kTH1D, {axisPt}, true); histos.add("MC/primsec/etahist_tpcits_secm", "#eta distribution - MC mat. sec. TPC+ITS tag", kTH1D, {axisEta}, true); histos.add("MC/primsec/phihist_tpcits_secm", "#phi distribution - MC mat. sec. TPC+ITS tag", kTH1D, {axisPhi}, true); + // - // pions only - // all + // DCA of identified + // + histos.add("MC/PID/zDCA_tpc_pi", "DCA along z - pions TPC tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("MC/PID/xyDCA_tpc_pi", "DCA in x-y plane - pions TPC tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("MC/PID/zDCA_tpcits_pi", "DCA along z - pions TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); @@ -734,6 +874,72 @@ struct qaMatchEff { histos.add("MC/PID/zDCA_tpcits_pr", "DCA along z - protons TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); histos.add("MC/PID/xyDCA_tpcits_pr", "DCA in x-y plane - protons TPC+ITS tag;dca [cm]", kTH1D, {{200, -20.0, 20.0}}, true); + // + // pions only + // all + // + // histos.add("MC/TPCclust/tpcNClsFound_pi", "Number of TPC found clusters - #pi", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pi", "Number of TPC findable clusters - #pi", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pi", "Number of TPC crossed rows - #pi", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pi", "Number of TPC findable clusters minus crossed rows - #pi", kTH1F, {{200, -200.0, 200.0}}, true); + // + // TPC found clusters distribution + // histos.add("MC/TPCclust/tpcNClsFound_pi_tpc", "Number of TPC found clusters - #pi TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pi_tpc", "Number of TPC findable clusters - #pi TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pi_tpc", "Number of TPC crossed rows - #pi TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc", "Number of TPC findable clusters minus crossed rows - #pi TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_pi_tpcits", "Number of TPC found clusters - #pi TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pi_tpcits", "Number of TPC findable clusters - #pi TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pi_tpcits", "Number of TPC crossed rows - #pi TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits", "Number of TPC findable clusters minus crossed rows - #pi TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // pt in [1,2] GeV + // histos.add("MC/TPCclust/tpcNClsFound_pi_tpc_1g", "Number of TPC found clusters - #pi TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pi_tpc_1g", "Number of TPC findable clusters - #pi TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pi_tpc_1g", "Number of TPC crossed rows - #pi TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc_1g", "Number of TPC findable clusters minus crossed rows - #pi TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_pi_tpcits_1g", "Number of TPC found clusters - #pi TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pi_tpcits_1g", "Number of TPC findable clusters - #pi TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pi_tpcits_1g", "Number of TPC crossed rows - #pi TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits_1g", "Number of TPC findable clusters minus crossed rows - #pi TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // for "MC truth" pions + // + histos.add("MC/TPCclust/tpcNClsFound_piMC", "Number of TPC found clusters - #pi_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_piMC", "Number of TPC findable clusters - #pi_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_piMC", "Number of TPC crossed rows - #pi_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC", "Number of TPC findable clusters minus crossed rows - #pi_{MC}", kTH1F, {{200, -200.0, 200.0}}, true); + // + // + // TPC found clusters distribution + histos.add("MC/TPCclust/tpcNClsFound_piMC_tpc", "TPC found clusters - #pi_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_piMC_tpc", "TPC findable clusters - #pi_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_piMC_tpc", "TPC crossed rows - #pi_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpc", "TPC findable clusters minus crossed rows - #pi_{MC} TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_piMC_tpcits", "TPC found clusters - #pi_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_piMC_tpcits", "TPC findable clusters - #pi_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_piMC_tpcits", "TPC crossed rows - #pi_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpcits", "TPC findable clusters minus crossed rows - #pi_{MC} TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // pt in [1,2] GeV + histos.add("MC/TPCclust/tpcNClsFound_piMC_tpc_1g", "Number of TPC found clusters - #pi_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_piMC_tpc_1g", "Number of TPC findable clusters - #pi_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_piMC_tpc_1g", "Number of TPC crossed rows - #pi_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpc_1g", "Number of TPC findable clusters minus crossed rows - #pi_{MC} TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_piMC_tpcits_1g", "Number of TPC found clusters - #pi_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_piMC_tpcits_1g", "Number of TPC findable clusters - #pi_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_piMC_tpcits_1g", "Number of TPC crossed rows - #pi_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpcits_1g", "Number of TPC findable clusters minus crossed rows - #pi_{MC} TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + // + // + histos.add("MC/PID/pthist_tpc_pi", "#it{p}_{T} distribution - #pi MC TPC tag", kTH1D, {axisPt}, true); histos.add("MC/PID/etahist_tpc_pi", "#eta distribution - #pi MC TPC tag", kTH1D, {axisEta}, true); histos.add("MC/PID/phihist_tpc_pi", "#phi distribution - #pi MC TPC tag", kTH1D, {axisPhi}, true); @@ -788,6 +994,67 @@ struct qaMatchEff { // // protons only // all + // + // + // TPC found clusters distribution + // histos.add("MC/TPCclust/tpcNClsFound_pr", "Number of TPC found clusters - protons", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pr", "Number of TPC findable clusters - protons", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pr", "Number of TPC crossed rows - protons", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pr", "Number of TPC findable clusters minus crossed rows - protons", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_pr_tpc", "Number of TPC found clusters - protons TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pr_tpc", "Number of TPC findable clusters - protons TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pr_tpc", "Number of TPC crossed rows - protons TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc", "Number of TPC findable clusters minus crossed rows - protons TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_pr_tpcits", "Number of TPC found clusters - protons TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pr_tpcits", "Number of TPC findable clusters - protons TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pr_tpcits", "Number of TPC crossed rows - protons TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits", "Number of TPC findable clusters minus crossed rows - protons TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + // // + // // pt in [1,2] GeV + // histos.add("MC/TPCclust/tpcNClsFound_pr_tpc_1g", "Number of TPC found clusters - protons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pr_tpc_1g", "Number of TPC findable clusters - protons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pr_tpc_1g", "Number of TPC crossed rows - protons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc_1g", "Number of TPC findable clusters minus crossed rows - protons TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_pr_tpcits_1g", "Number of TPC found clusters - protons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_pr_tpcits_1g", "Number of TPC findable clusters - protons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_pr_tpcits_1g", "Number of TPC crossed rows - protons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits_1g", "Number of TPC findable clusters minus crossed rows - protons TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + // + // + // MC truth protons + // + // TPC found clusters distribution + histos.add("MC/TPCclust/tpcNClsFound_prMC", "Number of TPC found clusters - protons_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_prMC", "Number of TPC findable clusters - protons_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_prMC", "Number of TPC crossed rows - protons_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC", "Number of TPC findable clusters minus crossed rows - protons_{MC}", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_prMC_tpc", "Number of TPC found clusters - protons_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_prMC_tpc", "Number of TPC findable clusters - protons_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_prMC_tpc", "Number of TPC crossed rows - protons_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpc", "Number of TPC findable clusters minus crossed rows - protons_{MC} TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_prMC_tpcits", "Number of TPC found clusters - protons_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_prMC_tpcits", "Number of TPC findable clusters - protons_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_prMC_tpcits", "Number of TPC crossed rows - protons_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpcits", "Number of TPC findable clusters minus crossed rows - protons_{MC} TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + // + // pt in [1,2] GeV + histos.add("MC/TPCclust/tpcNClsFound_prMC_tpc_1g", "Number of TPC found clusters - protons_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_prMC_tpc_1g", "Number of TPC findable clusters - protons_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_prMC_tpc_1g", "Number of TPC crossed rows - protons_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpc_1g", "Number of TPC findable clusters minus crossed rows - protons_{MC} TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_prMC_tpcits_1g", "Number of TPC found clusters - protons_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_prMC_tpcits_1g", "Number of TPC findable clusters - protons_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_prMC_tpcits_1g", "Number of TPC crossed rows - protons_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpcits_1g", "Number of TPC findable clusters minus crossed rows - protons_{MC} TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // histos.add("MC/PID/pthist_tpc_pr", "#it{p}_{T} distribution - prot MC TPC tag", kTH1D, {axisPt}, true); histos.add("MC/PID/etahist_tpc_pr", "#eta distribution - prot MC TPC tag", kTH1D, {axisEta}, true); histos.add("MC/PID/phihist_tpc_pr", "#phi distribution - prot MC TPC tag", kTH1D, {axisPhi}, true); @@ -814,6 +1081,68 @@ struct qaMatchEff { // // kaons only // all + // + // TPC found clusters distribution + // histos.add("MC/TPCclust/tpcNClsFound_ka", "Number of TPC found clusters - kaons", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_ka", "Number of TPC findable clusters - kaons ", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_ka", "Number of TPC crossed rows - kaons ", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_ka", "Number of TPC findable clusters minus crossed rows - kaons ", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_ka_tpc", "Number of TPC found clusters - kaons TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_ka_tpc", "Number of TPC findable clusters - kaons TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_ka_tpc", "Number of TPC crossed rows - kaons TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc", "Number of TPC findable clusters minus crossed rows - kaons TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_ka_tpcits", "Number of TPC found clusters - kaons TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_ka_tpcits", "Number of TPC findable clusters - kaons TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_ka_tpcits", "Number of TPC crossed rows - kaons TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits", "Number of TPC findable clusters minus crossed rows - kaons TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // // + // // pt in [1,2] GeV + // histos.add("MC/TPCclust/tpcNClsFound_ka_tpc_1g", "Number of TPC found clusters - kaons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_ka_tpc_1g", "Number of TPC findable clusters - kaons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_ka_tpc_1g", "Number of TPC crossed rows - kaons TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc_1g", "Number of TPC findable clusters minus crossed rows - kaons TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // histos.add("MC/TPCclust/tpcNClsFound_ka_tpcits_1g", "Number of TPC found clusters - kaons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcNClsFindable_ka_tpcits_1g", "Number of TPC findable clusters - kaons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcCrossedRows_ka_tpcits_1g", "Number of TPC crossed rows - kaons TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + // histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits_1g", "Number of TPC findable clusters minus crossed rows - kaons TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + // + // + // MC truth kaons + // + // TPC found clusters distribution + histos.add("MC/TPCclust/tpcNClsFound_kaMC", "Number of TPC found clusters - kaons_{MC}", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_kaMC", "Number of TPC findable clusters - kaons_{MC} ", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_kaMC", "Number of TPC crossed rows - kaons_{MC} ", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC", "Number of TPC findable clusters minus crossed rows - kaons_{MC} ", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_kaMC_tpc", "Number of TPC found clusters - kaons_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_kaMC_tpc", "Number of TPC findable clusters - kaons_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_kaMC_tpc", "Number of TPC crossed rows - kaons_{MC} TPC tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpc", "Number of TPC findable clusters minus crossed rows - kaons_{MC} TPC tag", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_kaMC_tpcits", "Number of TPC found clusters - kaons_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_kaMC_tpcits", "Number of TPC findable clusters - kaons_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_kaMC_tpcits", "Number of TPC crossed rows - kaons_{MC} TPC+ITS tag", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpcits", "Number of TPC findable clusters minus crossed rows - kaons_{MC} TPC+ITS tag", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // pt in [1,2] GeV + histos.add("MC/TPCclust/tpcNClsFound_kaMC_tpc_1g", "Number of TPC found clusters - kaons_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_kaMC_tpc_1g", "Number of TPC findable clusters - kaons_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_kaMC_tpc_1g", "Number of TPC crossed rows - kaons_{MC} TPC tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpc_1g", "Number of TPC findable clusters minus crossed rows - kaons_{MC} TPC tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + histos.add("MC/TPCclust/tpcNClsFound_kaMC_tpcits_1g", "Number of TPC found clusters - kaons_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcNClsFindable_kaMC_tpcits_1g", "Number of TPC findable clusters - kaons_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcCrossedRows_kaMC_tpcits_1g", "Number of TPC crossed rows - kaons_{MC} TPC+ITS tag pt1-2", kTH1F, {{161, -0.5, 160.5}}, true); + histos.add("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpcits_1g", "Number of TPC findable clusters minus crossed rows - kaons_{MC} TPC+ITS tag pt1-2", kTH1F, {{200, -200.0, 200.0}}, true); + + // + // histos.add("MC/PID/pthist_tpc_ka", "#it{p}_{T} distribution - kaons MC TPC tag", kTH1D, {axisPt}, true); histos.add("MC/PID/etahist_tpc_ka", "#eta distribution - kaons MC TPC tag", kTH1D, {axisEta}, true); histos.add("MC/PID/phihist_tpc_ka", "#phi distribution - kaons MC TPC tag", kTH1D, {axisPhi}, true); @@ -1024,10 +1353,18 @@ struct qaMatchEff { else trackPt = reco_pt; - /// special case for ITS tracks - /// Using pt calculated at the inner wall of TPC - /// Caveat: tgl still from tracking: this is not the value of tgl at the - /// inner wall of TPC + // + // here n of clusters of TPC assigned to float for histos (and to hack it if needed) :) + // + Float_t clustpc = (Float_t)track.tpcNClsFound(); + Float_t findcltpc = (Float_t)track.tpcNClsFindable(); + Float_t crowstpc = (Float_t)track.tpcNClsCrossedRows(); + Float_t finclusmincrotpc = (Float_t)track.tpcNClsFindableMinusCrossedRows(); + // + // special case for ITS tracks + // Using pt calculated at the inner wall of TPC + // Caveat: tgl still from tracking: this is not the value of tgl at the + // inner wall of TPC // if (b_useTPCinnerWallPtForITS) // ITStrackPt = tpcinner_pt; // else @@ -1128,8 +1465,109 @@ struct qaMatchEff { // // all tracks, no conditions // + + // TPC clusters - all particles all dets + // + if constexpr (IS_MC) { //////////////////////// MC + histos.get(HIST("MC/TPCclust/tpcNClsFound"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows"))->Fill(crowstpc); + } else { + histos.get(HIST("data/TPCclust/tpcNClsFound"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows"))->Fill(finclusmincrotpc); + } + + // TPC clusters all pions MC truth + // + if (tpPDGCode == 211) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_piMC"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_piMC"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_piMC"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC"))->Fill(crowstpc); + } + if (tpPDGCode == 321) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_kaMC"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_kaMC"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_kaMC"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC"))->Fill(crowstpc); + } + if (tpPDGCode == 2212) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_prMC"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_prMC"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_prMC"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC"))->Fill(crowstpc); + } + // TPC clusters all pions + // + if (isPion) { + // if constexpr (IS_MC) { //////////////////////// MC + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pi"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pi"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pi"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pi"))->Fill(crowstpc); + // } else { + if constexpr (!IS_MC) { // DATA + histos.get(HIST("data/TPCclust/tpcNClsFound_pi"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pi"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pi"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pi"))->Fill(finclusmincrotpc); + } + } + // TPC clusters all kaons + // + if (isKaon) { + // if constexpr (IS_MC) { //////////////////////// MC + // histos.get(HIST("MC/TPCclust/tpcNClsFound_ka"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_ka"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_ka"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_ka"))->Fill(crowstpc); + // } else { + if constexpr (!IS_MC) { // DATA + histos.get(HIST("data/TPCclust/tpcNClsFound_ka"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_ka"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_ka"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_ka"))->Fill(finclusmincrotpc); + } + } + // TPC clusters all protons + // + if (isProton) { + // if constexpr (IS_MC) { //////////////////////// MC + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pr"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pr"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pr"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pr"))->Fill(crowstpc); + // } else { + if constexpr (!IS_MC) { // DATA + histos.get(HIST("data/TPCclust/tpcNClsFound_pr"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pr"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pr"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pr"))->Fill(finclusmincrotpc); + } + } + // + // + // all tracks w/TPC + // if (trkWTPC && isTrackSelectedTPCCuts(track)) { if constexpr (IS_MC) { //////////////////////// MC + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_tpc"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_tpc"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_tpc"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_tpc_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_tpc_1g"))->Fill(crowstpc); + } // histos.fill(HIST("MC/control/zDCA_tpc"), track.dcaZ()); histos.fill(HIST("MC/control/xyDCA_tpc"), track.dcaXY()); @@ -1148,7 +1586,120 @@ struct qaMatchEff { histos.get(HIST("MC/phihist_toftpc"))->Fill(track.phi()); histos.get(HIST("MC/etahist_toftpc"))->Fill(track.eta()); } + // if (isPion) { + // // + // // TPC clusters + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pi_tpc"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pi_tpc"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pi_tpc"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc"))->Fill(crowstpc); + // // + // // pt 1-2 + // if (trackPt <= 2 && trackPt > 1) { + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pi_tpc_1g"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pi_tpc_1g"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pi_tpc_1g"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc_1g"))->Fill(crowstpc); + // } + // } + // if (isKaon) { + // // + // // TPC clusters + // histos.get(HIST("MC/TPCclust/tpcNClsFound_ka_tpc"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_ka_tpc"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_ka_tpc"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc"))->Fill(crowstpc); + // // + // // pt 1-2 + // if (trackPt <= 2 && trackPt > 1) { + // histos.get(HIST("MC/TPCclust/tpcNClsFound_ka_tpc_1g"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_ka_tpc_1g"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_ka_tpc_1g"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc_1g"))->Fill(crowstpc); + // } + // } + // if (isProton) { + // // + // // TPC clusters + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pr_tpc"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pr_tpc"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pr_tpc"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc"))->Fill(crowstpc); + // // + // // pt 1-2 + // if (trackPt <= 2 && trackPt > 1) { + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pr_tpc_1g"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pr_tpc_1g"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pr_tpc_1g"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc_1g"))->Fill(crowstpc); + // } + // } + // if (trkWITS && isTrackSelectedITSCuts(track)) { //////////////////////////////////////////// ITS tag inside TPC tagged + // if (isPion) { + // // + // // TPC clusters + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pi_tpcits"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pi_tpcits"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pi_tpcits"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits"))->Fill(crowstpc); + // // + // // pt 1-2 + // if (trackPt <= 2 && trackPt > 1) { + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pi_tpcits_1g"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pi_tpcits_1g"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pi_tpcits_1g"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits_1g"))->Fill(crowstpc); + // } + // } + // if (isKaon) { + // // + // // TPC clusters + // histos.get(HIST("MC/TPCclust/tpcNClsFound_ka_tpcits"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_ka_tpcits"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_ka_tpcits"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits"))->Fill(crowstpc); + // // + // // pt 1-2 + // if (trackPt <= 2 && trackPt > 1) { + // histos.get(HIST("MC/TPCclust/tpcNClsFound_ka_tpcits_1g"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_ka_tpcits_1g"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_ka_tpcits_1g"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits_1g"))->Fill(crowstpc); + // } + // } + // if (isProton) { + // // + // // TPC clusters + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pr_tpcits"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pr_tpcits"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pr_tpcits"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits"))->Fill(crowstpc); + // // + // // pt 1-2 + // if (trackPt <= 2 && trackPt > 1) { + // histos.get(HIST("MC/TPCclust/tpcNClsFound_pr_tpcits_1g"))->Fill(clustpc); + // histos.get(HIST("MC/TPCclust/tpcNClsFindable_pr_tpcits_1g"))->Fill(findcltpc); + // histos.get(HIST("MC/TPCclust/tpcCrossedRows_pr_tpcits_1g"))->Fill(crowstpc); + // histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits_1g"))->Fill(crowstpc); + // } + // } + // } + // // + // // } else { //////////////////////// DATA + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_tpc"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_tpc"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_tpc"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_tpc"))->Fill(crowstpc); + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_tpc_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_tpc_1g"))->Fill(crowstpc); + } // histos.fill(HIST("data/control/zDCA_tpc"), track.dcaZ()); histos.fill(HIST("data/control/xyDCA_tpc"), track.dcaXY()); @@ -1183,6 +1734,21 @@ struct qaMatchEff { // // PID is applied if (isPion) { + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_pi_tpc"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pi_tpc"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pi_tpc"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_pi_tpc_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pi_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pi_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpc_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/PID/zDCA_tpc_pi"))->Fill(track.dcaZ()); histos.get(HIST("data/PID/xyDCA_tpc_pi"))->Fill(track.dcaXY()); // @@ -1238,6 +1804,21 @@ struct qaMatchEff { } // end pions if (isKaon) { + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_ka_tpc"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_ka_tpc"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_ka_tpc"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_ka_tpc_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_ka_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_ka_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpc_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/PID/zDCA_tpc_ka"))->Fill(track.dcaZ()); histos.get(HIST("data/PID/xyDCA_tpc_ka"))->Fill(track.dcaXY()); // @@ -1293,6 +1874,21 @@ struct qaMatchEff { } // end kaons if (isProton) { + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_pr_tpc"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pr_tpc"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pr_tpc"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_pr_tpc_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pr_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pr_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpc_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/PID/zDCA_tpc_pr"))->Fill(track.dcaZ()); histos.get(HIST("data/PID/xyDCA_tpc_pr"))->Fill(track.dcaXY()); // @@ -1367,6 +1963,21 @@ struct qaMatchEff { // if (trkWITS && isTrackSelectedITSCuts(track)) { //////////////////////////////////////////// ITS tag inside TPC tagged if constexpr (IS_MC) { //////////////////////// MC + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_tpcits"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_tpcits"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_tpcits"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/control/zDCA_tpcits"))->Fill(track.dcaZ()); histos.get(HIST("MC/control/xyDCA_tpcits"))->Fill(track.dcaXY()); if (makept2d) @@ -1381,6 +1992,21 @@ struct qaMatchEff { histos.get(HIST("MC/etahist_toftpcits"))->Fill(track.eta()); } } else { //////////////////////// DATA + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_tpcits"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_tpcits"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_tpcits"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/control/zDCA_tpcits"))->Fill(track.dcaZ()); histos.get(HIST("data/control/xyDCA_tpcits"))->Fill(track.dcaXY()); if (makept2d) @@ -1389,6 +2015,21 @@ struct qaMatchEff { // // PID is applied if (isPion) { + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_pi_tpcits"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pi_tpcits"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pi_tpcits"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_pi_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pi_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pi_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pi_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/PID/zDCA_tpcits_pi"))->Fill(track.dcaZ()); histos.get(HIST("data/PID/xyDCA_tpcits_pi"))->Fill(track.dcaXY()); // @@ -1444,6 +2085,21 @@ struct qaMatchEff { } // end pions if (isKaon) { + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_ka_tpcits"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_ka_tpcits"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_ka_tpcits"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_ka_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_ka_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_ka_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_ka_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/PID/zDCA_tpcits_ka"))->Fill(track.dcaZ()); histos.get(HIST("data/PID/xyDCA_tpcits_ka"))->Fill(track.dcaXY()); // @@ -1499,6 +2155,21 @@ struct qaMatchEff { } // end kaons if (isProton) { + // + // TPC clusters + histos.get(HIST("data/TPCclust/tpcNClsFound_pr_tpcits"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pr_tpcits"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pr_tpcits"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("data/TPCclust/tpcNClsFound_pr_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("data/TPCclust/tpcNClsFindable_pr_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("data/TPCclust/tpcCrossedRows_pr_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("data/TPCclust/tpcsFindableMinusCrossedRows_pr_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("data/PID/zDCA_tpcits_pr"))->Fill(track.dcaZ()); histos.get(HIST("data/PID/xyDCA_tpcits_pr"))->Fill(track.dcaXY()); // @@ -1773,6 +2444,21 @@ struct qaMatchEff { // protons only if (tpPDGCode == 2212) { if (trkWTPC && isTrackSelectedTPCCuts(track)) { + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_prMC_tpc"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_prMC_tpc"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_prMC_tpc"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_prMC_tpc_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_prMC_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_prMC_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpc_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/PID/zDCA_tpc_pr"))->Fill(track.dcaZ()); histos.get(HIST("MC/PID/xyDCA_tpc_pr"))->Fill(track.dcaXY()); // @@ -1789,6 +2475,21 @@ struct qaMatchEff { histos.get(HIST("MC/PID/etahist_tpc_prminus"))->Fill(track.eta()); } if (trkWITS && isTrackSelectedITSCuts(track)) { + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_prMC_tpcits"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_prMC_tpcits"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_prMC_tpcits"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_prMC_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_prMC_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_prMC_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_prMC_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/PID/zDCA_tpcits_pr"))->Fill(track.dcaZ()); histos.get(HIST("MC/PID/xyDCA_tpcits_pr"))->Fill(track.dcaXY()); // @@ -1811,6 +2512,21 @@ struct qaMatchEff { // pions only if (tpPDGCode == 211) { if (trkWTPC && isTrackSelectedTPCCuts(track)) { + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_piMC_tpc"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_piMC_tpc"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_piMC_tpc"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_piMC_tpc_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_piMC_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_piMC_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpc_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/PID/zDCA_tpc_pi"))->Fill(track.dcaZ()); histos.get(HIST("MC/PID/xyDCA_tpc_pi"))->Fill(track.dcaXY()); // @@ -1827,6 +2543,21 @@ struct qaMatchEff { histos.get(HIST("MC/PID/etahist_tpc_piminus"))->Fill(track.eta()); } if (trkWITS && isTrackSelectedITSCuts(track)) { + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_piMC_tpcits"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_piMC_tpcits"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_piMC_tpcits"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_piMC_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_piMC_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_piMC_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_piMC_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/PID/zDCA_tpcits_pi"))->Fill(track.dcaZ()); histos.get(HIST("MC/PID/xyDCA_tpcits_pi"))->Fill(track.dcaXY()); // @@ -1916,6 +2647,21 @@ struct qaMatchEff { // kaons only if (tpPDGCode == 321) { if (trkWTPC && isTrackSelectedTPCCuts(track)) { + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_kaMC_tpc"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_kaMC_tpc"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_kaMC_tpc"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpc"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_kaMC_tpc_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_kaMC_tpc_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_kaMC_tpc_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpc_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/PID/zDCA_tpc_ka"))->Fill(track.dcaZ()); histos.get(HIST("MC/PID/xyDCA_tpc_ka"))->Fill(track.dcaXY()); // @@ -1932,6 +2678,21 @@ struct qaMatchEff { histos.get(HIST("MC/PID/etahist_tpc_kaminus"))->Fill(track.eta()); } if (trkWITS && isTrackSelectedITSCuts(track)) { + // + // TPC clusters + histos.get(HIST("MC/TPCclust/tpcNClsFound_kaMC_tpcits"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_kaMC_tpcits"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_kaMC_tpcits"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpcits"))->Fill(crowstpc); + // + // pt 1-2 + if (trackPt <= 2 && trackPt > 1) { + histos.get(HIST("MC/TPCclust/tpcNClsFound_kaMC_tpcits_1g"))->Fill(clustpc); + histos.get(HIST("MC/TPCclust/tpcNClsFindable_kaMC_tpcits_1g"))->Fill(findcltpc); + histos.get(HIST("MC/TPCclust/tpcCrossedRows_kaMC_tpcits_1g"))->Fill(crowstpc); + histos.get(HIST("MC/TPCclust/tpcsFindableMinusCrossedRows_kaMC_tpcits_1g"))->Fill(crowstpc); + } + // histos.get(HIST("MC/PID/zDCA_tpcits_ka"))->Fill(track.dcaZ()); histos.get(HIST("MC/PID/xyDCA_tpcits_ka"))->Fill(track.dcaXY()); // From a933cd2c9c41e956cb7d14b35a56810aac90cb8a Mon Sep 17 00:00:00 2001 From: Junlee Kim Date: Tue, 12 Dec 2023 17:09:59 +0900 Subject: [PATCH 032/156] [Common/EventPlane] Updates on initial assignment on constant, structrue of qvectors, and others (#4006) * updates on structure and etc * fix * Please consider the following formatting changes * MegaLinter fixes --------- Co-authored-by: junleekim Co-authored-by: ALICE Action Bot --- Common/Core/EventPlaneHelper.cxx | 4 +- Common/Core/EventPlaneHelper.h | 2 +- Common/DataModel/Qvectors.h | 62 +-------- Common/TableProducer/qVectorsTable.cxx | 169 +++++++++++++------------ Common/Tasks/qVectorsCorrection.cxx | 154 +++++++++++++--------- 5 files changed, 194 insertions(+), 197 deletions(-) diff --git a/Common/Core/EventPlaneHelper.cxx b/Common/Core/EventPlaneHelper.cxx index 01c8a097fae..3fddab0bbc8 100644 --- a/Common/Core/EventPlaneHelper.cxx +++ b/Common/Core/EventPlaneHelper.cxx @@ -199,9 +199,9 @@ void EventPlaneHelper::GetCorrTwistRecale(const std::shared_ptr histQ, lambdaMinus = b / aMinus; } -float EventPlaneHelper::GetEventPlane(const float qx, const float qy) +float EventPlaneHelper::GetEventPlane(const float qx, const float qy, int nmode) { - return (TMath::ATan2(qy, qx)); + return (1. / nmode) * (TMath::ATan2(qy, qx)); } float EventPlaneHelper::GetResolution(const float RefA, const float RefB, const float sig, int nmode) diff --git a/Common/Core/EventPlaneHelper.h b/Common/Core/EventPlaneHelper.h index c0928cf2c51..0293e38bd50 100644 --- a/Common/Core/EventPlaneHelper.h +++ b/Common/Core/EventPlaneHelper.h @@ -90,7 +90,7 @@ class EventPlaneHelper float& lambdaPlus, float& lambdaMinus); // Method to calculate the event plane from the provided (Qx, Qy), for n = 2. - float GetEventPlane(const float qx, const float qy); + float GetEventPlane(const float qx, const float qy, int nmode = 2); // Method to calculate the resolution R2 for the provided profile. float GetResolution(const float RefA, const float RefB, const float sig, int nmode = 2); diff --git a/Common/DataModel/Qvectors.h b/Common/DataModel/Qvectors.h index e02b0d431a5..7302440ac7f 100644 --- a/Common/DataModel/Qvectors.h +++ b/Common/DataModel/Qvectors.h @@ -30,57 +30,21 @@ namespace qvec { DECLARE_SOA_COLUMN(Cent, cent, float); DECLARE_SOA_COLUMN(CentBin, centBin, int); -DECLARE_SOA_COLUMN(QvecFT0CUncorRe, qvecFT0CUncorRe, float); -DECLARE_SOA_COLUMN(QvecFT0CUncorIm, qvecFT0CUncorIm, float); -DECLARE_SOA_COLUMN(QvecFT0CRectrRe, qvecFT0CRectrRe, float); -DECLARE_SOA_COLUMN(QvecFT0CRectrIm, qvecFT0CRectrIm, float); -DECLARE_SOA_COLUMN(QvecFT0CTwistRe, qvecFT0CTwistRe, float); -DECLARE_SOA_COLUMN(QvecFT0CTwistIm, qvecFT0CTwistIm, float); + +DECLARE_SOA_COLUMN(QvecRe, qvecRe, std::vector); +DECLARE_SOA_COLUMN(QvecIm, qvecIm, std::vector); +DECLARE_SOA_COLUMN(QvecAmp, qvecAmp, std::vector); + DECLARE_SOA_COLUMN(QvecFT0CRe, qvecFT0CRe, float); DECLARE_SOA_COLUMN(QvecFT0CIm, qvecFT0CIm, float); - -DECLARE_SOA_COLUMN(QvecFT0AUncorRe, qvecFT0AUncorRe, float); -DECLARE_SOA_COLUMN(QvecFT0AUncorIm, qvecFT0AUncorIm, float); -DECLARE_SOA_COLUMN(QvecFT0ARectrRe, qvecFT0ARectrRe, float); -DECLARE_SOA_COLUMN(QvecFT0ARectrIm, qvecFT0ARectrIm, float); -DECLARE_SOA_COLUMN(QvecFT0ATwistRe, qvecFT0ATwistRe, float); -DECLARE_SOA_COLUMN(QvecFT0ATwistIm, qvecFT0ATwistIm, float); DECLARE_SOA_COLUMN(QvecFT0ARe, qvecFT0ARe, float); DECLARE_SOA_COLUMN(QvecFT0AIm, qvecFT0AIm, float); - -DECLARE_SOA_COLUMN(QvecFT0MUncorRe, qvecFT0MUncorRe, float); -DECLARE_SOA_COLUMN(QvecFT0MUncorIm, qvecFT0MUncorIm, float); -DECLARE_SOA_COLUMN(QvecFT0MRectrRe, qvecFT0MRectrRe, float); -DECLARE_SOA_COLUMN(QvecFT0MRectrIm, qvecFT0MRectrIm, float); -DECLARE_SOA_COLUMN(QvecFT0MTwistRe, qvecFT0MTwistRe, float); -DECLARE_SOA_COLUMN(QvecFT0MTwistIm, qvecFT0MTwistIm, float); DECLARE_SOA_COLUMN(QvecFT0MRe, qvecFT0MRe, float); DECLARE_SOA_COLUMN(QvecFT0MIm, qvecFT0MIm, float); - -DECLARE_SOA_COLUMN(QvecFV0AUncorRe, qvecFV0AUncorRe, float); -DECLARE_SOA_COLUMN(QvecFV0AUncorIm, qvecFV0AUncorIm, float); -DECLARE_SOA_COLUMN(QvecFV0ARectrRe, qvecFV0ARectrRe, float); -DECLARE_SOA_COLUMN(QvecFV0ARectrIm, qvecFV0ARectrIm, float); -DECLARE_SOA_COLUMN(QvecFV0ATwistRe, qvecFV0ATwistRe, float); -DECLARE_SOA_COLUMN(QvecFV0ATwistIm, qvecFV0ATwistIm, float); DECLARE_SOA_COLUMN(QvecFV0ARe, qvecFV0ARe, float); DECLARE_SOA_COLUMN(QvecFV0AIm, qvecFV0AIm, float); - -DECLARE_SOA_COLUMN(QvecBPosUncorRe, qvecBPosUncorRe, float); -DECLARE_SOA_COLUMN(QvecBPosUncorIm, qvecBPosUncorIm, float); -DECLARE_SOA_COLUMN(QvecBPosRectrRe, qvecBPosRectrRe, float); -DECLARE_SOA_COLUMN(QvecBPosRectrIm, qvecBPosRectrIm, float); -DECLARE_SOA_COLUMN(QvecBPosTwistRe, qvecBPosTwistRe, float); -DECLARE_SOA_COLUMN(QvecBPosTwistIm, qvecBPosTwistIm, float); DECLARE_SOA_COLUMN(QvecBPosRe, qvecBPosRe, float); DECLARE_SOA_COLUMN(QvecBPosIm, qvecBPosIm, float); - -DECLARE_SOA_COLUMN(QvecBNegUncorRe, qvecBNegUncorRe, float); -DECLARE_SOA_COLUMN(QvecBNegUncorIm, qvecBNegUncorIm, float); -DECLARE_SOA_COLUMN(QvecBNegRectrRe, qvecBNegRectrRe, float); -DECLARE_SOA_COLUMN(QvecBNegRectrIm, qvecBNegRectrIm, float); -DECLARE_SOA_COLUMN(QvecBNegTwistRe, qvecBNegTwistRe, float); -DECLARE_SOA_COLUMN(QvecBNegTwistIm, qvecBNegTwistIm, float); DECLARE_SOA_COLUMN(QvecBNegRe, qvecBNegRe, float); DECLARE_SOA_COLUMN(QvecBNegIm, qvecBNegIm, float); @@ -95,21 +59,7 @@ DECLARE_SOA_COLUMN(LabelsBNeg, labelsBNeg, std::vector); } // namespace qvec DECLARE_SOA_TABLE(Qvectors, "AOD", "QVECTORDEVS", //! Table with all Qvectors. - qvec::Cent, qvec::CentBin, - qvec::QvecFT0CUncorRe, qvec::QvecFT0CUncorIm, qvec::QvecFT0CRectrRe, qvec::QvecFT0CRectrIm, - qvec::QvecFT0CTwistRe, qvec::QvecFT0CTwistIm, qvec::QvecFT0CRe, qvec::QvecFT0CIm, - qvec::QvecFT0AUncorRe, qvec::QvecFT0AUncorIm, qvec::QvecFT0ARectrRe, qvec::QvecFT0ARectrIm, - qvec::QvecFT0ATwistRe, qvec::QvecFT0ATwistIm, qvec::QvecFT0ARe, qvec::QvecFT0AIm, - qvec::QvecFT0MUncorRe, qvec::QvecFT0MUncorIm, qvec::QvecFT0MRectrRe, qvec::QvecFT0MRectrIm, - qvec::QvecFT0MTwistRe, qvec::QvecFT0MTwistIm, qvec::QvecFT0MRe, qvec::QvecFT0MIm, - qvec::QvecFV0AUncorRe, qvec::QvecFV0AUncorIm, qvec::QvecFV0ARectrRe, qvec::QvecFV0ARectrIm, - qvec::QvecFV0ATwistRe, qvec::QvecFV0ATwistIm, qvec::QvecFV0ARe, qvec::QvecFV0AIm, - qvec::QvecBPosUncorRe, qvec::QvecBPosUncorIm, qvec::QvecBPosRectrRe, qvec::QvecBPosRectrIm, - qvec::QvecBPosTwistRe, qvec::QvecBPosTwistIm, qvec::QvecBPosRe, qvec::QvecBPosIm, - qvec::QvecBNegUncorRe, qvec::QvecBNegUncorIm, qvec::QvecBNegRectrRe, qvec::QvecBNegRectrIm, - qvec::QvecBNegTwistRe, qvec::QvecBNegTwistIm, qvec::QvecBNegRe, qvec::QvecBNegIm, - qvec::SumAmplFT0C, qvec::SumAmplFT0A, qvec::SumAmplFT0M, qvec::SumAmplFV0A, qvec::NTrkBPos, qvec::NTrkBNeg, - qvec::LabelsBPos, qvec::LabelsBNeg); + qvec::Cent, qvec::CentBin, qvec::QvecRe, qvec::QvecIm, qvec::QvecAmp); using Qvector = Qvectors::iterator; DECLARE_SOA_TABLE(QvectorFT0Cs, "AOD", "QVECTORSFT0C", qvec::CentBin, qvec::QvecFT0CRe, qvec::QvecFT0CIm, qvec::SumAmplFT0C); diff --git a/Common/TableProducer/qVectorsTable.cxx b/Common/TableProducer/qVectorsTable.cxx index dd9a40b7024..0e51ffdd6bb 100644 --- a/Common/TableProducer/qVectorsTable.cxx +++ b/Common/TableProducer/qVectorsTable.cxx @@ -53,6 +53,15 @@ using MyCollisions = soa::Join; struct qVectorsTable { + enum { + kFT0C = 0, + kFT0A = 1, + kFT0M, + kFV0A, + kBPos, + kBNeg + }; + // Configurables. struct : ConfigurableGroup { Configurable cfgURL{"cfgURL", @@ -65,15 +74,16 @@ struct qVectorsTable { Configurable cfgCentEsti{"cfgCentEsti", 2, "Centrality estimator (Run3): 0 = FT0M, 1 = FT0A, 2 = FT0C, 3 = FV0A"}; - Configurable cfgMultName{"cfgDetName", "FT0C", "The name of detector to be analyzed, available systems: FT0A, FT0C, FV0A, TPCF, TPCB"}; - // LOKI: We have here all centrality estimators for Run 3 (except FDDM and NTPV), // but the Q-vectors are calculated only for some of them. // FIXME: 6 correction factors for each centrality and 8 centrality intervals are hard-coded. - - Configurable> cfgCorr{"cfgCorr", std::vector{0.0}, "Correction constants for detector"}; - Configurable> cfgBPosCorr{"cfgBPosCorr", std::vector{0.0}, "Correction constants for positive TPC tracks"}; - Configurable> cfgBNegCorr{"cfgBNegCorr", std::vector{0.0}, "Correction constants for negative TPC tracks"}; + // TODO: Constants from the CCDB + Configurable> cfgFT0CCorr{"cfgFT0CCorr", std::vector{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}, "Correction constants for FT0C"}; + Configurable> cfgFT0ACorr{"cfgFT0ACorr", std::vector{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}, "Correction constants for FT0A"}; + Configurable> cfgFT0MCorr{"cfgFT0MCorr", std::vector{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}, "Correction constants for FT0M"}; + Configurable> cfgFV0ACorr{"cfgFV0ACorr", std::vector{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}, "Correction constants for FV0A"}; + Configurable> cfgBPosCorr{"cfgBPosCorr", std::vector{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}, "Correction constants for positive TPC tracks"}; + Configurable> cfgBNegCorr{"cfgBNegCorr", std::vector{0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}, "Correction constants for negative TPC tracks"}; Configurable cfgMinPtOnTPC{"cfgMinPtOnTPC", 0.15, "minimum transverse momentum selection for TPC tracks participating in Q-vector reconstruction"}; Configurable cfgMaxPtOnTPC{"cfgMaxPtOnTPC", 5., "maximum transverse momentum selection for TPC tracks participating in Q-vector reconstruction"}; @@ -96,6 +106,10 @@ struct qVectorsTable { std::vector TrkBPosLabel; std::vector TrkBNegLabel; + std::vector qvecRe; + std::vector qvecIm; + std::vector qvecAmp; + std::vector> cfgCorr; // Variables for other classes. EventPlaneHelper helperEP; @@ -133,15 +147,30 @@ struct qVectorsTable { LOGF(fatal, "Could not get the alignment parameters for FV0."); } - if (cfgCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned"); + if (cfgFT0CCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0C"); + } + if (cfgFT0ACorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0A"); + } + if (cfgFT0MCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0M"); + } + if (cfgFV0ACorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FV0A"); } if (cfgBPosCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned"); + LOGF(fatal, "No proper correction factor assigned for positive TPC tracks"); } if (cfgBNegCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned"); + LOGF(fatal, "No proper correction factor assigned for negative TPC tracks"); } // will be replaced with method that call constants from CCDB + cfgCorr.push_back(cfgFT0CCorr); + cfgCorr.push_back(cfgFT0ACorr); + cfgCorr.push_back(cfgFT0MCorr); + cfgCorr.push_back(cfgFV0ACorr); + cfgCorr.push_back(cfgBPosCorr); + cfgCorr.push_back(cfgBNegCorr); /* // Debug printing. printf("Offset for FT0A: x = %.3f y = %.3f\n", (*offsetFT0)[0].getX(), (*offsetFT0)[0].getY()); @@ -210,7 +239,7 @@ struct qVectorsTable { float qVectBPos[2] = {0.}; float qVectBNeg[2] = {0.}; - TComplex QvecDet(0); // Complex value of the Q-vector for any detector. + TComplex QvecDet(0); // Complex value of the Q-vector for any detector. TComplex QvecFT0M(0); float sumAmplFT0A = 0.; // Sum of the amplitudes of all non-dead channels in any detector. float sumAmplFT0C = 0.; @@ -351,85 +380,65 @@ struct qVectorsTable { qVectBNeg[1] = 999.; } - /// TODO: Repeat here the procedure for any other Qvector columns. - /// Do not forget to add the configurable for the correction constants. + qvecRe.clear(); + qvecIm.clear(); + qvecAmp.clear(); - // Apply the correction constants (configurable) to the obtained Q-vectors. - // The function needs to be called for each detector/set separately. - // A correction constant set to zero means this correction is not applied. - // LOKI: Each detector must have their own vector of correction constants. int cBin = helperEP.GetCentBin(cent); - float qVectFT0ACorr[3][2]; - float qVectFT0CCorr[3][2]; - float qVectFT0MCorr[3][2]; - float qVectFV0ACorr[3][2]; - - float qVectBPosCorr[3][2]; - float qVectBNegCorr[3][2]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 2; j++) { - qVectFT0ACorr[i][j] = qVectFT0A[j]; - qVectFT0CCorr[i][j] = qVectFT0C[j]; - qVectFT0MCorr[i][j] = qVectFT0M[j]; - qVectFV0ACorr[i][j] = qVectFV0A[j]; - - qVectBPosCorr[i][j] = qVectBPos[j]; - qVectBNegCorr[i][j] = qVectBNeg[j]; - } + for (int i = 0; i < 4; i++) { + qvecRe.push_back(qVectFT0C[0]); + qvecIm.push_back(qVectFT0C[1]); + } + for (int i = 0; i < 4; i++) { + qvecRe.push_back(qVectFT0A[0]); + qvecIm.push_back(qVectFT0A[1]); + } + for (int i = 0; i < 4; i++) { + qvecRe.push_back(qVectFT0M[0]); + qvecIm.push_back(qVectFT0M[1]); + } + for (int i = 0; i < 4; i++) { + qvecRe.push_back(qVectFV0A[0]); + qvecIm.push_back(qVectFV0A[1]); + } + for (int i = 0; i < 4; i++) { + qvecRe.push_back(qVectBPos[0]); + qvecIm.push_back(qVectBPos[1]); + } + for (int i = 0; i < 4; i++) { + qvecRe.push_back(qVectBNeg[0]); + qvecIm.push_back(qVectBNeg[1]); } - if (cBin != -1) { // FIXME: will be improved when constants are obtained from CCDB - helperEP.DoRecenter(qVectFT0CCorr[1][0], qVectFT0CCorr[1][1], cfgCorr->at(cBin * 6), cfgCorr->at(cBin * 6 + 1)); - - helperEP.DoRecenter(qVectFT0CCorr[2][0], qVectFT0CCorr[2][1], cfgCorr->at(cBin * 6), cfgCorr->at(cBin * 6 + 1)); - helperEP.DoTwist(qVectFT0CCorr[2][0], qVectFT0CCorr[2][1], cfgCorr->at(cBin * 6 + 2), cfgCorr->at(cBin * 6 + 3)); - - helperEP.DoRecenter(qVectFT0C[0], qVectFT0C[1], cfgCorr->at(cBin * 6), cfgCorr->at(cBin * 6 + 1)); - helperEP.DoTwist(qVectFT0C[0], qVectFT0C[1], cfgCorr->at(cBin * 6 + 2), cfgCorr->at(cBin * 6 + 3)); - helperEP.DoRescale(qVectFT0C[0], qVectFT0C[1], cfgCorr->at(cBin * 6 + 4), cfgCorr->at(cBin * 6 + 5)); - - helperEP.DoRecenter(qVectBPosCorr[1][0], qVectBPosCorr[1][1], cfgBPosCorr->at(cBin * 6), cfgBPosCorr->at(cBin * 6 + 1)); - - helperEP.DoRecenter(qVectBPosCorr[2][0], qVectBPosCorr[2][1], cfgBPosCorr->at(cBin * 6), cfgBPosCorr->at(cBin * 6 + 1)); - helperEP.DoTwist(qVectBPosCorr[2][0], qVectBPosCorr[2][1], cfgBPosCorr->at(cBin * 6 + 2), cfgBPosCorr->at(cBin * 6 + 3)); - - helperEP.DoRecenter(qVectBPos[0], qVectBPos[1], cfgBPosCorr->at(cBin * 6), cfgBPosCorr->at(cBin * 6 + 1)); - helperEP.DoTwist(qVectBPos[0], qVectBPos[1], cfgBPosCorr->at(cBin * 6 + 2), cfgBPosCorr->at(cBin * 6 + 3)); - helperEP.DoRescale(qVectBPos[0], qVectBPos[1], cfgBPosCorr->at(cBin * 6 + 4), cfgBPosCorr->at(cBin * 6 + 5)); + qvecAmp.push_back(sumAmplFT0C); + qvecAmp.push_back(sumAmplFT0A); + qvecAmp.push_back(sumAmplFT0M); + qvecAmp.push_back(sumAmplFV0A); + qvecAmp.push_back(static_cast(nTrkBPos)); + qvecAmp.push_back(static_cast(nTrkBNeg)); - helperEP.DoRecenter(qVectBNegCorr[1][0], qVectBNegCorr[1][1], cfgBNegCorr->at(cBin * 6), cfgBNegCorr->at(cBin * 6 + 1)); + if (cBin != -1) { + for (int i = 0; i < 6; i++) { + helperEP.DoRecenter(qvecRe[i * 4 + 1], qvecIm[i * 4 + 1], cfgCorr[i][cBin * 6], cfgCorr[i][cBin * 6 + 1]); - helperEP.DoRecenter(qVectBNegCorr[2][0], qVectBNegCorr[2][1], cfgBNegCorr->at(cBin * 6), cfgBNegCorr->at(cBin * 6 + 1)); - helperEP.DoTwist(qVectBNegCorr[2][0], qVectBNegCorr[2][1], cfgBNegCorr->at(cBin * 6 + 2), cfgBNegCorr->at(cBin * 6 + 3)); + helperEP.DoRecenter(qvecRe[i * 4 + 2], qvecIm[i * 4 + 2], cfgCorr[i][cBin * 6], cfgCorr[i][cBin * 6 + 1]); + helperEP.DoTwist(qvecRe[i * 4 + 2], qvecIm[i * 4 + 2], cfgCorr[i][cBin * 6 + 2], cfgCorr[i][cBin * 6 + 3]); - helperEP.DoRecenter(qVectBNeg[0], qVectBNeg[1], cfgBNegCorr->at(cBin * 6), cfgBNegCorr->at(cBin * 6 + 1)); - helperEP.DoTwist(qVectBNeg[0], qVectBNeg[1], cfgBNegCorr->at(cBin * 6 + 2), cfgBNegCorr->at(cBin * 6 + 3)); - helperEP.DoRescale(qVectBNeg[0], qVectBNeg[1], cfgBNegCorr->at(cBin * 6 + 4), cfgBNegCorr->at(cBin * 6 + 5)); + helperEP.DoRecenter(qvecRe[i * 4 + 3], qvecIm[i * 4 + 3], cfgCorr[i][cBin * 6], cfgCorr[i][cBin * 6 + 1]); + helperEP.DoTwist(qvecRe[i * 4 + 3], qvecIm[i * 4 + 3], cfgCorr[i][cBin * 6 + 2], cfgCorr[i][cBin * 6 + 3]); + helperEP.DoRescale(qvecRe[i * 4 + 3], qvecIm[i * 4 + 3], cfgCorr[i][cBin * 6 + 4], cfgCorr[i][cBin * 6 + 5]); + } } + // Fill the columns of the Qvectors table. - qVector(cent, cBin, - qVectFT0ACorr[0][0], qVectFT0ACorr[0][1], qVectFT0ACorr[1][0], qVectFT0ACorr[1][1], - qVectFT0ACorr[2][0], qVectFT0ACorr[2][1], qVectFT0A[0], qVectFT0A[1], - qVectFT0CCorr[0][0], qVectFT0CCorr[0][1], qVectFT0CCorr[1][0], qVectFT0CCorr[1][1], - qVectFT0CCorr[2][0], qVectFT0CCorr[2][1], qVectFT0C[0], qVectFT0C[1], - qVectFT0MCorr[0][0], qVectFT0MCorr[0][1], qVectFT0MCorr[1][0], qVectFT0MCorr[1][1], - qVectFT0MCorr[2][0], qVectFT0MCorr[2][1], qVectFT0M[0], qVectFT0M[1], - qVectFV0ACorr[0][0], qVectFV0ACorr[0][1], qVectFV0ACorr[1][0], qVectFV0ACorr[1][1], - qVectFV0ACorr[2][0], qVectFV0ACorr[2][1], qVectFV0A[0], qVectFV0A[1], - qVectBPosCorr[0][0], qVectBPosCorr[0][1], qVectBPosCorr[1][0], qVectBPosCorr[1][1], - qVectBPosCorr[2][0], qVectBPosCorr[2][1], qVectBPos[0], qVectBPos[1], - qVectBNegCorr[0][0], qVectBNegCorr[0][1], qVectBNegCorr[1][0], qVectBNegCorr[1][1], - qVectBNegCorr[2][0], qVectBNegCorr[2][1], qVectBNeg[0], qVectBNeg[1], - sumAmplFT0A, sumAmplFT0C, sumAmplFT0M, sumAmplFV0A, nTrkBPos, nTrkBNeg, - TrkBPosLabel, TrkBNegLabel); - qVectorFT0A(cBin, qVectFT0A[0], qVectFT0A[1], sumAmplFT0A); - qVectorFT0C(cBin, qVectFT0C[0], qVectFT0C[1], sumAmplFT0C); - qVectorFT0M(cBin, qVectFT0M[0], qVectFT0M[1], sumAmplFT0M); - qVectorFV0A(cBin, qVectFV0A[0], qVectFV0A[1], sumAmplFV0A); - qVectorBPos(cBin, qVectBPos[0], qVectBPos[1], nTrkBPos, TrkBPosLabel); - qVectorBNeg(cBin, qVectBNeg[0], qVectBNeg[1], nTrkBNeg, TrkBNegLabel); + qVector(cent, cBin, qvecRe, qvecIm, qvecAmp); + qVectorFT0C(cBin, qvecRe[kFT0C * 4 + 3], qvecIm[kFT0C * 4 + 3], sumAmplFT0C); + qVectorFT0A(cBin, qvecRe[kFT0A * 4 + 3], qvecIm[kFT0A * 4 + 3], sumAmplFT0A); + qVectorFT0M(cBin, qvecRe[kFT0M * 4 + 3], qvecIm[kFT0M * 4 + 3], sumAmplFT0M); + qVectorFV0A(cBin, qvecRe[kFV0A * 4 + 3], qvecIm[kFV0A * 4 + 3], sumAmplFV0A); + qVectorBPos(cBin, qvecRe[kBPos * 4 + 3], qvecIm[kBPos * 4 + 3], nTrkBPos, TrkBPosLabel); + qVectorBNeg(cBin, qvecRe[kBNeg * 4 + 3], qvecIm[kBNeg * 4 + 3], nTrkBNeg, TrkBNegLabel); } // End process. }; diff --git a/Common/Tasks/qVectorsCorrection.cxx b/Common/Tasks/qVectorsCorrection.cxx index 06699bc6861..f63f260a350 100644 --- a/Common/Tasks/qVectorsCorrection.cxx +++ b/Common/Tasks/qVectorsCorrection.cxx @@ -59,14 +59,52 @@ struct qVectorsCorrection { // as TDirectoryFile. HistogramRegistry histosQA{"histosQA", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - Configurable cfgMinTPCTracks{"cfgMinTPCTracks", 20, "minimum TPC tracks participating in Q-vector reconstruction"}; Configurable cfgnMod{"cfgnMod", 2, "Modulation of interest"}; + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgRefAName{"cfgRefAName", "BPos", "The name of detector for reference A"}; + Configurable cfgRefBName{"cfgRefBName", "BNeg", "The name of detector for reference B"}; + // Helper variables. EventPlaneHelper helperEP; + int DetId; + int RefAId; + int RefBId; + + template + int GetDetId(const T& name) + { + if (name.value == "FT0C") { + return 0; + } else if (name.value == "FT0A") { + return 1; + } else if (name.value == "FT0M") { + return 2; + } else if (name.value == "FV0A") { + return 3; + } else if (name.value == "BPos") { + return 4; + } else if (name.value == "BNeg") { + return 5; + } else { + return 0; + } + } + void init(InitContext const&) { + DetId = GetDetId(cfgDetName); + RefAId = GetDetId(cfgRefAName); + RefBId = GetDetId(cfgRefBName); + + if (DetId == RefAId || DetId == RefBId || RefAId == RefBId) { + LOGF(info, "Wrong detector configuration \n The FT0C will be used to get Q-Vector \n The BPos and BNeg will be used as reference systems"); + DetId = 0; + RefAId = 4; + RefBId = 5; + } + // Fill the registry with the needed objects. const AxisSpec axisCent{110, 0., 110.}; const AxisSpec axisQvec{1000, -5, 5}; @@ -79,35 +117,35 @@ struct qVectorsCorrection { histosQA.add("Centrality_0-5/histCent", "Centrality distribution", HistType::kTH1F, {axisCent}); - histosQA.add("Centrality_0-5/histQvecFT0CUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecFT0CRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecFT0CTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecFT0CFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBPosUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBPosRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBPosTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBPosFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefAUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefARectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefATwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefAFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBNegUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBNegRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBNegTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecBNegFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefBUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefBRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefBTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefBFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histEvtPlFT0CUncor", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlFT0CRectr", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlFT0CTwist", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlFT0CFinal", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlUncor", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRectr", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlTwist", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlFinal", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosUncor", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosRectr", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosTwist", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosFinal", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefAUncor", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefARectr", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefATwist", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefAFinal", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegUncor", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegRectr", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegTwist", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegFinal", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefBUncor", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefBRectr", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefBTwist", "", {HistType::kTH1F, {axisEvtPl}}); + histosQA.add("Centrality_0-5/histEvtPlRefBFinal", "", {HistType::kTH1F, {axisEvtPl}}); histosQA.add("Centrality_0-5/histEvtPlResolution", "", {HistType::kTH1F, {axisEvtPl}}); @@ -123,47 +161,47 @@ struct qVectorsCorrection { { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histCent"), vec.cent()); - if (vec.sumAmplFT0C() > 1e-8) { - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFT0CUncor"), vec.qvecFT0CUncorRe(), vec.qvecFT0CUncorIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFT0CRectr"), vec.qvecFT0CRectrRe(), vec.qvecFT0CRectrIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFT0CTwist"), vec.qvecFT0CTwistRe(), vec.qvecFT0CTwistIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFT0CFinal"), vec.qvecFT0CRe(), vec.qvecFT0CIm()); + if (vec.qvecAmp()[DetId] > 1e-8) { + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecUncor"), vec.qvecRe()[DetId], vec.qvecIm()[DetId]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRectr"), vec.qvecRe()[DetId + 1], vec.qvecIm()[DetId + 1]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecTwist"), vec.qvecRe()[DetId + 2], vec.qvecIm()[DetId + 2]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFinal"), vec.qvecRe()[DetId + 3], vec.qvecIm()[DetId + 3]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFT0CUncor"), helperEP.GetEventPlane(vec.qvecFT0CUncorRe(), vec.qvecFT0CUncorIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFT0CRectr"), helperEP.GetEventPlane(vec.qvecFT0CRectrRe(), vec.qvecFT0CRectrIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFT0CTwist"), helperEP.GetEventPlane(vec.qvecFT0CTwistRe(), vec.qvecFT0CTwistIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFT0CFinal"), helperEP.GetEventPlane(vec.qvecFT0CRe(), vec.qvecFT0CIm())); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlUncor"), helperEP.GetEventPlane(vec.qvecRe()[DetId], vec.qvecIm()[DetId], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRectr"), helperEP.GetEventPlane(vec.qvecRe()[DetId + 1], vec.qvecIm()[DetId + 1], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlTwist"), helperEP.GetEventPlane(vec.qvecRe()[DetId + 2], vec.qvecIm()[DetId + 2], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFinal"), helperEP.GetEventPlane(vec.qvecRe()[DetId + 3], vec.qvecIm()[DetId + 3], 2)); } - if (vec.nTrkBPos() > cfgMinTPCTracks) { - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBPosUncor"), vec.qvecBPosUncorRe(), vec.qvecBPosUncorIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBPosRectr"), vec.qvecBPosRectrRe(), vec.qvecBPosRectrIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBPosTwist"), vec.qvecBPosTwistRe(), vec.qvecBPosTwistIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBPosFinal"), vec.qvecBPosRe(), vec.qvecBPosIm()); + if (vec.qvecAmp()[RefAId] > 1e-8) { + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAUncor"), vec.qvecRe()[RefAId], vec.qvecIm()[RefAId]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefARectr"), vec.qvecRe()[RefAId + 1], vec.qvecIm()[RefAId + 1]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefATwist"), vec.qvecRe()[RefAId + 2], vec.qvecIm()[RefAId + 2]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAFinal"), vec.qvecRe()[RefAId + 3], vec.qvecIm()[RefAId + 3]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBPosUncor"), helperEP.GetEventPlane(vec.qvecBPosUncorRe(), vec.qvecBPosUncorIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBPosRectr"), helperEP.GetEventPlane(vec.qvecBPosRectrRe(), vec.qvecBPosRectrIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBPosTwist"), helperEP.GetEventPlane(vec.qvecBPosTwistRe(), vec.qvecBPosTwistIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBPosFinal"), helperEP.GetEventPlane(vec.qvecBPosRe(), vec.qvecBPosIm())); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefAId], vec.qvecIm()[RefAId], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefARectr"), helperEP.GetEventPlane(vec.qvecRe()[RefAId + 1], vec.qvecIm()[RefAId + 1], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefATwist"), helperEP.GetEventPlane(vec.qvecRe()[RefAId + 2], vec.qvecIm()[RefAId + 2], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefAId + 3], vec.qvecIm()[RefAId + 3], 2)); } - if (vec.nTrkBNeg() > cfgMinTPCTracks) { - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBNegUncor"), vec.qvecBNegUncorRe(), vec.qvecBNegUncorIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBNegRectr"), vec.qvecBNegRectrRe(), vec.qvecBNegRectrIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBNegTwist"), vec.qvecBNegTwistRe(), vec.qvecBNegTwistIm()); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecBNegFinal"), vec.qvecBNegRe(), vec.qvecBNegIm()); + if (vec.qvecAmp()[RefBId] > 1e-8) { + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBUncor"), vec.qvecRe()[RefBId], vec.qvecIm()[RefBId]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBRectr"), vec.qvecRe()[RefBId + 1], vec.qvecIm()[RefBId + 1]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBTwist"), vec.qvecRe()[RefBId + 2], vec.qvecIm()[RefBId + 2]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBFinal"), vec.qvecRe()[RefBId + 3], vec.qvecIm()[RefBId + 3]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBNegUncor"), helperEP.GetEventPlane(vec.qvecBNegUncorRe(), vec.qvecBNegUncorIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBNegRectr"), helperEP.GetEventPlane(vec.qvecBNegRectrRe(), vec.qvecBNegRectrIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBNegTwist"), helperEP.GetEventPlane(vec.qvecBNegTwistRe(), vec.qvecBNegTwistIm())); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlBNegFinal"), helperEP.GetEventPlane(vec.qvecBNegRe(), vec.qvecBNegIm())); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefBId], vec.qvecIm()[RefBId], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBRectr"), helperEP.GetEventPlane(vec.qvecRe()[RefBId + 1], vec.qvecIm()[RefBId + 1], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBTwist"), helperEP.GetEventPlane(vec.qvecRe()[RefBId + 2], vec.qvecIm()[RefBId + 2], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefBId + 3], vec.qvecIm()[RefBId + 3], 2)); } - if (vec.nTrkBPos() > cfgMinTPCTracks && vec.nTrkBNeg() > cfgMinTPCTracks && vec.sumAmplFT0C() > 1e-8) { + if (vec.qvecAmp()[DetId] > 1e-8 && vec.qvecAmp()[RefAId] > 1e-8 && vec.qvecAmp()[RefBId] > 1e-8) { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlResolution"), helperEP.GetResolution( - helperEP.GetEventPlane(vec.qvecBPosRe(), vec.qvecBPosIm()), - helperEP.GetEventPlane(vec.qvecBNegRe(), vec.qvecBNegIm()), - helperEP.GetEventPlane(vec.qvecBPosRe(), vec.qvecBPosIm()), 2)); + helperEP.GetEventPlane(vec.qvecRe()[RefAId + 3], vec.qvecIm()[RefAId + 3], 2), + helperEP.GetEventPlane(vec.qvecRe()[RefBId + 3], vec.qvecIm()[RefBId + 3], 2), + helperEP.GetEventPlane(vec.qvecRe()[DetId + 3], vec.qvecIm()[DetId + 3], 2), 2)); } } @@ -197,8 +235,8 @@ struct qVectorsCorrection { case 7: fillHistosQvec<7>(qVec); break; - } // End switch(centBin) - } // End void process(...) + } // End switch(centBin) + } // End void process(...) }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 3240eb7a4bc0f0f22b9a3ede2f19aa629a744e9d Mon Sep 17 00:00:00 2001 From: Federica Zanone <94552525+ZFederica@users.noreply.github.com> Date: Tue, 12 Dec 2023 09:38:04 +0100 Subject: [PATCH 033/156] PWGHF: fix cascade index in derived data production and adapt task toXiPi (#4131) * Change cascade index globalIndex-->cascadeId * Adapt toXiPi creator * Please consider the following formatting changes * Please consider the following formatting changes * MegaLinter fixes * Fix save indexes and unused variables * Fix * Please consider the following formatting changes * Update PWGHF/TableProducer/candidateCreatorToXiPi.cxx Co-authored-by: Mattia Faggin * Remove cascade preselections (outdated) * Change variable name * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot Co-authored-by: Mattia Faggin --- .../TableProducer/candidateCreatorToXiPi.cxx | 789 +++++------------- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 20 +- 2 files changed, 220 insertions(+), 589 deletions(-) diff --git a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx index dcf300d35a4..bebed1e15af 100644 --- a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx @@ -40,6 +40,7 @@ #include "PWGHF/Utils/utilsBfieldCCDB.h" using namespace o2; +using namespace o2::track; using namespace o2::analysis; using namespace o2::aod; using namespace o2::aod::cascdata; @@ -53,8 +54,6 @@ using namespace o2::framework::expressions; struct HfCandidateCreatorToXiPi { Produces rowCandidate; - Configurable doPvRefit{"doPvRefit", false, "set to true if you do PV refit in trackIndexSkimCreator.cxx"}; - Configurable propagateToPCA{"propagateToPCA", false, "create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; Configurable useWeightedFinalPCA{"useWeightedFinalPCA", true, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; @@ -74,30 +73,19 @@ struct HfCandidateCreatorToXiPi { Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; - // cascade cuts - Configurable doCascadePreselection{"doCascadePreselection", true, "Use invariant mass and dcaXY cuts to preselect cascade candidates"}; - Configurable massToleranceCascade{"massToleranceCascade", 0.01, "Invariant mass tolerance for cascade"}; - Configurable dcaXYToPVCascadeMax{"dcaXYToPVCascadeMax", 3, "Max cascade DCA to PV in xy plane"}; - Service ccdb; o2::base::MatLayerCylSet* lut; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; int runNumber; - using SelectedCollisions = soa::Filtered>; - using MyTracks = soa::Join; - using FilteredHfTrackAssocSel = soa::Filtered>; using MyCascTable = soa::Join; // to use strangeness tracking, use aod::TraCascDatas instead of aod::CascDatas + using CascadesLinked = soa::Join; using MyV0Table = soa::Join; - using MySkimIdx = HfCascLf2Prongs; - - Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == 0); // filter to use only HF selected collisions - Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng > 0); + using V0sLinked = soa::Join; + using MySkimIdx = soa::Filtered; - Preslice trackIndicesPerCollision = aod::track_association::collisionId; // aod::hf_track_association::collisionId - Preslice cascadesPerCollision = aod::cascdata::collisionId; - Preslice candidatesPerCollision = hf_track_index::collisionId; + Filter filterSelectIndexes = (aod::hf_track_index::hfflag > static_cast(0)); OutputObj hInvMassCharmBaryon{TH1F("hInvMassCharmBaryon", "Charm baryon invariant mass;inv mass;entries", 500, 2.2, 3.1)}; OutputObj hFitterStatus{TH1F("hFitterStatus", "Charm DCAFitter status;status;entries", 3, -0.5, 2.5)}; // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) @@ -110,22 +98,14 @@ struct HfCandidateCreatorToXiPi { ccdb->setLocalObjectValidityChecking(); lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; - - if (doprocessIdxCombinatorics && doprocessDerivedData) { - LOGF(fatal, "Cannot enable processIdxCombinatorics and processDerivedData at the same time. Please choose one."); - } - if (!doprocessIdxCombinatorics && !doprocessDerivedData) { - LOGF(fatal, "Please enable at least one process, now both processIdxCombinatorics and processDerivedData are false."); - } } - void processIdxCombinatorics(SelectedCollisions const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyTracks const& tracks, - FilteredHfTrackAssocSel const& trackIndices, - MyCascTable const& cascades, - MyV0Table const&, - aod::V0sLinked const&) + void process(aod::Collisions const&, + aod::BCsWithTimestamps const&, + TracksWCovDca const&, + MyCascTable const&, CascadesLinked const&, + MyV0Table const&, V0sLinked const&, + MySkimIdx const& candidates) { double massPionFromPDG = MassPiPlus; // pdg code 211 @@ -146,319 +126,17 @@ struct HfCandidateCreatorToXiPi { df.setUseAbsDCA(useAbsDCA); df.setWeightedFinalPCA(useWeightedFinalPCA); - for (const auto& collision : collisions) { + for (const auto& cand : candidates) { - // set the magnetic field from CCDB - auto bc = collision.bc_as(); - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); - auto magneticField = o2::base::Propagator::Instance()->getNominalBz(); // z component + hCandidateCounter->Fill(0); - df.setBz(magneticField); - df.setRefitWithMatCorr(refitWithMatCorr); - - // loop over cascades reconstructed by cascadebuilder.cxx - auto thisCollId = collision.globalIndex(); - auto groupedCascades = cascades.sliceBy(cascadesPerCollision, thisCollId); - - for (const auto& casc : groupedCascades) { - - // preselect cascade candidates - if (doCascadePreselection) { - if (std::abs(casc.dcaXYCascToPV()) > dcaXYToPVCascadeMax) { - continue; - } - if (std::abs(casc.mXi() - massXiFromPDG) > massToleranceCascade) { - continue; - } - } - - //----------------accessing particles in the decay chain------------- - // cascade daughter - charged particle - // int indexTrackXiDauCharged = casc.bachelorId(); // pion <- xi index from cascade table (not used) - auto trackXiDauCharged = casc.bachelor_as(); // pion <- xi track from MyTracks table - // cascade daughter - V0 - if (!casc.v0_as().has_v0Data()) { // check that V0 data are stored - continue; - } - auto v0 = casc.v0_as(); - auto v0Element = v0.v0Data_as(); // V0 element from LF table containing V0 info - // V0 positive daughter - auto trackV0Dau0 = v0Element.posTrack_as(); // p <- V0 track (positive track) from MyTracks table - // V0 negative daughter - auto trackV0Dau1 = v0Element.negTrack_as(); // pion <- V0 track (negative track) from MyTracks table - - // check that particles come from the same collision - if (rejDiffCollTrack) { - if (trackV0Dau0.collisionId() != trackV0Dau1.collisionId()) { - continue; - } - if (trackXiDauCharged.collisionId() != trackV0Dau0.collisionId()) { - continue; - } - } - - //-------------------------- V0 info--------------------------- - // pseudorapidity - double pseudorapV0Dau0 = trackV0Dau0.eta(); - double pseudorapV0Dau1 = trackV0Dau1.eta(); - - // pion & p <- V0 tracks - auto trackParCovV0Dau0 = getTrackParCov(trackV0Dau0); - auto trackParCovV0Dau1 = getTrackParCov(trackV0Dau1); - - // info from LF table - std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; // pVec stands for vector containing the 3-momentum components - std::array vertexV0 = {casc.xlambda(), casc.ylambda(), casc.zlambda()}; - std::array pVecV0Dau0 = {casc.pxpos(), casc.pypos(), casc.pzpos()}; - std::array pVecV0Dau1 = {casc.pxneg(), casc.pyneg(), casc.pzneg()}; - - //-----------------------------reconstruct cascade track----------------------------- - // pseudorapidity - double pseudorapPiFromCas = trackXiDauCharged.eta(); - - // pion <- casc track - auto trackParCovXiDauCharged = getTrackParCov(trackXiDauCharged); - - // info from LF table - std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; - std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; - std::array covCasc = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = casc.momentumCovMat()[i]; - covCasc[i] = casc.positionCovMat()[i]; - } - // create cascade track - o2::track::TrackParCov trackCasc; - if (trackXiDauCharged.sign() > 0) { - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); - } else if (trackXiDauCharged.sign() < 0) { - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); - } else { - continue; - } - trackCasc.setAbsCharge(1); - trackCasc.setPID(o2::track::PID::XiMinus); - - std::array pVecPionFromCasc = {casc.pxbach(), casc.pybach(), casc.pzbach()}; - - //-------------------combining cascade and pion tracks-------------------------- - auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - for (const auto& trackIndexPion : groupedTrackIndices) { - - // use bachelor selections from HfTrackIndexSkimCreatorTagSelTracks --> bit = 4 is CandidateType::CandCascadeBachelor - if (!TESTBIT(trackIndexPion.isSelProng(), 4)) { - continue; - } - - auto trackPion = trackIndexPion.track_as(); - - if ((rejDiffCollTrack) && (trackXiDauCharged.collisionId() != trackPion.collisionId())) { - continue; - } - - // ask for opposite sign daughters (charm baryon daughters) - if (trackPion.sign() * trackXiDauCharged.sign() >= 0) { - continue; - } - - // check not to take the same particle twice in the decay chain - if (trackPion.globalIndex() == trackXiDauCharged.globalIndex() || trackPion.globalIndex() == trackV0Dau0.globalIndex() || trackPion.globalIndex() == trackV0Dau1.globalIndex()) { - continue; - } - - // pseudorapidity - double pseudorapPiFromCharmBaryon = trackPion.eta(); - - // charm bachelor pion track to be processed with DCAFitter - auto trackParVarPi = getTrackParCov(trackPion); - - // reconstruct charm baryon with DCAFitter - int nVtxFromFitterCharmBaryon = 0; - try { - nVtxFromFitterCharmBaryon = df.process(trackCasc, trackParVarPi); - } catch (...) { - LOG(error) << "Exception caught in charm DCA fitter process call!"; - hFitterStatus->Fill(1); - continue; - } - if (nVtxFromFitterCharmBaryon == 0) { - hFitterStatus->Fill(2); - continue; - } - hFitterStatus->Fill(0); - auto vertexCharmBaryonFromFitter = df.getPCACandidate(); - auto chi2PCACharmBaryon = df.getChi2AtPCACandidate(); - std::array pVecCascAsD; - std::array pVecPionFromCharmBaryon; - df.propagateTracksToVertex(); - if (!df.isPropagateTracksToVertexDone()) { - continue; - } - df.getTrack(0).getPxPyPzGlo(pVecCascAsD); - df.getTrack(1).getPxPyPzGlo(pVecPionFromCharmBaryon); - std::array pVecCharmBaryon = {pVecCascAsD[0] + pVecPionFromCharmBaryon[0], pVecCascAsD[1] + pVecPionFromCharmBaryon[1], pVecCascAsD[2] + pVecPionFromCharmBaryon[2]}; - - std::array coordVtxCharmBaryon = df.getPCACandidatePos(); - std::array covVtxCharmBaryon = df.calcPCACovMatrixFlat(); - - // DCAxy (computed with propagateToDCABxByBz method) - float dcaxyV0Dau0 = trackV0Dau0.dcaXY(); - float dcaxyV0Dau1 = trackV0Dau1.dcaXY(); - float dcaxyPiFromCasc = trackXiDauCharged.dcaXY(); - - // DCAz (computed with propagateToDCABxByBz method) - float dcazV0Dau0 = trackV0Dau0.dcaZ(); - float dcazV0Dau1 = trackV0Dau1.dcaZ(); - float dcazPiFromCasc = trackXiDauCharged.dcaZ(); - - // primary vertex of the collision - auto primaryVertex = getPrimaryVertex(collision); // get the associated covariance matrix with auto covMatrixPV = primaryVertex.getCov(); - std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - - if (doPvRefit && ((trackPion.pvRefitSigmaX2() != 1e10f) || (trackPion.pvRefitSigmaY2() != 1e10f) || (trackPion.pvRefitSigmaZ2() != 1e10f))) { // if I asked for PV refit in trackIndexSkimCreator.cxx - pvCoord[0] = trackPion.pvRefitX(); - pvCoord[1] = trackPion.pvRefitY(); - pvCoord[2] = trackPion.pvRefitZ(); - - // o2::dataformats::VertexBase Pvtx; - primaryVertex.setX(trackPion.pvRefitX()); - primaryVertex.setY(trackPion.pvRefitY()); - primaryVertex.setZ(trackPion.pvRefitZ()); - primaryVertex.setCov(trackPion.pvRefitSigmaX2(), trackPion.pvRefitSigmaXY(), trackPion.pvRefitSigmaY2(), trackPion.pvRefitSigmaXZ(), trackPion.pvRefitSigmaYZ(), trackPion.pvRefitSigmaZ2()); - - o2::dataformats::DCA impactParameterV0Dau0; - o2::dataformats::DCA impactParameterV0Dau1; - o2::dataformats::DCA impactParameterPiFromCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0Dau0, 2.f, matCorr, &impactParameterV0Dau0); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0Dau1, 2.f, matCorr, &impactParameterV0Dau1); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovXiDauCharged, 2.f, matCorr, &impactParameterPiFromCasc); - dcaxyV0Dau0 = impactParameterV0Dau0.getY(); - dcaxyV0Dau1 = impactParameterV0Dau1.getY(); - dcaxyPiFromCasc = impactParameterPiFromCasc.getY(); - dcazV0Dau0 = impactParameterV0Dau0.getZ(); - dcazV0Dau1 = impactParameterV0Dau1.getZ(); - dcazPiFromCasc = impactParameterPiFromCasc.getZ(); - } - - // impact parameters - o2::dataformats::DCA impactParameterCasc; - o2::dataformats::DCA impactParameterPiFromCharmBaryon; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarPi, 2.f, matCorr, &impactParameterPiFromCharmBaryon); - float impactParPiFromCharmBaryonXY = impactParameterPiFromCharmBaryon.getY(); - float impactParPiFromCharmBaryonZ = impactParameterPiFromCharmBaryon.getZ(); - - // invariant mass under the hypothesis of particles ID corresponding to the decay chain - double mLambda = casc.mLambda(); // from LF table, V0 mass under lambda hypothesis - double mCasc = casc.mXi(); - const std::array arrMassCharmBaryon = {massXiFromPDG, massPionFromPDG}; - double mCharmBaryon = RecoDecay::m(std::array{pVecCascAsD, pVecPionFromCharmBaryon}, arrMassCharmBaryon); - - // computing cosPA - double cpaV0 = RecoDecay::cpa(vertexCasc, vertexV0, pVecV0); - double cpaCharmBaryon = RecoDecay::cpa(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); - double cpaCasc = RecoDecay::cpa(coordVtxCharmBaryon, vertexCasc, pVecCasc); - double cpaxyV0 = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); - double cpaxyCharmBaryon = RecoDecay::cpaXY(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); - double cpaxyCasc = RecoDecay::cpaXY(coordVtxCharmBaryon, vertexCasc, pVecCasc); - - // computing decay length and ctau - double decLenCharmBaryon = RecoDecay::distance(pvCoord, coordVtxCharmBaryon); - double decLenCascade = RecoDecay::distance(coordVtxCharmBaryon, vertexCasc); - double decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); - - double phiCharmBaryon, thetaCharmBaryon; - getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, coordVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon); - auto errorDecayLengthCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); - auto errorDecayLengthXYCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, 0.) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, 0.)); - - double ctOmegac = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, massOmegacFromPDG); - double ctXic = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, massXicFromPDG); - double ctCascade = RecoDecay::ct(pVecCasc, decLenCascade, massXiFromPDG); - double ctV0 = RecoDecay::ct(pVecV0, decLenV0, massLambdaFromPDG); - - // computing eta - double pseudorapCharmBaryon = RecoDecay::eta(pVecCharmBaryon); - double pseudorapCascade = RecoDecay::eta(pVecCasc); - double pseudorapV0 = RecoDecay::eta(pVecV0); - - // DCA between daughters - float dcaCascDau = casc.dcacascdaughters(); - float dcaV0Dau = casc.dcaV0daughters(); - float dcaCharmBaryonDau = std::sqrt(df.getChi2AtPCACandidate()); - - // set hfFlag - int hfFlag = 1 << aod::hf_cand_toxipi::DecayType::DecayToXiPi; - - // fill test histograms - hInvMassCharmBaryon->Fill(mCharmBaryon); - - // fill the table - rowCandidate(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackXiDauCharged.sign(), - chi2PCACharmBaryon, covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCasc[0], pVecCasc[1], pVecCasc[2], - pVecPionFromCharmBaryon[0], pVecPionFromCharmBaryon[1], pVecPionFromCharmBaryon[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecPionFromCasc[0], pVecPionFromCasc[1], pVecPionFromCasc[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - impactParameterCasc.getY(), impactParPiFromCharmBaryonXY, - impactParameterCasc.getZ(), impactParPiFromCharmBaryonZ, - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterPiFromCharmBaryon.getSigmaY2()), - v0Element.globalIndex(), v0Element.posTrackId(), v0Element.negTrackId(), - casc.globalIndex(), trackPion.globalIndex(), trackXiDauCharged.globalIndex(), - mLambda, mCasc, mCharmBaryon, - cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac, ctCascade, ctV0, ctXic, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapPiFromCas, pseudorapPiFromCharmBaryon, - pseudorapCharmBaryon, pseudorapCascade, pseudorapV0, - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyPiFromCasc, - dcazV0Dau0, dcazV0Dau1, dcazPiFromCasc, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon, - hfFlag); - - } // loop over pions - } // loop over cascades - } // close loop collisions - } // end of process - PROCESS_SWITCH(HfCandidateCreatorToXiPi, processIdxCombinatorics, "Do indexes combinatorics", true); - - void processDerivedData(SelectedCollisions const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyTracks const& tracks, - MyCascTable const& cascades, - MyV0Table const&, - aod::V0sLinked const&, - MySkimIdx const& candidates) - { - - double massPionFromPDG = MassPiPlus; // pdg code 211 - double massLambdaFromPDG = MassLambda0; // pdg code 3122 - double massXiFromPDG = MassXiMinus; // pdg code 3312 - double massOmegacFromPDG = MassOmegaC0; // pdg code 4332 - double massXicFromPDG = MassXiCZero; // pdg code 4132 + if (!TESTBIT(cand.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi)) { + continue; + } - // 2-prong vertex fitter to build the omegac/xic vertex - o2::vertexing::DCAFitterN<2> df; - df.setPropagateToPCA(propagateToPCA); - df.setMaxR(maxR); - df.setMaxDZIni(maxDZIni); - df.setMaxDXYIni(maxDXYIni); - df.setMinParamChange(minParamChange); - df.setMinRelChi2Change(minRelChi2Change); - df.setMaxChi2(maxChi2); - df.setUseAbsDCA(useAbsDCA); - df.setWeightedFinalPCA(useWeightedFinalPCA); + hCandidateCounter->Fill(1); - for (const auto& collision : collisions) { + auto collision = cand.collision_as(); // set the magnetic field from CCDB auto bc = collision.bc_as(); @@ -468,238 +146,191 @@ struct HfCandidateCreatorToXiPi { df.setBz(magneticField); df.setRefitWithMatCorr(refitWithMatCorr); - // loop over cascades reconstructed by cascadebuilder.cxx - auto thisCollId = collision.globalIndex(); - auto groupedCandidates = candidates.sliceBy(candidatesPerCollision, thisCollId); - - for (const auto& cand : groupedCandidates) { - - hCandidateCounter->Fill(0); - - if (!TESTBIT(cand.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi)) { - continue; - } - - hCandidateCounter->Fill(1); - - auto casc = cand.cascade_as(); - auto trackPion = cand.prong0_as(); // pi <-- charm baryon - auto trackXiDauCharged = casc.bachelor_as(); // pion <- xi track - auto v0 = casc.v0_as(); - auto v0Element = v0.v0Data_as(); // V0 <-- xi - auto trackV0Dau0 = v0Element.posTrack_as(); // V0 positive daughter track - auto trackV0Dau1 = v0Element.negTrack_as(); // V0 negative daughter track - - //-------------------------- V0 info--------------------------- - // pseudorapidity - double pseudorapV0Dau0 = trackV0Dau0.eta(); - double pseudorapV0Dau1 = trackV0Dau1.eta(); - - // pion & p <- V0 tracks - auto trackParCovV0Dau0 = getTrackParCov(trackV0Dau0); - auto trackParCovV0Dau1 = getTrackParCov(trackV0Dau1); - - // info from LF table - std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; - std::array vertexV0 = {casc.xlambda(), casc.ylambda(), casc.zlambda()}; - std::array pVecV0Dau0 = {casc.pxpos(), casc.pypos(), casc.pzpos()}; - std::array pVecV0Dau1 = {casc.pxneg(), casc.pyneg(), casc.pzneg()}; - - //-------------------reconstruct cascade track------------------ - // pseudorapidity - double pseudorapPiFromCas = trackXiDauCharged.eta(); - - auto trackParCovXiDauCharged = getTrackParCov(trackXiDauCharged); - - // info from LF table - std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; - std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; - std::array covCasc = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = casc.momentumCovMat()[i]; - covCasc[i] = casc.positionCovMat()[i]; - } - // create cascade track - o2::track::TrackParCov trackCasc; - if (trackXiDauCharged.sign() > 0) { - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); - } else if (trackXiDauCharged.sign() < 0) { - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); - } else { - continue; - } - trackCasc.setAbsCharge(1); - trackCasc.setPID(o2::track::PID::XiMinus); - - std::array pVecPionFromCasc = {casc.pxbach(), casc.pybach(), casc.pzbach()}; - - //------------reconstruct charm baryon decay vtx--------------- - auto trackParVarPi = getTrackParCov(trackPion); // charm bachelor pion track to be processed with DCAFitter - - // reconstruct charm baryon with DCAFitter - int nVtxFromFitterCharmBaryon = 0; - try { - nVtxFromFitterCharmBaryon = df.process(trackCasc, trackParVarPi); - } catch (...) { - LOG(error) << "Exception caught in charm DCA fitter process call!"; - hFitterStatus->Fill(1); - continue; - } - if (nVtxFromFitterCharmBaryon == 0) { - hFitterStatus->Fill(2); - continue; - } - hFitterStatus->Fill(0); - hCandidateCounter->Fill(2); - auto vertexCharmBaryonFromFitter = df.getPCACandidate(); - auto chi2PCACharmBaryon = df.getChi2AtPCACandidate(); - std::array pVecCascAsD; - std::array pVecPionFromCharmBaryon; - df.propagateTracksToVertex(); - if (!df.isPropagateTracksToVertexDone()) { - continue; - } - df.getTrack(0).getPxPyPzGlo(pVecCascAsD); - df.getTrack(1).getPxPyPzGlo(pVecPionFromCharmBaryon); - std::array pVecCharmBaryon = {pVecCascAsD[0] + pVecPionFromCharmBaryon[0], pVecCascAsD[1] + pVecPionFromCharmBaryon[1], pVecCascAsD[2] + pVecPionFromCharmBaryon[2]}; - - std::array coordVtxCharmBaryon = df.getPCACandidatePos(); - std::array covVtxCharmBaryon = df.calcPCACovMatrixFlat(); - - // pseudorapidity - double pseudorapPiFromCharmBaryon = trackPion.eta(); - - // DCAxy (computed with propagateToDCABxByBz method) - float dcaxyV0Dau0 = trackV0Dau0.dcaXY(); - float dcaxyV0Dau1 = trackV0Dau1.dcaXY(); - float dcaxyPiFromCasc = trackXiDauCharged.dcaXY(); - - // DCAz (computed with propagateToDCABxByBz method) - float dcazV0Dau0 = trackV0Dau0.dcaZ(); - float dcazV0Dau1 = trackV0Dau1.dcaZ(); - float dcazPiFromCasc = trackXiDauCharged.dcaZ(); - - // primary vertex of the collision - auto primaryVertex = getPrimaryVertex(collision); // get the associated covariance matrix with auto covMatrixPV = primaryVertex.getCov(); - std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - - if (doPvRefit && ((trackPion.pvRefitSigmaX2() != 1e10f) || (trackPion.pvRefitSigmaY2() != 1e10f) || (trackPion.pvRefitSigmaZ2() != 1e10f))) { // if I asked for PV refit in trackIndexSkimCreator.cxx - pvCoord[0] = trackPion.pvRefitX(); - pvCoord[1] = trackPion.pvRefitY(); - pvCoord[2] = trackPion.pvRefitZ(); - - // o2::dataformats::VertexBase Pvtx; - primaryVertex.setX(trackPion.pvRefitX()); - primaryVertex.setY(trackPion.pvRefitY()); - primaryVertex.setZ(trackPion.pvRefitZ()); - primaryVertex.setCov(trackPion.pvRefitSigmaX2(), trackPion.pvRefitSigmaXY(), trackPion.pvRefitSigmaY2(), trackPion.pvRefitSigmaXZ(), trackPion.pvRefitSigmaYZ(), trackPion.pvRefitSigmaZ2()); - - o2::dataformats::DCA impactParameterV0Dau0; - o2::dataformats::DCA impactParameterV0Dau1; - o2::dataformats::DCA impactParameterPiFromCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0Dau0, 2.f, matCorr, &impactParameterV0Dau0); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0Dau1, 2.f, matCorr, &impactParameterV0Dau1); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovXiDauCharged, 2.f, matCorr, &impactParameterPiFromCasc); - dcaxyV0Dau0 = impactParameterV0Dau0.getY(); - dcaxyV0Dau1 = impactParameterV0Dau1.getY(); - dcaxyPiFromCasc = impactParameterPiFromCasc.getY(); - dcazV0Dau0 = impactParameterV0Dau0.getZ(); - dcazV0Dau1 = impactParameterV0Dau1.getZ(); - dcazPiFromCasc = impactParameterPiFromCasc.getZ(); - } - - // impact parameters - o2::dataformats::DCA impactParameterCasc; - o2::dataformats::DCA impactParameterPiFromCharmBaryon; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarPi, 2.f, matCorr, &impactParameterPiFromCharmBaryon); - float impactParPiFromCharmBaryonXY = impactParameterPiFromCharmBaryon.getY(); - float impactParPiFromCharmBaryonZ = impactParameterPiFromCharmBaryon.getZ(); - - // invariant mass under the hypothesis of particles ID corresponding to the decay chain - double mLambda = casc.mLambda(); // from LF table, V0 mass under lambda hypothesis - double mCasc = casc.mXi(); - const std::array arrMassCharmBaryon = {massXiFromPDG, massPionFromPDG}; - double mCharmBaryon = RecoDecay::m(std::array{pVecCascAsD, pVecPionFromCharmBaryon}, arrMassCharmBaryon); - - // computing cosPA - double cpaV0 = RecoDecay::cpa(vertexCasc, vertexV0, pVecV0); - double cpaCharmBaryon = RecoDecay::cpa(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); - double cpaCasc = RecoDecay::cpa(coordVtxCharmBaryon, vertexCasc, pVecCasc); - double cpaxyV0 = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); - double cpaxyCharmBaryon = RecoDecay::cpaXY(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); - double cpaxyCasc = RecoDecay::cpaXY(coordVtxCharmBaryon, vertexCasc, pVecCasc); - - // computing decay length and ctau - double decLenCharmBaryon = RecoDecay::distance(pvCoord, coordVtxCharmBaryon); - double decLenCascade = RecoDecay::distance(coordVtxCharmBaryon, vertexCasc); - double decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); - - double phiCharmBaryon, thetaCharmBaryon; - getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, coordVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon); - auto errorDecayLengthCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); - auto errorDecayLengthXYCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, 0.) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, 0.)); - - double ctOmegac = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, massOmegacFromPDG); - double ctXic = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, massXicFromPDG); - double ctCascade = RecoDecay::ct(pVecCasc, decLenCascade, massXiFromPDG); - double ctV0 = RecoDecay::ct(pVecV0, decLenV0, massLambdaFromPDG); - - // computing eta - double pseudorapCharmBaryon = RecoDecay::eta(pVecCharmBaryon); - double pseudorapCascade = RecoDecay::eta(pVecCasc); - double pseudorapV0 = RecoDecay::eta(pVecV0); - - // DCA between daughters - float dcaCascDau = casc.dcacascdaughters(); - float dcaV0Dau = casc.dcaV0daughters(); - float dcaCharmBaryonDau = std::sqrt(df.getChi2AtPCACandidate()); - - // set hfFlag - int hfFlag = 1 << aod::hf_cand_toxipi::DecayType::DecayToXiPi; - - // fill test histograms - hInvMassCharmBaryon->Fill(mCharmBaryon); - hCandidateCounter->Fill(3); - - // fill the table - rowCandidate(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackXiDauCharged.sign(), - chi2PCACharmBaryon, covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCasc[0], pVecCasc[1], pVecCasc[2], - pVecPionFromCharmBaryon[0], pVecPionFromCharmBaryon[1], pVecPionFromCharmBaryon[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecPionFromCasc[0], pVecPionFromCasc[1], pVecPionFromCasc[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - impactParameterCasc.getY(), impactParPiFromCharmBaryonXY, - impactParameterCasc.getZ(), impactParPiFromCharmBaryonZ, - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterPiFromCharmBaryon.getSigmaY2()), - v0Element.globalIndex(), v0Element.posTrackId(), v0Element.negTrackId(), - casc.globalIndex(), trackPion.globalIndex(), trackXiDauCharged.globalIndex(), - mLambda, mCasc, mCharmBaryon, - cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac, ctCascade, ctV0, ctXic, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapPiFromCas, pseudorapPiFromCharmBaryon, - pseudorapCharmBaryon, pseudorapCascade, pseudorapV0, - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyPiFromCasc, - dcazV0Dau0, dcazV0Dau1, dcazPiFromCasc, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon, - hfFlag); - - } // loop over LF Cascade-bachelor candidates - } // loop over collisions - } // end of process - PROCESS_SWITCH(HfCandidateCreatorToXiPi, processDerivedData, "Process derived data", false); - -}; // end of struct + auto trackPion = cand.prong0_as(); + auto cascAodElement = cand.cascade_as(); + auto casc = cascAodElement.cascData_as(); + auto trackXiDauCharged = casc.bachelor_as(); // pion <- xi track + auto v0AodElement = casc.v0_as(); + auto v0 = v0AodElement.v0Data_as(); // V0 <-- xi + auto trackV0Dau0 = v0.posTrack_as(); // V0 positive daughter track + auto trackV0Dau1 = v0.negTrack_as(); // V0 negative daughter track + + //-------------------------- V0 info--------------------------- + // pseudorapidity + double pseudorapV0Dau0 = trackV0Dau0.eta(); + double pseudorapV0Dau1 = trackV0Dau1.eta(); + + // info from LF table + std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; + std::array vertexV0 = {casc.xlambda(), casc.ylambda(), casc.zlambda()}; + std::array pVecV0Dau0 = {casc.pxpos(), casc.pypos(), casc.pzpos()}; + std::array pVecV0Dau1 = {casc.pxneg(), casc.pyneg(), casc.pzneg()}; + + //-------------------reconstruct cascade track------------------ + // pseudorapidity + double pseudorapPiFromCas = trackXiDauCharged.eta(); + + // info from LF table + std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; + std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; + std::array covCasc = {0.}; + constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + for (int i = 0; i < 6; i++) { + covCasc[MomInd[i]] = casc.momentumCovMat()[i]; + covCasc[i] = casc.positionCovMat()[i]; + } + // create cascade track + o2::track::TrackParCov trackCasc; + if (trackXiDauCharged.sign() > 0) { + trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); + } else if (trackXiDauCharged.sign() < 0) { + trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); + } else { + continue; + } + trackCasc.setAbsCharge(1); + trackCasc.setPID(o2::track::PID::XiMinus); + + std::array pVecPionFromCasc = {casc.pxbach(), casc.pybach(), casc.pzbach()}; + + //------------reconstruct charm baryon decay vtx--------------- + auto trackParVarPi = getTrackParCov(trackPion); // charm bachelor pion track to be processed with DCAFitter + + // reconstruct charm baryon with DCAFitter + int nVtxFromFitterCharmBaryon = 0; + try { + nVtxFromFitterCharmBaryon = df.process(trackCasc, trackParVarPi); + } catch (...) { + LOG(error) << "Exception caught in charm DCA fitter process call!"; + hFitterStatus->Fill(1); + continue; + } + if (nVtxFromFitterCharmBaryon == 0) { + hFitterStatus->Fill(2); + continue; + } + hFitterStatus->Fill(0); + hCandidateCounter->Fill(2); + auto vertexCharmBaryonFromFitter = df.getPCACandidate(); + auto chi2PCACharmBaryon = df.getChi2AtPCACandidate(); + std::array pVecCascAsD; + std::array pVecPionFromCharmBaryon; + df.propagateTracksToVertex(); + if (!df.isPropagateTracksToVertexDone()) { + continue; + } + df.getTrack(0).getPxPyPzGlo(pVecCascAsD); + df.getTrack(1).getPxPyPzGlo(pVecPionFromCharmBaryon); + std::array pVecCharmBaryon = {pVecCascAsD[0] + pVecPionFromCharmBaryon[0], pVecCascAsD[1] + pVecPionFromCharmBaryon[1], pVecCascAsD[2] + pVecPionFromCharmBaryon[2]}; + + std::array coordVtxCharmBaryon = df.getPCACandidatePos(); + std::array covVtxCharmBaryon = df.calcPCACovMatrixFlat(); + + // pseudorapidity + double pseudorapPiFromCharmBaryon = trackPion.eta(); + + // DCAxy (computed with propagateToDCABxByBz method) + float dcaxyV0Dau0 = trackV0Dau0.dcaXY(); + float dcaxyV0Dau1 = trackV0Dau1.dcaXY(); + float dcaxyPiFromCasc = trackXiDauCharged.dcaXY(); + + // DCAz (computed with propagateToDCABxByBz method) + float dcazV0Dau0 = trackV0Dau0.dcaZ(); + float dcazV0Dau1 = trackV0Dau1.dcaZ(); + float dcazPiFromCasc = trackXiDauCharged.dcaZ(); + + // primary vertex of the collision + auto primaryVertex = getPrimaryVertex(collision); // get the associated covariance matrix with auto covMatrixPV = primaryVertex.getCov(); + std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; + + // impact parameters + o2::dataformats::DCA impactParameterCasc; + o2::dataformats::DCA impactParameterPiFromCharmBaryon; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarPi, 2.f, matCorr, &impactParameterPiFromCharmBaryon); + float impactParPiFromCharmBaryonXY = impactParameterPiFromCharmBaryon.getY(); + float impactParPiFromCharmBaryonZ = impactParameterPiFromCharmBaryon.getZ(); + + // invariant mass under the hypothesis of particles ID corresponding to the decay chain + double mLambda = casc.mLambda(); // from LF table, V0 mass under lambda hypothesis + double mCasc = casc.mXi(); + const std::array arrMassCharmBaryon = {massXiFromPDG, massPionFromPDG}; + double mCharmBaryon = RecoDecay::m(std::array{pVecCascAsD, pVecPionFromCharmBaryon}, arrMassCharmBaryon); + + // computing cosPA + double cpaV0 = RecoDecay::cpa(vertexCasc, vertexV0, pVecV0); + double cpaCharmBaryon = RecoDecay::cpa(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); + double cpaCasc = RecoDecay::cpa(coordVtxCharmBaryon, vertexCasc, pVecCasc); + double cpaxyV0 = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); + double cpaxyCharmBaryon = RecoDecay::cpaXY(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); + double cpaxyCasc = RecoDecay::cpaXY(coordVtxCharmBaryon, vertexCasc, pVecCasc); + + // computing decay length and ctau + double decLenCharmBaryon = RecoDecay::distance(pvCoord, coordVtxCharmBaryon); + double decLenCascade = RecoDecay::distance(coordVtxCharmBaryon, vertexCasc); + double decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); + + double phiCharmBaryon, thetaCharmBaryon; + getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, coordVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon); + auto errorDecayLengthCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); + auto errorDecayLengthXYCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, 0.) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, 0.)); + + double ctOmegac = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, massOmegacFromPDG); + double ctXic = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, massXicFromPDG); + double ctCascade = RecoDecay::ct(pVecCasc, decLenCascade, massXiFromPDG); + double ctV0 = RecoDecay::ct(pVecV0, decLenV0, massLambdaFromPDG); + + // computing eta + double pseudorapCharmBaryon = RecoDecay::eta(pVecCharmBaryon); + double pseudorapCascade = RecoDecay::eta(pVecCasc); + double pseudorapV0 = RecoDecay::eta(pVecV0); + + // DCA between daughters + float dcaCascDau = casc.dcacascdaughters(); + float dcaV0Dau = casc.dcaV0daughters(); + float dcaCharmBaryonDau = std::sqrt(df.getChi2AtPCACandidate()); + + // set hfFlag + int hfFlag = 1 << aod::hf_cand_toxipi::DecayType::DecayToXiPi; + + // fill test histograms + hInvMassCharmBaryon->Fill(mCharmBaryon); + hCandidateCounter->Fill(3); + + // fill the table + rowCandidate(collision.globalIndex(), + pvCoord[0], pvCoord[1], pvCoord[2], + vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], + vertexCasc[0], vertexCasc[1], vertexCasc[2], + vertexV0[0], vertexV0[1], vertexV0[2], + trackXiDauCharged.sign(), + chi2PCACharmBaryon, covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], + pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], + pVecCasc[0], pVecCasc[1], pVecCasc[2], + pVecPionFromCharmBaryon[0], pVecPionFromCharmBaryon[1], pVecPionFromCharmBaryon[2], + pVecV0[0], pVecV0[1], pVecV0[2], + pVecPionFromCasc[0], pVecPionFromCasc[1], pVecPionFromCasc[2], + pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], + pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], + impactParameterCasc.getY(), impactParPiFromCharmBaryonXY, + impactParameterCasc.getZ(), impactParPiFromCharmBaryonZ, + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterPiFromCharmBaryon.getSigmaY2()), + casc.v0Id(), v0.posTrackId(), v0.negTrackId(), + casc.cascadeId(), trackPion.globalIndex(), casc.bachelorId(), + mLambda, mCasc, mCharmBaryon, + cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, + ctOmegac, ctCascade, ctV0, ctXic, + pseudorapV0Dau0, pseudorapV0Dau1, pseudorapPiFromCas, pseudorapPiFromCharmBaryon, + pseudorapCharmBaryon, pseudorapCascade, pseudorapV0, + dcaxyV0Dau0, dcaxyV0Dau1, dcaxyPiFromCasc, + dcazV0Dau0, dcazV0Dau1, dcazPiFromCasc, + dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, + decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon, + hfFlag); + + } // loop over LF Cascade-bachelor candidates + } // end of process +}; // end of struct /// Performs MC matching. struct HfCandidateCreatorToXiPiMc { @@ -732,13 +363,13 @@ struct HfCandidateCreatorToXiPiMc { int8_t debugGenXi = 0; int8_t debugGenLambda = 0; - int pdgCodeOmegac0 = Pdg::kOmegaC0; // 4332 - int pdgCodeXic0 = Pdg::kXiCZero; // 4132 - int pdgCodeXiMinus = kXiMinus; // 3312 - int pdgCodeLambda = kLambda0; // 3122 - int pdgCodePiPlus = kPiPlus; // 211 - int pdgCodePiMinus = kPiMinus; // -211 - int pdgCodeProton = kProton; // 2212 + int pdgCodeOmegac0 = Pdg::kOmegaC0; // 4332 + int pdgCodeXic0 = Pdg::kXiCZero; // 4132 + int pdgCodeXiMinus = kXiMinus; // 3312 + int pdgCodeLambda = kLambda0; // 3122 + int pdgCodePiPlus = kPiPlus; // 211 + int pdgCodePiMinus = kPiMinus; // -211 + int pdgCodeProton = kProton; // 2212 // Match reconstructed candidates. for (const auto& candidate : candidates) { diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index dcc68082aa1..4a6d3d11ecc 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -1345,11 +1345,11 @@ struct HfTrackIndexSkimCreator { // int nColls{0}; //can be added to run over limited collisions per file - for tesing purposes - static constexpr int kN2ProngDecays = hf_cand_2prong::DecayType::N2ProngDecays; // number of 2-prong hadron types - static constexpr int kN3ProngDecays = hf_cand_3prong::DecayType::N3ProngDecays; // number of 3-prong hadron types + static constexpr int kN2ProngDecays = hf_cand_2prong::DecayType::N2ProngDecays; // number of 2-prong hadron types + static constexpr int kN3ProngDecays = hf_cand_3prong::DecayType::N3ProngDecays; // number of 3-prong hadron types static constexpr int kNCuts2Prong[kN2ProngDecays] = {hf_cuts_presel_2prong::nCutVars, hf_cuts_presel_2prong::nCutVars, hf_cuts_presel_2prong::nCutVars}; // how many different selections are made on 2-prongs static constexpr int kNCuts3Prong[kN3ProngDecays] = {hf_cuts_presel_3prong::nCutVars, hf_cuts_presel_3prong::nCutVars + 1, hf_cuts_presel_ds::nCutVars, hf_cuts_presel_3prong::nCutVars + 1}; // how many different selections are made on 3-prongs (Lc and Xic have also PID potentially) - static constexpr int kNCutsDstar = 3; // how many different selections are made on Dstars + static constexpr int kNCutsDstar = 3; // how many different selections are made on Dstars std::array, 2>, kN2ProngDecays> arrMass2Prong; std::array, 2>, kN3ProngDecays> arrMass3Prong; // arrays of 2-prong and 3-prong cuts @@ -2357,9 +2357,9 @@ struct HfTrackIndexSkimCreator { // first we build D*+ candidates if enabled auto isSelProngPos2 = trackIndexPos2.isSelProng(); uint8_t isSelectedDstar{0}; - if (doDstar && TESTBIT(isSelected2ProngCand, hf_cand_2prong::DecayType::D0ToPiK) && TESTBIT(whichHypo2Prong[0], 0)) { // the 2-prong decay is compatible with a D0 - if (TESTBIT(isSelProngPos2, CandidateType::CandDstar) && trackPos2.globalIndex() != trackPos1.globalIndex()) { // compatible with a soft pion - if (thisCollId != trackPos2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it + if (doDstar && TESTBIT(isSelected2ProngCand, hf_cand_2prong::DecayType::D0ToPiK) && TESTBIT(whichHypo2Prong[0], 0)) { // the 2-prong decay is compatible with a D0 + if (TESTBIT(isSelProngPos2, CandidateType::CandDstar) && trackPos2.globalIndex() != trackPos1.globalIndex()) { // compatible with a soft pion + if (thisCollId != trackPos2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarPos2, 2.f, noMatCorr, &dcaInfoPos2); getPxPyPz(trackParVarPos2, pVecTrackPos2); propagatedPos2 = true; @@ -2614,8 +2614,8 @@ struct HfTrackIndexSkimCreator { auto isSelProngNeg2 = trackIndexNeg2.isSelProng(); uint8_t isSelectedDstar{0}; if (doDstar && TESTBIT(isSelected2ProngCand, hf_cand_2prong::DecayType::D0ToPiK) && TESTBIT(whichHypo2Prong[0], 1)) { // the 2-prong decay is compatible with a D0bar - if (TESTBIT(isSelProngNeg2, CandidateType::CandDstar) && trackNeg2.globalIndex() != trackNeg1.globalIndex()) { // compatible with a soft pion - if (thisCollId != trackNeg2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it + if (TESTBIT(isSelProngNeg2, CandidateType::CandDstar) && trackNeg2.globalIndex() != trackNeg1.globalIndex()) { // compatible with a soft pion + if (thisCollId != trackNeg2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarNeg2, 2.f, noMatCorr, &dcaInfoNeg2); getPxPyPz(trackParVarNeg2, pVecTrackNeg2); propagatedNeg2 = true; @@ -3580,7 +3580,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // fill table row only if a vertex was found if (hfFlag != 0) { rowTrackIndexCasc2Prong(thisCollId, - casc.globalIndex(), + casc.cascadeId(), trackPion1.globalIndex(), hfFlag); } @@ -3650,7 +3650,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // fill table row only if a vertex was found if (hfFlag != 0) { rowTrackIndexCasc3Prong(thisCollId, - casc.globalIndex(), + casc.cascadeId(), trackPion1.globalIndex(), trackPion2.globalIndex()); } From f7ddabec05220019633964385d95b7db743fc82b Mon Sep 17 00:00:00 2001 From: Victor Gonzalez Date: Tue, 12 Dec 2023 10:05:30 +0100 Subject: [PATCH 034/156] Considering ambiguous tracks (#4136) * Considering ambiguous tracks * For pushing CI --------- Co-authored-by: Victor --- PWGCF/TableProducer/dptdptfilter.cxx | 149 ++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 4 deletions(-) diff --git a/PWGCF/TableProducer/dptdptfilter.cxx b/PWGCF/TableProducer/dptdptfilter.cxx index 2b617bf26d8..842215eb001 100644 --- a/PWGCF/TableProducer/dptdptfilter.cxx +++ b/PWGCF/TableProducer/dptdptfilter.cxx @@ -22,6 +22,7 @@ #include "PWGCF/Core/AnalysisConfigurableCuts.h" #include "PWGCF/DataModel/DptDptFiltered.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "Framework/runDataProcessing.h" #include #include @@ -47,10 +48,15 @@ using namespace o2::analysis; namespace o2::analysis::dptdptfilter { -using DptDptFullTracksPID = soa::Join; -using DptDptFullTracksPIDDetLevel = soa::Join; using DptDptFullTracks = soa::Join; +using DptDptFullTracksAmbiguous = soa::Join; +using DptDptTracksPID = soa::Join; +using DptDptFullTracksPID = soa::Join; +using DptDptFullTracksPIDAmbiguous = soa::Join; using DptDptFullTracksDetLevel = soa::Join; +using DptDptFullTracksDetLevelAmbiguous = soa::Join; +using DptDptFullTracksPIDDetLevel = soa::Join; +using DptDptFullTracksPIDDetLevelAmbiguous = soa::Join; bool fullDerivedData = false; /* produce full derived data for its external storage */ @@ -72,7 +78,8 @@ const char* speciesName[kDptDptNoOfSpecies] = {"h", "e", "mu", "pi", "ka", "p"}; const char* speciesTitle[kDptDptNoOfSpecies] = {"", "e", "#mu", "#pi", "K", "p"}; //============================================================================================ -// The DptDptFilter output objects +// The DptDptFilter histogram objects +// TODO: consider registering in the histogram registry //============================================================================================ TH1F* fhCentMultB = nullptr; TH1F* fhCentMultA = nullptr; @@ -104,6 +111,11 @@ TH1F* fhDCAzB = nullptr; TH1F* fhDCAzA = nullptr; TH1F* fhFineDCAzA = nullptr; +TH2D* fhAmbiguousTrackType = nullptr; +TH2F* fhAmbiguousTrackPt = nullptr; +TH2F* fhAmbiguityDegree = nullptr; +TH2F* fhCompatibleCollisionsZVtxRms = nullptr; + TH1F* fhTrueCentMultB = nullptr; TH1F* fhTrueCentMultA = nullptr; TH1F* fhTrueVertexZB = nullptr; @@ -499,6 +511,22 @@ void DptDptFilter::processVertexGenerated(aod::McCollisions const& mccollisions) } } +/// RMS calculation. Taken from PWGHF/Tasks/taskMcValidation.cxx +/// \param vec vector of values to compute RMS +template +T computeRMS(std::vector& vec) +{ + T sum = std::accumulate(vec.begin(), vec.end(), 0.0); + T mean = sum / vec.size(); + + std::vector diff(vec.size()); + std::transform(vec.begin(), vec.end(), diff.begin(), [mean](T x) { return x - mean; }); + T sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0); + T stdev = std::sqrt(sq_sum / vec.size()); + + return stdev; +} + struct DptDptFilterTracks { Produces scannedtracks; Produces tracksinfo; @@ -518,6 +546,7 @@ struct DptDptFilterTracks { Configurable cfgTrackSelection{"tracksel", {false, false, 0, 70, 0.8, 2.4, 3.2}, "Track selection: {useit: true/false, ongen: true/false, tpccls, tpcxrws, tpcxrfc, dcaxy, dcaz}. Default {false,0.70.0.8,2.4,3.2}"}; OutputObj fOutput{"DptDptFilterTracksInfo", OutputObjHandlingPolicy::AnalysisObject}; + bool checkAmbiguousTracks = false; void init(InitContext&) { @@ -577,6 +606,11 @@ struct DptDptFilterTracks { fDataType = getDataType(cfgDataType); fPDG = TDatabasePDG::Instance(); + /* required ambiguous tracks checks? */ + if (dofilterDetectorLevelWithoutPIDAmbiguous || dofilterDetectorLevelWithPIDAmbiguous || dofilterRecoWithoutPIDAmbiguous || dofilterRecoWithPIDAmbiguous) { + checkAmbiguousTracks = true; + } + /* create the output list which will own the task histograms */ TList* fOutputList = new TList(); fOutputList->SetOwner(true); @@ -604,6 +638,14 @@ struct DptDptFilterTracks { fhDCAzA = new TH1F("DCAzA", "DCA_{z} distribution for reconstructed;DCA_{z} (cm);counts", 1000, -4.0, 4.0); fhFineDCAzA = new TH1F("FineDCAzA", "DCA_{z} distribution for reconstructed;DCA_{z} (cm);counts", 4000, -1.0, 1.0); + if (checkAmbiguousTracks) { + /* let's allocate the ambigous tracks tracking histograms*/ + fhAmbiguousTrackType = new TH2D("fHistAmbiguousTracksType", "Ambiguous tracks type vs. multiplicity class;Ambiguous track type;Multiplicity (%);counts", 4, -0.5, 3.5, 101, -0.5, 100.5); + fhAmbiguousTrackPt = new TH2F("fHistAmbiguousTracksPt", "Ambiguous tracks #it{p}_{T} vs. multiplicity class;#it{p}_{T} (GeV/#it{c});Multiplicity (%);counts", 100, 0.0, 15.0, 101, -0.5, 100.5); + fhAmbiguityDegree = new TH2F("fHistAmbiguityDegree", "Ambiguity degree vs. multiplicity class;Ambiguity degree;Multiplicity (%);counts", 31, -0.5, 30.5, 101, -0.5, 100.5); + fhCompatibleCollisionsZVtxRms = new TH2F("fHistCompatibleCollisionsZVtxRms", "Compatible collisions #it{z}_{vtx} RMS;#sigma_{#it{z}_{vtx}};Multiplicity (%);counts", 100, -10.0, 10.0, 101, -0.5, 100.5); + } + for (int sp = 0; sp < kDptDptNoOfSpecies; ++sp) { fhPA[sp] = new TH1F(TString::Format("fHistPA_%s", speciesName[sp]).Data(), TString::Format("p distribution for reconstructed %s;p (GeV/c);dN/dp (c/GeV)", speciesTitle[sp]).Data(), @@ -640,6 +682,12 @@ struct DptDptFilterTracks { fOutputList->Add(fhDCAzB); fOutputList->Add(fhDCAzA); fOutputList->Add(fhFineDCAzA); + if (checkAmbiguousTracks) { + fOutputList->Add(fhAmbiguousTrackType); + fOutputList->Add(fhAmbiguousTrackPt); + fOutputList->Add(fhAmbiguityDegree); + fOutputList->Add(fhCompatibleCollisionsZVtxRms); + } for (int sp = 0; sp < kDptDptNoOfSpecies; ++sp) { fOutputList->Add(fhPA[sp]); @@ -726,6 +774,8 @@ struct DptDptFilterTracks { MatchRecoGenSpecies trackIdentification(TrackObject const& track); template int8_t selectTrack(TrackObject const& track); + template + int8_t selectTrackAmbiguousCheck(CollisionObjects const& collisions, TrackObject const& track); template inline MatchRecoGenSpecies IdentifyParticle(ParticleObject const& particle); template @@ -761,10 +811,11 @@ struct DptDptFilterTracks { for (auto track : tracks) { int8_t pid = -1; if (track.has_collision() && (track.template collision_as>()).collisionaccepted()) { - pid = selectTrack(track); + pid = selectTrackAmbiguousCheck(collisions, track); if (!(pid < 0)) { naccepted++; if (fullDerivedData) { + LOGF(fatal, "Stored derived data not prepared for saving the proper new collision id"); scannedtracks((track.template collision_as>()).globalIndex(), pid, track.pt(), track.eta(), track.phi()); } else { tracksinfo(pid); @@ -883,12 +934,48 @@ struct DptDptFilterTracks { } PROCESS_SWITCH(DptDptFilterTracks, filterRecoWithPID, "Not stored derived data track filtering", false) + void filterRecoWithPIDAmbiguous(soa::Join& collisions, DptDptFullTracksPIDAmbiguous const& tracks) + { + filterTracks(collisions, tracks); + } + PROCESS_SWITCH(DptDptFilterTracks, filterRecoWithPIDAmbiguous, "Not stored derived data track filtering with ambiguous tracks check", false) + + void filterDetectorLevelWithPID(soa::Join& collisions, DptDptFullTracksPIDDetLevel const& tracks) + { + filterTracks(collisions, tracks); + } + PROCESS_SWITCH(DptDptFilterTracks, filterDetectorLevelWithPID, "Not stored derived data detector level track filtering", false) + + void filterDetectorLevelWithPIDAmbiguous(soa::Join& collisions, DptDptFullTracksPIDDetLevelAmbiguous const& tracks) + { + filterTracks(collisions, tracks); + } + PROCESS_SWITCH(DptDptFilterTracks, filterDetectorLevelWithPIDAmbiguous, "Not stored derived data detector level track filtering with ambiguous tracks check", false) + void filterRecoWithoutPID(soa::Join const& collisions, DptDptFullTracks const& tracks) { filterTracks(collisions, tracks); } PROCESS_SWITCH(DptDptFilterTracks, filterRecoWithoutPID, "Track filtering without PID information", true) + void filterRecoWithoutPIDAmbiguous(soa::Join const& collisions, DptDptFullTracksAmbiguous const& tracks) + { + filterTracks(collisions, tracks); + } + PROCESS_SWITCH(DptDptFilterTracks, filterRecoWithoutPIDAmbiguous, "Track filtering without PID information with ambiguous tracks check", false) + + void filterDetectorLevelWithoutPID(soa::Join const& collisions, DptDptFullTracksDetLevel const& tracks) + { + filterTracks(collisions, tracks); + } + PROCESS_SWITCH(DptDptFilterTracks, filterDetectorLevelWithoutPID, "Detector level track filtering without PID information", false) + + void filterDetectorLevelWithoutPIDAmbiguous(soa::Join const& collisions, DptDptFullTracksDetLevelAmbiguous const& tracks) + { + filterTracks(collisions, tracks); + } + PROCESS_SWITCH(DptDptFilterTracks, filterDetectorLevelWithoutPIDAmbiguous, "Detector level track filtering without PID information with ambiguous tracks check", false) + void filterGenerated(soa::Join const& gencollisions, aod::McParticles const& particles) { filterParticles(gencollisions, particles); @@ -1058,6 +1145,60 @@ int8_t DptDptFilterTracks::selectTrack(TrackObject const& track) return pid; } +template +int8_t DptDptFilterTracks::selectTrackAmbiguousCheck(CollisionObjects const& collisions, TrackObject const& track) +{ + bool ambiguoustrack = false; + int tracktype = 0; /* no ambiguous */ + std::vector zvertexes{}; + /* ambiguous tracks checks if required */ + if constexpr (has_type_v) { + if (track.compatibleCollIds().size() > 0) { + if (track.compatibleCollIds().size() == 1) { + if (track.collisionId() != track.compatibleCollIds()[0]) { + /* ambiguous track! */ + ambiguoustrack = true; + /* in principle we should not be here because the track is associated to two collisions at least */ + tracktype = 2; + zvertexes.push_back(collisions.iteratorAt(track.collisionId()).posZ()); + zvertexes.push_back(collisions.iteratorAt(track.compatibleCollIds()[0]).posZ()); + } else { + /* we consider the track as no ambiguous */ + tracktype = 1; + } + } else { + /* ambiguous track! */ + ambiguoustrack = true; + tracktype = 3; + /* the track is associated to more than one collision */ + for (const auto& collIdx : track.compatibleCollIds()) { + zvertexes.push_back(collisions.iteratorAt(collIdx).posZ()); + } + } + } + } + + float multiplicityclass = (track.template collision_as>()).centmult(); + if (ambiguoustrack) { + /* keep track of ambiguous tracks */ + fhAmbiguousTrackType->Fill(tracktype, multiplicityclass); + fhAmbiguousTrackPt->Fill(track.pt(), multiplicityclass); + fhAmbiguityDegree->Fill(zvertexes.size(), multiplicityclass); + if (tracktype == 2) { + fhCompatibleCollisionsZVtxRms->Fill(-computeRMS(zvertexes), multiplicityclass); + } else { + fhCompatibleCollisionsZVtxRms->Fill(computeRMS(zvertexes), multiplicityclass); + } + return -1; + } else { + if (checkAmbiguousTracks) { + /* feedback of no ambiguous tracks only if checks required */ + fhAmbiguousTrackType->Fill(tracktype, multiplicityclass); + } + return selectTrack(track); + } +} + template void DptDptFilterTracks::fillTrackHistosBeforeSelection(TrackObject const& track) { From ac943f5be994fec00e162dddf7d5a2740f8c84d5 Mon Sep 17 00:00:00 2001 From: Marvin Hemmer <53471402+mhemmer-cern@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:55:55 +0100 Subject: [PATCH 035/156] [EMC-1108] emctmmonitor: Add catch for clusters outside of EMCal Geometry (#4137) - Apperently some clusters are outside of EMCal Geometry and they throw an excpetion. Now corectly catch this exception and skip those clusters. --- PWGJE/Tasks/emctmmonitor.cxx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/PWGJE/Tasks/emctmmonitor.cxx b/PWGJE/Tasks/emctmmonitor.cxx index 2fa9f597690..2b99fdb6943 100644 --- a/PWGJE/Tasks/emctmmonitor.cxx +++ b/PWGJE/Tasks/emctmmonitor.cxx @@ -292,7 +292,15 @@ struct TrackMatchingMonitor { // using globTracks = o2::soa::Join; // In this example the counter t is just used to only look at the closest match double dEta, dPhi, pT, abs_p, trackEta, trackPhi, NSigmaEl; - auto supermoduleID = mGeometry->SuperModuleNumberFromEtaPhi(cluster.eta(), cluster.phi()); + int supermoduleID; + try { + supermoduleID = mGeometry->SuperModuleNumberFromEtaPhi(cluster.eta(), cluster.phi()); + } catch (o2::emcal::InvalidPositionException& e) { + // Imprecision of the position at the sector boundaries, mostly due to + // vertex imprecision. Skip these clusters for the now. + continue; + } + pT = cluster.energy() / cosh(cluster.eta()); if (M02highPt > 0. && cluster.m02() >= maxM02HighPt && pT >= M02highPt) { // high pT M02 cut continue; From c01264104642ec7d1220e760aaf4045a14fc7936 Mon Sep 17 00:00:00 2001 From: Alexandre BIGOT <77975111+AlexBigO@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:32:42 +0100 Subject: [PATCH 036/156] PWGHF: Add tree creator in B0 reduced task + fix bug in Dmeson ML selection (#4118) * PWGHF: add possibility to use ML scores of D- mesons and improve B0 task * Please consider the following formatting changes * Implement a Tree creator inside B0 reduced selector * Clang format * Move Tree creator from selector to task * Use column already defined for B0 selection flag + solve MegaLinter error * MegaLinter fixes * Fix bug in Dmeson ML score cut in B0 reduced selector * Add Mattia's comments * Clang format --------- Co-authored-by: Fabrizio Grosa Co-authored-by: ALICE Action Bot Co-authored-by: Alexandre Bigot --- PWGHF/Core/SelectorCuts.h | 1 + PWGHF/D2H/DataModel/ReducedDataModel.h | 2 +- .../candidateSelectorB0ToDPiReduced.cxx | 2 +- PWGHF/D2H/Tasks/taskB0Reduced.cxx | 168 +++++++++++++++++- 4 files changed, 163 insertions(+), 10 deletions(-) diff --git a/PWGHF/Core/SelectorCuts.h b/PWGHF/Core/SelectorCuts.h index bc366dffd57..41fac07b5dd 100644 --- a/PWGHF/Core/SelectorCuts.h +++ b/PWGHF/Core/SelectorCuts.h @@ -163,6 +163,7 @@ static const std::vector labelsPt = { // column labels static const std::vector labelsCutScore = {"score class 1", "score class 2", "score class 3"}; +static const std::vector labelsDmesCutScore = {"ML score charm bkg", "ML score charm prompt", "ML score charm nonprompt"}; } // namespace hf_cuts_ml namespace hf_cuts_presel_2prong diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index fd0a9f3b1f1..3ca7fbb410f 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -280,7 +280,7 @@ DECLARE_SOA_TABLE(HfMcGenRedB0s, "AOD", "HFMCGENREDB0", //! Generation-level MC // so we can use them in the B0 part namespace hf_cand_b0_config { -DECLARE_SOA_COLUMN(MySelectionFlagD, mySelectionFlagD, int8_t); //! Flag to filter selected D+ mesons +DECLARE_SOA_COLUMN(MySelectionFlagD, mySelectionFlagD, int8_t); //! Flag to filter selected D+ mesons DECLARE_SOA_COLUMN(MyInvMassWindowDPi, myInvMassWindowDPi, float); //! Half-width of the B0 invariant-mass window in GeV/c2 } // namespace hf_cand_b0_config diff --git a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx index 262ef26aca5..0f312fa0c44 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx @@ -54,7 +54,7 @@ struct HfCandidateSelectorB0ToDPiReduced { Configurable> cuts{"cuts", {hf_cuts_b0_to_d_pi::cuts[0], hf_cuts_b0_to_d_pi::nBinsPt, hf_cuts_b0_to_d_pi::nCutVars, hf_cuts_b0_to_d_pi::labelsPt, hf_cuts_b0_to_d_pi::labelsCutVar}, "B0 candidate selection per pT bin"}; // D-meson ML cuts Configurable> binsPtDmesMl{"binsPtDmesMl", std::vector{hf_cuts_ml::vecBinsPt}, "D-meson pT bin limits for ML cuts"}; - Configurable> cutsDmesMl{"cutsDmesMl", {hf_cuts_ml::cuts[0], hf_cuts_ml::nBinsPt, hf_cuts_ml::nCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "D-meson ML cuts per pT bin"}; + Configurable> cutsDmesMl{"cutsDmesMl", {hf_cuts_ml::cuts[0], hf_cuts_ml::nBinsPt, hf_cuts_ml::nCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsDmesCutScore}, "D-meson ML cuts per pT bin"}; // QA switch Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index d1c69d61b33..fe08c538e8a 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -32,8 +32,62 @@ using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; +namespace o2::aod +{ +namespace hf_cand_b0_lite +{ +DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong0 (GeV/c) +DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong1 (GeV/c) +DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate +DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) +DECLARE_SOA_COLUMN(NSigTpcPi1, nSigTpcPi1, float); //! TPC Nsigma separation for prong1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPi1, nSigTofPi1, float); //! TOF Nsigma separation for prong1 with pion mass hypothesis +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate +DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! Normalised transverse decay length of candidate +DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane +DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! Maximum normalized difference between measured and expected impact parameter of candidate prongs +} // namespace hf_cand_b0_lite + +DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with some B0 properties + hf_cand::Chi2PCA, + hf_cand_b0_lite::DecayLength, + hf_cand_b0_lite::DecayLengthXY, + hf_cand_b0_lite::DecayLengthNormalised, + hf_cand_b0_lite::DecayLengthXYNormalised, + hf_cand_b0_lite::PtProng0, + hf_cand_b0_lite::PtProng1, + hf_cand::ImpactParameter0, + hf_cand::ImpactParameter1, + hf_cand_b0_lite::NSigTpcPi1, + hf_cand_b0_lite::NSigTofPi1, + hf_cand_b0_reduced::Prong0MlScoreBkg, + hf_cand_b0_reduced::Prong0MlScorePrompt, + hf_cand_b0_reduced::Prong0MlScoreNonprompt, + hf_sel_candidate_b0::IsSelB0ToDPi, + hf_cand_b0_lite::M, + hf_cand_b0_lite::Pt, + hf_cand_b0_lite::Cpa, + hf_cand_b0_lite::CpaXY, + hf_cand_b0_lite::MaxNormalisedDeltaIP, + hf_cand_b0_lite::Eta, + hf_cand_b0_lite::Phi, + hf_cand_b0_lite::Y, + hf_cand_3prong::FlagMcMatchRec, + hf_cand_3prong::OriginMcRec); +} // namespace o2::aod + /// B0 analysis task struct HfTaskB0Reduced { + Produces hfRedCandB0Lite; + Configurable selectionFlagB0{"selectionFlagB0", 1, "Selection Flag for B0"}; Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; @@ -41,7 +95,10 @@ struct HfTaskB0Reduced { Configurable ptTrackMin{"ptTrackMin", 0.1, "min. track transverse momentum"}; Configurable fillHistograms{"fillHistograms", true, "Flag to enable histogram filling"}; Configurable fillSparses{"fillSparses", false, "Flag to enable sparse filling"}; - Configurable fillBackground{"fillBackground", false, "Flag to enable filling of background histograms/sparses (only MC)"}; + Configurable fillTree{"fillTree", false, "Flag to enable tree filling"}; + Configurable fillBackground{"fillBackground", false, "Flag to enable filling of background histograms/sparses/tree (only MC)"}; + Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; HfHelper hfHelper; @@ -49,6 +106,8 @@ struct HfTaskB0Reduced { HistogramRegistry registry{"registry"}; + using TracksPion = soa::Join; + void init(InitContext&) { std::array processFuncData{doprocessData, doprocessDataWithDmesMl}; @@ -60,6 +119,11 @@ struct HfTaskB0Reduced { LOGP(fatal, "Only one process function for MC can be enabled at a time."); } + if (((doprocessData || doprocessDataWithDmesMl) && fillTree && downSampleBkgFactor >= 1.) || + ((doprocessMc || doprocessMcWithDmesMl) && fillTree && fillBackground && downSampleBkgFactor >= 1.)) { + LOGP(fatal, "Set downSampleBkgFactor below unity when filling tree with background."); + } + const AxisSpec axisMlScore{100, 0.f, 1.f}; const AxisSpec axisMassB0{300, 4.5f, 6.0f}; const AxisSpec axisMassDminus{300, 1.75f, 2.05f}; @@ -262,6 +326,49 @@ struct HfTaskB0Reduced { registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); } } + if (fillTree) { + float pseudoRndm = ptD * 1000. - (int64_t)(ptD * 1000); + if (ptCandB0 >= ptMaxForDownSample || pseudoRndm < downSampleBkgFactor) { + int8_t flag{0}; + int8_t origin{0}; + float prong0MlScoreBkg = -1.; + float prong0MlScorePrompt = -1.; + float prong0MlScoreNonprompt = -1.; + if constexpr (withDmesMl) { + prong0MlScoreBkg = candidate.prong0MlScoreBkg(); + prong0MlScorePrompt = candidate.prong0MlScorePrompt(); + prong0MlScoreNonprompt = candidate.prong0MlScoreNonprompt(); + } + auto prong1 = candidate.template prong1_as(); + + hfRedCandB0Lite( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + ptD, + candidate.ptProng1(), + candidate.impactParameter0(), + candidate.impactParameter1(), + prong1.tpcNSigmaPi(), + prong1.tofNSigmaPi(), + prong0MlScoreBkg, + prong0MlScorePrompt, + prong0MlScoreNonprompt, + candidate.isSelB0ToDPi(), + invMassB0, + ptCandB0, + candidate.cpa(), + candidate.cpaXY(), + candidate.maxNormalisedDeltaIP(), + candidate.eta(), + candidate.phi(), + hfHelper.yB0(candidate), + flag, + origin); + } + } } /// Fill candidate histograms (reco MC truth) @@ -284,7 +391,8 @@ struct HfTaskB0Reduced { auto decLenD = RecoDecay::distance(posPv, posSvD); auto decLenXyD = RecoDecay::distanceXY(posPv, posSvD); - bool isSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), hf_cand_b0::DecayType::B0ToDPi); + int8_t flagMcMatchRec = candidate.flagMcMatchRec(); + bool isSignal = TESTBIT(std::abs(flagMcMatchRec), hf_cand_b0::DecayTypeMc::B0ToDplusPiToPiKPiPi); if (fillHistograms) { if (isSignal) { registry.fill(HIST("hMassRecSig"), ptCandB0, hfHelper.invMassB0ToDPi(candidate)); @@ -351,6 +459,46 @@ struct HfTaskB0Reduced { } } } + if (fillTree) { + float prong0MlScoreBkg = -1.; + float prong0MlScorePrompt = -1.; + float prong0MlScoreNonprompt = -1.; + if constexpr (withDmesMl) { + prong0MlScoreBkg = candidate.prong0MlScoreBkg(); + prong0MlScorePrompt = candidate.prong0MlScorePrompt(); + prong0MlScoreNonprompt = candidate.prong0MlScoreNonprompt(); + } + auto prong1 = candidate.template prong1_as(); + float pseudoRndm = ptD * 1000. - (int64_t)(ptD * 1000); + if (isSignal || (fillBackground && (ptCandB0 >= ptMaxForDownSample || pseudoRndm < downSampleBkgFactor))) { + hfRedCandB0Lite( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + ptD, + candidate.ptProng1(), + candidate.impactParameter0(), + candidate.impactParameter1(), + prong1.tpcNSigmaPi(), + prong1.tofNSigmaPi(), + prong0MlScoreBkg, + prong0MlScorePrompt, + prong0MlScoreNonprompt, + candidate.isSelB0ToDPi(), + invMassB0, + ptCandB0, + candidate.cpa(), + candidate.cpaXY(), + candidate.maxNormalisedDeltaIP(), + candidate.eta(), + candidate.phi(), + hfHelper.yB0(candidate), + flagMcMatchRec, + isSignal); + } + } } /// Fill particle histograms (gen MC truth) @@ -393,7 +541,8 @@ struct HfTaskB0Reduced { // Process functions void processData(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD) + aod::HfRed3Prongs const& candidatesD, + TracksPion const&) { for (const auto& candidate : candidates) { if (!TESTBIT(candidate.hfflag(), hf_cand_b0::DecayType::B0ToDPi)) { @@ -409,7 +558,8 @@ struct HfTaskB0Reduced { PROCESS_SWITCH(HfTaskB0Reduced, processData, "Process data without ML scores for D daughter", true); void processDataWithDmesMl(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD) + aod::HfRed3Prongs const& candidatesD, + TracksPion const&) { for (const auto& candidate : candidates) { if (!TESTBIT(candidate.hfflag(), hf_cand_b0::DecayType::B0ToDPi)) { @@ -424,9 +574,10 @@ struct HfTaskB0Reduced { PROCESS_SWITCH(HfTaskB0Reduced, processDataWithDmesMl, "Process data with ML scores for D daughter", false); - void processMc(soa::Join const& candidates, + void processMc(soa::Join const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD) + aod::HfRed3Prongs const& candidatesD, + TracksPion const&) { // MC rec for (const auto& candidate : candidates) { @@ -446,9 +597,10 @@ struct HfTaskB0Reduced { } // processMc PROCESS_SWITCH(HfTaskB0Reduced, processMc, "Process MC without ML scores for D daughter", false); - void processMcWithDmesMl(soa::Join const& candidates, + void processMcWithDmesMl(soa::Join const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD) + aod::HfRed3Prongs const& candidatesD, + TracksPion const&) { // MC rec for (const auto& candidate : candidates) { From 2fdafcea42ac73d894464919dc4b4643fa3e0070 Mon Sep 17 00:00:00 2001 From: Giovanni Malfattore <89481844+giovannimalfattore@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:43:08 +0100 Subject: [PATCH 037/156] [PWFLG] LightNucleiTask - Add rapidity asymmetric cut and low p cut (#4139) * [PWFLG] LightNucleiTask - Add rapidity asymmetric cut and low p cut * [PWFLG] LightNucleiTask - Minor fix --- PWGLF/Tasks/LFNucleiBATask.cxx | 204 ++++++++++++++++----------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/LFNucleiBATask.cxx index b7948be8b05..4f1d64a3183 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/LFNucleiBATask.cxx @@ -65,8 +65,11 @@ struct LFNucleiBATask { Configurable nITSLayer{"nITSLayer", 0, "ITS Layer (0-6)"}; // Set the kinematic and PID cuts for tracks + Configurable pCut{"pCut", 0.3f, "Value of the p selection for spectra (default 0.3)"}; Configurable etaCut{"etaCut", 0.8f, "Value of the eta selection for spectra (default 0.8)"}; Configurable yCut{"yCut", 1.0f, "Value of the rapidity selection for spectra (default 1.0)"}; + Configurable yLowCut{"yLowCut", -1.0f, "Value of the low rapidity selection for spectra (default -1.0)"}; + Configurable yHighCut{"yHighCut", 1.0f, "Value of the high rapidity selection for spectra (default 1.0)"}; Configurable isPVContributorCut{"isPVContributorCut", false, "Flag to enable isPVContributor cut."}; Configurable DCAxyCustomCut{"DCAxyCustomCut", 2.0f, "Value of the DCAxy selection for spectra (default 2.0 cm)"}; @@ -379,8 +382,8 @@ struct LFNucleiBATask { histos.add("tracks/deuteron/h2DeuteronYvsPt", "#it{y} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); histos.add("tracks/deuteron/h2antiDeuteronYvsPt", "#it{y} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/deuteron/h2DeuteronEtavsPt", "it{#eta} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/deuteron/h2antiDeuteronEtavsPt", "it{#eta} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2DeuteronEtavsPt", "#it{#eta} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2antiDeuteronEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableTr) { histos.add("tracks/triton/h1TritonSpectra", "#it{p}_{T} (t)", HistType::kTH1F, {ptAxis}); @@ -392,16 +395,16 @@ struct LFNucleiBATask { histos.add("tracks/helium/h2HeliumYvsPt", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); histos.add("tracks/helium/h2HeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2HeliumEtavsPt", "it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); histos.add("tracks/helium/h1HeliumSpectra_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h1antiHeliumSpectra_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); histos.add("tracks/helium/h2antiHeliumYvsPt", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2antiHeliumEtavsPt", "it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectra", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -1343,8 +1346,11 @@ struct LFNucleiBATask { float gamma = 0., massTOF = 0., hePt = 0.f, antihePt = 0.f, antiDPt = 0.f; bool isTriton = kFALSE; + bool prRapCut = kFALSE; bool deRapCut = kFALSE; + bool trRapCut = kFALSE; bool heRapCut = kFALSE; + bool alRapCut = kFALSE; // Event histos fill histos.fill(HIST("event/h1VtxZ"), event.posZ()); @@ -1432,9 +1438,16 @@ struct LFNucleiBATask { break; } + // p cut + if (TMath::Abs(track.tpcInnerParam()) < pCut) + continue; + // debug on helium rapidity cut - deRapCut = TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron))) < yCut; - heRapCut = TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3))) < yCut; + prRapCut = track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton)) > yLowCut && track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton)) < yHighCut; + deRapCut = track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)) > yLowCut && track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)) < yHighCut; + trRapCut = track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton)) > yLowCut && track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton)) < yHighCut; + heRapCut = track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)) > yLowCut && track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)) < yHighCut; + alRapCut = track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha)) > yLowCut && track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha)) < yHighCut; // Tracks DCA histos fill if (makeDCABeforeCutPlots) { @@ -1885,26 +1898,25 @@ struct LFNucleiBATask { return; if (track.sign() > 0) { - if (enablePr) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton))) < yCut) { - if (enableExpSignalTPC) - histos.fill(HIST("tracks/proton/h2ProtonTPCExpSignalDiffVsPt"), track.pt(), track.tpcExpSignalDiffPr()); + if (enablePr && prRapCut) { - switch (useHasTRDConfig) { - case 0: + if (enableExpSignalTPC) + histos.fill(HIST("tracks/proton/h2ProtonTPCExpSignalDiffVsPt"), track.pt(), track.tpcExpSignalDiffPr()); + + switch (useHasTRDConfig) { + case 0: + histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); + break; + case 1: + if (track.hasTRD()) { histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); - break; - case 1: - if (track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); - } - break; - case 2: - if (!track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); - } - break; - } + } + break; + case 2: + if (!track.hasTRD()) { + histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } + break; } } if (enableDe && deRapCut) { @@ -1930,10 +1942,9 @@ struct LFNucleiBATask { break; } } - if (enableTr) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut) { - histos.fill(HIST("tracks/triton/h2TritonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaTr()); - } + if (enableTr && trRapCut) { + + histos.fill(HIST("tracks/triton/h2TritonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaTr()); } if (enableHe && heRapCut) { if (enableExpSignalTPC) @@ -1941,32 +1952,28 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/h2HeliumVspTNSigmaTPC"), hePt, track.tpcNSigmaHe()); } - if (enableAl) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { - histos.fill(HIST("tracks/alpha/h2AlphaVspTNSigmaTPC"), track.pt(), track.tpcNSigmaAl()); - } + if (enableAl && alRapCut) { + histos.fill(HIST("tracks/alpha/h2AlphaVspTNSigmaTPC"), track.pt(), track.tpcNSigmaAl()); } } else { - if (enablePr) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton))) < yCut) { - if (enableExpSignalTPC) - histos.fill(HIST("tracks/proton/h2antiProtonTPCExpSignalDiffVsPt"), track.pt(), track.tpcExpSignalDiffPr()); + if (enablePr && prRapCut) { + if (enableExpSignalTPC) + histos.fill(HIST("tracks/proton/h2antiProtonTPCExpSignalDiffVsPt"), track.pt(), track.tpcExpSignalDiffPr()); - switch (useHasTRDConfig) { - case 0: + switch (useHasTRDConfig) { + case 0: + histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); + break; + case 1: + if (track.hasTRD()) { histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); - break; - case 1: - if (track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); - } - break; - case 2: - if (!track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); - } - break; - } + } + break; + case 2: + if (!track.hasTRD()) { + histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } + break; } } if (enableDe && deRapCut) { @@ -1992,10 +1999,8 @@ struct LFNucleiBATask { break; } } - if (enableTr) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Triton))) < yCut) { - histos.fill(HIST("tracks/triton/h2antiTritonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaTr()); - } + if (enableTr && trRapCut) { + histos.fill(HIST("tracks/triton/h2antiTritonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaTr()); } if (enableHe && heRapCut) { if (enableExpSignalTPC) @@ -2003,10 +2008,8 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/h2antiHeliumVspTNSigmaTPC"), antihePt, track.tpcNSigmaHe()); } - if (enableAl) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { - histos.fill(HIST("tracks/alpha/h2antiAlphaVspTNSigmaTPC"), track.pt(), track.tpcNSigmaAl()); - } + if (enableAl && alRapCut) { + histos.fill(HIST("tracks/alpha/h2antiAlphaVspTNSigmaTPC"), track.pt(), track.tpcNSigmaAl()); } } @@ -2015,26 +2018,25 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/pion/h2PionVspTNSigmaTOF"), track.pt(), track.tofNSigmaPi()); histos.fill(HIST("tracks/kaon/h2KaonVspTNSigmaTOF"), track.pt(), track.tofNSigmaKa()); if (track.sign() > 0) { - if (enablePr) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton))) < yCut) { - switch (useHasTRDConfig) { - case 0: + if (enablePr && prRapCut) { + + switch (useHasTRDConfig) { + case 0: + histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); + break; + case 1: + if (track.hasTRD()) { histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); - break; - case 1: - if (track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); - } - break; - case 2: - if (!track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); - } - break; - } - if (enableExpSignalTOF) - histos.fill(HIST("tracks/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); + } + break; + case 2: + if (!track.hasTRD()) { + histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); + } + break; } + if (enableExpSignalTOF) + histos.fill(HIST("tracks/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); } if (enableDe && deRapCut) { switch (useHasTRDConfig) { @@ -2197,26 +2199,24 @@ struct LFNucleiBATask { } } else { - if (enablePr) { - if (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton))) < yCut) { - switch (useHasTRDConfig) { - case 0: + if (enablePr && prRapCut) { + switch (useHasTRDConfig) { + case 0: + histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); + break; + case 1: + if (track.hasTRD()) { histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); - break; - case 1: - if (track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); - } - break; - case 2: - if (!track.hasTRD()) { - histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); - } - break; - } - if (enableExpSignalTOF) - histos.fill(HIST("tracks/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); + } + break; + case 2: + if (!track.hasTRD()) { + histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); + } + break; } + if (enableExpSignalTOF) + histos.fill(HIST("tracks/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); } if (enableDe && deRapCut) { switch (useHasTRDConfig) { @@ -2381,7 +2381,7 @@ struct LFNucleiBATask { } if (enablePr) { - if ((std::abs(track.tpcNSigmaPr()) < nsigmaTPCPr) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton))) < yCut)) { + if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCPr && prRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { histos.fill(HIST("tracks/eff/proton/hPtPr"), track.pt()); @@ -2484,7 +2484,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/h1HeliumSpectra_Z2"), 2 * hePt); histos.fill(HIST("tracks/helium/h2HeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); histos.fill(HIST("tracks/helium/h2HeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); - histos.fill(HIST("tracks/helium/h2HeliumEtavsPt"), track.eta(), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumEtavsPt"), track.eta(), hePt); histos.fill(HIST("tracks/helium/h2HeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (enablePIDplot) @@ -2501,7 +2501,7 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/h1antiHeliumSpectra_Z2"), 2 * antihePt); histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); - histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt"), track.eta(), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt"), track.eta(), hePt); histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumantiHelium"), track.tpcInnerParam(), track.tpcSignal()); @@ -2512,7 +2512,7 @@ struct LFNucleiBATask { } } if (enableAl) { - if ((std::abs(track.tpcNSigmaAl()) < nsigmaTPCAl) && TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Alpha))) < yCut) { + if ((std::abs(track.tpcNSigmaAl()) < nsigmaTPCAl) && alRapCut < yCut) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/h1AlphaSpectra"), track.pt()); if (enablePIDplot) @@ -2690,7 +2690,7 @@ struct LFNucleiBATask { } if (enablePr) { - if ((std::abs(track.tpcNSigmaPr()) < nsigmaTPCPr) && (TMath::Abs(track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Proton))) < yCut)) { + if ((std::abs(track.tpcNSigmaPr()) < nsigmaTPCPr) && prRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { histos.fill(HIST("tracks/eff/proton/hPtPrTOF"), track.pt()); @@ -3298,7 +3298,7 @@ struct LFNucleiBATask { { histos.fill(HIST("spectraGen/histGenVetxZ"), mcCollision.posZ()); for (auto& mcParticleGen : mcParticles) { - if (abs(mcParticleGen.y()) > std::abs(yCut)) { + if (mcParticleGen.y() > yHighCut || mcParticleGen.y() < yLowCut) { continue; } From ff917fdcf18992c3324bd0a37f21a0b4971c2690 Mon Sep 17 00:00:00 2001 From: kgwizdzi <116073883+kgwizdzi@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:30:55 +0100 Subject: [PATCH 038/156] PWGCF - adding DO mesons to FemtoUniverse (#4135) * PWGCF - adding DO mesons to FemtoUniverse * Fixing clang-format * Changing the bool from isPhi to isPhiOrD0 * Fixing alibuild --- .../Core/FemtoUniverseDetaDphiStar.h | 36 +- .../Core/FemtoUniversePairCleaner.h | 13 + .../Core/FemtoUniverseParticleHisto.h | 7 + PWGCF/FemtoUniverse/DataModel/FemtoDerived.h | 2 +- .../femtoUniverseProducerTask.cxx | 143 ++++- PWGCF/FemtoUniverse/Tasks/CMakeLists.txt | 5 + .../Tasks/femtoUniversePairTaskTrackD0.cxx | 546 ++++++++++++++++++ 7 files changed, 744 insertions(+), 8 deletions(-) create mode 100644 PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h index 3438b1726ad..cb4532079c3 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h @@ -84,6 +84,18 @@ class FemtoUniverseDetaDphiStar } } } + if constexpr (mPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kD0) { + for (int i = 0; i < 2; i++) { + std::string dirName = static_cast(dirNames[3]); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + if (plotForEveryRadii) { + for (int j = 0; j < 9; j++) { + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + } + } + } + } } /// Check if pair is close or not template @@ -116,6 +128,28 @@ class FemtoUniverseDetaDphiStar return false; } + bool pass = false; + for (int i = 0; i < 2; i++) { + auto indexOfDaughter = part2.index() - 2 + i; + auto daughter = particles.begin() + indexOfDaughter; + auto deta = part1.eta() - daughter.eta(); + auto dphiAvg = AveragePhiStar(part1, *daughter, i); + histdetadpi[i][0]->Fill(deta, dphiAvg); + if (pow(dphiAvg, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + histdetadpi[i][1]->Fill(deta, dphiAvg); + } + } + return pass; + } else if constexpr (mPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kD0) { + /// Track-D0 combination + // check if provided particles are in agreement with the class instantiation + if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kD0) { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar instantiation! Please provide kTrack, kD0 candidates."; + return false; + } + bool pass = false; for (int i = 0; i < 2; i++) { auto indexOfDaughter = part2.index() - 2 + i; @@ -161,7 +195,7 @@ class FemtoUniverseDetaDphiStar private: HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output - static constexpr std::string_view dirNames[3] = {"kTrack_kTrack/", "kTrack_kV0/", "kTrack_kPhi/"}; + static constexpr std::string_view dirNames[4] = {"kTrack_kTrack/", "kTrack_kV0/", "kTrack_kPhi/", "kTrack_kD0/"}; static constexpr std::string_view histNames[2][2] = {{"detadphidetadphi0Before_0", "detadphidetadphi0Before_1"}, {"detadphidetadphi0After_0", "detadphidetadphi0After_1"}}; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h index 165bdcea6e6..e2e24821890 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h @@ -84,6 +84,19 @@ class FemtoUniversePairCleaner return false; } return part1.globalIndex() != part2.globalIndex(); + } else if constexpr (mPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kD0) { + /// Track-D0 combination part1 is hadron and part2 is D0 + if (part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kD0) { + LOG(fatal) << "FemtoUniversePairCleaner: passed arguments don't agree with FemtoUniversePairCleaner instantiation! Please provide second argument kD0 candidate."; + return false; + } + // Getting D0 (part2) children + const auto& posChild = particles.iteratorAt(part2.index() - 2); + const auto& negChild = particles.iteratorAt(part2.index() - 1); + if (part1.globalIndex() == posChild.globalIndex() || part1.globalIndex() == negChild.globalIndex()) { + return false; + } + return part1.globalIndex() != part2.globalIndex(); } else if constexpr (mPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kPhi) { /// Track-Phi combination part1 is Phi and part 2 is hadron if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kPhi) { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h index 40c1cac7a7f..be3817e8b05 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h @@ -143,6 +143,8 @@ class FemtoUniverseParticleHisto /// to be implemented } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kPhi) { // Phi histograms + } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kD0) { + // D0/D0bar histograms } else { LOG(fatal) << "FemtoUniverseParticleHisto: Histogramming for requested object not defined - quitting!"; } @@ -179,6 +181,9 @@ class FemtoUniverseParticleHisto } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kPhi) { // Phi histograms tempFitVarAxisTitle = "#Phi invariant mass"; + } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kD0) { + // D0/D0bar histograms + tempFitVarAxisTitle = "D^{0}/#bar{D^{0}} invariant mass"; } else { LOG(fatal) << "FemtoUniverseParticleHisto: Histogramming for requested object not defined - quitting!"; } @@ -317,6 +322,8 @@ class FemtoUniverseParticleHisto /// Cascade histograms } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kPhi) { // Phi histograms + } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kD0) { + // D0/D0bar histograms } else { LOG(fatal) << "FemtoUniverseParticleHisto: Histogramming for requested object not defined - quitting!"; } diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index ca218e212f9..b7fd3e34524 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -62,7 +62,7 @@ enum ParticleType { }; static constexpr std::string_view ParticleTypeName[kNParticleTypes] = {"Tracks", "MCTruthTracks", "V0", "V0Child", "Cascade", "CascadeBachelor", "Phi", "PhiChild", "D0", "D0Child"}; //! Naming of the different particle types -static constexpr std::string_view TempFitVarName[kNParticleTypes] = {"/hDCAxy", "/hPDGvspT", "/hCPA", "/hDCAxy", "/hCPA", "/hDCAxy", "/hInvMass", "/hDCAxy"}; +static constexpr std::string_view TempFitVarName[kNParticleTypes] = {"/hDCAxy", "/hPDGvspT", "/hCPA", "/hDCAxy", "/hCPA", "/hDCAxy", "/hInvMass", "/hDCAxy", "/hInvMass", "/hDCAxy"}; using cutContainerType = uint32_t; //! Definition of the data type for the bit-wise container for the different selection criteria diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index d4cd080b9ee..3bed62946eb 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -30,6 +30,9 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUtils.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Core/HfHelper.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" @@ -226,6 +229,16 @@ struct femtoUniverseProducerTask { Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 321, "Particle 2 - PDG code"}; } ConfPhiChildTwo; + // D0/D0bar mesons + struct : o2::framework::ConfigurableGroup { + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable yCandMax{"yCandMax", 4.0, "max. cand. rapidity"}; + Configurable ptCandMin{"ptCandMin", -1., "min. cand. pT"}; + } ConfD0Selection; + + HfHelper hfHelper; + bool IsKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) { //|nsigma_TPC| < 5 for p < 0.4 GeV/c @@ -288,10 +301,10 @@ struct femtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackD0mesonData) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackD0mesonData) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); @@ -417,7 +430,7 @@ struct femtoUniverseProducerTask { mRunNumber = bc.runNumber(); } - template + template void fillDebugParticle(ParticleType const& particle) { if constexpr (isTrackOrV0) { @@ -433,15 +446,15 @@ struct femtoUniverseProducerTask { particle.tofNSigmaStorePi(), particle.tofNSigmaStoreKa(), particle.tofNSigmaStorePr(), particle.tofNSigmaStoreDe(), -999., -999., -999., -999., -999., -999.); - } else if constexpr (isPhi) { + } else if constexpr (isPhiOrD0) { outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., - -999.); // QA for phi + -999.); // QA for phi or D0/D0bar } else { - LOGF(info, "isTrack0orV0: %d, isPhi: %d", isTrackOrV0, isPhi); + LOGF(info, "isTrack0orV0: %d, isPhi: %d", isTrackOrV0, isPhiOrD0); outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., @@ -679,6 +692,108 @@ struct femtoUniverseProducerTask { } } + template + void fillD0mesons(CollisionType const& col, TrackType const& tracks, HfCandidate const& hfCands) + { + std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children + std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index + double invMassD0 = 0.0; + double invMassD0bar = 0.0; + // phiCuts.fillQA(col, p1, p1, p2, ConfPhiChildOne.ConfPDGCodePartOne, ConfPhiChildTwo.ConfPDGCodePartTwo); ///\todo fill QA also for daughters + + for (auto const& hfCand : hfCands) { + + if (!(hfCand.hfflag() & 1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { + continue; + } + + if (ConfD0Selection.yCandMax >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.yCandMax) { + continue; + } + + int postrackID = hfCand.globalIndex(); + int rowInPrimaryTrackTablePos = -1; + rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); + childIDs[0] = rowInPrimaryTrackTablePos; + childIDs[1] = 0; + auto postrack = hfCand.template prong0_as(); + auto negtrack = hfCand.template prong1_as(); + + if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { + invMassD0 = hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = -hfHelper.invMassD0ToPiK(hfCand); + } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { + invMassD0 = -hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = hfHelper.invMassD0ToPiK(hfCand); + } else if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 1) { + invMassD0 = hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = hfHelper.invMassD0ToPiK(hfCand); + } else { + invMassD0 = 0.0; + invMassD0bar = 0.0; + } + + outputParts(outputCollision.lastIndex(), + hfCand.ptProng0(), + -999, // eta + -999, // phi + aod::femtouniverseparticle::ParticleType::kD0Child, + -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kPosCuts), + -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kPosPID), + -999, + childIDs, + 0, // D0 mass + 0); // D0bar mass + const int rowOfPosTrack = outputParts.lastIndex(); + /*if constexpr (isMC) { + fillMCParticle(tracks, o2::aod::femtouniverseparticle::ParticleType::kDmesonChild); + }*/ + int negtrackID = hfCand.prong1().globalIndex(); + int rowInPrimaryTrackTableNeg = -1; + rowInPrimaryTrackTableNeg = getRowDaughters(negtrackID, tmpIDtrack); + childIDs[0] = 0; + childIDs[1] = rowInPrimaryTrackTableNeg; + + outputParts(outputCollision.lastIndex(), + hfCand.ptProng1(), + -999, // eta + -999, // phi + aod::femtouniverseparticle::ParticleType::kD0Child, + -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kNegCuts), + -999, // cutContainerV0.at(femtoUniverseV0Selection::V0ContainerPosition::kNegPID), + -999, + childIDs, + 0, + 0); + const int rowOfNegTrack = outputParts.lastIndex(); + /*if constexpr (isMC) { + fillMCParticle(p2, o2::aod::femtouniverseparticle::ParticleType::kDmesonChild); + }*/ + std::vector indexChildID = {rowOfPosTrack, rowOfNegTrack}; + + outputParts(outputCollision.lastIndex(), + hfCand.pt(), + hfCand.eta(), + hfCand.phi(), + aod::femtouniverseparticle::ParticleType::kD0, + -999, // cut, cutContainerType + -999, // PID, cutContainerType + -999, + indexChildID, + invMassD0, // D0 mass (mLambda) + invMassD0bar); // D0bar mass (mAntiLambda) + + if (ConfIsDebug) { + fillDebugParticle(postrack); // QA for positive daughter + fillDebugParticle(negtrack); // QA for negative daughter + fillDebugParticle(hfCand); // QA for D0/D0bar + } + if constexpr (isMC) { + fillMCParticle(hfCand, o2::aod::femtouniverseparticle::ParticleType::kD0); + } + } + } + template void fillPhi(CollisionType const& col, TrackType const& tracks) { @@ -955,6 +1070,22 @@ struct femtoUniverseProducerTask { PROCESS_SWITCH(femtoUniverseProducerTask, processTrackPhiData, "Provide experimental data for track phi", false); + void + processTrackD0mesonData(aod::FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + soa::Filtered const& tracks, + soa::Join const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + // fill the tables + fillCollisions(col, tracks); + fillTracks(tracks); + fillD0mesons(col, tracks, candidates); + } + PROCESS_SWITCH(femtoUniverseProducerTask, processTrackD0mesonData, + "Provide experimental data for track D0 meson", false); + void processTrackMCTruth(aod::FemtoFullCollisionMC const& col, aod::BCsWithTimestamps const&, diff --git a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt index 01d65d0390b..88a89cd7f43 100644 --- a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt @@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(femtouniverse-pair-track-v0 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femtouniverse-pair-track-d0 + SOURCES femtoUniversePairTaskTrackD0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femtouniverse-pair-track-phi SOURCES femtoUniversePairTaskTrackPhi.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx new file mode 100644 index 00000000000..ff893fabc63 --- /dev/null +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -0,0 +1,546 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoUniversePairTaskTrackD0.cxx +/// \brief Tasks that reads the track tables and D0/D0bar mesons +/// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +/// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de +/// \author Anton Riedel, TU München, anton.riedel@tum.de +/// \author Zuzanna Chochulska, WUT Warsaw, zuzanna.chochulska.stud@pw.edu.pl +/// \author Katarzyna Gwiździel, WUT Warsaw, katarzyna.gwizdziel@cern.ch + +#include +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "TDatabasePDG.h" +#include "ReconstructionDataFormats/PID.h" +#include "Common/DataModel/PIDResponse.h" + +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUtils.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" + +using namespace o2; +using namespace o2::analysis::femtoUniverse; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +namespace +{ +static constexpr int nPart = 2; +static constexpr int nCuts = 5; +static const std::vector partNames{"D0", "Track"}; +static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; +static const float cutsTable[nPart][nCuts]{ + {4.05f, 1.f, 3.f, 3.f, 100.f}, + {4.05f, 1.f, 3.f, 3.f, 100.f}}; +} // namespace + +struct femtoUniversePairTaskTrackD0 { + + using FemtoFullParticles = soa::Join; + SliceCache cache; + Preslice perCol = aod::femtouniverseparticle::fdCollisionId; + + /// Table for both particles + struct : o2::framework::ConfigurableGroup { + Configurable ConfNsigmaCombinedProton{"ConfNsigmaCombinedProton", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > 0.5"}; + Configurable ConfNsigmaTPCProton{"ConfNsigmaTPCProton", 3.0, "TPC Proton Sigma for momentum < 0.5"}; + Configurable ConfNsigmaCombinedPion{"ConfNsigmaCombinedPion", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > 0.5"}; + Configurable ConfNsigmaTPCPion{"ConfNsigmaTPCPion", 3.0, "TPC Pion Sigma for momentum < 0.5"}; + + Configurable> ConfCutTable{"ConfCutTable", {cutsTable[0], nPart, nCuts, partNames, cutNames}, "Particle selections"}; + Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; + Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; + Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; + Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; + Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; + } ConfBothTracks; + + /// Particle 1 --- IDENTIFIED TRACK + struct : o2::framework::ConfigurableGroup { + Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; + Configurable ConfPDGCodeTrack{"ConfPDGCodeTrack", 2212, "Particle 2 - PDG code"}; + // Configurable ConfCutTrack{"ConfCutTrack", 5542474, "Particle 2 - Selection bit"}; + Configurable ConfPIDTrack{"ConfPIDTrack", 2, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> + Configurable ConfTrackSign{"ConfTrackSign", 1, "Track sign"}; + Configurable ConfIsTrackIdentified{"ConfIsTrackIdentified", true, "Enable PID for the track"}; + } ConfTrack; + + /// Particle 2 --- D0/D0bar meson + struct : o2::framework::ConfigurableGroup { + Configurable ConfPDGCodeD0{"ConfPDGCodeD0", 421, "D0 meson - PDG code"}; + Configurable ConfPDGCodeD0bar{"ConfPDGCodeD0bar", -421, "D0bar meson - PDG code"}; + } ConfDmesons; + + /// Partitions for particle 1 + Partition partsTrack = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == int8_t(ConfTrack.ConfTrackSign)); + Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)); + + /// Partitions for particle 2 + Partition partsD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); + Partition> partsD0D0barMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); + + /// Histogramming for particle 1 + FemtoUniverseParticleHisto trackHistoPartTrack; + + /// Histogramming for particle 2 + FemtoUniverseParticleHisto trackHistoPartD0D0bar; + + /// Histogramming for Event + FemtoUniverseEventHisto eventHisto; + + /// The configurables need to be passed to an std::vector + int vPIDTrack; + std::vector kNsigma; + + /// particle part + ConfigurableAxis ConfTempFitVarBins{"ConfDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfTempFitVarInvMassBins{"ConfDTempFitVarInvMassBins", {6000, 0.9, 4.0}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + + /// Correlation part + ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task + // ConfigurableAxis ConfMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + 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 ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis ConfmultBins3D{"ConfmultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + + ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + + ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; + Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; + Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + + FemtoUniverseFemtoContainer sameEventFemtoCont; + FemtoUniverseFemtoContainer mixedEventFemtoCont; + FemtoUniverseAngularContainer sameEventAngularCont; + FemtoUniverseAngularContainer mixedEventAngularCont; + FemtoUniversePairCleaner pairCleaner; + FemtoUniverseDetaDphiStar pairCloseRejection; + FemtoUniverseTrackSelection trackCuts; + + /// Histogram output + HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + HistogramRegistry registry{"registry", + {{"hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{300, 1.75, 2.05}}}}, + {"hInvMassD0bar", ";#it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{300, 1.75, 2.05}}}}, + {"hPtD0", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 15.}}}}, + {"hPtD0bar", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 15.}}}}, + {"hPhiD0", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, + {"hPhiD0bar", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, + {"hEtaD0", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, + {"hEtaD0bar", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, + {"hDecayLengthD0", ";decay length (cm);counts", {HistType::kTH1F, {{100, 0., 0.5}}}}, + {"hDecayLengthD0bar", ";decay length (cm);counts", {HistType::kTH1F, {{100, 0., 0.5}}}}, + {"hDeltaPhi", "; #Delta #varphi (rad);counts", {HistType::kTH1F, {{80, -0.5 * o2::constants::math::PI, 2. * o2::constants::math::PI}}}}, + {"hPtDaughters", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 12.}}}}, + {"hMomentumDaughters", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 15.}}}}, + {"hSignDaughters", ";sign ;counts", {HistType::kTH1F, {{10, -2.5, 2.5}}}}, + {"hbetaDaughters", "; p (GeV/#it{c}); TOF #beta", {HistType::kTH2F, {{300, 0., 15.}, {200, 0., 2.}}}}, + {"hdEdxDaughters", "; p (GeV/#it{c}); TPC dE/dx (KeV/cm)", {HistType::kTH2F, {{300, 0., 15.}, {500, 0., 500.}}}}, + {"hDCAxyDaughters", "; #it{DCA}_{xy} (cm); counts", {HistType::kTH1F, {{140, 0., 0.14}}}}, + {"hDCAzDaughters", "; #it{DCA}_{z} (cm); counts", {HistType::kTH1F, {{140, 0., 0.14}}}}}}; + + // PID for protons + bool IsProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx + { + //|nsigma_TPC| < 3 for p < 0.5 GeV/c + //|nsigma_combined| < 3 for p > 0.5 + + // using configurables: + // ConfNsigmaTPCProton -> TPC Kaon Sigma for momentum < 0.5 + // ConfNsigmaCombinedProton -> TPC and TOF Kaon Sigma (combined) for momentum > 0.5 + + if (mom < 0.5) { + if (TMath::Abs(nsigmaTPCPr) < ConfBothTracks.ConfNsigmaTPCProton) { + return true; + } else { + return false; + } + } else if (mom > 0.4) { + if (TMath::Hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.ConfNsigmaCombinedProton) { + // if (TMath::Abs(nsigmaTPCPr) < ConfBothTracks.ConfNsigmaCombinedProton) { + return true; + } else { + return false; + } + } + return false; + } + + bool IsKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) + { + if (mom < 0.3) { // 0.0-0.3 + if (TMath::Abs(nsigmaTPCK) < 3.0) { + return true; + } else { + return false; + } + } else if (mom < 0.45) { // 0.30 - 0.45 + if (TMath::Abs(nsigmaTPCK) < 2.0) { + return true; + } else { + return false; + } + } else if (mom < 0.55) { // 0.45-0.55 + if (TMath::Abs(nsigmaTPCK) < 1.0) { + return true; + } else { + return false; + } + } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) + if ((TMath::Abs(nsigmaTOFK) < 3.0) && (TMath::Abs(nsigmaTPCK) < 3.0)) { + { + return true; + } + } else { + return false; + } + } else if (mom > 1.5) { // 1.5 - + if ((TMath::Abs(nsigmaTOFK) < 2.0) && (TMath::Abs(nsigmaTPCK) < 3.0)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + bool IsPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) + { + //|nsigma_TPC| < 3 for p < 0.5 GeV/c + //|nsigma_combined| < 3 for p > 0.5 + + // using configurables: + // ConfNsigmaTPCPion -> TPC Kaon Sigma for momentum < 0.5 + // ConfNsigmaCombinedPion -> TPC and TOF Pion Sigma (combined) for momentum > 0.5 + if (true) { + if (mom < 0.5) { + if (TMath::Abs(nsigmaTPCPi) < ConfBothTracks.ConfNsigmaTPCPion) { + return true; + } else { + return false; + } + } else if (mom > 0.5) { + if (TMath::Hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.ConfNsigmaCombinedPion) { + // if (TMath::Abs(nsigmaTPCPi) < ConfBothTracks.ConfNsigmaCombinedPion) { + return true; + } else { + return false; + } + } + } + return false; + } + + bool IsParticleNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) + { + switch (ConfTrack.ConfPDGCodeTrack) { + case 2212: // Proton + case -2212: // anty Proton + return IsProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); + break; + case 211: // Pion + case -211: // Pion- + return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + break; + case 321: // Kaon+ + case -321: // Kaon- + return IsKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + break; + default: + return false; + } + } + + void init(InitContext&) + { + eventHisto.init(&qaRegistry); + trackHistoPartD0D0bar.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarInvMassBins, ConfBothTracks.ConfIsMC, ConfDmesons.ConfPDGCodeD0); + if (!ConfTrack.ConfIsSame) { + trackHistoPartTrack.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfBothTracks.ConfIsMC, ConfTrack.ConfPDGCodeTrack); + } + + MixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + MixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + + sameEventFemtoCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfBothTracks.ConfIsMC, ConfBothTracks.ConfUse3D); + mixedEventFemtoCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfBothTracks.ConfIsMC, ConfBothTracks.ConfUse3D); + sameEventAngularCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfBothTracks.ConfEtaBins, ConfBothTracks.ConfPhiBins, ConfBothTracks.ConfIsMC, ConfBothTracks.ConfUse3D); + mixedEventAngularCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfBothTracks.ConfEtaBins, ConfBothTracks.ConfPhiBins, ConfBothTracks.ConfIsMC, ConfBothTracks.ConfUse3D); + + sameEventFemtoCont.setPDGCodes(ConfDmesons.ConfPDGCodeD0, ConfTrack.ConfPDGCodeTrack); + mixedEventFemtoCont.setPDGCodes(ConfDmesons.ConfPDGCodeD0, ConfTrack.ConfPDGCodeTrack); + sameEventAngularCont.setPDGCodes(ConfDmesons.ConfPDGCodeD0, ConfTrack.ConfPDGCodeTrack); + mixedEventAngularCont.setPDGCodes(ConfDmesons.ConfPDGCodeD0, ConfTrack.ConfPDGCodeTrack); + + pairCleaner.init(&qaRegistry); + if (ConfIsCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + } + + vPIDTrack = ConfTrack.ConfPIDTrack.value; + kNsigma = ConfBothTracks.ConfTrkPIDnSigmaMax.value; + } + + template + void fillCollision(CollisionType col) + { + MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); + eventHisto.fillQA(col); + } + + void processD0mesons(o2::aod::FDCollision& col, FemtoFullParticles& parts) + { + auto groupPartsD0D0bar = partsD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + // auto groupPartsD0D0barDaugh = partsD0D0barDaughters->sliceByCached(aod::femtoworldparticle::femtoWorldCollisionId, col.globalIndex(), cache); + + for (auto& d0d0bar : groupPartsD0D0bar) { + if (d0d0bar.mLambda() > 0 && d0d0bar.mAntiLambda() < 0) { + registry.fill(HIST("hInvMassD0"), d0d0bar.mLambda()); + registry.fill(HIST("hPtD0"), d0d0bar.pt()); + registry.fill(HIST("hPhiD0"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0"), d0d0bar.eta()); + } + if (d0d0bar.mLambda() < 0 && d0d0bar.mAntiLambda() > 0) { + registry.fill(HIST("hInvMassD0bar"), d0d0bar.mAntiLambda()); + registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); + registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); + } + } + + /*for (auto& daughD0D0bar : groupPartsD0D0barDaugh) { + if (daughD0D0bar.flagD0() == 1) { + registry.fill(HIST("hMomentumDaughters"), daughD0D0bar.p()); + registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); + registry.fill(HIST("hSignDaughters"), daughD0D0bar.sign()); + registry.fill(HIST("hbetaDaughters"), daughD0D0bar.beta(), daughD0D0bar.p()); + registry.fill(HIST("hdEdxDaughters"), daughD0D0bar.tpcSignal(), daughD0D0bar.p()); + registry.fill(HIST("hDCAxyDaughters"), daughD0D0bar.dcaXY()); + registry.fill(HIST("hDCAzDaughters"), daughD0D0bar.dcaZ()); + } + if (daughD0D0bar.flagD0bar() == 1) { + registry.fill(HIST("hMomentumDaughters"), daughD0D0bar.p()); + registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); + registry.fill(HIST("hSignDaughters"), daughD0D0bar.sign()); + registry.fill(HIST("hbetaDaughters"), daughD0D0bar.beta(), daughD0D0bar.p()); + registry.fill(HIST("hdEdxDaughters"), daughD0D0bar.tpcSignal(), daughD0D0bar.p()); + registry.fill(HIST("hDCAxyDaughters"), daughD0D0bar.dcaXY()); + registry.fill(HIST("hDCAzDaughters"), daughD0D0bar.dcaZ()); + } + }*/ + } + PROCESS_SWITCH(femtoUniversePairTaskTrackD0, processD0mesons, "Enable processing D0 mesons", true); + + /// This function processes the same event and takes care of all the histogramming + /// \todo the trivial loops over the tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... + /// @tparam PartitionType + /// @tparam PartType + /// @tparam isMC: enables Monte Carlo truth specific histograms + /// @param groupPartsTrack partition for the first particle passed by the process function + /// @param groupPartsD0 partition for the second particle passed by the process function + /// @param parts femtoUniverseParticles table (in case of Monte Carlo joined with FemtoUniverseMCLabels) + /// @param magFieldTesla magnetic field of the collision + /// @param multCol multiplicity of the collision + template + void doSameEvent(PartitionType groupPartsTrack, PartitionType groupPartsD0, PartType parts, float magFieldTesla, int multCol) + { + + /// Histogramming same event + for (auto& d0candidate : groupPartsD0) { + trackHistoPartD0D0bar.fillQA(d0candidate); + } + + if (!ConfTrack.ConfIsSame) { + for (auto& track : groupPartsTrack) { + if (ConfTrack.ConfIsTrackIdentified) { + if (!IsParticleNSigma(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + continue; + } + } + trackHistoPartTrack.fillQA(track); + } + } + /// Now build the combinations + for (auto& [track, d0candidate] : combinations(CombinationsFullIndexPolicy(groupPartsTrack, groupPartsD0))) { + if (ConfTrack.ConfIsTrackIdentified) { + if (!IsParticleNSigma(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + continue; + } + } + // // Close Pair Rejection + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(track, d0candidate, parts, magFieldTesla)) { + continue; + } + } + + // Track Cleaning + if (!pairCleaner.isCleanPair(track, d0candidate, parts)) { + continue; + } + sameEventFemtoCont.setPair(track, d0candidate, multCol, ConfBothTracks.ConfUse3D); + sameEventAngularCont.setPair(track, d0candidate, multCol, ConfBothTracks.ConfUse3D); + } + } + + /// process function for to call doSameEvent with Data + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoUniverseParticleTable + void processSameEvent(o2::aod::FDCollision& col, + FemtoFullParticles& parts) + { + fillCollision(col); + + auto thegroupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsD0 = partsD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + doSameEvent(thegroupPartsTrack, thegroupPartsD0, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackD0, processSameEvent, "Enable processing same event", true); + + /// process function for to call doSameEvent with Monte Carlo + /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) + /// \param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth + /// \param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table + void processSameEventMC(o2::aod::FDCollision& col, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + fillCollision(col); + + auto thegroupPartsD0 = partsD0D0barMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsTrack = partsTrackMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + doSameEvent(thegroupPartsTrack, thegroupPartsD0, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackD0, processSameEventMC, "Enable processing same event for Monte Carlo", false); + + /// This function processes the mixed event + /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... + /// \tparam PartitionType + /// \tparam PartType + /// \tparam isMC: enables Monte Carlo truth specific histograms + /// \param groupPartsTrack partition for the identified passed by the process function + /// \param groupPartsD0 partition for D0 meson passed by the process function + /// \param parts femtoUniverseParticles table (in case of Monte Carlo joined with FemtoUniverseMCLabels) + /// \param magFieldTesla magnetic field of the collision + /// \param multCol multiplicity of the collision + template + void doMixedEvent(PartitionType groupPartsTrack, PartitionType groupPartsD0, PartType parts, float magFieldTesla, int multCol) + { + + for (auto& [track, d0candidate] : combinations(CombinationsFullIndexPolicy(groupPartsTrack, groupPartsD0))) { + if (ConfTrack.ConfIsTrackIdentified) { + if (!IsParticleNSigma(track.p(), trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton), trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion), trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon))) { + continue; + } + } + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(track, d0candidate, parts, magFieldTesla)) { + continue; + } + } + + mixedEventFemtoCont.setPair(track, d0candidate, multCol, ConfBothTracks.ConfUse3D); + mixedEventAngularCont.setPair(track, d0candidate, multCol, ConfBothTracks.ConfUse3D); + } + } + + /// process function for to call doMixedEvent with Data + /// @param cols subscribe to the collisions table (Data) + /// @param parts subscribe to the femtoUniverseParticleTable + void processMixedEvent(o2::aod::FDCollisions& cols, + FemtoFullParticles& parts) + { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + + const int multiplicityCol = collision1.multNtr(); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + auto groupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsD0 = partsD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + /// \todo before mixing we should check whether both collisions contain a pair of particles! + // if (partsD0.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTrack.size() == 0 ) continue; + + doMixedEvent(groupPartsTrack, groupPartsD0, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackD0, processMixedEvent, "Enable processing mixed events", true); + + /// brief process function for to call doMixedEvent with Monte Carlo + /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) + /// @param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth + /// @param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table + void processMixedEventMC(o2::aod::FDCollisions& cols, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + + const int multiplicityCol = collision1.multNtr(); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + auto groupPartsTrack = partsTrackMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsD0 = partsD0D0barMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + /// \todo before mixing we should check whether both collisions contain a pair of particles! + // if (partsD0.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTrack.size() == 0 ) continue; + + doMixedEvent(groupPartsTrack, groupPartsD0, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackD0, processMixedEventMC, "Enable processing mixed events MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} From cbae76ba95d0dadf78009f8ccc9827a60cb8e133 Mon Sep 17 00:00:00 2001 From: kgwizdzi <116073883+kgwizdzi@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:34:57 +0100 Subject: [PATCH 039/156] PWGCF - FemtoUniverse - V0 process switched to false (#4142) * PWGCF - adding DO mesons to FemtoUniverse * Fixing clang-format * Changing the bool from isPhi to isPhiOrD0 * Fixing alibuild * PROCESS_SWITCH for V0s changed to false by default --- PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 3bed62946eb..26b889e34f5 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -1009,7 +1009,7 @@ struct femtoUniverseProducerTask { // fill the tables fillCollisionsAndTracksAndV0AndPhi(col, tracks, fullV0s); } - PROCESS_SWITCH(femtoUniverseProducerTask, processTrackV0, "Provide experimental data for track v0", true); + PROCESS_SWITCH(femtoUniverseProducerTask, processTrackV0, "Provide experimental data for track v0", false); void processFullMC(aod::FemtoFullCollisionMC const& col, From f3fca2a0b20b785fb7421c68fb6f6c141f535e28 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:48:36 +0100 Subject: [PATCH 040/156] added QA plots for jet axis (#4140) --- PWGLF/Tasks/nuclei_in_jets.cxx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 1608c60c32c..924a5821757 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -124,11 +124,13 @@ struct nuclei_in_jets { registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("pt_leading", "pt leading", HistType::kTH1F, {{500, 0, 50, "#it{p}_{T} (GeV/#it{c})"}}); - registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{500, -0.5, 0.5, "#Delta#eta"}, {500, 0.0, TMath::Pi(), "#Delta#phi"}}); - registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{500, -0.5, 0.5, "#Delta#eta"}, {500, 0.0, TMath::Pi(), "#Delta#phi"}}); - registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}_{max}"}}); - registryQC.add("r_jet", "R jet", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}"}}); - registryQC.add("r_ue", "R ue", HistType::kTH1F, {{400, 0.0, 0.8, "#it{R}"}}); + registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, 0.0, TMath::Pi(), "#Delta#phi"}}); + registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, 0.0, TMath::Pi(), "#Delta#phi"}}); + registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{100, 0.0, 2.0, "#it{R}_{max}"}}); + registryQC.add("r_jet", "R jet", HistType::kTH1F, {{100, 0.0, 0.8, "#it{R}"}}); + registryQC.add("r_ue", "R ue", HistType::kTH1F, {{100, 0.0, 0.8, "#it{R}"}}); + registryQC.add("eta_leading", "eta_leading", HistType::kTH1F, {{100, -1, 1, "#eta"}}); + registryQC.add("phi_leading", "phi_leading", HistType::kTH1F, {{100, 0, TMath::Pi(), "#phi"}}); // Antiprotons registryData.add("antiproton_jet_tpc", "antiproton_jet_tpc", HistType::kTH3F, {{20, 0.0, 1.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); @@ -514,6 +516,10 @@ struct nuclei_in_jets { return; registryQC.fill(HIST("number_of_events_data"), 6.5); + // QA Plots + registryQC.fill(HIST("eta_leading"), p_leading.Eta()); + registryQC.fill(HIST("phi_leading"), TVector2::Phi_0_2pi(p_leading.Phi())); + // Find Maximum Distance from Jet Axis float Rmax(0); @@ -538,7 +544,7 @@ struct nuclei_in_jets { // Event Counter: Skip Events with jet not fully inside acceptance float eta_jet_axis = p_leading.Eta(); - if ((TMath::Abs(eta_jet_axis) + Rmax) > max_eta) + if ((TMath::Abs(eta_jet_axis) + max_jet_radius) > max_eta) return; registryQC.fill(HIST("number_of_events_data"), 8.5); @@ -554,7 +560,7 @@ struct nuclei_in_jets { double angle = gRandom->Uniform(0.0, TMath::TwoPi()); ue_axis.Rotate(angle, p_leading); double eta_ue_axis = ue_axis.Eta(); - dEta = (TMath::Abs(eta_ue_axis) + Rmax); + dEta = (TMath::Abs(eta_ue_axis) + max_jet_radius); } while (dEta > max_eta); // Store UE @@ -575,7 +581,7 @@ struct nuclei_in_jets { float dr = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); // Store Particles in the UE - if (dr < Rmax) { + if (dr < max_jet_radius) { registryQC.fill(HIST("eta_phi_ue"), deltaEta, deltaPhi); registryQC.fill(HIST("r_ue"), dr); ue_particle_ID.push_back(particle_ID[i]); From d49c0008fe594c7139882ebba102cdedab14cb51 Mon Sep 17 00:00:00 2001 From: Jochen Klein Date: Tue, 12 Dec 2023 17:57:01 +0100 Subject: [PATCH 041/156] Update cuts for Omega_c tree creator (#4143) --- PWGHF/TableProducer/treeCreatorOmegacSt.cxx | 39 +++++++++------------ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index efc542f76cc..b398185c034 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -30,7 +30,7 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" - +#include "Common/DataModel/EventSelection.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/PIDResponse.h" @@ -174,6 +174,7 @@ struct HfTreeCreatorOmegacSt { Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; Configurable minNoClsTrackedCascade{"minNoClsTrackedCascade", 70, "Minimum number of clusters required for daughters of tracked cascades"}; Configurable minNoClsTrackedPion{"minNoClsTrackedPion", 70, "Minimum number of clusters required for associated pions"}; + Configurable filterCollisions{"filterCollisions", 8, "0: no filtering; 8: sel8"}; Configurable massWindowTrackedOmega{"massWindowTrackedOmega", 0.05, "Inv. mass window for tracked Omega"}; Configurable massWindowXiExclTrackedOmega{"massWindowXiExclTrackedOmega", 0.005, "Inv. mass window for exclusion of Xi for tracked Omega-"}; Configurable massWindowTrackedXi{"massWindowTrackedXi", 0., "Inv. mass window for tracked Xi"}; @@ -182,22 +183,24 @@ struct HfTreeCreatorOmegacSt { Configurable massWindowOmegaC{"massWindowOmegaC", 0.1, "Inv. mass window for Omegac"}; Configurable maxMatchingChi2TrackedCascade{"maxMatchingChi2TrackedCascade", 2000., "Max matching chi2 for tracked cascades"}; Configurable recalculateMasses{"recalculateMasses", true, "Recalculate Xi/Omega masses"}; - Configurable maxNSigmaBachelor{"maxNSigmaBachelor", 5., "Max Nsigma for bachelor of tracked Xi (Ka)"}; - Configurable maxNSigmaV0Pr{"maxNSigmaV0Pr", 5., "Max Nsigma for proton from V0 fromtracked Xi"}; - Configurable maxNSigmaV0Pi{"maxNSigmaV0Pi", 5., "Max Nsigma for pion from V0 fromtracked Xi"}; - Configurable maxNSigmaPion{"maxNSigmaPion", 5., "Max Nsigma for pion to be paired with Omega2git s2"}; + Configurable maxNSigmaBachelor{"maxNSigmaBachelor", 5., "Max Nsigma for bachelor of tracked cascade"}; + Configurable maxNSigmaV0Pr{"maxNSigmaV0Pr", 5., "Max Nsigma for proton from V0 from tracked cascade"}; + Configurable maxNSigmaV0Pi{"maxNSigmaV0Pi", 5., "Max Nsigma for pion from V0 from tracked cascade"}; + Configurable maxNSigmaPion{"maxNSigmaPion", 5., "Max Nsigma for pion to be paired with Omega"}; + Configurable bzOnly{"bzOnly", true, "Use B_z instead of full field map"}; Produces outputTable; Produces outputTableGen; Service ccdb; o2::vertexing::DCAFitterN<2> df2; - TrackSelection trackSelector; + Filter collisionFilter = (filterCollisions.node() == 0) || + (filterCollisions.node() == 8 && o2::aod::evsel::sel8 == true); - bool bzOnly = true; float bz = 0.; int runNumber{0}; + using Collisions = soa::Filtered>; using TracksExt = soa::Join; using TracksExtMc = soa::Join; @@ -239,19 +242,6 @@ struct HfTreeCreatorOmegacSt { o2::base::Propagator::Instance(true)->setMatLUT(lut); } - trackSelector.SetTrackType(o2::aod::track::TrackTypeEnum::Track); - trackSelector.SetEtaRange(-.9, .9); - trackSelector.SetRequireITSRefit(true); - trackSelector.SetRequireTPCRefit(true); - trackSelector.SetRequireGoldenChi2(false); - trackSelector.SetMinNCrossedRowsTPC(minNoClsTrackedPion); - trackSelector.SetMinNCrossedRowsOverFindableClustersTPC(0.8f); - trackSelector.SetMaxChi2PerClusterTPC(4.f); - trackSelector.SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any of the first three layers of IB - trackSelector.SetMaxChi2PerClusterITS(36.f); - trackSelector.SetMaxDcaXY(1.f); - trackSelector.SetMaxDcaZ(2.f); - df2.setPropagateToPCA(propToDCA); df2.setMaxR(maxR); df2.setMaxDZIni(maxDZIni); @@ -281,7 +271,7 @@ struct HfTreeCreatorOmegacSt { } PROCESS_SWITCH(HfTreeCreatorOmegacSt, processMc, "Process MC", true); - void processData(aod::Collision const& collision, + void processData(Collisions::iterator const& collision, aod::AssignedTrackedCascades const& trackedCascades, aod::Cascades const& cascades, aod::V0s const& v0s, @@ -409,7 +399,12 @@ struct HfTreeCreatorOmegacSt { trackId == bachelor.globalIndex()) { continue; } - if (trackSelector.IsSelected(track) && + if ((track.itsNCls() >= 4) && + (track.tpcNClsFound() >= minNoClsTrackedPion) && + (track.tpcNClsCrossedRows() >= minNoClsTrackedPion) && + (track.tpcNClsCrossedRows() >= 0.8 * track.tpcNClsFindable()) && + (track.tpcChi2NCl() <= 4.f) && + (track.itsChi2NCl() <= 36.f) && (std::abs(track.tpcNSigmaPi()) < maxNSigmaPion)) { LOGF(debug, " .. combining with pion candidate %d", track.globalIndex()); auto trackParCovCasc = getTrackParCov(trackCasc); From 37cd3517d6d6023b010a456fa9325f3b60d6c303 Mon Sep 17 00:00:00 2001 From: Alessandro Sturniolo <123940165+AlessandroSturniolo@users.noreply.github.com> Date: Tue, 12 Dec 2023 18:18:30 +0100 Subject: [PATCH 042/156] PWGLF - First commit of charged K*(892) analysis (#4145) * First commit of charged K*(892) analysis * Please consider the following formatting changes --------- Co-authored-by: AlessandroSturniolo Co-authored-by: ALICE Action Bot --- PWGLF/Tasks/CMakeLists.txt | 5 + PWGLF/Tasks/k892pmanalysis.cxx | 302 +++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 PWGLF/Tasks/k892pmanalysis.cxx diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index ddd2aa5cf32..0e4ae82b2c4 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -176,6 +176,11 @@ o2physics_add_dpl_workflow(k892analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(k892pmanalysis + SOURCES k892pmanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(lambda1520analysis SOURCES lambda1520analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/k892pmanalysis.cxx b/PWGLF/Tasks/k892pmanalysis.cxx new file mode 100644 index 00000000000..83561df888a --- /dev/null +++ b/PWGLF/Tasks/k892pmanalysis.cxx @@ -0,0 +1,302 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file k892pmanalysis.cxx +/// \brief Reconstruction of track-V0 decay resonance candidates +/// +/// +/// \author Bong-Hwi Lim , Alessandro Sturniolo + +#include + +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "DataFormatsParameters/GRPObject.h" +#include "CommonConstants/PhysicsConstants.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; +using namespace o2::constants::physics; + +struct k892pmanalysis { + SliceCache cache; + Preslice perRCol = aod::resodaughter::resoCollisionId; + Preslice perCollision = aod::track::collisionId; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + ///// Configurables + /// Histograms + ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 7.0, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9.0, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 11.0, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12.0, 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14.0, 14.1, 14.2, 14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15.0}, "Binning of the pT axis"}; + ConfigurableAxis binsPtQA{"binsPtQA", {VARIABLE_WIDTH, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0}, "Binning of the pT axis"}; + ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0., 1., 5., 10., 30., 50., 70., 100., 110.}, "Binning of the centrality axis"}; + Configurable cInvMassStart{"cInvMassStart", 0.6, "Invariant mass start"}; + Configurable cInvMassEnd{"cInvMassEnd", 1.5, "Invariant mass end"}; + Configurable cInvMassBins{"cInvMassBins", 900, "Invariant mass binning"}; + Configurable cK0shortMassStart{"cK0shortMassStart", 0.4, "K0Short mass start"}; + Configurable cK0shortMassEnd{"cK0shortMassEnd", 0.6, "K0Short mass end"}; + Configurable cK0shortMassBins{"cK0shortMassBins", 50, "K0Short mass binning"}; + Configurable cDCABins{"cDCABins", 150, "DCA binning"}; + /// Pre-selection cuts + Configurable cMinPtcut{"cMinPtcut", 0.15, "Track minimum pt cut"}; + /// DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; + /// PID Selections + Configurable cMaxTPCnSigmaPion{"cMaxTPCnSigmaPion", 3.0, "TPC nSigma cut for Pion"}; // TPC + Configurable cMaxTOFnSigmaPion{"cMaxTOFnSigmaPion", 3.0, "TOF nSigma cut for Pion"}; // TOF + Configurable nsigmaCutCombinedPion{"nsigmaCutCombinedPion", -999, "Combined nSigma cut for Pion"}; // Combined + Configurable cUseOnlyTOFTrackPi{"cUseOnlyTOFTrackPi", false, "Use only TOF track for PID selection"}; // Use only TOF track for Pion PID selection + Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection + // Track selections + Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cfgPVContributor{"cfgPVContributor", true, "PV contributor track selection"}; // PV Contributor + // V0 selections + Configurable cV0MinCosPA{"cV0MinCosPA", 0.97, "V0 minimum pointing angle cosine"}; + Configurable cV0MaxDaughDCA{"cV0MaxDaughDCA", 1.0, "V0 daughter DCA Maximum"}; + + void init(o2::framework::InitContext&) + { + AxisSpec centAxis = {binsCent, "V0M (%)"}; + AxisSpec dcaxyAxis = {cDCABins, 0.0, 3.0, "DCA_{#it{xy}} (cm)"}; + AxisSpec dcazAxis = {cDCABins, 0.0, 3.0, "DCA_{#it{xy}} (cm)"}; + AxisSpec ptAxis = {binsPt, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec ptAxisQA = {binsPtQA, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec invMassAxis = {cInvMassBins, cInvMassStart, cInvMassEnd, "Invariant Mass (GeV/#it{c}^2)"}; + AxisSpec k0sMassAxis = {cK0shortMassBins, cK0shortMassStart, cK0shortMassEnd, "K^{0}_{S} Mass (GeV/#it{c}^2)"}; + + // Mass QA (quick check) + histos.add("k892pminvmass", "Invariant mass of charged K*(892)", kTH1F, {invMassAxis}); + histos.add("QAafter/k0shortmass", "Invariant mass of K0Short", kTH1F, {k0sMassAxis}); + // DCA QA + histos.add("QAbefore/collMult", "Collision multiplicity", HistType::kTH1F, {binsCent}); + histos.add("QAbefore/trkDCAxy_pi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {dcaxyAxis}); + histos.add("QAbefore/trkDCAz_pi", "DCAz distribution of pion track candidates", HistType::kTH1F, {dcazAxis}); + // histos.add("QAbefore/trkDCAz_k0s", "DCAz distribution of k0short track candidates", HistType::kTH1F, {dcazAxis}); + histos.add("QAafter/trkDCAxy_pi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {dcaxyAxis}); + histos.add("QAafter/trkDCAz_pi", "DCAz distribution of pion track candidates", HistType::kTH1F, {dcazAxis}); + // histos.add("QAafter/trkDCAz_k0s", "DCAz distribution of k0short track candidates", HistType::kTH1F, {dcazAxis}); + // pT QA + histos.add("QAbefore/trkpT_pi", "pT distribution of pion track candidates", kTH1F, {ptAxisQA}); + histos.add("QAbefore/trkpT_k0s", "pT distribution of k0short track candidates", kTH1F, {ptAxisQA}); + histos.add("QAafter/trkpT_pi", "pT distribution of pion track candidates", kTH1F, {ptAxisQA}); + histos.add("QAafter/trkpT_k0s", "pT distribution of k0short track candidates", kTH1F, {ptAxisQA}); + + /*if (doprocessMCLight) { + // MC QA + histos.add("QAMCTrue/trkDCAxy_pi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {dcaxyAxis}); + histos.add("QAMCTrue/trkDCAxy_ka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {dcaxyAxis}); + histos.add("QAMCTrue/trkDCAz_pi", "DCAz distribution of pion track candidates", HistType::kTH1F, {dcazAxis}); + histos.add("QAMCTrue/trkDCAz_ka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {dcazAxis}); + histos.add("h3Reck892invmass", "Invariant mass of Reconstructed MC K(892)0", kTH3F, {centAxis, ptAxis, invMassAxis}); + histos.add("h3Reck892invmassAnti", "Invariant mass of Reconstructed MC Anti-K(892)0", kTH3F, {centAxis, ptAxis, invMassAxis}); + histos.add("k892pmGen", "pT distribution of True MC K(892)0", kTH1F, {ptAxis}); + histos.add("k892pmGenAnti", "pT distribution of True MC Anti-K(892)0", kTH1F, {ptAxis}); + histos.add("k892Rec", "pT distribution of Reconstructed MC K(892)0", kTH1F, {ptAxis}); + histos.add("k892RecAnti", "pT distribution of Reconstructed MC Anti-K(892)0", kTH1F, {ptAxis}); + histos.add("k892Recinvmass", "Inv mass distribution of Reconstructed MC Phi", kTH1F, {invMassAxis}); + }*/ + // Print output histograms statistics + LOG(info) << "Size of the histograms in spectraTOF"; + histos.print(); + } + + double massK0 = MassK0Short; + double massPi = MassPionCharged; + + template + bool trackCut(const TrackType track) + { + // basic track cuts + if (std::abs(track.pt()) < cMinPtcut) + return false; + if (std::abs(track.dcaXY()) > cMaxDCArToPVcut) + return false; + if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut) + return false; + if (cfgPrimaryTrack && !track.isPrimaryTrack()) + return false; + if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + return false; + if (cfgPVContributor && !track.isPVContributor()) + return false; + + return true; + } + + template + bool V0Cut(const V0Type v0) + { + // V0 track cuts + if (std::abs(v0.eta()) > 0.8) + return false; + if (v0.v0CosPA() < cV0MinCosPA) + return false; + if (v0.daughDCA() > cV0MaxDaughDCA) + return false; + + return true; + } + + // Primary PID selection tools + template + bool selectionPIDPrimaryPion(const T& candidate) + { + bool tpcPIDPassed{false}, tofPIDPassed{false}; + if (std::abs(candidate.tpcNSigmaPi()) < cMaxTPCnSigmaPion) { + tpcPIDPassed = true; + } + if (candidate.hasTOF()) { + if (std::abs(candidate.tofNSigmaPi()) < cMaxTOFnSigmaPion) { + tofPIDPassed = true; + } + if ((nsigmaCutCombinedPion > 0) && (candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi() + candidate.tofNSigmaPi() * candidate.tofNSigmaPi() < nsigmaCutCombinedPion * nsigmaCutCombinedPion)) { + tofPIDPassed = true; + } + } else { + tofPIDPassed = true; + } + if (tpcPIDPassed && tofPIDPassed) { + return true; + } + return false; + } + + template + void fillHistograms(const CollisionType& collision, const TracksType& dTracks, const V0sType& dV0s) + { + // auto multiplicity = collision.cent(); + auto multiplicity = collision.cent(); + histos.fill(HIST("QAbefore/collMult"), multiplicity); + TLorentzVector lDecayDaughter, lDecayV0, lResonance; + + bool IsV0Processed = false; + bool IsV0QAFilled = false; + + for (auto& trk : dTracks) { + // Full index policy is needed to consider all possible combinations + //// Initialize variables + // trk: Pion, v0: K0s + + auto trkId = trk.index(); + auto trkptPi = trk.pt(); + + // DCA QA (before cuts) + histos.fill(HIST("QAbefore/trkDCAxy_pi"), trk.dcaXY()); + histos.fill(HIST("QAbefore/trkDCAz_pi"), trk.dcaZ()); + // pT QA (before cuts) + histos.fill(HIST("QAbefore/trkpT_pi"), trkptPi); + + // apply the track cut + if (!trackCut(trk) || !selectionPIDPrimaryPion(trk)) + continue; + + // DCA QA (QAafter cuts) + histos.fill(HIST("QAafter/trkDCAxy_pi"), trk.dcaXY()); + histos.fill(HIST("QAafter/trkDCAz_pi"), trk.dcaZ()); + // pT QA (after cuts) + histos.fill(HIST("QAafter/trkpT_pi"), trk.pt()); + + for (auto& v0 : dV0s) { + // Full index policy is needed to consider all possible combinations + if (v0.indices()[0] == trkId || v0.indices()[1] == trkId) + continue; // To avoid comibining secondary and primary pions + //// Initialize variables + // trk: Pion, v0: K0s + + auto v0ptK0s = v0.pt(); + + if (!IsV0QAFilled) { + // pT QA (before cuts) + histos.fill(HIST("QAbefore/trkpT_k0s"), v0ptK0s); + } + + // apply the track cut + if (!V0Cut(v0)) + continue; + + if (!IsV0QAFilled) { + // pt QA (after cuts) + histos.fill(HIST("QAafter/trkpT_k0s"), v0.pt()); + } + + lDecayDaughter.SetXYZM(trk.px(), trk.py(), trk.pz(), massPi); + lDecayV0.SetXYZM(v0.px(), v0.py(), v0.pz(), massK0); + lResonance = lDecayDaughter + lDecayV0; + // Filling invariant mass histograms + // K0s mass QA (after cuts) + histos.fill(HIST("QAafter/k0shortmass"), lDecayV0.M()); + // K*(892)pm mass + histos.fill(HIST("k892pminvmass"), lResonance.M()); + IsV0Processed = true; + } + if (IsV0Processed) { + IsV0QAFilled = true; + } + } + } + + void processDataLight(aod::ResoCollision& collision, + aod::ResoTracks const& resotracks, + aod::ResoV0s const& resov0s) + { + // LOG(info) << "new collision, zvtx: " << collision.posZ(); + fillHistograms(collision, resotracks, resov0s); + } + PROCESS_SWITCH(k892pmanalysis, processDataLight, "Process Event for data", false); + + /*void processMCLight(aod::ResoCollision& collision, + soa::Join const& resotracks) + { + fillHistograms(collision, resotracks, resotracks); + } + PROCESS_SWITCH(k892pmanalysis, processMCLight, "Process Event for MC", false);*/ + + void processMCTrue(aod::ResoMCParents& resoParents) + { + for (auto& part : resoParents) { // loop over all pre-filtered MC particles + if (abs(part.pdgCode()) != 323) // K*892(pm) + continue; + if (abs(part.y()) > 0.5) { // rapidity cut + continue; + } + bool pass1 = false; + bool pass2 = false; + if (abs(part.daughterPDG1()) == 211 || abs(part.daughterPDG2()) == 310) { // At least one decay to K0s + pass1 = true; + } + if (abs(part.daughterPDG1()) == 310 || abs(part.daughterPDG2()) == 211) { // At least one decay to K0s + pass2 = true; + } + if (!pass1 || !pass2) // If we have both decay products + continue; + if (part.pdgCode() > 0) + histos.fill(HIST("k892pmGen"), part.pt()); + else + histos.fill(HIST("k892pmGenAnti"), part.pt()); + } + } + PROCESS_SWITCH(k892pmanalysis, processMCTrue, "Process Event for MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"lf-k892pmanalysis"})}; +} From 1d54d0e29c034c5f1a01fce3632e107e0180931e Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Tue, 12 Dec 2023 18:41:32 +0100 Subject: [PATCH 043/156] [PWGLF] Additional V0 Cascades information in the Resonance Table (#4146) * Add more information for analysis * Please consider the following formatting changes * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot --- PWGLF/DataModel/LFResonanceTables.h | 48 +++++++++++-------- .../TableProducer/LFResonanceInitializer.cxx | 18 ++++++- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index b321c8ff9a0..5fef3be9aa6 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -23,6 +23,7 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/Core/RecoDecay.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Framework/AnalysisDataModel.h" @@ -31,10 +32,10 @@ namespace o2::aod /// Resonance Collisions namespace resocollision { -DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality (Multiplicity) percentile (Default: FT0M) -DECLARE_SOA_COLUMN(Mult, mult, int); //! FT0 multiplicity -DECLARE_SOA_COLUMN(Spherocity, spherocity, float); //! Spherocity of the event -DECLARE_SOA_COLUMN(BMagField, bMagField, float); //! Magnetic field +DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality (Multiplicity) percentile (Default: FT0M) +DECLARE_SOA_COLUMN(Mult, mult, int); //! FT0 multiplicity +DECLARE_SOA_COLUMN(Spherocity, spherocity, float); //! Spherocity of the event +DECLARE_SOA_COLUMN(BMagField, bMagField, float); //! Magnetic field } // namespace resocollision DECLARE_SOA_TABLE(ResoCollisions, "AOD", "RESOCOL", o2::soa::Index<>, @@ -54,21 +55,21 @@ namespace resodaughter { DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); -DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) -DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c) -DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c) -DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c) -DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta -DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi -DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType -DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) -DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations -DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge -DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows -DECLARE_SOA_COLUMN(IsGlobalTrackWoDCA, isGlobalTrackWoDCA, bool); //! Is global track without DCA -DECLARE_SOA_COLUMN(IsPrimaryTrack, isPrimaryTrack, bool); //! Is primary track -DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! Is primary vertex contributor -DECLARE_SOA_COLUMN(HasTOF, hasTOF, bool); //! Has TOF +DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) +DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c) +DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c) +DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi +DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType +DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) +DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge +DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(IsGlobalTrackWoDCA, isGlobalTrackWoDCA, bool); //! Is global track without DCA +DECLARE_SOA_COLUMN(IsPrimaryTrack, isPrimaryTrack, bool); //! Is primary track +DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! Is primary vertex contributor +DECLARE_SOA_COLUMN(HasTOF, hasTOF, bool); //! Has TOF DECLARE_SOA_COLUMN(TPCCrossedRowsOverFindableCls, tpcCrossedRowsOverFindableCls, float); DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters DECLARE_SOA_COLUMN(CascDaughDCA, cascdaughDCA, float); //! DCA between daughters from cascade @@ -142,6 +143,9 @@ DECLARE_SOA_TABLE(ResoV0s, "AOD", "RESOV0S", resodaughter::Indices, resodaughter::V0CosPA, resodaughter::DaughDCA, + v0data::DCAPosToPV, + v0data::DCANegToPV, + v0data::DCAV0ToPV, resodaughter::MLambda, resodaughter::MAntiLambda, resodaughter::MK0Short, @@ -165,6 +169,12 @@ DECLARE_SOA_TABLE(ResoCascades, "AOD", "RESOCASCADES", resodaughter::CascCosPA, resodaughter::DaughDCA, resodaughter::CascDaughDCA, + cascdata::DCAPosToPV, + cascdata::DCANegToPV, + cascdata::DCABachToPV, + v0data::DCAV0ToPV, + cascdata::DCAXYCascToPV, + cascdata::DCAZCascToPV, resodaughter::MXi, resodaughter::TransRadius, resodaughter::CascTransRadius, diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index d313b748f3a..07a5d67a64a 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -472,7 +472,13 @@ struct reso2initializer { v0.phi(), childIDs, v0.v0cosPA(), - v0.dcaV0daughters(), v0.mLambda(), v0.mAntiLambda(), v0.mK0Short(), + v0.dcaV0daughters(), + v0.dcapostopv(), + v0.dcanegtopv(), + v0.dcav0topv(), + v0.mLambda(), + v0.mAntiLambda(), + v0.mK0Short(), v0.v0radius(), v0.x(), v0.y(), v0.z()); if constexpr (isMC) { fillMCV0(v0); @@ -500,7 +506,15 @@ struct reso2initializer { childIDs, casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()), - casc.dcaV0daughters(), casc.dcacascdaughters(), casc.mXi(), + casc.dcaV0daughters(), + casc.dcacascdaughters(), + casc.dcapostopv(), + casc.dcanegtopv(), + casc.dcabachtopv(), + casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()), + casc.dcaXYCascToPV(), + casc.dcaZCascToPV(), + casc.mXi(), casc.v0radius(), casc.cascradius(), casc.x(), casc.y(), casc.z()); if constexpr (isMC) { fillMCCascade(casc); From 5eb1ba1bd4360f3334bd8b39634c98ba371a38a0 Mon Sep 17 00:00:00 2001 From: feisenhu <53603353+feisenhu@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:58:33 +0100 Subject: [PATCH 044/156] PWGEM: Add new cut for trigger study (#4144) --- PWGDQ/Core/CutsLibrary.cxx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 2188aa916f7..0b84c67cd24 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -1583,6 +1583,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare(Form("lmee_skimmingtesta_TOF%s", vecPIDcase.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("lmeeStandardKine")); + cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + + AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + cut_tof_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data()))); + + cut->AddCut(cut_tof_nSigma); + return cut; + } + // some older cuts if (!nameStr.compare(Form("lmee_pp502TeV_PID%s", vecPIDcase.at(icase).Data()))) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); @@ -4026,6 +4038,11 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("pairLMeeIMR")) { + cut->AddCut(VarManager::kMass, 1., 2.); + return cut; + } + if (!nameStr.compare("pairJpsi")) { cut->AddCut(VarManager::kMass, 2.8, 3.3); return cut; From 8f91637114cfb13ab3cd0a246da438ba7334155c Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Wed, 13 Dec 2023 08:11:20 +0100 Subject: [PATCH 045/156] Add V0 converter (#4138) * Add V0 converter * Please consider the following formatting changes (#200) --------- Co-authored-by: ALICE Builder --- Common/TableProducer/CMakeLists.txt | 5 ++++ Common/TableProducer/v0converter.cxx | 36 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 Common/TableProducer/v0converter.cxx diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index ab25105274f..886951f21d0 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -51,6 +51,11 @@ o2physics_add_dpl_workflow(weak-decay-indices PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(v0converter + SOURCES v0converter.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(ft0-corrected-table SOURCES ft0CorrectedTable.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/Common/TableProducer/v0converter.cxx b/Common/TableProducer/v0converter.cxx new file mode 100644 index 00000000000..671c592bd9b --- /dev/null +++ b/Common/TableProducer/v0converter.cxx @@ -0,0 +1,36 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" + +using namespace o2; +using namespace o2::framework; + +// Converts V0 version 001 to 002 + +struct V0Converter { + Produces v0s_002; + + void process(aod::V0s_001 const& v0s) + { + for (auto& v0 : v0s) { + uint8_t bitMask = static_cast(255); + v0s_002(v0.posTrack().collisionId(), v0.posTrackId(), v0.negTrackId(), bitMask); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} From c9c16ec683a0137122a16068010d42e94b3372cd Mon Sep 17 00:00:00 2001 From: eloviyo <38348689+Eloviyo@users.noreply.github.com> Date: Wed, 13 Dec 2023 08:52:37 +0100 Subject: [PATCH 046/156] commented out debug print option (#4147) * commented out debug print option * fixed formatting issue --------- Co-authored-by: Shirajum Monira --- PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 26b889e34f5..22ee91cca79 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -454,7 +454,7 @@ struct femtoUniverseProducerTask { -999., -999., -999., -999.); // QA for phi or D0/D0bar } else { - LOGF(info, "isTrack0orV0: %d, isPhi: %d", isTrackOrV0, isPhiOrD0); + // LOGF(info, "isTrack0orV0: %d, isPhi: %d", isTrackOrV0, isPhiOrD0); outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., From fae15ece36f662341b94727d50ce30aa299873e8 Mon Sep 17 00:00:00 2001 From: hhesouno <119694396+hhesouno@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:25:28 +0100 Subject: [PATCH 047/156] Adding selections (#4149) --- PWGMM/Mult/Tasks/multiplicityPbPb.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/PWGMM/Mult/Tasks/multiplicityPbPb.cxx b/PWGMM/Mult/Tasks/multiplicityPbPb.cxx index c5450c1c268..624a6d575ff 100644 --- a/PWGMM/Mult/Tasks/multiplicityPbPb.cxx +++ b/PWGMM/Mult/Tasks/multiplicityPbPb.cxx @@ -21,6 +21,8 @@ #include "ReconstructionDataFormats/GlobalTrackID.h" +#include "Common/DataModel/EventSelection.h" + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -88,8 +90,12 @@ struct multiplicityPbPb { } // void process(aod::Collision const& collision, soa::Filtered const& tracks, aod::McParticles const&) - void process(aod::Collision const& collision, soa::Filtered const& tracks) + void process(soa::Join::iterator const& collision, soa::Filtered const& tracks) { + if (!collision.sel8()) { + return; + } + int trackCounter = 0; // auto groupedTracks = tracks.sliceBy(perCollision, collision.globalIndex()); From 2cafe0e9733b50f76992713103a6360c00f3e69b Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Wed, 13 Dec 2023 12:02:25 +0100 Subject: [PATCH 048/156] Change default V0Type to standard V0 (#4151) * Change default V0Type to standard V0 @shahor02 * Update v0converter.cxx * Update v0converter.cxx * Update v0converter.cxx --- Common/TableProducer/v0converter.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/TableProducer/v0converter.cxx b/Common/TableProducer/v0converter.cxx index 671c592bd9b..f83e7428e5c 100644 --- a/Common/TableProducer/v0converter.cxx +++ b/Common/TableProducer/v0converter.cxx @@ -23,7 +23,7 @@ struct V0Converter { void process(aod::V0s_001 const& v0s) { for (auto& v0 : v0s) { - uint8_t bitMask = static_cast(255); + uint8_t bitMask = static_cast(1); // first bit on v0s_002(v0.posTrack().collisionId(), v0.posTrackId(), v0.negTrackId(), bitMask); } } From f11d38f002935acab00f6a89f71bd37f30141966 Mon Sep 17 00:00:00 2001 From: Fabrizio Chinu <91954233+fchinu@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:29:20 +0100 Subject: [PATCH 049/156] PWGHF: Fix delta mass (phi,KK) selection in track skimming (#4152) --- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 4a6d3d11ecc..21a54bcd699 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -1587,7 +1587,7 @@ struct HfTrackIndexSkimCreator { } } if (TESTBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 1)) { - double massPhiPiKK = RecoDecay::m(std::array{pVecTrack1, pVecTrack2}, std::array{arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][0][1], arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][0][2]}); + double massPhiPiKK = RecoDecay::m(std::array{pVecTrack1, pVecTrack2}, std::array{arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][1][1], arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][1][2]}); if (std::abs(massPhiPiKK - massPhi) > cut3Prong[hf_cand_3prong::DecayType::DsToKKPi].get(pTBin, deltaMassPhiIndex)) { CLRBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 1); } From 139c7ce84e0e3eb0aeca6994c115b7887f1c6dcb Mon Sep 17 00:00:00 2001 From: Alexandre BIGOT <77975111+AlexBigO@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:01:32 +0100 Subject: [PATCH 050/156] Fix bug in DplusPi creator (#4153) Co-authored-by: Alexandre Bigot --- PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx index b22f294688c..4f22e9f5450 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx @@ -538,7 +538,7 @@ struct HfDataCreatorDplusPiReduced { auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsD.sliceBy(candsDPerCollisionWithMl, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsD, trackIndices, tracks, particlesMc, bcs); + runDataCreation(collision, candsDThisColl, trackIdsThisCollision, tracks, particlesMc, bcs); } runMcGen(particlesMc); } From 6470591025445cbe6b93bb8f4f0e3b88b9434030 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Wed, 13 Dec 2023 14:33:07 +0100 Subject: [PATCH 051/156] Switch table producers that produce V0s to produce V0s_001 temporarily (#4156) * lambdakzerofinder.cxx -> temporarily produce V0s_001 * lambdakzeromcfinder.cxx -> temporarily produce V0s_001 --- PWGLF/TableProducer/lambdakzerofinder.cxx | 2 +- PWGLF/TableProducer/lambdakzeromcfinder.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/TableProducer/lambdakzerofinder.cxx b/PWGLF/TableProducer/lambdakzerofinder.cxx index 451f32f9168..08becfdc176 100644 --- a/PWGLF/TableProducer/lambdakzerofinder.cxx +++ b/PWGLF/TableProducer/lambdakzerofinder.cxx @@ -125,7 +125,7 @@ struct lambdakzerofinder { Produces v0indices; Produces v0cores; Produces v0trackXs; - Produces v0; + Produces v0; Produces v0datalink; Service ccdb; diff --git a/PWGLF/TableProducer/lambdakzeromcfinder.cxx b/PWGLF/TableProducer/lambdakzeromcfinder.cxx index 9cb691e897e..12da54eed8d 100644 --- a/PWGLF/TableProducer/lambdakzeromcfinder.cxx +++ b/PWGLF/TableProducer/lambdakzeromcfinder.cxx @@ -66,7 +66,7 @@ using namespace ROOT::Math; using LabeledTracks = soa::Join; struct lambdakzeromcfinder { - Produces v0; + Produces v0; Produces fullv0labels; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; From e8efdf1d6455b17f6f0965b7bea76d9b20b6a2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Wed, 13 Dec 2023 15:50:49 +0100 Subject: [PATCH 052/156] Add min dca cut (#4157) * Add min dca cut --- DPG/Tasks/AOTTrack/qaEfficiency.cxx | 194 +++++++++++++++++++--------- 1 file changed, 130 insertions(+), 64 deletions(-) diff --git a/DPG/Tasks/AOTTrack/qaEfficiency.cxx b/DPG/Tasks/AOTTrack/qaEfficiency.cxx index 06780878400..026b74a3d8c 100644 --- a/DPG/Tasks/AOTTrack/qaEfficiency.cxx +++ b/DPG/Tasks/AOTTrack/qaEfficiency.cxx @@ -35,6 +35,29 @@ using namespace o2::framework; +static constexpr int trkCutIdxTrkRead = 1; +static constexpr int trkCutIdxHasMcPart = 2; +static constexpr int trkCutIdxPassedPt = 3; +static constexpr int trkCutIdxPassedEta = 4; +static constexpr int trkCutIdxPassedPhi = 5; +static constexpr int trkCutIdxPassedY = 6; +static constexpr int trkCutIdxPassedFake = 7; +static constexpr int trkCutIdxHasCollision = 8; +static constexpr int trkCutIdxPassedTrkType = 9; +static constexpr int trkCutIdxPassedPtRange = 10; +static constexpr int trkCutIdxPassedEtaRange = 11; +static constexpr int trkCutIdxPassedDcaXYMax = 12; +static constexpr int trkCutIdxPassedDcaXYMin = 13; +static constexpr int trkCutIdxPassedDcaZMax = 14; +static constexpr int trkCutIdxPassedDcaZMin = 15; +static constexpr int trkCutIdxPassedGoldenChi2 = 16; +static constexpr int trkCutIdxPassedIsPvCont = 17; +static constexpr int trkCutIdxPassedITSPartial = 18; +static constexpr int trkCutIdxPassedTPCPartial = 19; +static constexpr int trkCutIdxPassedTOFPartial = 20; +static constexpr int trkCutIdxPassedGlobal = 21; +static constexpr int trkCutIdxN = 22; + struct QaEfficiency { // Particle information static constexpr int nSpecies = o2::track::PID::NIDs; // One per PDG @@ -87,7 +110,9 @@ struct QaEfficiency { Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 4.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; + Configurable minDcaXY{"minDcaXY", -1.f, "Additional cut on the minimum value of the DCA xy"}; Configurable maxDcaZ{"maxDcaZ", 2.f, "Additional cut on the maximum value of the DCA z"}; + Configurable minDcaZ{"minDcaZ", -2.f, "Additional cut on the minimum value of the DCA z"}; Configurable minTPCNClsFound{"minTPCNClsFound", 0.f, "Additional cut on the minimum value of the number of found clusters in the TPC"}; OutputObj listEfficiencyMC{"EfficiencyMC"}; @@ -691,52 +716,54 @@ struct QaEfficiency { } auto h = histos.add("MC/trackSelection", "Track Selection", kTH1F, {axisSel}); - h->GetXaxis()->SetBinLabel(1, "Tracks read"); - h->GetXaxis()->SetBinLabel(2, "Passed has MC part."); - h->GetXaxis()->SetBinLabel(3, "Passed #it{p}_{T}"); - h->GetXaxis()->SetBinLabel(4, "Passed #it{#eta}"); - h->GetXaxis()->SetBinLabel(5, "Passed #it{#varphi}"); - h->GetXaxis()->SetBinLabel(6, "Passed y"); - h->GetXaxis()->SetBinLabel(7, "Passed Fake"); - h->GetXaxis()->SetBinLabel(8, "Passed has collision"); - h->GetXaxis()->SetBinLabel(9, "passedTrackType"); - h->GetXaxis()->SetBinLabel(10, "passedPtRange"); - h->GetXaxis()->SetBinLabel(11, "passedEtaRange"); - h->GetXaxis()->SetBinLabel(12, "passedDCAxy"); - h->GetXaxis()->SetBinLabel(13, "passedDCAz"); - h->GetXaxis()->SetBinLabel(14, "passedGoldenChi2"); - h->GetXaxis()->SetBinLabel(15, "passed isPVContributor"); - h->GetXaxis()->SetBinLabel(16, "passedITS (partial)"); - h->GetXaxis()->SetBinLabel(17, "passedTPC (partial)"); - h->GetXaxis()->SetBinLabel(18, "passedTOF (partial)"); + h->GetXaxis()->SetBinLabel(trkCutIdxTrkRead, "Tracks read"); + h->GetXaxis()->SetBinLabel(trkCutIdxHasMcPart, "Passed has MC part."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedPt, "Passed #it{p}_{T}"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedEta, "Passed #it{#eta}"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedPhi, "Passed #it{#varphi}"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedY, "Passed y"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedFake, "Passed Fake"); + h->GetXaxis()->SetBinLabel(trkCutIdxHasCollision, "Passed has collision"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedTrkType, "passedTrackType"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedPtRange, "passedPtRange"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedEtaRange, "passedEtaRange"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaXYMax, "passedDCAxy max."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaXYMin, "passedDCAxy min."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaZMax, "passedDCAz max."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaZMin, "passedDCAz min."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGoldenChi2, "passedGoldenChi2"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedIsPvCont, "passed isPVContributor"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedITSPartial, "passedITS (partial)"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedTPCPartial, "passedTPC (partial)"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedTOFPartial, "passedTOF (partial)"); switch (globalTrackSelection) { case 0: - h->GetXaxis()->SetBinLabel(19, "No extra selection"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "No extra selection"); break; case 1: - h->GetXaxis()->SetBinLabel(19, "isGlobalTrack"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isGlobalTrack"); break; case 2: - h->GetXaxis()->SetBinLabel(19, "isGlobalTrackWoPtEta"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isGlobalTrackWoPtEta"); break; case 3: - h->GetXaxis()->SetBinLabel(19, "isGlobalTrackWoDCA"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isGlobalTrackWoDCA"); break; case 4: - h->GetXaxis()->SetBinLabel(19, "isQualityTrack"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isQualityTrack"); break; case 5: - h->GetXaxis()->SetBinLabel(19, "isInAcceptanceTrack"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isInAcceptanceTrack"); break; case 6: - h->GetXaxis()->SetBinLabel(19, "customTrackSelection"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "customTrackSelection"); break; default: LOG(fatal) << "Can't interpret track asked selection " << globalTrackSelection; } for (int i = 0; i < nSpecies; i++) { - h->GetXaxis()->SetBinLabel(19 + i, Form("Passed PDG %i %s", PDGs[i], particleTitle[i])); + h->GetXaxis()->SetBinLabel(trkCutIdxN + i, Form("Passed PDG %i %s", PDGs[i], particleTitle[i])); } histos.add("MC/fakeTrackNoiseHits", "Fake tracks from noise hits", kTH1F, {{1, 0, 1}}); @@ -797,25 +824,51 @@ struct QaEfficiency { } auto h = histos.add("Data/trackSelection", "Track Selection", kTH1F, {axisSel}); - h->GetXaxis()->SetBinLabel(1, "Tracks read"); - h->GetXaxis()->SetBinLabel(2, ""); - h->GetXaxis()->SetBinLabel(3, "Passed #it{p}_{T}"); - h->GetXaxis()->SetBinLabel(4, "Passed #it{#eta}"); - h->GetXaxis()->SetBinLabel(5, "Passed #it{#varphi}"); - h->GetXaxis()->SetBinLabel(6, ""); - h->GetXaxis()->SetBinLabel(7, ""); - h->GetXaxis()->SetBinLabel(8, "Passed has collision"); - h->GetXaxis()->SetBinLabel(9, "passedTrackType"); - h->GetXaxis()->SetBinLabel(10, "passedPtRange"); - h->GetXaxis()->SetBinLabel(11, "passedEtaRange"); - h->GetXaxis()->SetBinLabel(12, "passedDCAxy"); - h->GetXaxis()->SetBinLabel(13, "passedDCAz"); - h->GetXaxis()->SetBinLabel(14, "passedGoldenChi2"); - h->GetXaxis()->SetBinLabel(15, "passed isPVContributor"); - h->GetXaxis()->SetBinLabel(16, "passedITS (partial)"); - h->GetXaxis()->SetBinLabel(17, "passedTPC (partial)"); - h->GetXaxis()->SetBinLabel(18, "passedTOF (partial)"); - h->GetXaxis()->SetBinLabel(19, "Passed globalCut"); + h->GetXaxis()->SetBinLabel(trkCutIdxTrkRead, "Tracks read"); + h->GetXaxis()->SetBinLabel(trkCutIdxHasMcPart, ""); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedPt, "Passed #it{p}_{T}"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedEta, "Passed #it{#eta}"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedPhi, "Passed #it{#varphi}"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedY, ""); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedFake, ""); + h->GetXaxis()->SetBinLabel(trkCutIdxHasCollision, "Passed has collision"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedTrkType, "passedTrackType"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedPtRange, "passedPtRange"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedEtaRange, "passedEtaRange"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaXYMax, "passedDCAxy max."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaXYMin, "passedDCAxy min."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaZMax, "passedDCAz max."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedDcaZMin, "passedDCAz min."); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGoldenChi2, "passedGoldenChi2"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedIsPvCont, "passed isPVContributor"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedITSPartial, "passedITS (partial)"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedTPCPartial, "passedTPC (partial)"); + h->GetXaxis()->SetBinLabel(trkCutIdxPassedTOFPartial, "passedTOF (partial)"); + switch (globalTrackSelection) { + case 0: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "No extra selection"); + break; + case 1: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isGlobalTrack"); + break; + case 2: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isGlobalTrackWoPtEta"); + break; + case 3: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isGlobalTrackWoDCA"); + break; + case 4: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isQualityTrack"); + break; + case 5: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "isInAcceptanceTrack"); + break; + case 6: + h->GetXaxis()->SetBinLabel(trkCutIdxPassedGlobal, "customTrackSelection"); + break; + default: + LOG(fatal) << "Can't interpret track asked selection " << globalTrackSelection; + } const TString tagPt = Form("#it{#eta} [%.2f,%.2f] #it{#varphi} [%.2f,%.2f]", etaMin, etaMax, @@ -1092,7 +1145,7 @@ struct QaEfficiency { return; } - histos.fill(HIST("MC/trackSelection"), 19 + id); + histos.fill(HIST("MC/trackSelection"), trkCutIdxN + id); if (passedITS) { h->fill(HIST(hPtIts[histogramIndex]), mcParticle.pt()); @@ -1442,7 +1495,7 @@ struct QaEfficiency { passedTOF = false; if constexpr (doFillHisto) { - histos.fill(countingHisto, 1); // Read tracks + histos.fill(countingHisto, trkCutIdxTrkRead); // Read tracks } if constexpr (isMC) { // MC only @@ -1451,10 +1504,10 @@ struct QaEfficiency { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 2); // Tracks with particles (i.e. no fakes) + histos.fill(countingHisto, trkCutIdxHasMcPart); // Tracks with particles (i.e. no fakes) } const auto mcParticle = track.mcParticle(); - if (!isInAcceptance(mcParticle, countingHisto, 2)) { + if (!isInAcceptance(mcParticle, countingHisto, trkCutIdxHasMcPart)) { // 3: pt cut 4: eta cut 5: phi cut 6: y cut return false; } @@ -1472,10 +1525,11 @@ struct QaEfficiency { } } if constexpr (doFillHisto) { - histos.fill(countingHisto, 7); + histos.fill(countingHisto, trkCutIdxPassedFake); } } else { // Data only - if (!isInAcceptance(track, countingHisto, 2)) { + if (!isInAcceptance(track, countingHisto, trkCutIdxHasMcPart)) { + // 3: pt cut 4: eta cut 5: phi cut 6: y cut return false; } } @@ -1484,7 +1538,7 @@ struct QaEfficiency { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 8); + histos.fill(countingHisto, trkCutIdxHasCollision); } if (trackSelection) { // Check general cuts @@ -1492,43 +1546,55 @@ struct QaEfficiency { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 9); + histos.fill(countingHisto, trkCutIdxPassedTrkType); } if (!track.passedPtRange()) { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 10); + histos.fill(countingHisto, trkCutIdxPassedPtRange); } if (!track.passedEtaRange()) { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 11); + histos.fill(countingHisto, trkCutIdxPassedEtaRange); } if (!track.passedDCAxy()) { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 12); + histos.fill(countingHisto, trkCutIdxPassedDcaXYMax); + } + if (std::abs(track.dcaXY()) < minDcaXY) { + return false; + } + if constexpr (doFillHisto) { + histos.fill(countingHisto, trkCutIdxPassedDcaXYMin); } if (!track.passedDCAz()) { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 13); + histos.fill(countingHisto, trkCutIdxPassedDcaZMax); + } + if (std::abs(track.passedDCAz()) < minDcaZ) { + return false; + } + if constexpr (doFillHisto) { + histos.fill(countingHisto, trkCutIdxPassedDcaZMin); } if (!track.passedGoldenChi2()) { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 14); + histos.fill(countingHisto, trkCutIdxPassedGoldenChi2); } if (doPVContributorCut && !track.isPVContributor()) { return false; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 15); + histos.fill(countingHisto, trkCutIdxPassedIsPvCont); } passedITS = track.passedITSNCls() && @@ -1554,19 +1620,19 @@ struct QaEfficiency { if (passedITS) { // Partial if constexpr (doFillHisto) { - histos.fill(countingHisto, 16); + histos.fill(countingHisto, trkCutIdxPassedITSPartial); } } if (passedTPC) { // Partial if constexpr (doFillHisto) { - histos.fill(countingHisto, 17); + histos.fill(countingHisto, trkCutIdxPassedTPCPartial); } } if (passedTOF) { // Partial if constexpr (doFillHisto) { - histos.fill(countingHisto, 18); + histos.fill(countingHisto, trkCutIdxPassedTOFPartial); } } @@ -1589,7 +1655,7 @@ struct QaEfficiency { LOG(fatal) << "Can't interpret track asked selection " << globalTrackSelection; } if constexpr (doFillHisto) { - histos.fill(countingHisto, 19); + histos.fill(countingHisto, trkCutIdxPassedGlobal); } return false; @@ -1879,4 +1945,4 @@ struct QaEfficiency { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} \ No newline at end of file +} From e36fba5ef5c419ad0b848ce647cb4d58b534cb26 Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:12:27 +0100 Subject: [PATCH 053/156] Separating the collision counter to the J/psi-D0 task (#4158) Co-authored-by: Lucamicheletti93 --- PWGDQ/Tasks/taskJpsiHf.cxx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/PWGDQ/Tasks/taskJpsiHf.cxx b/PWGDQ/Tasks/taskJpsiHf.cxx index 8514b3410b0..a98411ee7a6 100644 --- a/PWGDQ/Tasks/taskJpsiHf.cxx +++ b/PWGDQ/Tasks/taskJpsiHf.cxx @@ -132,18 +132,23 @@ struct taskJPsiHf { } } - void processRedJspiD0(RedJpDmColCounts const& normCounters, MyRedEvents const& events, MyRedPairCandidatesSelected const& dileptons, MyRedD0CandidatesSelected const& dmesons) + void processRedJspiD0(MyRedEvents::iterator const& event, MyRedPairCandidatesSelected const& dileptons, MyRedD0CandidatesSelected const& dmesons) { + // Fill the column of collisions with pairs + hCollisions->Fill(1.f); + runDileptonDmeson(event, dileptons, dmesons); + } + + void processNormCounter(RedJpDmColCounts const& normCounters) + { + // Fill the column with all collisions for (const auto& normCounter : normCounters) { hCollisions->Fill(0.f, static_cast(normCounter.numColls())); } - for (const auto& event : events) { - hCollisions->Fill(1.f); - runDileptonDmeson(event, dileptons, dmesons); - } } PROCESS_SWITCH(taskJPsiHf, processRedJspiD0, "Process J/psi - D0", true); + PROCESS_SWITCH(taskJPsiHf, processNormCounter, "Process normalization counter", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From e573e0c5e71a8664dd6cff59c7a4c1c13f1a3f08 Mon Sep 17 00:00:00 2001 From: feisenhu <53603353+feisenhu@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:13:49 +0100 Subject: [PATCH 054/156] PWGEM: Add additional pair cut for IMR (#4150) * PWGEM: Add new cut for trigger study * PWGEM: add second cut with pairMass intervall, rename cut --- PWGDQ/Core/CutsLibrary.cxx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 0b84c67cd24..80fe27d6e63 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -2011,6 +2011,16 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("pairMass1to2")) { + cut->AddCut(GetAnalysisCut("pairMass1to2")); + return cut; + } + + if (!nameStr.compare("pairMassIMR")) { + cut->AddCut(GetAnalysisCut("pairMassIMR")); + return cut; + } + if (!nameStr.compare("pairDalitz1")) { cut->AddCut(GetAnalysisCut("pairDalitz1")); return cut; @@ -4038,11 +4048,16 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pairLMeeIMR")) { + if (!nameStr.compare("pairMass1to2")) { cut->AddCut(VarManager::kMass, 1., 2.); return cut; } + if (!nameStr.compare("pairMassIMR")) { + cut->AddCut(VarManager::kMass, 1.1, 2.7); + return cut; + } + if (!nameStr.compare("pairJpsi")) { cut->AddCut(VarManager::kMass, 2.8, 3.3); return cut; From 9e25ec3b344892feeb30edfd491d89b9a9dc1793 Mon Sep 17 00:00:00 2001 From: Yash Patley <52608802+yashpatley@users.noreply.github.com> Date: Wed, 13 Dec 2023 21:04:00 +0530 Subject: [PATCH 055/156] PWGLF: Update lambda1520SpherocityAnalysis.cxx (#4159) --- PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx | 156 +++++++++++-------- 1 file changed, 94 insertions(+), 62 deletions(-) diff --git a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx index 4535d908a24..fbc9118c01d 100644 --- a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx +++ b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx @@ -60,17 +60,19 @@ struct lambdaAnalysis { Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection Configurable cUseTpcAndTof{"cUseTpcAndTof", true, "Use TPC and TOF PID selection"}; // TPC And TOF tracks Configurable cUseTpcOnly{"cUseTpcOnly", false, "Use TPC Only tracks (No TOF Veto)"}; // TPC only selection + Configurable cRejNsigma{"cRejNsigma", 3.0, "Reject tracks to improve purity of PID"}; + Configurable cMaxPtpc{"cMaxPtpc", 1.8, "Maximum p for tracks without TOF"}; // Proton Configurable cMaxTPCnSigmaProton{"cMaxTPCnSigmaProton", 3.0, "TPC nSigma cut for Proton"}; // TPC Configurable cMaxTOFnSigmaProton{"cMaxTOFnSigmaProton", 3.0, "TOF nSigma cut for Proton"}; // TOF Configurable nsigmaCutCombinedProton{"nsigmaCutCombinedProton", 3.0, "Combined nSigma cut for Proton"}; // Combined - Configurable> protonTPCPIDpt{"protonTPCPIDpt", {0, 0.5, 0.7, 0.8}, "pT dependent TPC cuts protons"}; + Configurable> protonTPCPIDp{"protonTPCPIDp", {0, 0.5, 0.7, 0.8}, "p dependent TPC cuts protons"}; Configurable> protonTPCPIDcut{"protonTPCPIDcut", {5., 3.5, 2.5}, "TPC nsigma cuts protons"}; // Kaon Configurable cMaxTPCnSigmaKaon{"cMaxTPCnSigmaKaon", 3.0, "TPC nSigma cut for Kaon"}; // TPC Configurable cMaxTOFnSigmaKaon{"cMaxTOFnSigmaKaon", 3.0, "TOF nSigma cut for Kaon"}; // TOF Configurable nsigmaCutCombinedKaon{"nsigmaCutCombinedKaon", 3.0, "Combined nSigma cut for Kaon"}; // Combined - Configurable> kaonTPCPIDpt{"kaonTPCPIDpt", {0., 0.25, 0.3, 0.45}, "pT dependent TPC cuts kaons"}; + Configurable> kaonTPCPIDp{"kaonTPCPIDp", {0., 0.25, 0.3, 0.45}, "pT dependent TPC cuts kaons"}; Configurable> kaonTPCPIDcut{"kaonTPCPIDcut", {6, 3.5, 2.5}, "TPC nsigma cuts kaons"}; // Event Mixing. Configurable doSphMix{"doSphMix", true, "Include Sph Bins to be mixed"}; @@ -88,7 +90,7 @@ struct lambdaAnalysis { // Define Axis. const AxisSpec axisSp(nBinsSp, 0., 1., "S_{0}"); const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); - const AxisSpec axisPtQA(100, 0., 2., "p_{T} (GeV/c)"); + const AxisSpec axisP_pid(400, 0., 4., "p (GeV/c)"); const AxisSpec axisPt(nBinsPt, 0., 10., "p_{T} (GeV/c)"); const AxisSpec axisEta(40, -1, 1, "#eta"); const AxisSpec axisDCAz(500, -0.5, 0.5, {"DCA_{z} (cm)"}); @@ -105,29 +107,29 @@ struct lambdaAnalysis { histos.add("Event/hSpCent", "Spherocity vs FT0M(%)", kTH2F, {axisCent, axisSp}); // QA Before - histos.add("QAbefore/Proton/hTPCNsigma", "n#sigma^{TPC} Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAbefore/Proton/hTOFNsigma", "n#sigma^{TOF} Protons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAbefore/Proton/hTPCNsigma", "n#sigma^{TPC} Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAbefore/Proton/hTOFNsigma", "n#sigma^{TOF} Protons", kTH2F, {axisP_pid, axisTOFNsigma}); histos.add("QAbefore/Proton/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); - histos.add("QAbefore/Kaon/hTPCNsigma", "n#sigma^{TPC} Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAbefore/Kaon/hTOFNsigma", "n#sigma^{TOF} Kaons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAbefore/Kaon/hTPCNsigma", "n#sigma^{TPC} Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAbefore/Kaon/hTOFNsigma", "n#sigma^{TOF} Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); histos.add("QAbefore/Kaon/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // QA After histos.add("QAafter/Proton/hPt", "p_{T}-spectra Protons", kTH1F, {axisPt}); - histos.add("QAafter/Proton/hDcaZ", "dca_{z} Protons", kTH2F, {axisPtQA, axisDCAz}); - histos.add("QAafter/Proton/hDcaXY", "dca_{xy} Protons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAafter/Proton/hTPCNsigmaFull", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTPCNsigma", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma(TPC) Protons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Proton/hTOFNsigma", "n#sigma(TOF) Protons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAafter/Proton/hDcaZ", "dca_{z} Protons", kTH2F, {axisP_pid, axisDCAz}); + histos.add("QAafter/Proton/hDcaXY", "dca_{xy} Protons", kTH2F, {axisP_pid, axisDCAxy}); + histos.add("QAafter/Proton/hTPCNsigmaFull", "n#sigma(TPC) Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/hTPCNsigma", "n#sigma(TPC) Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma(TPC) Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/hTOFNsigma", "n#sigma(TOF) Protons", kTH2F, {axisP_pid, axisTOFNsigma}); histos.add("QAafter/Proton/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); histos.add("QAafter/Kaon/hPt", "p_{T}-spectra Kaons", kTH1F, {axisPt}); - histos.add("QAafter/Kaon/hDcaZ", "dca_{z} Kaons", kTH2F, {axisPtQA, axisDCAz}); - histos.add("QAafter/Kaon/hDcaXY", "dca_{xy} Kaons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAafter/Kaon/hTPCNsigmaFull", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma(TPC) Kaons", kTH2F, {axisPtQA, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma(TOF) Kaons", kTH2F, {axisPtQA, axisTOFNsigma}); + histos.add("QAafter/Kaon/hDcaZ", "dca_{z} Kaons", kTH2F, {axisP_pid, axisDCAz}); + histos.add("QAafter/Kaon/hDcaXY", "dca_{xy} Kaons", kTH2F, {axisP_pid, axisDCAxy}); + histos.add("QAafter/Kaon/hTPCNsigmaFull", "n#sigma(TPC) Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma(TPC) Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma(TPC) Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma(TOF) Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); histos.add("QAafter/Kaon/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // Analysis @@ -149,10 +151,10 @@ struct lambdaAnalysis { if (doprocessMC) { histos.add("Event/hSphRec", "Reconstructed S_{0}", kTH1F, {axisSp}); histos.add("Event/hSpCentRec", "Reconstructed S_{0} vs FT0M(%)", kTH2F, {axisCent, axisSp}); - histos.add("QAMCTrue/DcaZ_pr", "dca_{z}^{MC} Protons", kTH2F, {axisPtQA, axisDCAz}); - histos.add("QAMCTrue/DcaZ_ka", "dca_{z}^{MC} Kaons", kTH2F, {axisPtQA, axisDCAz}); - histos.add("QAMCTrue/DcaXY_pr", "dca_{xy}^{MC} Protons", kTH2F, {axisPtQA, axisDCAxy}); - histos.add("QAMCTrue/DcaXY_ka", "dca_{xy}^{MC} Kaons", kTH2F, {axisPtQA, axisDCAxy}); + histos.add("QAMCTrue/DcaZ_pr", "dca_{z}^{MC} Protons", kTH2F, {axisP_pid, axisDCAz}); + histos.add("QAMCTrue/DcaZ_ka", "dca_{z}^{MC} Kaons", kTH2F, {axisP_pid, axisDCAz}); + histos.add("QAMCTrue/DcaXY_pr", "dca_{xy}^{MC} Protons", kTH2F, {axisP_pid, axisDCAxy}); + histos.add("QAMCTrue/DcaXY_ka", "dca_{xy}^{MC} Kaons", kTH2F, {axisP_pid, axisDCAxy}); histos.add("Analysis/hLambdaGen", "Generated #Lambda(1520) p_{T}", kTH1D, {axisPt}); histos.add("Analysis/hLambdaGenAnti", "Generated #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); histos.add("Analysis/hLambdaRec", "Reconstructed #Lambda(1520) p_{T}", kTH1D, {axisPt}); @@ -190,38 +192,51 @@ struct lambdaAnalysis { } // PID selection tools template - bool selectionPIDProton(const T& candidate) + bool selectionPIDProton(const T& candidate, float p) { bool tpcPIDPassed{false}, tofPIDPassed{false}; - auto tpcPIDpt = static_cast>(protonTPCPIDpt); + auto tpcPIDp = static_cast>(protonTPCPIDp); auto tpcPIDcut = static_cast>(protonTPCPIDcut); - int nitr = static_cast(tpcPIDpt.size()); + int nitr = static_cast(tpcPIDp.size()); + + float tpcNsigmaPi = std::abs(candidate.tpcNSigmaPi()); + float tpcNsigmaKa = std::abs(candidate.tpcNSigmaKa()); + float tpcNsigmaPr = std::abs(candidate.tpcNSigmaPr()); + float tofNsigmaPi = std::abs(candidate.tofNSigmaPi()); + float tofNsigmaKa = std::abs(candidate.tofNSigmaKa()); + float tofNsigmaPr = std::abs(candidate.tofNSigmaPr()); + + float tpcTofNsigmaPi = tpcNsigmaPi * tpcNsigmaPi + tofNsigmaPi * tofNsigmaPi; + float tpcTofNsigmaKa = tpcNsigmaKa * tpcNsigmaKa + tofNsigmaKa * tofNsigmaKa; + float tpcTofNsigmaPr = tpcNsigmaPr * tpcNsigmaPr + tofNsigmaPr * tofNsigmaPr; + float combinedCut = nsigmaCutCombinedProton * nsigmaCutCombinedProton; + float combinedRejCut = cRejNsigma * cRejNsigma; if (!cUseTpcOnly && candidate.hasTOF()) { - if (std::abs(candidate.tofNSigmaPr()) < cMaxTOFnSigmaProton) { + if (tofNsigmaPr < cMaxTOFnSigmaProton && tofNsigmaPi > cRejNsigma && tofNsigmaKa > cRejNsigma) { tofPIDPassed = true; } // square cut - if ((nsigmaCutCombinedProton < 0) && (std::abs(candidate.tpcNSigmaPr()) < cMaxTPCnSigmaProton)) { + if ((nsigmaCutCombinedProton < 0) && (tpcNsigmaPr < cMaxTPCnSigmaProton)) { tpcPIDPassed = true; } // circular cut - if ((nsigmaCutCombinedProton > 0) && (candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr() + candidate.tofNSigmaPr() * candidate.tofNSigmaPr() < nsigmaCutCombinedProton * nsigmaCutCombinedProton)) { + if ((nsigmaCutCombinedProton > 0) && (tpcTofNsigmaPr < combinedCut && tpcTofNsigmaPi > combinedRejCut && tpcTofNsigmaKa > combinedRejCut)) { tofPIDPassed = true; tpcPIDPassed = true; } } else { tofPIDPassed = true; if (cUseTpcOnly) { - if (std::abs(candidate.tpcNSigmaPr()) < cMaxTPCnSigmaProton) { + if (tpcNsigmaPr < cMaxTPCnSigmaProton && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma) { tpcPIDPassed = true; } } else { for (int i = 0; i < nitr - 1; ++i) { - if (candidate.pt() >= tpcPIDpt[i] && candidate.pt() < tpcPIDpt[i + 1] && std::abs(candidate.tpcNSigmaPr()) < tpcPIDcut[i]) { + if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaPr < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma)) { tpcPIDPassed = true; } - if (!cUseTpcAndTof && candidate.pt() >= tpcPIDpt[nitr - 1] && std::abs(candidate.tpcNSigmaPr()) < tpcPIDcut[nitr - 2]) { + if (!cUseTpcAndTof && p >= tpcPIDp[nitr - 1] && p < cMaxPtpc && (tpcNsigmaPr < tpcPIDcut[nitr - 2] && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma)) { tpcPIDPassed = true; } } @@ -233,38 +248,51 @@ struct lambdaAnalysis { return false; } template - bool selectionPIDKaon(const T& candidate) + bool selectionPIDKaon(const T& candidate, float p) { bool tpcPIDPassed{false}, tofPIDPassed{false}; - auto tpcPIDpt = static_cast>(kaonTPCPIDpt); + auto tpcPIDp = static_cast>(kaonTPCPIDp); auto tpcPIDcut = static_cast>(kaonTPCPIDcut); - int nitr = static_cast(tpcPIDpt.size()); + int nitr = static_cast(tpcPIDp.size()); + + float tpcNsigmaPi = std::abs(candidate.tpcNSigmaPi()); + float tpcNsigmaKa = std::abs(candidate.tpcNSigmaKa()); + float tpcNsigmaPr = std::abs(candidate.tpcNSigmaPr()); + float tofNsigmaPi = std::abs(candidate.tofNSigmaPi()); + float tofNsigmaKa = std::abs(candidate.tofNSigmaKa()); + float tofNsigmaPr = std::abs(candidate.tofNSigmaPr()); + + float tpcTofNsigmaPi = tpcNsigmaPi * tpcNsigmaPi + tofNsigmaPi * tofNsigmaPi; + float tpcTofNsigmaKa = tpcNsigmaKa * tpcNsigmaKa + tofNsigmaKa * tofNsigmaKa; + float tpcTofNsigmaPr = tpcNsigmaPr * tpcNsigmaPr + tofNsigmaPr * tofNsigmaPr; + float combinedCut = nsigmaCutCombinedKaon * nsigmaCutCombinedKaon; + float combinedRejCut = cRejNsigma * cRejNsigma; if (!cUseTpcOnly && candidate.hasTOF()) { - if (std::abs(candidate.tofNSigmaKa()) < cMaxTOFnSigmaKaon) { + if (tofNsigmaKa < cMaxTOFnSigmaKaon && tofNsigmaPi > cRejNsigma && tofNsigmaPr > cRejNsigma) { tofPIDPassed = true; } // square cut - if ((nsigmaCutCombinedKaon < 0) && (std::abs(candidate.tpcNSigmaKa()) < cMaxTPCnSigmaKaon)) { + if ((nsigmaCutCombinedKaon < 0) && (tpcNsigmaKa < cMaxTPCnSigmaKaon)) { tpcPIDPassed = true; } // circular - if ((nsigmaCutCombinedKaon > 0) && (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa() < nsigmaCutCombinedKaon * nsigmaCutCombinedKaon)) { + if ((nsigmaCutCombinedKaon > 0) && (tpcTofNsigmaKa < combinedCut && tpcTofNsigmaPi > combinedRejCut && tpcTofNsigmaPr > combinedRejCut)) { tofPIDPassed = true; tpcPIDPassed = true; } } else { tofPIDPassed = true; if (cUseTpcOnly) { - if (std::abs(candidate.tpcNSigmaKa()) < cMaxTPCnSigmaKaon) { + if (tpcNsigmaKa < cMaxTPCnSigmaKaon && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma) { tpcPIDPassed = true; } } else { for (int i = 0; i < nitr - 1; ++i) { - if (candidate.pt() >= tpcPIDpt[i] && candidate.pt() < tpcPIDpt[i + 1] && std::abs(candidate.tpcNSigmaKa()) < tpcPIDcut[i]) { + if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaKa < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma)) { tpcPIDPassed = true; } - if (!cUseTpcAndTof && candidate.pt() >= tpcPIDpt[nitr - 1] && std::abs(candidate.tpcNSigmaKa()) < tpcPIDcut[nitr - 2]) { + if (!cUseTpcAndTof && p >= tpcPIDp[nitr - 1] && p < cMaxPtpc && (tpcNsigmaKa < tpcPIDcut[nitr - 2] && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma)) { tpcPIDPassed = true; } } @@ -281,6 +309,7 @@ struct lambdaAnalysis { { TLorentzVector p1, p2, p; TRandom* rn = new TRandom(); + float p_ptot = 0., k_ptot = 0.; for (auto const& [trkPr, trkKa] : soa::combinations(soa::CombinationsFullIndexPolicy(trk1, trk2))) { // Do not analyse same index tracks. @@ -298,16 +327,19 @@ struct lambdaAnalysis { if ((trkPr.hasTOF() && std::abs(trkPr.tofNSigmaPr()) > cfgPIDprecut) || (trkKa.hasTOF() && std::abs(trkKa.tofNSigmaKa()) > cfgPIDprecut)) continue; + p_ptot = TMath::Sqrt(trkPr.px() * trkPr.px() + trkPr.py() * trkPr.py() + trkPr.py() * trkPr.py()); + k_ptot = TMath::Sqrt(trkKa.px() * trkKa.px() + trkKa.py() * trkKa.py() + trkKa.py() * trkKa.py()); + // Fill QA before track selection. if (!mix) { - histos.fill(HIST("QAbefore/Proton/hTPCNsigma"), trkPr.pt(), trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAbefore/Proton/hTPCNsigma"), p_ptot, trkPr.tpcNSigmaPr()); if (trkPr.hasTOF()) { - histos.fill(HIST("QAbefore/Proton/hTOFNsigma"), trkPr.pt(), trkPr.tofNSigmaPr()); + histos.fill(HIST("QAbefore/Proton/hTOFNsigma"), p_ptot, trkPr.tofNSigmaPr()); histos.fill(HIST("QAbefore/Proton/hTpcTofNsigma"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); } - histos.fill(HIST("QAbefore/Kaon/hTPCNsigma"), trkKa.pt(), trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAbefore/Kaon/hTPCNsigma"), k_ptot, trkKa.tpcNSigmaKa()); if (trkKa.hasTOF()) { - histos.fill(HIST("QAbefore/Kaon/hTOFNsigma"), trkKa.pt(), trkKa.tofNSigmaKa()); + histos.fill(HIST("QAbefore/Kaon/hTOFNsigma"), k_ptot, trkKa.tofNSigmaKa()); histos.fill(HIST("QAbefore/Kaon/hTpcTofNsigma"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); } } @@ -317,32 +349,32 @@ struct lambdaAnalysis { continue; if (cUseOnlyTOFTrackKa && !trkKa.hasTOF()) continue; - if (!selectionPIDProton(trkPr) || !selectionPIDKaon(trkKa)) + if (!selectionPIDProton(trkPr, p_ptot) || !selectionPIDKaon(trkKa, k_ptot)) continue; // Fill QA after track selection. if (!mix) { histos.fill(HIST("QAafter/Proton/hPt"), trkPr.pt()); - histos.fill(HIST("QAafter/Proton/hDcaZ"), trkPr.pt(), trkPr.dcaZ()); - histos.fill(HIST("QAafter/Proton/hDcaXY"), trkPr.pt(), trkPr.dcaXY()); - histos.fill(HIST("QAafter/Proton/hTPCNsigmaFull"), trkPr.pt(), trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAafter/Proton/hDcaZ"), p_ptot, trkPr.dcaZ()); + histos.fill(HIST("QAafter/Proton/hDcaXY"), p_ptot, trkPr.dcaXY()); + histos.fill(HIST("QAafter/Proton/hTPCNsigmaFull"), p_ptot, trkPr.tpcNSigmaPr()); if (!cUseTpcOnly && trkPr.hasTOF()) { - histos.fill(HIST("QAafter/Proton/hTPCNsigmaTOF"), trkPr.pt(), trkPr.tpcNSigmaPr()); - histos.fill(HIST("QAafter/Proton/hTOFNsigma"), trkPr.pt(), trkPr.tofNSigmaPr()); + histos.fill(HIST("QAafter/Proton/hTPCNsigmaTOF"), p_ptot, trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAafter/Proton/hTOFNsigma"), p_ptot, trkPr.tofNSigmaPr()); histos.fill(HIST("QAafter/Proton/hTpcTofNsigma"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); } else { - histos.fill(HIST("QAafter/Proton/hTPCNsigma"), trkPr.pt(), trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAafter/Proton/hTPCNsigma"), p_ptot, trkPr.tpcNSigmaPr()); } histos.fill(HIST("QAafter/Kaon/hPt"), trkKa.pt()); - histos.fill(HIST("QAafter/Kaon/hDcaZ"), trkKa.pt(), trkKa.dcaZ()); - histos.fill(HIST("QAafter/Kaon/hDcaXY"), trkKa.pt(), trkKa.dcaXY()); - histos.fill(HIST("QAafter/Kaon/hTPCNsigmaFull"), trkKa.pt(), trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/hDcaZ"), k_ptot, trkKa.dcaZ()); + histos.fill(HIST("QAafter/Kaon/hDcaXY"), k_ptot, trkKa.dcaXY()); + histos.fill(HIST("QAafter/Kaon/hTPCNsigmaFull"), k_ptot, trkKa.tpcNSigmaKa()); if (!cUseTpcOnly && trkKa.hasTOF()) { - histos.fill(HIST("QAafter/Kaon/hTPCNsigmaTOF"), trkKa.pt(), trkKa.tpcNSigmaKa()); - histos.fill(HIST("QAafter/Kaon/hTOFNsigma"), trkKa.pt(), trkKa.tofNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/hTPCNsigmaTOF"), k_ptot, trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/hTOFNsigma"), k_ptot, trkKa.tofNSigmaKa()); histos.fill(HIST("QAafter/Kaon/hTpcTofNsigma"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); } else { - histos.fill(HIST("QAafter/Kaon/hTPCNsigma"), trkKa.pt(), trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/hTPCNsigma"), k_ptot, trkKa.tpcNSigmaKa()); } } @@ -399,10 +431,10 @@ struct lambdaAnalysis { continue; // Track selection check. - histos.fill(HIST("QAMCTrue/DcaXY_pr"), trkPr.pt(), trkPr.dcaXY()); - histos.fill(HIST("QAMCTrue/DcaXY_ka"), trkKa.pt(), trkKa.dcaXY()); - histos.fill(HIST("QAMCTrue/DcaZ_pr"), trkPr.pt(), trkPr.dcaZ()); - histos.fill(HIST("QAMCTrue/DcaZ_ka"), trkKa.pt(), trkKa.dcaZ()); + histos.fill(HIST("QAMCTrue/DcaXY_pr"), p_ptot, trkPr.dcaXY()); + histos.fill(HIST("QAMCTrue/DcaXY_ka"), k_ptot, trkKa.dcaXY()); + histos.fill(HIST("QAMCTrue/DcaZ_pr"), p_ptot, trkPr.dcaZ()); + histos.fill(HIST("QAMCTrue/DcaZ_ka"), k_ptot, trkKa.dcaZ()); // MC histograms if (trkPr.motherPDG() > 0) { From b796951b667f3ee644568d1bd9ba4b8f518419df Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:10:23 +0100 Subject: [PATCH 056/156] Changes to the MC Truth producer (#4160) --- .../femtoUniverseProducerMCTruthTask.cxx | 49 +++++-------------- ...femtoUniversePairTaskTrackTrackMcTruth.cxx | 12 ++--- 2 files changed, 19 insertions(+), 42 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index c781072170d..2dafa1ccbbc 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -135,38 +135,15 @@ struct femtoUniverseProducerMCTruthTask { template void fillCollisions(CollisionType const& col, TrackType const& tracks) { - const auto vtxZ = col.posZ(); - const auto spher = 0; // colCuts.computeSphericity(col, tracks); - int mult = 0; - int multNtr = 0; - if (ConfIsRun3) { - mult = col.multFV0M(); - multNtr = col.multNTracksPV(); - } else { - mult = 0.5 * (col.multFV0M()); /// For benchmarking on Run 2, V0M in - /// FemtoUniverseRun2 is defined V0M/2 - multNtr = col.multTracklets(); + for (auto& c : col) { + const auto vtxZ = c.posZ(); + const auto spher = 0; // colCuts.computeSphericity(col, tracks); + int mult = 0; + int multNtr = 0; + + // colCuts.fillQA(c); //for now, TODO: create a configurable so in the FemroUniverseCollisionSelection.h there is an option to plot QA just for the posZ + outputCollision(vtxZ, mult, multNtr, spher, mMagField); } - if (ConfEvtUseTPCmult) { - multNtr = col.multTPC(); - } - - // check whether the basic event selection criteria are fulfilled - // if the basic selection is NOT fulfilled: - // in case of skimming run - don't store such collisions - // in case of trigger run - store such collisions but don't store any - // particle candidates for such collisions - - // CHECK WHAT CUTS SHOULD BE USED FOR MC TRUTH - // if (!colCuts.isSelected(col)) { - // if (ConfIsTrigger) { - // outputCollision(vtxZ, mult, multNtr, spher, mMagField); - // } - // return; - // } - - colCuts.fillQA(col); - outputCollision(vtxZ, mult, multNtr, spher, mMagField); } template @@ -229,14 +206,14 @@ struct femtoUniverseProducerMCTruthTask { } void - processTrackMC(aod::FemtoFullCollisionMC const& col, - aod::BCsWithTimestamps const&, - aod::McCollisions const& mcCollisions, - aod::McParticles const& mcParticles) + processTrackMC(aod::McCollision const& mcCol, + soa::SmallGroups> const& collisions, + aod::McParticles const& mcParticles, + aod::BCsWithTimestamps const&) { // magnetic field for run not needed for mc truth // fill the tables - fillCollisions(col, mcParticles); + fillCollisions(collisions, mcParticles); fillParticles(mcParticles); } PROCESS_SWITCH(femtoUniverseProducerMCTruthTask, processTrackMC, "Provide MC data for track analysis", true); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx index 96b4bcfbeed..ad5a60a11ef 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx @@ -50,10 +50,10 @@ struct femtoUniversePairTaskTrackTrackMcTruth { Configurable ConfEtaMax{"ConfEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; /// Particle 1 - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 2212, "Particle 1 - PDG code"}; + Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 211, "Particle 1 - PDG code"}; Configurable ConfNoPDGPartOne{"ConfNoPDGPartOne", false, "0: selecting part by PDG, 1: no PID selection"}; - Configurable ConfPtLowPart1{"ConfPtLowPart1", 0.5, "Lower limit for Pt for the first particle"}; - Configurable ConfPtHighPart1{"ConfPtHighPart1", 1.5, "Higher limit for Pt for the first particle"}; + Configurable ConfPtLowPart1{"ConfPtLowPart1", 0.2, "Lower limit for Pt for the first particle"}; + Configurable ConfPtHighPart1{"ConfPtHighPart1", 2.5, "Higher limit for Pt for the first particle"}; /// Partition for particle 1 Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (ConfNoPDGPartOne || aod::femtouniverseparticle::pidcut == ConfPDGCodePartOne) && @@ -64,10 +64,10 @@ struct femtoUniversePairTaskTrackTrackMcTruth { /// Particle 2 Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 2212, "Particle 2 - PDG code"}; + Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 211, "Particle 2 - PDG code"}; Configurable ConfNoPDGPartTwo{"ConfNoPDGPartTwo", false, "0: selecting part by PDG, 1: no PID selection"}; - Configurable ConfPtLowPart2{"ConfPtLowPart2", 0.5, "Lower limit for Pt for the second particle"}; - Configurable ConfPtHighPart2{"ConfPtHighPart2", 1.5, "Higher limit for Pt for the second particle"}; + Configurable ConfPtLowPart2{"ConfPtLowPart2", 0.2, "Lower limit for Pt for the second particle"}; + Configurable ConfPtHighPart2{"ConfPtHighPart2", 2.5, "Higher limit for Pt for the second particle"}; /// Partition for particle 2 Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (ConfNoPDGPartTwo || aod::femtouniverseparticle::pidcut == ConfPDGCodePartTwo) && From ddb87c60f1701b7587331f9f926192f982a3dbb2 Mon Sep 17 00:00:00 2001 From: Giovanni Malfattore <89481844+giovannimalfattore@users.noreply.github.com> Date: Wed, 13 Dec 2023 22:35:31 +0100 Subject: [PATCH 057/156] [PWFLG] LightNucleiTask - Improve TOF mass with P shift (#4161) * [PWFLG] LightNucleiTask - Fix TOF mass estimation with momentum shift * [PWFLG] LightNucleiTask - TOF mass correction * [PWFLG] LightNucleiTask - Fix typo --- PWGLF/Tasks/LFNucleiBATask.cxx | 172 ++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 55 deletions(-) diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/LFNucleiBATask.cxx index 4f1d64a3183..cc3eec7267e 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/LFNucleiBATask.cxx @@ -128,13 +128,20 @@ struct LFNucleiBATask { Configurable antiDeuteronPt{"antiDeuteronPt", 0, "Select use default pT (0) or use instead pT shift (1) for antideuteron"}; // Additional function used for pT-shift calibration - TF1* fShiftHe = 0; - TF1* fShiftantiHe = 0; + TF1* fShiftPtHe = 0; + TF1* fShiftPtantiHe = 0; + TF1* fShiftPHe = 0; + TF1* fShiftPantiHe = 0; + TF1* fShiftAntiD = 0; + Configurable enablePShift{"enablePShift", false, "Flag to enable P shift (for He only)"}; Configurable enablePtShift{"enablePtShift", false, "Flag to enable Pt shift (for He only)"}; Configurable enablePtShiftAntiD{"enablePtShiftAntiD", true, "Flag to enable Pt shift (for antiDeuteron only)"}; + Configurable> parShiftPtHe{"parShiftPtHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for helium3-Pt shift (if enabled)."}; Configurable> parShiftPtantiHe{"parShiftPtantiHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for anti-helium3-Pt shift (if enabled)."}; + Configurable> parShiftPHe{"parShiftPHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for helium3-P shift (if enabled)."}; + Configurable> parShiftPantiHe{"parShiftPantiHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for anti-helium3-P shift (if enabled)."}; Configurable> parShiftPtAntiD{"parShiftPtAntiD", {-0.0955412, 0.798164, -0.536111, 0.0887876, -1.11022e-13}, "Parameters for Pt shift (if enabled)."}; Configurable enableCentrality{"enableCentrality", true, "Flag to enable centrality 3D histos)"}; @@ -1216,24 +1223,35 @@ struct LFNucleiBATask { } // MC histograms - all, primary, sec. from weak decay, sec. from material histos.add("spectraGen/histGenVetxZ", "PosZ generated events", HistType::kTH1F, {{1500, -15.f, 15.f, "Vertex Z (cm)"}}); + histos.add("spectraGen/helium/histPtGenHe", "PtGenHe", HistType::kTH1F, {{800, 0.f, 8.f}}); histos.add("spectraGen/helium/histPtRecHe", "PtRecHe", HistType::kTH1F, {{800, 0.f, 8.f}}); histos.add("spectraGen/helium/histPtShiftHe", "PtReco-PtGen vs PtReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); - histos.add("spectraGen/helium/histPShiftHe", "PReco-PGen vs PtReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); histos.add("spectraGen/helium/histPtShiftVsEtaHe", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/helium/histPGenHe", "PGenHe", HistType::kTH1F, {{800, 0.f, 8.f}}); + histos.add("spectraGen/helium/histPRecHe", "PRecHe", HistType::kTH1F, {{800, 0.f, 8.f}}); + histos.add("spectraGen/helium/histPShiftHe", "PReco-PGen vs PReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/helium/histPShiftVsEtaHe", "PReco-PGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/helium/histPtGenantiHe", "PtGenantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); histos.add("spectraGen/helium/histPtRecantiHe", "PtRecantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); histos.add("spectraGen/helium/histPtShiftantiHe", "PtReco-PtGen vs PtReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); - histos.add("spectraGen/helium/histPShiftantiHe", "PReco-PtGen vs PReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); histos.add("spectraGen/helium/histPtShiftVsEtaantiHe", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); - histos.add("spectraGen/histPtShift_Pr", "PtReco-PtGen vs PtReco (protons) ", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/helium/histPGenantiHe", "PGenantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); + histos.add("spectraGen/helium/histPRecantiHe", "PRecantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); + histos.add("spectraGen/helium/histPShiftantiHe", "PReco-PGen vs PReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/helium/histPShiftVsEtaantiHe", "PReco-PGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); histos.add("spectraGen/histPtShift", "PtReco-PtGen vs PtReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); - histos.add("spectraGen/histPShift", "PReco-PGen vs PReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); histos.add("spectraGen/histPtShiftVsEta", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/histPShift", "PReco-PGen vs PReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/histPShiftVsEta", "PReco-PGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); + + histos.add("spectraGen/histPtShift_Pr", "PtReco-PtGen vs PtReco (protons) ", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/pion/histGenPtPion", "generated particles", HistType::kTH1F, {ptAxis}); histos.add("spectraGen/pion/histGenPtPionPrim", "generated particles", HistType::kTH1F, {ptAxis}); histos.add("spectraGen/pion/histGenPtPionSec", "generated particles", HistType::kTH1F, {ptAxis}); @@ -1344,7 +1362,7 @@ struct LFNucleiBATask { // if (event.posZ() < cfgLowCutVertex || event.posZ() > cfgHighCutVertex) // return; - float gamma = 0., massTOF = 0., hePt = 0.f, antihePt = 0.f, antiDPt = 0.f; + float gamma = 0., massTOF = 0., massTOFhe = 0., massTOFantihe = 0., heTPCmomentum = 0.f, antiheTPCmomentum = 0.f, heP = 0.f, antiheP = 0.f, hePt = 0.f, antihePt = 0.f, antiDPt = 0.f; bool isTriton = kFALSE; bool prRapCut = kFALSE; bool deRapCut = kFALSE; @@ -1386,19 +1404,34 @@ struct LFNucleiBATask { break; } - float shiftPos = 0.f; - float shiftNeg = 0.f; + float shiftPtPos = 0.f; + float shiftPtNeg = 0.f; - if (enablePtShift && !fShiftHe) { - fShiftHe = new TF1("fShiftHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + float shiftPPos = 0.f; + float shiftPNeg = 0.f; + + if (enablePtShift && !fShiftPtHe) { + fShiftPtHe = new TF1("fShiftPtHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); auto par = (std::vector)parShiftPtHe; - fShiftHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); + fShiftPtHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); } - if (enablePtShift && !fShiftantiHe) { - fShiftantiHe = new TF1("fShiftantiHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + if (enablePtShift && !fShiftPtantiHe) { + fShiftPtantiHe = new TF1("fShiftPtantiHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); auto par = (std::vector)parShiftPtantiHe; - fShiftantiHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); + fShiftPtantiHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); + } + + if (enablePShift && !fShiftPHe) { + fShiftPHe = new TF1("fShiftPHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + auto par = (std::vector)parShiftPHe; + fShiftPHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); + } + + if (enablePShift && !fShiftPantiHe) { + fShiftPantiHe = new TF1("fShiftPantiHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + auto par = (std::vector)parShiftPantiHe; + fShiftPantiHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); } if (enablePtShiftAntiD && !fShiftAntiD) { @@ -1422,14 +1455,14 @@ struct LFNucleiBATask { switch (helium3Pt) { case 0: hePt = track.pt(); - if (enablePtShift && fShiftHe) { - shiftPos = fShiftHe->Eval(2 * track.pt()); - hePt = track.pt() - shiftPos / 2.f; + if (enablePtShift && fShiftPtHe) { + shiftPtPos = fShiftPtHe->Eval(2 * track.pt()); + hePt = track.pt() - shiftPtPos / 2.f; } antihePt = track.pt(); - if (enablePtShift && fShiftantiHe) { - shiftNeg = fShiftantiHe->Eval(2 * track.pt()); - antihePt = track.pt() - shiftNeg / 2.f; + if (enablePtShift && fShiftPtantiHe) { + shiftPtNeg = fShiftPtantiHe->Eval(2 * track.pt()); + antihePt = track.pt() - shiftPtNeg / 2.f; } break; case 1: @@ -1438,6 +1471,23 @@ struct LFNucleiBATask { break; } + heP = track.p(); + antiheP = track.p(); + heTPCmomentum = track.tpcInnerParam(); + antiheTPCmomentum = track.tpcInnerParam(); + + if (enablePShift && fShiftPHe) { + shiftPPos = fShiftPHe->Eval(2 * track.tpcInnerParam()); + heP = track.p() - shiftPPos / 2.f; + heTPCmomentum = track.tpcInnerParam() - shiftPPos / 2.f; + } + + if (enablePShift && fShiftPantiHe) { + shiftPNeg = fShiftPantiHe->Eval(2 * track.tpcInnerParam()); + antiheP = track.p() - shiftPNeg / 2.f; + antiheTPCmomentum = track.tpcInnerParam() - shiftPNeg / 2.f; + } + // p cut if (TMath::Abs(track.tpcInnerParam()) < pCut) continue; @@ -1667,10 +1717,14 @@ struct LFNucleiBATask { if (isPhysPrim) { if constexpr (!IsFilteredData) { histos.fill(HIST("spectraGen/helium/histPtGenHe"), std::abs(track.mcParticle().pt())); - histos.fill(HIST("spectraGen/helium/histPtRecHe"), (2.f * hePt)); - histos.fill(HIST("spectraGen/helium/histPtShiftHe"), (2.f * hePt), (2.f * hePt) - track.mcParticle().pt()); - histos.fill(HIST("spectraGen/helium/histPShiftHe"), 2.f * track.p(), 2.f * track.p() - track.mcParticle().p()); - histos.fill(HIST("spectraGen/helium/histPtShiftVsEtaHe"), track.eta(), (2.f * hePt) - track.mcParticle().pt()); + histos.fill(HIST("spectraGen/helium/histPtRecHe"), 2.f * hePt); + histos.fill(HIST("spectraGen/helium/histPtShiftHe"), 2.f * hePt, 2.f * hePt - track.mcParticle().pt()); + histos.fill(HIST("spectraGen/helium/histPtShiftVsEtaHe"), track.eta(), 2.f * hePt - track.mcParticle().pt()); + + histos.fill(HIST("spectraGen/helium/histPGenHe"), std::abs(track.mcParticle().p())); + histos.fill(HIST("spectraGen/helium/histPRecHe"), 2.f * heP); + histos.fill(HIST("spectraGen/helium/histPShiftHe"), 2.f * heP, 2.f * heP - track.mcParticle().p()); + histos.fill(HIST("spectraGen/helium/histPShiftVsEtaHe"), track.eta(), 2.f * heP - track.mcParticle().p()); } histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); @@ -1692,10 +1746,14 @@ struct LFNucleiBATask { if (isPhysPrim) { if constexpr (!IsFilteredData) { histos.fill(HIST("spectraGen/helium/histPtGenantiHe"), std::abs(track.mcParticle().pt())); - histos.fill(HIST("spectraGen/helium/histPtRecantiHe"), (2.f * antihePt)); - histos.fill(HIST("spectraGen/helium/histPtShiftantiHe"), (2.f * antihePt), (2.f * antihePt) - track.mcParticle().pt()); - histos.fill(HIST("spectraGen/helium/histPShiftantiHe"), 2.f * track.p(), 2.f * track.p() - track.mcParticle().p()); - histos.fill(HIST("spectraGen/helium/histPtShiftVsEtaantiHe"), track.eta(), (2.f * antihePt) - track.mcParticle().pt()); + histos.fill(HIST("spectraGen/helium/histPtRecantiHe"), 2.f * antihePt); + histos.fill(HIST("spectraGen/helium/histPtShiftantiHe"), 2.f * antihePt, 2.f * antihePt - track.mcParticle().pt()); + histos.fill(HIST("spectraGen/helium/histPtShiftVsEtaantiHe"), track.eta(), 2.f * antihePt - track.mcParticle().pt()); + + histos.fill(HIST("spectraGen/helium/histPGenantiHe"), std::abs(track.mcParticle().p())); + histos.fill(HIST("spectraGen/helium/histPRecantiHe"), 2.f * antiheP); + histos.fill(HIST("spectraGen/helium/histPShiftantiHe"), 2.f * antiheP, 2.f * antiheP - track.mcParticle().p()); + histos.fill(HIST("spectraGen/helium/histPShiftVsEtaantiHe"), track.eta(), 2.f * antiheP - track.mcParticle().p()); } histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); @@ -2478,35 +2536,35 @@ struct LFNucleiBATask { if (track.sign() > 0) { if (enablePtSpectra) { histos.fill(HIST("tracks/eff/helium/hPtHe"), hePt); - histos.fill(HIST("tracks/eff/helium/h2pVsTPCmomentumHe"), track.tpcInnerParam(), track.p()); + histos.fill(HIST("tracks/eff/helium/h2pVsTPCmomentumHe"), heTPCmomentum, heP); } histos.fill(HIST("tracks/helium/h1HeliumSpectra"), hePt); histos.fill(HIST("tracks/helium/h1HeliumSpectra_Z2"), 2 * hePt); - histos.fill(HIST("tracks/helium/h2HeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), hePt); histos.fill(HIST("tracks/helium/h2HeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); histos.fill(HIST("tracks/helium/h2HeliumEtavsPt"), track.eta(), hePt); histos.fill(HIST("tracks/helium/h2HeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (enablePIDplot) - histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumHelium"), track.tpcInnerParam(), track.tpcSignal()); + histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumHelium"), heTPCmomentum, track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCStrongCut)) { - histos.fill(HIST("tracks/helium/hc/h2TPCsignVsTPCmomentumHelium_hard"), track.tpcInnerParam(), track.tpcSignal()); + histos.fill(HIST("tracks/helium/hc/h2TPCsignVsTPCmomentumHelium_hard"), heTPCmomentum, track.tpcSignal()); } } else { if (enablePtSpectra) { histos.fill(HIST("tracks/eff/helium/hPtantiHe"), antihePt); - histos.fill(HIST("tracks/eff/helium/h2pVsTPCmomentumantiHe"), track.tpcInnerParam(), track.p()); + histos.fill(HIST("tracks/eff/helium/h2pVsTPCmomentumantiHe"), antiheTPCmomentum, antiheP); } histos.fill(HIST("tracks/helium/h1antiHeliumSpectra"), antihePt); histos.fill(HIST("tracks/helium/h1antiHeliumSpectra_Z2"), 2 * antihePt); - histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), hePt); histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt"), track.eta(), hePt); histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (enablePIDplot) - histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumantiHelium"), track.tpcInnerParam(), track.tpcSignal()); + histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumantiHelium"), antiheTPCmomentum, track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaHe()) < nsigmaTPCStrongCut)) { - histos.fill(HIST("tracks/helium/hc/h2TPCsignVsTPCmomentumantiHelium_hard"), track.tpcInnerParam(), track.tpcSignal()); + histos.fill(HIST("tracks/helium/hc/h2TPCsignVsTPCmomentumantiHelium_hard"), antiheTPCmomentum, track.tpcSignal()); } } } @@ -2613,17 +2671,17 @@ struct LFNucleiBATask { } if (enableHe) { if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe && track.sign() > 0) { - histos.fill(HIST("tracks/helium/h2HeliumTOFbetaVsP"), track.p(), track.beta()); + histos.fill(HIST("tracks/helium/h2HeliumTOFbetaVsP"), heP, track.beta()); if (enablePtSpectra) { - histos.fill(HIST("tracks/eff/helium/h2pVsTOFExpMomentumHe"), track.tofExpMom(), track.p()); - histos.fill(HIST("tracks/eff/helium/h2TPCmomentumVsTOFExpMomentumHe"), track.tofExpMom(), track.tpcInnerParam()); + histos.fill(HIST("tracks/eff/helium/h2pVsTOFExpMomentumHe"), track.tofExpMom(), heP); + histos.fill(HIST("tracks/eff/helium/h2TPCmomentumVsTOFExpMomentumHe"), track.tofExpMom(), heTPCmomentum); } } if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe && track.sign() < 0) { - histos.fill(HIST("tracks/helium/h2antiHeliumTOFbetaVsP"), track.p(), track.beta()); + histos.fill(HIST("tracks/helium/h2antiHeliumTOFbetaVsP"), antiheP, track.beta()); if (enablePtSpectra) { - histos.fill(HIST("tracks/eff/helium/h2pVsTOFExpMomentumantiHe"), track.tofExpMom(), track.p()); - histos.fill(HIST("tracks/eff/helium/h2TPCmomentumVsTOFExpMomentumantiHe"), track.tofExpMom(), track.tpcInnerParam()); + histos.fill(HIST("tracks/eff/helium/h2pVsTOFExpMomentumantiHe"), track.tofExpMom(), antiheP); + histos.fill(HIST("tracks/eff/helium/h2TPCmomentumVsTOFExpMomentumantiHe"), track.tofExpMom(), antiheTPCmomentum); } } } @@ -2665,6 +2723,8 @@ struct LFNucleiBATask { switch (massTOFConfig) { case 0: massTOF = track.tpcInnerParam() * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); + massTOFhe = heTPCmomentum * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); + massTOFantihe = antiheTPCmomentum * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); break; case 1: massTOF = track.tofExpMom() * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); @@ -2673,6 +2733,8 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/h2TPCsignVsBetaGamma"), (track.beta() * gamma) / (1.f * track.sign()), track.tpcSignal()); } else { massTOF = -99.f; + massTOFhe = -99.f; + massTOFantihe = -99.f; } histos.fill(HIST("tracks/h2TOFmassVsPt"), massTOF, track.pt()); @@ -2861,32 +2923,32 @@ struct LFNucleiBATask { if (track.sign() > 0) { if (enablePtSpectra) histos.fill(HIST("tracks/eff/helium/hPtHeTOF"), hePt); - histos.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt"), 2.f * massTOF, hePt); - histos.fill(HIST("tracks/helium/h2TOFmassDeltaHeliumVsPt"), 2.f * massTOF - fMassHelium, hePt); - histos.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), 2.f * massTOF * 2.f * massTOF - fMassHelium * fMassHelium, hePt); + histos.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt"), 2.f * massTOFhe, hePt); + histos.fill(HIST("tracks/helium/h2TOFmassDeltaHeliumVsPt"), 2.f * massTOFhe - fMassHelium, hePt); + histos.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), 2.f * massTOFhe * 2.f * massTOFhe - fMassHelium * fMassHelium, hePt); if (enableBetaCut && (track.beta() > betaCut)) { - histos.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt_BetaCut"), 2.f * massTOF, hePt); - histos.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_BetaCut"), 2.f * massTOF * 2.f * massTOF - fMassHelium * fMassHelium, hePt); + histos.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt_BetaCut"), 2.f * massTOFhe, hePt); + histos.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_BetaCut"), 2.f * massTOFhe * 2.f * massTOFhe - fMassHelium * fMassHelium, hePt); } if (enableExpSignalTOF) histos.fill(HIST("tracks/helium/h2HeliumTOFExpSignalDiffVsPtCut"), hePt, track.tofExpSignalDiffHe()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaTr()) > 2)) { - histos.fill(HIST("tracks/helium/hc/h2TOFmass2HeliumVsPt_hard"), 2.f * massTOF * 2.f * massTOF - fMassHelium * fMassHelium, hePt); + histos.fill(HIST("tracks/helium/hc/h2TOFmass2HeliumVsPt_hard"), 2.f * massTOFhe * 2.f * massTOFhe - fMassHelium * fMassHelium, hePt); } } else { if (enablePtSpectra) histos.fill(HIST("tracks/eff/helium/hPtantiHeTOF"), antihePt); - histos.fill(HIST("tracks/helium/h2TOFmassantiHeliumVsPt"), 2.f * massTOF, antihePt); - histos.fill(HIST("tracks/helium/h2TOFmassDeltaantiHeliumVsPt"), 2.f * massTOF - fMassHelium, antihePt); - histos.fill(HIST("tracks/helium/h2TOFmass2antiHeliumVsPt"), 2.f * massTOF * 2.f * massTOF - fMassHelium * fMassHelium, antihePt); + histos.fill(HIST("tracks/helium/h2TOFmassantiHeliumVsPt"), 2.f * massTOFantihe, antihePt); + histos.fill(HIST("tracks/helium/h2TOFmassDeltaantiHeliumVsPt"), 2.f * massTOFantihe - fMassHelium, antihePt); + histos.fill(HIST("tracks/helium/h2TOFmass2antiHeliumVsPt"), 2.f * massTOFantihe * 2.f * massTOFantihe - fMassHelium * fMassHelium, antihePt); if (enableBetaCut && (track.beta() > betaCut)) { - histos.fill(HIST("tracks/helium/h2TOFmassantiHeliumVsPt_BetaCut"), 2.f * massTOF, antihePt); - histos.fill(HIST("tracks/helium/h2TOFmass2antiHeliumVsPt_BetaCut"), 2.f * massTOF * 2.f * massTOF - fMassHelium * fMassHelium, antihePt); + histos.fill(HIST("tracks/helium/h2TOFmassantiHeliumVsPt_BetaCut"), 2.f * massTOFantihe, antihePt); + histos.fill(HIST("tracks/helium/h2TOFmass2antiHeliumVsPt_BetaCut"), 2.f * massTOFantihe * 2.f * massTOFantihe - fMassHelium * fMassHelium, antihePt); } if (enableExpSignalTOF) histos.fill(HIST("tracks/helium/h2antiHeliumTOFExpSignalDiffVsPtCut"), antihePt, track.tofExpSignalDiffHe()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaTr()) > 2)) { - histos.fill(HIST("tracks/helium/hc/h2TOFmass2antiHeliumVsPt_hard"), 2.f * massTOF * 2.f * massTOF - fMassHelium * fMassHelium, antihePt); + histos.fill(HIST("tracks/helium/hc/h2TOFmass2antiHeliumVsPt_hard"), 2.f * massTOFantihe * 2.f * massTOFantihe - fMassHelium * fMassHelium, antihePt); } } } From 8beee9cc965837a279c7e4f09809bf65931a7aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Thu, 14 Dec 2023 07:06:17 +0100 Subject: [PATCH 058/156] PWGHF: Rename XiCZero -> XiC0 (#4045) --- PWGHF/TableProducer/candidateCreatorToXiPi.cxx | 4 ++-- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 4 ---- PWGHF/TableProducer/treeCreatorOmegacSt.cxx | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx index bebed1e15af..0f7e503907f 100644 --- a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx @@ -112,7 +112,7 @@ struct HfCandidateCreatorToXiPi { double massLambdaFromPDG = MassLambda0; // pdg code 3122 double massXiFromPDG = MassXiMinus; // pdg code 3312 double massOmegacFromPDG = MassOmegaC0; // pdg code 4332 - double massXicFromPDG = MassXiCZero; // pdg code 4132 + double massXicFromPDG = MassXiC0; // pdg code 4132 // 2-prong vertex fitter to build the omegac/xic vertex o2::vertexing::DCAFitterN<2> df; @@ -364,7 +364,7 @@ struct HfCandidateCreatorToXiPiMc { int8_t debugGenLambda = 0; int pdgCodeOmegac0 = Pdg::kOmegaC0; // 4332 - int pdgCodeXic0 = Pdg::kXiCZero; // 4132 + int pdgCodeXic0 = Pdg::kXiC0; // 4132 int pdgCodeXiMinus = kXiMinus; // 3312 int pdgCodeLambda = kLambda0; // 3122 int pdgCodePiPlus = kPiPlus; // 211 diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 21a54bcd699..20ee224bc03 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3253,8 +3253,6 @@ struct HfTrackIndexSkimCreatorLfCascades { double massXi{0.}; double massOmega{0.}; double massLambda{0.}; - double massXiczero{0.}; - double massXicplus{0.}; // histograms HistogramRegistry registry{"registry"}; @@ -3270,8 +3268,6 @@ struct HfTrackIndexSkimCreatorLfCascades { massXi = o2::constants::physics::MassXiMinus; massOmega = o2::constants::physics::MassOmegaMinus; massLambda = o2::constants::physics::MassLambda0; - massXiczero = o2::constants::physics::MassXiCZero; - massXicplus = o2::constants::physics::MassXiCPlus; arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi] = std::array{massXi, massPi}; arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi] = std::array{massOmega, massPi}; diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index b398185c034..9ae7aa1d7ec 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -433,7 +433,7 @@ struct HfTreeCreatorOmegacSt { registry.fill(HIST("hMassOmegacVsPt"), massOmegaC, RecoDecay::pt(momenta[0], momenta[1])); if ((std::abs(massOmegaC - o2::constants::physics::MassOmegaC0) < massWindowOmegaC) || - (std::abs(massXiC - o2::constants::physics::MassXiCZero) < massWindowXiC)) { + (std::abs(massXiC - o2::constants::physics::MassXiC0) < massWindowXiC)) { registry.fill(HIST("hDecayLength"), decayLength * 1e4); registry.fill(HIST("hDecayLengthScaled"), decayLength * o2::constants::physics::MassOmegaC0 / RecoDecay::p(momenta[0], momenta[1]) * 1e4); outputTable(massOmega, From 6473d6541a558409a01f325ff88927a983cdd015 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Thu, 14 Dec 2023 11:15:22 +0100 Subject: [PATCH 059/156] Fix bug (#4163) --- Common/TableProducer/v0converter.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/TableProducer/v0converter.cxx b/Common/TableProducer/v0converter.cxx index f83e7428e5c..849e35591e1 100644 --- a/Common/TableProducer/v0converter.cxx +++ b/Common/TableProducer/v0converter.cxx @@ -24,7 +24,7 @@ struct V0Converter { { for (auto& v0 : v0s) { uint8_t bitMask = static_cast(1); // first bit on - v0s_002(v0.posTrack().collisionId(), v0.posTrackId(), v0.negTrackId(), bitMask); + v0s_002(v0.collisionId(), v0.posTrackId(), v0.negTrackId(), bitMask); } } }; From e5fee719e294635cc89826154d48c91f68ac96e9 Mon Sep 17 00:00:00 2001 From: Deependra Sharma <38365215+deependra170598@users.noreply.github.com> Date: Thu, 14 Dec 2023 15:56:39 +0530 Subject: [PATCH 060/156] PWGHF: Dstar Framework Development (#3567) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Redefining V0 table and using Histogram Registry * mass valuse to YD0, ED0, E2D0 and CtD0 columns. * Addressing vit's comment again * using namespace o2::constants::physics from CommonConstant/PhysicsConstant.h and removing use of namespace o2::analysis::pdg to resolve conflict * clang formatting in working branch * Fix typo --------- Co-authored-by: Vít Kučera --- PWGHF/Core/SelectorCuts.h | 49 +++ .../DataModel/CandidateReconstructionTables.h | 219 ++++++++++ PWGHF/DataModel/CandidateSelectionTables.h | 21 +- PWGHF/TableProducer/CMakeLists.txt | 5 + PWGHF/TableProducer/candidateCreatorDstar.cxx | 396 ++++++++++++++++-- .../candidateSelectorDstarToD0Pi.cxx | 366 ++++++++++++++++ 6 files changed, 1024 insertions(+), 32 deletions(-) create mode 100644 PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx diff --git a/PWGHF/Core/SelectorCuts.h b/PWGHF/Core/SelectorCuts.h index 41fac07b5dd..cfeeeb8dcbb 100644 --- a/PWGHF/Core/SelectorCuts.h +++ b/PWGHF/Core/SelectorCuts.h @@ -354,6 +354,55 @@ static const std::vector labelsPt = { static const std::vector labelsCutVar = {"m", "DCA", "cos theta*", "pT K", "pT Pi", "d0K", "d0pi", "d0d0", "cos pointing angle", "cos pointing angle xy", "min norm decay length XY", "max decay length", "max decay length XY", "min decay length", "norm dauImpPar XY"}; } // namespace hf_cuts_d0_to_pi_k +namespace hf_cuts_dstar_to_d0_pi +{ +static constexpr int nBinsPt = 10; +static constexpr int nCutVars = 8; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double binsPt[nBinsPt + 1] = { + 1.0, + 1.5, + 2.0, + 2.5, + 3.0, + 3.5, + 4.0, + 4.5, + 5.0, + 5.5, + 6.0}; +auto vecBinsPt = std::vector{binsPt, binsPt + nBinsPt + 1}; + +// row labels +static const std::vector labelsPt = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9"}; + +// column label +static const std::vector labelsCutVar = {"ptSoftPiMin", "ptSoftPiMax", "d0SoftPi", "d0SoftPiNormalised", "deltaMInvDstar", "chi2PCA", "d0Prong0Normalised", "d0Prong1Normalised"}; + +// default values for the cuts +constexpr double cuts[nBinsPt][nCutVars] = {{0.05, 0.3, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 0.3, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 0.4, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 0.4, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 0.6, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 0.6, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 0.6, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 100, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 100, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, + {0.05, 100, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}}; +} // namespace hf_cuts_dstar_to_d0_pi + namespace hf_cuts_lc_to_p_k_pi { static constexpr int nBinsPt = 10; diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 7cf7ca784b5..05c33e82869 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -1474,6 +1474,225 @@ DECLARE_SOA_TABLE(HfCandScMcGen, "AOD", "HFCANDSCMCGEN", //! hf_cand_sigmac::FlagMcMatchGen, hf_cand_sigmac::OriginMcGen); +/// D*± → D0(bar) π± +namespace hf_cand_dstar +{ +DECLARE_SOA_EXPRESSION_COLUMN(PxD0, pxD0, float, 1.f * aod::hf_cand::pxProng0 + 1.f * aod::hf_cand::pxProng1); +DECLARE_SOA_EXPRESSION_COLUMN(PyD0, pyD0, float, 1.f * aod::hf_cand::pyProng0 + 1.f * aod::hf_cand::pyProng1); +DECLARE_SOA_EXPRESSION_COLUMN(PzD0, pzD0, float, 1.f * aod::hf_cand::pzProng0 + 1.f * aod::hf_cand::pzProng1); +DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProductD0, impactParameterProductD0, + [](float dca1, float dca2) -> float { return dca1 * dca2; }); +// Dynamic Columns for D0 candidate using PDG masses of daughters +DECLARE_SOA_DYNAMIC_COLUMN(InvMassD0, invMassD0, + [](float px0, float py0, float pz0, float px1, float py1, float pz1) -> float { return RecoDecay::m(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{constants::physics::MassPiPlus, constants::physics::MassKPlus}); }); +DECLARE_SOA_DYNAMIC_COLUMN(InvMass2D0, invMass2D0, + [](float px0, float py0, float pz0, float px1, float py1, float pz1) -> float { return RecoDecay::m2(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{constants::physics::MassPiPlus, constants::physics::MassKPlus}); }); +DECLARE_SOA_DYNAMIC_COLUMN(CosThetaStarD0, cosThetaStarD0, + [](float px0, float py0, float pz0, float px1, float py1, float pz1) -> float { return RecoDecay::cosThetaStar(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{constants::physics::MassPiPlus, constants::physics::MassKPlus}, constants::physics::MassD0, 1); }); +// Dynamic Columns for D0Bar candidate using PDG masses of daughters +DECLARE_SOA_DYNAMIC_COLUMN(InvMassD0Bar, invMassD0Bar, + [](float px0, float py0, float pz0, float px1, float py1, float pz1) -> float { return RecoDecay::m(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{constants::physics::MassKPlus, constants::physics::MassPiPlus}); }); +DECLARE_SOA_DYNAMIC_COLUMN(InvMass2D0Bar, invMass2D0Bar, + [](float px0, float py0, float pz0, float px1, float py1, float pz1) -> float { return RecoDecay::m2(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{constants::physics::MassKPlus, constants::physics::MassPiPlus}); }); +DECLARE_SOA_DYNAMIC_COLUMN(CosThetaStarD0Bar, cosThetaStarD0Bar, + [](float px0, float py0, float pz0, float px1, float py1, float pz1) -> float { return RecoDecay::cosThetaStar(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, std::array{constants::physics::MassKPlus, constants::physics::MassPiPlus}, constants::physics::MassD0, 0); }); +DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProngSqSumD0, impactParameterProngSqSumD0, + [](float impParProng0, float impParProng1) -> float { return RecoDecay::sumOfSquares(impParProng0, impParProng1); }); +DECLARE_SOA_DYNAMIC_COLUMN(DeltaIPNormalisedMaxD0, deltaIPNormalisedMaxD0, + [](float xVtxP, float yVtxP, float xVtxS, float yVtxS, float errDlxy, float pxM, float pyM, float ip0, float errIp0, float ip1, float errIp1, float px0, float py0, float px1, float py1) -> float { return RecoDecay::maxNormalisedDeltaIP(std::array{xVtxP, yVtxP}, std::array{xVtxS, yVtxS}, errDlxy, std::array{pxM, pyM}, std::array{ip0, ip1}, std::array{errIp0, errIp1}, std::array{std::array{px0, py0}, std::array{px1, py1}}); }); +DECLARE_SOA_DYNAMIC_COLUMN(PtD0, ptD0, + [](float px, float py) -> float { return RecoDecay::pt(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pt2D0, pt2D0, + [](float px, float py) -> float { return RecoDecay::pt2(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(PD0, pD0, + [](float px, float py, float pz) -> float { return RecoDecay::p(px, py, pz); }); +DECLARE_SOA_DYNAMIC_COLUMN(P2D0, p2D0, + [](float px, float py, float pz) -> float { return RecoDecay::p2(px, py, pz); }); +DECLARE_SOA_DYNAMIC_COLUMN(PVectorD0, pVectorD0, + [](float px, float py, float pz) -> std::array { return std::array{px, py, pz}; }); +DECLARE_SOA_DYNAMIC_COLUMN(EtaD0, etaD0, + [](float px, float py, float pz) -> float { return RecoDecay::eta(std::array{px, py, pz}); }); +DECLARE_SOA_DYNAMIC_COLUMN(PhiD0, phiD0, + [](float px, float py) -> float { return RecoDecay::phi(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(YD0, yD0, + [](float px, float py, float pz) -> float { return RecoDecay::y(std::array{px, py, pz}, constants::physics::MassD0); }); +DECLARE_SOA_DYNAMIC_COLUMN(ED0, eD0, + [](float px, float py, float pz) -> float { return RecoDecay::e(px, py, pz, constants::physics::MassD0); }); +DECLARE_SOA_DYNAMIC_COLUMN(E2D0, e2D0, + [](float px, float py, float pz) -> float { return RecoDecay::e2(px, py, pz, constants::physics::MassD0); }); +// secondary vertex +DECLARE_SOA_COLUMN(Chi2PCAD0, chi2PCAD0, float); +DECLARE_SOA_COLUMN(XSecondaryVertexD0, xSecondaryVertexD0, float); +DECLARE_SOA_COLUMN(YSecondaryVertexD0, ySecondaryVertexD0, float); +DECLARE_SOA_COLUMN(ZSecondaryVertexD0, zSecondaryVertexD0, float); +DECLARE_SOA_DYNAMIC_COLUMN(RSecondaryVertexD0, rSecondaryVertexD0, + [](float xVtxS, float yVtxS) -> float { return RecoDecay::sqrtSumOfSquares(xVtxS, yVtxS); }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthD0, decayLengthD0, + [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS) -> float { return RecoDecay::distance(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}); }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthXYD0, decayLengthXYD0, + [](float xVtxP, float yVtxP, float xVtxS, float yVtxS) -> float { return RecoDecay::distanceXY(std::array{xVtxP, yVtxP}, std::array{xVtxS, yVtxS}); }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthNormalisedD0, decayLengthNormalisedD0, + [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS, float err) -> float { return RecoDecay::distance(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}) / err; }); +DECLARE_SOA_DYNAMIC_COLUMN(DecayLengthXYNormalisedD0, decayLengthXYNormalisedD0, + [](float xVtxP, float yVtxP, float xVtxS, float yVtxS, float err) -> float { return RecoDecay::distanceXY(std::array{xVtxP, yVtxP}, std::array{xVtxS, yVtxS}) / err; }); +DECLARE_SOA_COLUMN(ErrorDecayLengthD0, errorDecayLengthD0, float); +DECLARE_SOA_COLUMN(ErrorDecayLengthXYD0, errorDecayLengthXYD0, float); +DECLARE_SOA_DYNAMIC_COLUMN(CPAD0, cpaD0, + [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS, float px, float py, float pz) -> float { return RecoDecay::cpa(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}, std::array{px, py, pz}); }); +DECLARE_SOA_DYNAMIC_COLUMN(CPAXYD0, cpaXYD0, + [](float xVtxP, float yVtxP, float xVtxS, float yVtxS, float px, float py) -> float { return RecoDecay::cpaXY(std::array{xVtxP, yVtxP}, std::array{xVtxS, yVtxS}, std::array{px, py}); }); +DECLARE_SOA_DYNAMIC_COLUMN(CtD0, ctD0, + [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS, float px, float py, float pz) -> float { return RecoDecay::ct(std::array{px, py, pz}, RecoDecay::distance(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}), constants::physics::MassD0); }); +DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterXYD0, impactParameterXYD0, + [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS, float px, float py, float pz) -> float { return RecoDecay::impParXY(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}, std::array{px, py, pz}); }); + +// Columns only for D* properties +DECLARE_SOA_INDEX_COLUMN_FULL(ProngPi, prongPi, int, Tracks, ""); //! soft-pion index + +// soft pion prong +DECLARE_SOA_COLUMN(ImpParamSoftPi, impParamSoftPi, float); +DECLARE_SOA_COLUMN(ErrorImpParamSoftPi, errorImpParamSoftPi, float); +DECLARE_SOA_DYNAMIC_COLUMN(NormalisedImpParamSoftPi, normalisedImpParamSoftPi, + [](float dca, float err) -> float { return dca / err; }); +DECLARE_SOA_COLUMN(PxSoftPi, pxSoftPi, float); +DECLARE_SOA_COLUMN(PySoftPi, pySoftPi, float); +DECLARE_SOA_COLUMN(PzSoftPi, pzSoftPi, float); +// Dstar momenta +DECLARE_SOA_EXPRESSION_COLUMN(PxDstar, pxDstar, float, 1.f * aod::hf_cand::pxProng0 + 1.f * aod::hf_cand::pxProng1 + 1.f * aod::hf_cand_dstar::pxSoftPi); +DECLARE_SOA_EXPRESSION_COLUMN(PyDstar, pyDstar, float, 1.f * aod::hf_cand::pyProng0 + 1.f * aod::hf_cand::pyProng1 + 1.f * aod::hf_cand_dstar::pySoftPi); +DECLARE_SOA_EXPRESSION_COLUMN(PzDstar, pzDstar, float, 1.f * aod::hf_cand::pzProng0 + 1.f * aod::hf_cand::pzProng1 + 1.f * aod::hf_cand_dstar::pzSoftPi); +// Inv Mass (accept mass array of size 3 {π , π, k}) +DECLARE_SOA_DYNAMIC_COLUMN(InvMassDstar, invMassDstar, + [](float pxSoftPi, float pySoftPi, float pzSoftPi, float pxProng0, float pyProng0, float pzProng0, float pxProng1, float pyProng1, float pzProng1) + -> float { return RecoDecay::m(std::array{std::array{pxSoftPi, pySoftPi, pzSoftPi}, std::array{pxProng0, pyProng0, pzProng0}, std::array{pxProng1, pyProng1, pzProng1}}, std::array{constants::physics::MassPiPlus, constants::physics::MassPiPlus, constants::physics::MassKPlus}); }); + +DECLARE_SOA_DYNAMIC_COLUMN(InvMassAntiDstar, invMassAntiDstar, + [](float pxSoftPi, float pySoftPi, float pzSoftPi, float pxProng0, float pyProng0, float pzProng0, float pxProng1, float pyProng1, float pzProng1) + -> float { return RecoDecay::m(std::array{std::array{pxSoftPi, pySoftPi, pzSoftPi}, std::array{pxProng0, pyProng0, pzProng0}, std::array{pxProng1, pyProng1, pzProng1}}, std::array{constants::physics::MassPiPlus, constants::physics::MassKPlus, constants::physics::MassPiPlus}); }); + +DECLARE_SOA_DYNAMIC_COLUMN(PtSoftPi, ptSoftPi, [](float pxSoftPi, float pySoftPi) -> float { return RecoDecay::pt(pxSoftPi, pySoftPi); }); +DECLARE_SOA_DYNAMIC_COLUMN(PVecSoftPi, pVecSoftPi, [](float px, float py, float pz) -> std::array { return std::array{px, py, pz}; }); + +// MC matching result: +DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! reconstruction level +DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! generator level +DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); //! particle origin, reconstruction level +DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); //! particle origin, generator level + +enum DecayType { + DstarToD0Pi = 0, + D0ToPiK, + NDstarDecayType +}; + +} // namespace hf_cand_dstar + +/// D0 (table) from DStar +DECLARE_SOA_TABLE(HfD0FromDstarBase, "AOD", "HFD0FRMDSTR", + o2::soa::Index<>, + // gener columns + hf_cand::CollisionId, + collision::PosX, collision::PosY, collision::PosZ, + hf_cand_dstar::XSecondaryVertexD0, hf_cand_dstar::YSecondaryVertexD0, hf_cand_dstar::ZSecondaryVertexD0, + hf_cand_dstar::ErrorDecayLengthD0, hf_cand_dstar::ErrorDecayLengthXYD0, + hf_cand_dstar::Chi2PCAD0, + /* dynamic columns */ hf_cand_dstar::RSecondaryVertexD0, + hf_cand_dstar::DecayLengthD0, + hf_cand_dstar::DecayLengthXYD0, + hf_cand_dstar::DecayLengthNormalisedD0, + hf_cand_dstar::DecayLengthXYNormalisedD0, + /* prong 0 */ hf_cand::ImpactParameterNormalised0, + hf_cand::PtProng0, + hf_cand::Pt2Prong0, + hf_cand::PVectorProng0, + /* prong 1 */ hf_cand::ImpactParameterNormalised1, + hf_cand::PtProng1, + hf_cand::Pt2Prong1, + hf_cand::PVectorProng1, + + // HFCAND_COLUMNS, + // 2-prong specific columns + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, + hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, + hf_track_index::Prong0Id, hf_track_index::Prong1Id, + hf_track_index::HFflag, + /* dynamic columns */ + hf_cand_dstar::InvMassD0, + hf_cand_dstar::InvMassD0Bar, + hf_cand_dstar::InvMass2D0, + hf_cand_dstar::InvMass2D0Bar, + hf_cand_dstar::ImpactParameterProductD0, + hf_cand_dstar::CosThetaStarD0, + hf_cand_dstar::CosThetaStarD0Bar, + hf_cand_dstar::ImpactParameterProngSqSumD0, + /* dynamic columns that use candidate momentum components */ + hf_cand_dstar::PtD0, + hf_cand_dstar::Pt2D0, + hf_cand_dstar::PD0, + hf_cand_dstar::P2D0, + hf_cand_dstar::PVectorD0, + hf_cand_dstar::CPAD0, + hf_cand_dstar::CPAXYD0, + hf_cand_dstar::CtD0, + hf_cand_dstar::ImpactParameterXYD0, + hf_cand_dstar::DeltaIPNormalisedMaxD0, + hf_cand_dstar::EtaD0, + hf_cand_dstar::PhiD0, + hf_cand_dstar::YD0, + hf_cand_dstar::ED0, + hf_cand_dstar::E2D0); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfD0FromDstarExt, HfD0FromDstarBase, "HFD0FRMDSTREXT", + hf_cand_dstar::PxD0, hf_cand_dstar::PyD0, hf_cand_dstar::PzD0); + +using HfD0FromDstar = HfD0FromDstarExt; + +DECLARE_SOA_TABLE(HfCandDstarBase, "AOD", "HFCANDDSTRBASE", + o2::soa::Index<>, + hf_cand::CollisionId, + // Primary vertex + collision::PosX, collision::PosY, collision::PosZ, + hf_cand_dstar::ProngPiId, // Index column to softPi track table + hf_track_index::ProngD0Id, // Index column points to Hf2Prongs table filled by indexSkimcreator + // Softpi + hf_cand_dstar::PxSoftPi, hf_cand_dstar::PySoftPi, hf_cand_dstar::PzSoftPi, + hf_cand_dstar::ImpParamSoftPi, hf_cand_dstar::ErrorImpParamSoftPi, + // Two pronges of D0 + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + // Dynamic + hf_cand_dstar::PtSoftPi, + hf_cand_dstar::PVecSoftPi, + hf_cand_dstar::NormalisedImpParamSoftPi, + hf_cand::Pt, + hf_cand::P, + hf_cand::PVector, + hf_cand::Eta, + hf_cand::Phi, + hf_cand::Y, + hf_cand::E, + hf_cand_dstar::InvMassDstar, + hf_cand_dstar::InvMassAntiDstar); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfCandDstarExt, HfCandDstarBase, "HFCANDDSTREXT", + hf_cand_dstar::PxDstar, hf_cand_dstar::PyDstar, hf_cand_dstar::PzDstar); + +using HfCandDstar = HfCandDstarExt; + +// table with results of reconstruction level MC matching +DECLARE_SOA_TABLE(HfCandDstarMcRec, "AOD", "HFCANDDSTRMCREC", + hf_cand_dstar::FlagMcMatchRec, + hf_cand_dstar::OriginMcRec); + +// table with results of generator level MC matching +DECLARE_SOA_TABLE(HfCandDstarMcGen, "AOD", "HFCANDDSTRMCGEN", + hf_cand_dstar::FlagMcMatchGen, + hf_cand_dstar::OriginMcGen); + #undef HFCAND_COLUMNS } // namespace o2::aod diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index b24ef333c8d..2406ab13ec8 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -134,6 +134,23 @@ DECLARE_SOA_TABLE(HfSelDsToKKPi, "AOD", "HFSELDS", //! DECLARE_SOA_TABLE(HfMlDsToKKPi, "AOD", "HFMLDS", //! hf_sel_candidate_ds::MlProbDsToKKPi, hf_sel_candidate_ds::MlProbDsToPiKK); +namespace hf_sel_candidate_dstar +{ +DECLARE_SOA_COLUMN(IsSelDstarToD0Pi, isSelDstarToD0Pi, bool); //! checking if all four of following check pass +DECLARE_SOA_COLUMN(IsRecoD0Flag, isRecoD0Flag, bool); //! checking DecayType::D0ToPiK of D0prong +DECLARE_SOA_COLUMN(IsRecoTopol, isRecoTopol, bool); //! checking conjugate independent Topological selection on Dstar +DECLARE_SOA_COLUMN(IsRecoCand, isRecoCand, bool); //! checking conjugate dependent Topological selecton on Dstar +DECLARE_SOA_COLUMN(IsRecoPid, isRecoPid, bool); //! checking PID selection on daughters of D0Prong + +} // namespace hf_sel_candidate_dstar + +DECLARE_SOA_TABLE(HfSelDstarToD0Pi, "AOD", "HFSELDSTAR", //! Table stores information about selection flag on Dstar candidate + hf_sel_candidate_dstar::IsSelDstarToD0Pi, + hf_sel_candidate_dstar::IsRecoD0Flag, + hf_sel_candidate_dstar::IsRecoTopol, + hf_sel_candidate_dstar::IsRecoCand, + hf_sel_candidate_dstar::IsRecoPid); + namespace hf_sel_candidate_lc { DECLARE_SOA_COLUMN(IsSelLcToPKPi, isSelLcToPKPi, int); //! @@ -269,8 +286,8 @@ DECLARE_SOA_TABLE(HfSelChicToJpsiGamma, "AOD", "HFSELCHIC", //! namespace hf_sel_candidate_xic { -DECLARE_SOA_COLUMN(IsSelXicToPKPi, isSelXicToPKPi, int); //! -DECLARE_SOA_COLUMN(IsSelXicToPiKP, isSelXicToPiKP, int); //! +DECLARE_SOA_COLUMN(IsSelXicToPKPi, isSelXicToPKPi, int); //! +DECLARE_SOA_COLUMN(IsSelXicToPiKP, isSelXicToPiKP, int); //! DECLARE_SOA_COLUMN(MlProbXicToPKPi, mlProbXicToPKPi, std::vector); //! DECLARE_SOA_COLUMN(MlProbXicToPiKP, mlProbXicToPiKP, std::vector); //! } // namespace hf_sel_candidate_xic diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index 14922bb4578..0468776625b 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -110,6 +110,11 @@ o2physics_add_dpl_workflow(candidate-selector-ds-to-k-k-pi PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(candidate-selector-dstar-to-d0-pi + SOURCES candidateSelectorDstarToD0Pi.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(candidate-selector-lb-to-lc-pi SOURCES candidateSelectorLbToLcPi.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/TableProducer/candidateCreatorDstar.cxx b/PWGHF/TableProducer/candidateCreatorDstar.cxx index 68394e24d4e..da2acba4396 100644 --- a/PWGHF/TableProducer/candidateCreatorDstar.cxx +++ b/PWGHF/TableProducer/candidateCreatorDstar.cxx @@ -13,67 +13,403 @@ /// \brief Reconstruction of D* decay candidates /// /// \author Vít Kučera , CERN +/// \author Deependra Sharma , IITB +/// \author Fabrizio Grosa , CERN +// ROOT +#include +// O2 #include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" - +// O2Physics +#include "Common/Core/trackUtilities.h" +// PWGHF #include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" using namespace o2; using namespace o2::constants::physics; using namespace o2::framework; +namespace o2::aod +{ +using HfDstarsWithPvRefitInfo = soa::Join; +} // namespace o2::aod + /// Reconstruction of D* decay candidates struct HfCandidateCreatorDstar { + Produces rowCandD0Base; + Produces rowCandDstarBase; + Configurable fillHistograms{"fillHistograms", true, "fill histograms"}; - OutputObj hMass{TH1F("hMass", "D* candidates;inv. mass (#pi D^{0}) (GeV/#it{c}^{2});entries", 500, 0., 5.)}; - OutputObj hPtPi{TH1F("hPtPi", "#pi candidates;#it{p}_{T} (GeV/#it{c});entries", 500, 0., 5.)}; - OutputObj hPtD0Prong0{TH1F("hPtD0Prong0", "D^{0} candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", 500, 0., 5.)}; - OutputObj hPtD0Prong1{TH1F("hPtD0Prong1", "D^{0} candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", 500, 0., 5.)}; - OutputObj hPtD0{TH1F("hPtD0", "D^{0} candidates;candidate #it{p}_{T} (GeV/#it{c});entries", 500, 0., 5.)}; + // magnetic field setting from CCDB + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; + Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + + // vertexing + Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; + Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; // ........... what is unit of this? + Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; // ..........What it DZ? + Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations is chi2/chi2old > this"}; + Configurable useAbsDCA{"useAbsDCA", false, "Minimise abs. distance rather than chi2"}; + Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; + + Service ccdb; // From utilsBfieldCCDB.h + o2::base::MatLayerCylSet* lut; // From MatLayercylSet.h + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + // D0-prong vertex fitter + o2::vertexing::DCAFitterN<2> df; + int runNumber; + double bz; + static constexpr float CmToMicrometers = 10000.; // from cm to µm + double massPi, massK, massD0; + + AxisSpec ptAxis = {100, 0., 2.0, "#it{p}_{T} (GeV/#it{c}"}; + AxisSpec dcaAxis = {200, -500., 500., "#it{d}_{xy,z} (#mum)"}; + + HistogramRegistry registry{ + "registry", + {{"Refit/hCovPVXX", "2-prong candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}}, + {"Refit/hCovSVXX", "2-prong candidates;XX element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 0.2}}}}, + {"Refit/hCovPVYY", "2-prong candidates;YY element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}}, + {"Refit/hCovSVYY", "2-prong candidates;YY element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 0.2}}}}, + {"Refit/hCovPVXZ", "2-prong candidates;XZ element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, -1.e-4, 1.e-4}}}}, + {"Refit/hCovSVXZ", "2-prong candidates;XZ element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, -1.e-4, 0.2}}}}, + {"Refit/hCovPVZZ", "2-prong candidates;ZZ element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}}, + {"Refit/hCovSVZZ", "2-prong candidates;ZZ element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 0.2}}}}, + + {"QA/hDcaXYProngsD0", "DCAxy of 2-prong candidates;#it{p}_{T} (GeV/#it{c};#it{d}_{xy}) (#mum);entries", {HistType::kTH2F, {ptAxis, dcaAxis}}}, + {"QA/hDcaZProngsD0", "DCAz of 2-prong candidates;#it{p}_{T} (GeV/#it{c};#it{d}_{z}) (#mum);entries", {HistType::kTH2F, {ptAxis, dcaAxis}}}, + {"QA/hDCAXYPi", "DCAxy of Soft Pi;#it{p}_{T} (GeV/#it{c};#it{d}_{xy}) (#mum);entries", {HistType::kTH2F, {ptAxis, dcaAxis}}}, + {"QA/hDCAZPi", "DCAz of Soft Pi;#it{p}_{T} (GeV/#it{c};#it{d}_{z}) (#mum);entries", {HistType::kTH2F, {ptAxis, dcaAxis}}}, - void process(aod::Collisions const&, - aod::HfDstars const& rowsTrackIndexDstar, - aod::Tracks const&, - aod::Hf2Prongs const&) + {"QA/hPtPi", "#pi candidates", {HistType::kTH1F, {ptAxis}}}, + {"QA/hPtD0Prong0", "D^{0} candidates' prong0", {HistType::kTH1F, {ptAxis}}}, + {"QA/hPtD0Prong1", "D^{0} candidates' prong1", {HistType::kTH1F, {ptAxis}}}, + {"QA/hPtD0", "D^{0} candidates", {HistType::kTH1F, {ptAxis}}}, + {"QA/hPtDstar", "D* candidates", {HistType::kTH1F, {ptAxis}}}}}; + + /// @brief This function initializes the ccdb setting, vertex fitter and runs function MatLayerCylSet::rectifyPtrFromFile(..args..) + void init(InitContext const&) { - auto massPi = MassPiPlus; - auto massD0 = MassD0; + if (doprocessPvRefit && doprocessNoPvRefit) { //............Warning! remove this if any of this function is removed + LOGP(fatal, "Only one process function between processPvRefit and processNoPvRefit can be enabled at a time."); + } + // LOG(info) << "Init Function Invoked"; + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); // set the flag to check object validity before CCDB query + // LOG(info) << "Retriving ccdb object"; + auto rectification = ccdb->get(ccdbPathLut); // retrieve an object of type T from CCDB as stored under path; will use the timestamp member + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(rectification); + // LOG(info) << "Successfully Retrived"; + runNumber = 0; + bz = 0; + + df.setPropagateToPCA(propagateToPCA); + df.setMaxR(maxR); + df.setMaxDZIni(maxDZIni); + df.setMinParamChange(minParamChange); + df.setMinRelChi2Change(minRelChi2Change); + df.setUseAbsDCA(useAbsDCA); + df.setWeightedFinalPCA(useWeightedFinalPCA); + + massPi = MassPiPlus; + massK = MassKPlus; + massD0 = MassD0; + } - // loop over pairs of prong indices + /// @brief function for secondary vertex reconstruction and candidate creator + /// @tparam CandsDstar Table type of Dstar table object + /// @tparam doPvRefit True/False PV refit option + /// @param collisions collision object + /// @param rowsTrackIndexDstar Dstar table object from trackIndexSkimCreator.cxx + /// @param rowsTrackIndexD0 D0 table object from trackIndexSkimCreator.cxx + /// @param tracks track table with Cov object + /// @param bcWithTimeStamps Bunch Crossing with timestamps + template + void runCreatorDstar(aod::Collisions const& collisions, + CandsDstar const& rowsTrackIndexDstar, + aod::Hf2Prongs const& rowsTrackIndexD0, + aod::TracksWCov const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + // LOG(info) << "runCreatorDstar function called"; + // LOG(info) << "candidate loop starts"; + // loop over suspected Dstar Candidate for (const auto& rowTrackIndexDstar : rowsTrackIndexDstar) { - auto trackPi = rowTrackIndexDstar.prong0(); - auto prongD0 = rowTrackIndexDstar.prongD0_as(); - auto trackD0Prong0 = prongD0.prong0(); - auto trackD0Prong1 = prongD0.prong1(); + + auto trackPi = rowTrackIndexDstar.template prong0_as(); + auto prongD0 = rowTrackIndexDstar.template prongD0_as(); + auto trackD0Prong0 = prongD0.template prong0_as(); + auto trackD0Prong1 = prongD0.template prong1_as(); + + auto collision = rowTrackIndexDstar.collision(); + + // Extracts primary vertex position and covariance matrix from a collision + auto primaryVertex = getPrimaryVertex(collision); + auto covMatrixPV = primaryVertex.getCov(); + + // Extracts track parameters and covariance matrix from a track + auto trackPiParVar = getTrackParCov(trackPi); + // These will be used in DCA Fitter to reconstruct secondary vertex + auto trackD0Prong0ParVarPos1 = getTrackParCov(trackD0Prong0); // from trackUtilities.h + auto trackD0Prong1ParVarNeg1 = getTrackParCov(trackD0Prong1); + // auto collisionPiId = trackPi.collisionId(); // auto collisionD0Id = trackD0Prong0.collisionId(); - // LOGF(info, "Pi collision %ld, D0 collision %ld", collisionPiId, collisionD0Id); + //..................................................Doubt: Should I apply a condition of (collisionPiId == collisionD0Id) + + /// Set the magnetic field from ccdb. + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + // LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; + initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); // Sets up the grp object for magnetic field (w/o matCorr for propagation) + bz = o2::base::Propagator::Instance()->getNominalBz(); + // LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + } + df.setBz(bz); + + // reconstruct the 2-prong secondary vertex + if (df.process(trackD0Prong0ParVarPos1, trackD0Prong1ParVarNeg1) == 0) { + continue; + } + const auto& secondaryVertex = df.getPCACandidate(); + auto chi2PCA = df.getChi2AtPCACandidate(); + auto covMatrixPCA = df.calcPCACovMatrixFlat(); + + registry.fill(HIST("Refit/hCovSVXX"), covMatrixPCA[0]); + registry.fill(HIST("Refit/hCovSVYY"), covMatrixPCA[2]); + registry.fill(HIST("Refit/hCovSVXZ"), covMatrixPCA[3]); + registry.fill(HIST("Refit/hCovSVZZ"), covMatrixPCA[5]); + + // Doubt:................Below, track object are at secondary vertex! + // < track param propagated to V0 candidate (no check for the candidate validity). propagateTracksToVertex must be called in advance + auto trackD0ProngParVar0 = df.getTrack(0); + auto trackD0ProngParVar1 = df.getTrack(1); - std::array pVecPi = {trackPi.px(), trackPi.py(), trackPi.pz()}; - std::array pVecD0Prong0 = {trackD0Prong0.px(), trackD0Prong0.py(), trackD0Prong0.pz()}; - std::array pVecD0Prong1 = {trackD0Prong1.px(), trackD0Prong1.py(), trackD0Prong1.pz()}; + std::array pVecD0Prong0; + std::array pVecD0Prong1; + trackD0ProngParVar0.getPxPyPzGlo(pVecD0Prong0); + trackD0ProngParVar1.getPxPyPzGlo(pVecD0Prong1); + + // This modifies track momenta! + if constexpr (doPvRefit) { + /// use PV refit + /// Using it in the *HfCand3ProngBase/HfCand2ProngBase* all dynamic columns shall take it into account + // coordinates + primaryVertex.setX(rowTrackIndexDstar.pvRefitX()); + primaryVertex.setY(rowTrackIndexDstar.pvRefitY()); + primaryVertex.setZ(rowTrackIndexDstar.pvRefitZ()); + // covariance matrix + primaryVertex.setSigmaX2(rowTrackIndexDstar.pvRefitSigmaX2()); + primaryVertex.setSigmaXY(rowTrackIndexDstar.pvRefitSigmaXY()); + primaryVertex.setSigmaY2(rowTrackIndexDstar.pvRefitSigmaY2()); + primaryVertex.setSigmaXZ(rowTrackIndexDstar.pvRefitSigmaXZ()); + primaryVertex.setSigmaYZ(rowTrackIndexDstar.pvRefitSigmaYZ()); + primaryVertex.setSigmaZ2(rowTrackIndexDstar.pvRefitSigmaZ2()); + covMatrixPV = primaryVertex.getCov(); /// Here covMatrixPV Updated! + } + registry.fill(HIST("Refit/hCovPVXX"), covMatrixPV[0]); + registry.fill(HIST("Refit/hCovPVYY"), covMatrixPV[2]); + registry.fill(HIST("Refit/hCovPVXZ"), covMatrixPV[3]); + registry.fill(HIST("Refit/hCovPVZZ"), covMatrixPV[5]); + + // get track impact parameters + o2::dataformats::DCA impactParameter0; // GPUROOTCartesianFwd.h + o2::dataformats::DCA impactParameter1; + // Propagating D0 prongs to DCA + trackD0ProngParVar0.propagateToDCA(primaryVertex, bz, &impactParameter0); + trackD0ProngParVar1.propagateToDCA(primaryVertex, bz, &impactParameter1); + + // Propagating Soft Pi to DCA + o2::dataformats::DCA impactParameterPi; + trackPiParVar.propagateToDCA(primaryVertex, bz, &impactParameterPi); + registry.fill(HIST("QA/hDcaXYProngsD0"), trackD0Prong0.pt(), impactParameter0.getY() * CmToMicrometers); + registry.fill(HIST("QA/hDcaXYProngsD0"), trackD0Prong1.pt(), impactParameter1.getY() * CmToMicrometers); + registry.fill(HIST("QA/hDcaZProngsD0"), trackD0Prong0.pt(), impactParameter0.getZ() * CmToMicrometers); + registry.fill(HIST("QA/hDcaZProngsD0"), trackD0Prong1.pt(), impactParameter1.getZ() * CmToMicrometers); + + registry.fill(HIST("QA/hDCAXYPi"), trackPi.pt(), impactParameterPi.getY() * CmToMicrometers); + registry.fill(HIST("QA/hDCAZPi"), trackPi.pt(), impactParameterPi.getZ() * CmToMicrometers); + + // get uncertainty of the decay length + double phi, theta; + getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, secondaryVertex, phi, theta); + // Calculates the XX element of a XYZ covariance matrix after rotation of the coordinate system by phi around the z-axis and by minus theta around the new y-axis. + auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixPCA, phi, theta)); + auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.)); + + // Calculation of kinematics for inv mass auto pVecD0 = RecoDecay::pVec(pVecD0Prong0, pVecD0Prong1); - // fill histograms + // D0 pt magnitude + auto ptD0 = RecoDecay::pt(pVecD0); + + // Soft pi momentum vector + std::array pVecSoftPi; + trackPiParVar.getPxPyPzGlo(pVecSoftPi); + + // D* pt magnitude + auto ptDstar = RecoDecay::pt(pVecD0, pVecSoftPi); + + // Fill candidate Table for DStar + rowCandDstarBase(collision.globalIndex(), + primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), + rowTrackIndexDstar.prong0Id(), rowTrackIndexDstar.prongD0Id(), + pVecSoftPi[0], pVecSoftPi[1], pVecSoftPi[2], + impactParameterPi.getY(), std::sqrt(impactParameterPi.getSigmaY2()), + pVecD0Prong0[0], pVecD0Prong0[1], pVecD0Prong0[2], + pVecD0Prong1[0], pVecD0Prong1[1], pVecD0Prong1[2]); + // Fill candidate Table for D0 + rowCandD0Base(collision.globalIndex(), + primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), + secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], + errorDecayLength, errorDecayLengthXY, + chi2PCA, + pVecD0Prong0[0], pVecD0Prong0[1], pVecD0Prong0[2], + pVecD0Prong1[0], pVecD0Prong1[1], pVecD0Prong1[2], + impactParameter0.getY(), impactParameter1.getY(), + std::sqrt(impactParameter0.getSigmaY2()), std::sqrt(impactParameter1.getSigmaY2()), + prongD0.prong0Id(), prongD0.prong1Id(), + prongD0.hfflag()); + if (fillHistograms) { - hPtPi->Fill(RecoDecay::pt(pVecPi)); - hPtD0->Fill(RecoDecay::pt(pVecD0)); - hPtD0Prong0->Fill(RecoDecay::pt(pVecD0Prong0)); - hPtD0Prong1->Fill(RecoDecay::pt(pVecD0Prong1)); - // calculate invariant mass - auto mass = RecoDecay::m(std::array{pVecPi, pVecD0}, std::array{massPi, massD0}); - hMass->Fill(mass); + registry.fill(HIST("QA/hPtD0"), ptD0); + registry.fill(HIST("QA/hPtPi"), RecoDecay::pt(pVecSoftPi)); + registry.fill(HIST("QA/hPtD0Prong0"), RecoDecay::pt(pVecD0Prong0)); + registry.fill(HIST("QA/hPtD0Prong1"), RecoDecay::pt(pVecD0Prong1)); + registry.fill(HIST("QA/hPtDstar"), ptDstar); + } + } + // LOG(info) << "Candidate for loop ends"; + } + + void processPvRefit(aod::Collisions const& collisions, + aod::Hf2Prongs const& rowsTrackIndexD0, + aod::HfDstarsWithPvRefitInfo const& rowsTrackIndexDstar, + aod::TracksWCov const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + runCreatorDstar(collisions, rowsTrackIndexDstar, rowsTrackIndexD0, tracks, bcWithTimeStamps); + } + PROCESS_SWITCH(HfCandidateCreatorDstar, processPvRefit, " Run candidate creator with PV refit", false); + + void processNoPvRefit(aod::Collisions const& collisions, + aod::Hf2Prongs const& rowsTrackIndexD0, + aod::HfDstars const& rowsTrackIndexDstar, + aod::TracksWCov const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + runCreatorDstar(collisions, rowsTrackIndexDstar, rowsTrackIndexD0, tracks, bcWithTimeStamps); + } + PROCESS_SWITCH(HfCandidateCreatorDstar, processNoPvRefit, " Run candidate creator without PV refit", true); +}; + +struct HfCandidateCreatorDstarExpressions { + Spawns rowsCandidateD0; + Produces rowsMcMatchRecD0; + Produces rowsMcMatchGenD0; + + Spawns rowsCandidateDstar; + Produces rowsMcMatchRecDstar; + Produces rowsMcMatchGenDstar; + + void init(InitContext const&) {} + + /// Perform MC Matching. + void processMc(aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles) + { + rowsCandidateD0->bindExternalIndices(&tracks); + rowsCandidateDstar->bindExternalIndices(&tracks); + + int indexRecDstar = -1, indexRecD0 = -1; + int8_t signDstar = 0, signD0 = 0; + int8_t flagDstar = 0, flagD0 = 0; + int8_t originDstar = 0, originD0 = 0; + + // Match reconstructed candidates. + for (const auto& rowCandidateDstar : *rowsCandidateDstar) { + flagDstar = 0; + flagD0 = 0; + originDstar = 0; + originD0 = 0; + + auto indexDstar = rowCandidateDstar.globalIndex(); + auto candD0 = rowsCandidateD0->iteratorAt(indexDstar); + auto candSoftPi = rowCandidateDstar.prongPi_as(); + + auto arrayDaughtersDstar = std::array{candSoftPi, candD0.prong0_as(), candD0.prong1_as()}; + auto arrayDaughtersofD0 = std::array{candD0.prong0_as(), candD0.prong1_as()}; + + // D*± → D0(bar) π± + indexRecDstar = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersDstar, Pdg::kDStar, std::array{+kPiPlus, +kPiPlus, -kKPlus}, true, &signDstar, 2); + // D0(bar) → π± K∓ + indexRecD0 = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersofD0, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD0); + + if (indexRecDstar > -1) { + flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + } + if (indexRecD0 > -1) { + flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiK)); + } + + // check wether the particle is non-promt (from a B0 hadron) + if (flagDstar != 0) { + auto particleDstar = mcParticles.iteratorAt(indexRecDstar); + originDstar = RecoDecay::getCharmHadronOrigin(mcParticles, particleDstar); + } + if (flagD0 != 0) { + auto particleD0 = mcParticles.iteratorAt(indexRecD0); + originD0 = RecoDecay::getCharmHadronOrigin(mcParticles, particleD0); + } + rowsMcMatchRecDstar(flagDstar, originDstar); + rowsMcMatchRecD0(flagD0, originD0); + } + + // Match generated particles. + for (const auto& particle : mcParticles) { + flagDstar = 0; + flagD0 = 0; + originDstar = 0; + originD0 = 0; + + // D*± → D0(bar) π± + if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kDStar, std::array{+kPiPlus, +kPiPlus, -kKPlus}, true, &signDstar, 2)) { + flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + } + // D0(bar) → π± K∓ + if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD0)) { + flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiK)); + } + + // check wether the particle is non-promt (from a B0 hadron) + if (flagDstar != 0) { + originDstar = RecoDecay::getCharmHadronOrigin(mcParticles, particle); + } + if (flagD0 != 0) { + originD0 = RecoDecay::getCharmHadronOrigin(mcParticles, particle); } + rowsMcMatchGenDstar(flagDstar, originDstar); + rowsMcMatchGenD0(flagD0, originD0); } } + PROCESS_SWITCH(HfCandidateCreatorDstarExpressions, processMc, "Process MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx new file mode 100644 index 00000000000..49f6c097898 --- /dev/null +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -0,0 +1,366 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file candidateSelectorDstarToD0Pi.cxx +/// \brief Selection on D*± → D0(bar) π± decay candidates +/// +/// \author Deependra Sharma , IITB +/// \author Fabrizio Grosa , CERN + +// O2 +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Logger.h" +#include "Framework/runDataProcessing.h" +// O2Physics +#include "Common/Core/TrackSelectorPID.h" +// PWGHF +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" + +using namespace o2; +using namespace o2::constants::physics; +using namespace o2::analysis; +using namespace o2::framework; + +// Struct to applying Dstar selection cuts +struct HfCandidateSelectorDstarToD0Pi { + Produces hfSelDstarCandidate; + + // Configurable specific to D0 + Configurable ptD0CandMin{"ptD0CandMin", 0., "Minimum D0 candidate pT"}; + Configurable ptD0CandMax{"ptD0CandMax", 50., "Maximum D0 candidate pT"}; + Configurable> binsPtD0{"binsPtD0", std::vector{hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits for D0"}; + Configurable> cutsD0{"cutsD0", {hf_cuts_d0_to_pi_k::cuts[0], hf_cuts_d0_to_pi_k::nBinsPt, hf_cuts_d0_to_pi_k::nCutVars, hf_cuts_d0_to_pi_k::labelsPt, hf_cuts_d0_to_pi_k::labelsCutVar}, "D0 candidate selection per pT bin"}; + + // Configurable specific to Dstar + Configurable ptDstarCandMin{"ptDstarCandMin", 0., "Minimum Dstar candidate pT"}; + Configurable ptDstarCandMax{"ptDstarCandMax", 50., "Maximum Dstar candidate pT"}; + Configurable> binsPtDstar{"binsPtDstar", std::vector{hf_cuts_dstar_to_d0_pi::vecBinsPt}, "pT bin limits for Dstar"}; + Configurable> cutsDstar{"cutsDstar", {hf_cuts_dstar_to_d0_pi::cuts[0], hf_cuts_dstar_to_d0_pi::nBinsPt, hf_cuts_dstar_to_d0_pi::nCutVars, hf_cuts_dstar_to_d0_pi::labelsPt, hf_cuts_dstar_to_d0_pi::labelsCutVar}, "Dstar candidate selection per pT bin"}; + + // common Configurable + // TPC PID + Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Minimum track pT for TPC PID"}; + Configurable ptPidTpcMax{"ptPidTpcMax", 5., "Maximum track pT for TPC PID"}; + Configurable nSigmaTpcMax{"nSigmaTpcMax", 3., "Nsigma cut on TPC only"}; + Configurable nSigmaTpcCombinedMax{"nSigmaTpcCombinedMax", 5., "Nsigma cut on TPC combined with TOF"}; + + // TOF PID + Configurable ptPidTofMin{"ptPidTofMin", 0.15, "Minimum track pT for TOF PID"}; + Configurable ptPidTofMax{"ptPidTofMax", 5., "Maximum track pT for TOF PID"}; + Configurable nSigmaTofMax{"nSigmaTofMax", 3., "Nsigma cut on TOF only"}; + Configurable nSigmaTofCombinedMax{"nSigmaTofCombinedMax", 5., "Nsigma cut on TOF combined with TPC"}; + + // AND logic for TOF+TPC PID + Configurable usePidTpcAndTof{"usePidTpcAndTof", false, "Use AND logic for TPC and TOF PID"}; + + // selecting only background candidates + Configurable keepOnlySidebandCandidates{"keepOnlySidebandCandidates", false, "Select only sideband candidates, for studying background cut variable distributions"}; + Configurable distanceFromDeltaMassForSidebands{"distanceFromDeltaMassForSidebands", 0.05, "Minimum distance from nominal (D*-D0) mass value for sideband region"}; + + // CCDB configuration + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + + // PDG mass for kaon, pion and D0 + double massD0, massPi, massK; + + TrackSelectorPi selectorPion; + TrackSelectorKa selectorKaon; + + using TracksSel = soa::Join; + // using TracksSel = soa::Join; + using HfFullDstarCandidate = soa::Join; + + void init(InitContext& initContext) + { + massPi = MassPiPlus; + massK = MassKPlus; + massD0 = MassD0; + + selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); + selectorPion.setRangeNSigmaTpc(-nSigmaTpcMax, nSigmaTpcMax); + selectorPion.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedMax, nSigmaTpcCombinedMax); + selectorPion.setRangePtTof(ptPidTofMin, ptPidTofMax); + selectorPion.setRangeNSigmaTof(-nSigmaTofMax, nSigmaTofMax); + selectorPion.setRangeNSigmaTofCondTpc(-nSigmaTofCombinedMax, nSigmaTofCombinedMax); + selectorKaon = selectorPion; + } + + /// Conjugate-independent topological cuts on D0 + /// @brief Topological selection on D0 candidate from Dstar + /// @tparam T table iterator type of the candidate + /// @param candidate candidate instance(object) + /// @return true or false depending on selected or not + template + bool selectionTopolD0(const T& candidate) + { + auto candpT = candidate.ptD0(); + auto binPt = findBin(binsPtD0, candpT); + if (binPt == -1) { + return false; + } + + // check that the candidate pT is within the analysis range + if (candpT < ptD0CandMin || candpT >= ptD0CandMax) { + return false; + } + // product of daughter impact parameters + if (candidate.impactParameterProductD0() > cutsD0->get(binPt, "d0d0")) { + return false; + } + // cosine of pointing angle + if (candidate.cpaD0() < cutsD0->get(binPt, "cos pointing angle")) { + return false; + } + // cosine of pointing angle XY + if (candidate.cpaXYD0() < cutsD0->get(binPt, "cos pointing angle xy")) { + return false; + } + // normalised decay length in XY plane + if (candidate.decayLengthXYNormalisedD0() < cutsD0->get(binPt, "normalized decay length XY")) { + return false; + } + + // Note: follwoing two cuts are not defined in namespace: hf_cuts_d0_to_pi_k of SelectionCuts.h, while are defined in namespace: hf_cuts_dstar_to_d0_pi + // Chi2PCA of secondary vertex reconstruction + if (candidate.chi2PCAD0() > cutsDstar->get(binPt, "chi2PCA")) { + return false; + } + if (candidate.impactParameterXYD0() > cutsD0->get(binPt, "DCA")) { + return false; + } + // d0Prong0Normalised,1 + if (std::abs(candidate.impactParameterNormalised0()) < cutsDstar->get(binPt, "d0Prong0Normalised") || std::abs(candidate.impactParameterNormalised1()) < cutsDstar->get(binPt, "d0Prong1Normalised")) { + return false; + } + + // decay exponentail law, with tau = beta*gamma*ctau + // decay length > ctau retains (1-1/e) + + double decayLengthCut = std::min((candidate.pD0() * 0.0066) + 0.01, cutsD0->get(binPt, "minimum decay length")); + if (candidate.decayLengthD0() * candidate.decayLengthD0() < decayLengthCut * decayLengthCut) { + return false; + } + if (candidate.decayLengthD0() > cutsD0->get(binPt, "decay length")) { + return false; + } + if (candidate.decayLengthXYD0() > cutsD0->get(binPt, "decay length XY")) { + return false; + } + + //.............Why is this if condition commented? + if (candidate.decayLengthNormalisedD0() * candidate.decayLengthNormalisedD0() < 1.0) { + // return false; // add back when getter fixed + } + return true; + } + + /// Conjugate-independent topological cuts on Dstar + /// @brief selection on Dstar candidate + /// @tparam T table iterator type of the candidate + /// @param candidate object + /// @return true or false depending on selected or not + template + bool selectionDstar(const T& candidate) + { + auto ptDstar = candidate.pt(); + auto binPt = findBin(binsPtDstar, ptDstar); + if (binPt == -1) { + return false; + } + // check that the candidate pT is within the analysis range + if (ptDstar < ptDstarCandMin || ptDstar >= ptDstarCandMax) { + return false; + } + // selction on DCA of softpi + if (std::abs(candidate.impParamSoftPi()) > cutsDstar->get(binPt, "d0SoftPi")) { + return false; + } + if (std::abs(candidate.normalisedImpParamSoftPi()) > cutsDstar->get(binPt, "d0SoftPiNormalised")) { + return false; + } + // selection on pT of soft Pi + if ((candidate.ptSoftPi() < cutsDstar->get(binPt, "ptSoftPiMin")) || (candidate.ptSoftPi() > cutsDstar->get(binPt, "ptSoftPiMax"))) { + return false; + } + + // selection on D0Candidate + if (!selectionTopolD0(candidate)) { + return false; + } + return true; + } + + /// @brief Conjugate-dependent topological cuts + /// @tparam T Table iterator type of candidate + /// @param candidate candidate object + /// @return true/false depending on success of selection + template + bool selectionTopolConjugate(const T& candidate) + { + auto ptDstar = candidate.pt(); + auto binPt = findBin(binsPtDstar, ptDstar); + if (binPt == -1) { + return false; + } + auto prongSoftPi = candidate.template prongPi_as(); + double mInvDstar = -999., mInvD0 = -999., mInvAntiDstar = -999., mInvD0Bar = -999.; + + if (prongSoftPi.sign() > 0.) { // Selection of D*+ + mInvDstar = candidate.invMassDstar(); + mInvD0 = candidate.invMassD0(); + if (std::abs(mInvD0 - massD0) > cutsD0->get(binPt, "m")) { + return false; + } + // cut on daughter pT + auto d0prong0 = candidate.template prong0_as(); + auto d0prong1 = candidate.template prong1_as(); + if (d0prong0.pt() < cutsD0->get(binPt, "pT Pi") || d0prong1.pt() < cutsD0->get(binPt, "pT K")) { + return false; + } + // cut on difference of Dstar and D0 invariant mass + if (std::abs(mInvDstar - mInvD0) > cutsDstar->get(binPt, "deltaMInvDstar")) { + return false; + } + // cut on D0 daughter DCA - need to add secondary vertex constraint here + if (std::abs(candidate.impactParameter0()) > cutsD0->get(binPt, "d0pi") || std::abs(candidate.impactParameter1()) > cutsD0->get(binPt, "d0K")) { + return false; + } + // cut on cos(theta*) + if (std::abs(candidate.cosThetaStarD0()) > cutsD0->get(binPt, "cos theta*")) { + return false; + } + + } else if (prongSoftPi.sign() < 0.) { // Selection of D*- + mInvAntiDstar = candidate.invMassAntiDstar(); + mInvD0Bar = candidate.invMassD0Bar(); + if (std::abs(mInvD0Bar - massD0) > cutsD0->get(binPt, "m")) { + return false; + } + // cut on daughter pT + auto d0prong0 = candidate.template prong0_as(); + auto d0prong1 = candidate.template prong1_as(); + if (d0prong0.pt() < cutsD0->get(binPt, "pT K") || d0prong1.pt() < cutsD0->get(binPt, "pT Pi")) { + return false; + } + // cut on difference of Dstar and D0 invariant mass + if (std::abs(mInvAntiDstar - mInvD0Bar) > cutsDstar->get(binPt, "deltaMInvDstar")) { + return false; + } + // cut on D0 daughter DCA - need to add secondary vertex constraint here + if (std::abs(candidate.impactParameter0()) > cutsD0->get(binPt, "d0K") || std::abs(candidate.impactParameter1()) > cutsD0->get(binPt, "d0pi")) { + return false; + } + // cut on cos(theta*) + if (std::abs(candidate.cosThetaStarD0Bar()) > cutsD0->get(binPt, "cos theta*")) { + return false; + } + } + + // in case only sideband candidates have to be stored, additional invariant-mass cut + if (keepOnlySidebandCandidates && prongSoftPi.sign() > 0.) { + if (std::abs((mInvDstar - mInvD0) - massPi) < distanceFromDeltaMassForSidebands) { + return false; + } + } else if (keepOnlySidebandCandidates && prongSoftPi.sign() < 0.) { + if (std::abs((mInvAntiDstar - mInvD0Bar) - massPi) < distanceFromDeltaMassForSidebands) { + return false; + } + } + + return true; + } + + void process(TracksSel const&, + HfFullDstarCandidate const& rowsDstarCand) + { + // LOG(info) << "selector called"; + for (const auto& candDstar : rowsDstarCand) { + // final selection flag: 0 - rejected, 1 - accepted + int statusDstar = 0, statusD0Flag = 0, statusTopol = 0, statusCand = 0, statusPID = 0; + + if (!(candDstar.hfflag() & 1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { + hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); + continue; + } + statusD0Flag = 1; + if (!selectionDstar(candDstar)) { + hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); + continue; + } + statusTopol = 1; + // implement filter bit 4 cut - should be done before this task at the track selection level + // need to add special cuts (additional cuts on decay length and d0 norm) + + // conjugate-dependent topological selection for Dstar + bool topoDstar = selectionTopolConjugate(candDstar); + if (!topoDstar) { + hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); + continue; + } + statusCand = 1; + + // track-level PID selection + int pidTrackPosKaon = -1; + int pidTrackPosPion = -1; + int pidTrackNegKaon = -1; + int pidTrackNegPion = -1; + + if (usePidTpcAndTof) { + pidTrackPosKaon = selectorKaon.statusTpcAndTof(candDstar.prong0_as()); + pidTrackPosPion = selectorPion.statusTpcAndTof(candDstar.prong0_as()); + pidTrackNegKaon = selectorKaon.statusTpcAndTof(candDstar.prong1_as()); + pidTrackNegPion = selectorPion.statusTpcAndTof(candDstar.prong1_as()); + } else { + pidTrackPosKaon = selectorKaon.statusTpcOrTof(candDstar.prong0_as()); + pidTrackPosPion = selectorPion.statusTpcOrTof(candDstar.prong0_as()); + pidTrackNegKaon = selectorKaon.statusTpcOrTof(candDstar.prong1_as()); + pidTrackNegPion = selectorPion.statusTpcOrTof(candDstar.prong1_as()); + } + + int pidDstar = -1; + if (candDstar.prongPi_as().sign() > 0.) { + if (pidTrackPosPion == TrackSelectorPID::Accepted && pidTrackNegKaon == TrackSelectorPID::Accepted) { + pidDstar = 1; // accept D*+ + } else if (pidTrackPosPion == TrackSelectorPID::Rejected && pidTrackNegKaon == TrackSelectorPID::Rejected) { + pidDstar = 0; // reject D*+ + } + } else if (candDstar.prongPi_as().sign() < 0.) { + if (pidTrackNegPion == TrackSelectorPID::Accepted && pidTrackPosKaon == TrackSelectorPID::Accepted) { + pidDstar = 1; // Accept D*- + } else if (pidTrackNegPion == TrackSelectorPID::Rejected && pidTrackPosKaon == TrackSelectorPID::Rejected) { + pidDstar = 0; // reject D*- + } + } + + if (pidDstar == 0) { + hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); + continue; + } + + if ((pidDstar == -1 || pidDstar == 1) && topoDstar) { + statusDstar = 1; // identified as dstar + } + + statusPID = 1; + hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} From 3df964c5457ea6af2e50a0454cab805ec0f387ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 14 Dec 2023 11:58:30 +0100 Subject: [PATCH 061/156] Update codeowners (#4165) --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index 4c222d06b34..76206f02372 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,6 +18,7 @@ /DPG @alibuild @chiarazampolli @noferini /DPG/Tasks/AOTEvent @alibuild @ekryshen @strogolo /DPG/Tasks/AOTTrack @alibuild @mfaggin @belikov @njacazio +/DPG/Tasks/TOF @alibuild @noferini @njacazio /EventFiltering @alibuild @mpuccio @strogolo /EventFiltering/PWGHF @alibuild @fgrosa @zhangbiao-phy @vkucera @mpuccio @strogolo /EventFiltering/PWGUD @alibuild @pbuehler @mpuccio @strogolo From cb5fe0ed9592938a7765f2d9a0c082c2e62d683f Mon Sep 17 00:00:00 2001 From: GijsvWeelden <55794847+GijsvWeelden@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:02:51 +0100 Subject: [PATCH 062/156] PWGJE: Changed default z bins to exclude 0 and include 1 (#4162) Fixed bug in calculation of z Weight is now properly propagated when filling response matrix First attempt at dealing with unmatched particle level jets Added track pt resolution histogram Use V0 mass constants Changed default binnings to even numbers to allow for easier rebinning --- PWGJE/Tasks/jetfragmentation.cxx | 48 +++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/PWGJE/Tasks/jetfragmentation.cxx b/PWGJE/Tasks/jetfragmentation.cxx index 0f68426bca6..719b2b35a2c 100644 --- a/PWGJE/Tasks/jetfragmentation.cxx +++ b/PWGJE/Tasks/jetfragmentation.cxx @@ -24,12 +24,13 @@ #include "Framework/RunningWorkflowInfo.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" + +#include "CommonConstants/PhysicsConstants.h" #include "PWGJE/DataModel/Jet.h" #include "PWGJE/Core/JetFinder.h" -#include "Common/DataModel/PIDResponse.h" - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -53,20 +54,21 @@ struct JetFragmentation { ConfigurableAxis binJetPt{"binJetPt", {40, 0.f, 200.f}, ""}; ConfigurableAxis binEta{"binEta", {20, -1.f, 1.f}, ""}; ConfigurableAxis binPhi{"binPhi", {18 * 8, 0.f, 2. * TMath::Pi()}, ""}; - ConfigurableAxis binZ{"binZ", {40, 0.f, 1.f}, ""}; + ConfigurableAxis binZ{"binZ", {40, 0.0001f, 1.0001f}, ""}; ConfigurableAxis binXi{"binXi", {50, 0.f, 10.f}, ""}; - ConfigurableAxis binTheta{"binTheta", {41, -0.05f, 0.405f}, ""}; + ConfigurableAxis binTheta{"binTheta", {40, -0.05f, 0.395f}, ""}; ConfigurableAxis binJetR{"binJetR", {6, 0.05f, 0.65f}, ""}; ConfigurableAxis binTrackPt{"binTrackPt", {200, 0.f, 100.f}, ""}; ConfigurableAxis binPDG{"binPDG", {static_cast(pdgVector.size()), -0.5f, static_cast(pdgVector.size()) - 0.5f}, ""}; ConfigurableAxis binVtxZ{"binVtxZ", {200, -20, 20}, ""}; - ConfigurableAxis binPtDiff{"binPtDiff", {121, -20.5f, 100.5f}, ""}; - ConfigurableAxis binEtaDiff{"binEtaDiff", {41, -0.205f, 0.205f}, ""}; - ConfigurableAxis binPhiDiff{"binPhiDiff", {41, -0.205f, 0.205f}, ""}; - ConfigurableAxis binZDiff{"binZDiff", {21, -1.05f, 1.05f}, ""}; - ConfigurableAxis binXiDiff{"binXiDiff", {201, -10.5f, 10.5f}, ""}; - ConfigurableAxis binThetaDiff{"binThetaDiff", {201, -10.5f, 10.5f}, ""}; + ConfigurableAxis binPtTrackDiff{"binPtTrackDiff", {121, -20.5f, 100.5f}, ""}; + ConfigurableAxis binPtDiff{"binPtDiff", {600, -299.5f, 300.5f}, ""}; + ConfigurableAxis binEtaDiff{"binEtaDiff", {40, -0.195f, 0.205f}, ""}; + ConfigurableAxis binPhiDiff{"binPhiDiff", {40, -0.195f, 0.205f}, ""}; + ConfigurableAxis binZDiff{"binZDiff", {80, -1.05f, 0.95f}, ""}; + ConfigurableAxis binXiDiff{"binXiDiff", {100, -9.5f, 10.5f}, ""}; + ConfigurableAxis binThetaDiff{"binThetaDiff", {80, -0.35f, 0.45f}, ""}; ConfigurableAxis binPtRatio{"binPtRatio", {100, -0.5f, 9.5f}, ""}; // Ratio of pt, eta, phi ConfigurableAxis binMatchDist{"binMatchDist", {50, 0.f, 0.5f}, ""}; // Distance between matched jets @@ -103,6 +105,7 @@ struct JetFragmentation { AxisSpec pdgAxis = {binPDG, ""}; AxisSpec trackPtAxis = {binTrackPt, "#it{p}_{T}^{tr}"}; + AxisSpec ptTrackDiffAxis = {binPtTrackDiff, "#it{p}_{T}^{particle} - #it{p}_{T}^{track}"}; AxisSpec ptDiffAxis = {binPtDiff, "#it{p}_{T}^{jet, part} - #it{p}_{T}^{jet, det}"}; AxisSpec etaDiffAxis = {binEtaDiff, "#eta^{jet, part} - #eta^{jet, det}"}; AxisSpec phiDiffAxis = {binPhiDiff, "#varphi^{jet, part} - #varphi^{jet, det}"}; @@ -196,6 +199,7 @@ struct JetFragmentation { registry.add("matching/jets/matchPartJetPtResolutionEta", "#eta^{jet, part} - #eta^{jet, det}", HistType::kTH3F, {partJetPtAxis, partEtaAxis, etaDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionPhi", "#phi^{jet, part} - #phi^{jet, det}", HistType::kTH3F, {partJetPtAxis, partPhiAxis, phiDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionChargeFrag", "Resolution #it{p}_{T}^{tr} / #it{p}_{T}^{jet}", HistType::kTH3F, {partJetPtAxis, partZAxis, zDiffAxis}); + registry.add("matching/jets/matchPartJetPtResolutionTrackPt", "Resolution #it{p}_{T}^{track}", HistType::kTH3F, {partJetPtAxis, trackPtAxis, ptTrackDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionTrackProj", "Resolution #it{p}^{proj} / #it{p}^{jet}", HistType::kTH3F, {partJetPtAxis, partZAxis, zDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionXi", "Resolution ln(1/#it{z})", HistType::kTH3F, {partJetPtAxis, partXiAxis, xiDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionTheta", "Resolution #theta", HistType::kTH3F, {partJetPtAxis, partThetaAxis, thetaDiffAxis}); @@ -338,10 +342,10 @@ struct JetFragmentation { detTheta = Theta(detJet, track); detXi = Xi(detJet, track); - partChargeFrag = ChargeFrag(partJet, track); - partTrackProj = TrackProj(partJet, track); - partTheta = Theta(partJet, track); - partXi = Xi(partJet, track); + partChargeFrag = ChargeFrag(partJet, particle); + partTrackProj = TrackProj(partJet, particle); + partTheta = Theta(partJet, particle); + partXi = Xi(partJet, particle); // Detector level registry.fill(HIST("matching/jets/matchDetJetTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), weight); @@ -364,6 +368,7 @@ struct JetFragmentation { registry.fill(HIST("matching/jets/matchPartJetPtZTheta"), partJet.pt(), partTrackProj, partTheta, weight); // Resolution + registry.fill(HIST("matching/jets/matchPartJetPtResolutionTrackPt"), partJet.pt(), particle.pt(), (particle.pt() - track.pt()), weight); registry.fill(HIST("matching/jets/matchPartJetPtResolutionChargeFrag"), partJet.pt(), partChargeFrag, (partChargeFrag - detChargeFrag), weight); registry.fill(HIST("matching/jets/matchPartJetPtResolutionTrackProj"), partJet.pt(), partTrackProj, (partTrackProj - detTrackProj), weight); registry.fill(HIST("matching/jets/matchPartJetPtResolutionXi"), partJet.pt(), partXi, (partXi - detXi), weight); @@ -519,6 +524,7 @@ struct JetFragmentation { McTracks const& tracks, aod::JMcCollisions const& mcCollisions, McPJets const& mcPartJets, + // soa::Join const& mcPartJets aod::JMcParticles const& mcParticles) { double weight = collision.mcCollision().weight(); @@ -535,7 +541,7 @@ struct JetFragmentation { for (const auto& particle : partJet.tracks_as()) { if (track.has_mcParticle() && particle.globalIndex() == track.template mcParticle_as().globalIndex()) { isTrackMatched = true; - fillMatchingHistogramsConstituent(detJet, partJet, track, particle); + fillMatchingHistogramsConstituent(detJet, partJet, track, particle, weight); break; // No need to inspect other particles } // if track has mcParticle and particle is in matched jet } // for particle in matched partJet @@ -553,8 +559,16 @@ struct JetFragmentation { } } // if detJet does not have a match } // for det jet - // TODO: how to deal with misses? - // -> ParticleToDetector table is currently bugged: size does not correspond to ParticleLevelJets (04.06.2023) + // for (const auto& partJet : mcPartJets) { + // // We've already treated the matched jets in the previous loop + // if (!partJet.has_matchedJetGeo()) { + // isFake = false; + // registry.fill(HIST("matching/jets/missPartJetPtEtaPhi"), partJet.pt(), partJet.eta(), partJet.phi(), weight); + // for (const auto& particle : partJet.tracks_as()) { + // fillMatchingFakeOrMiss(partJet, particle, isFake, weight); + // } + // } + // } } PROCESS_SWITCH(JetFragmentation, processMcMatched, "Monte Carlo particle and detector level", false); }; From 31c9abc933a0e1abf7ef1027ea3617c7c92d3421 Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Thu, 14 Dec 2023 13:01:21 +0100 Subject: [PATCH 063/156] PWGCF: FemtoUniverse: FemtoUniverse Tasks readme (#4164) * FemtoUniverse Tasks readme * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot --- PWGCF/FemtoUniverse/Tasks/Femto.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 PWGCF/FemtoUniverse/Tasks/Femto.md diff --git a/PWGCF/FemtoUniverse/Tasks/Femto.md b/PWGCF/FemtoUniverse/Tasks/Femto.md new file mode 100644 index 00000000000..68028b6028e --- /dev/null +++ b/PWGCF/FemtoUniverse/Tasks/Femto.md @@ -0,0 +1,24 @@ +# Welcome to the FemtoUniverse Tasks directory +Here you can find a summary of the tasks and information about who is developing it! + + +| Task name | What it does? | Who is developing it? | +|---------------------------------------------|-----------------------------------|-----------------------| +| femtoUniversePairTaskTrackTrack.cxx | | | +| femtoUniversePairTaskTrackTrackExtended.cxx | | | +| femtoUniversePairTaskTrackPhi.cxx | Angular correlations of h--$\Phi$ | Zuzanna Chochulska | + + + +> **Note:** If you have any issues or questions feel free to contact us via mattermost ;) + + +## FemtoUniverse +That's how FemtoUniverse works! You can find the Producer file in the TableProducer directory + + +```mermaid +graph LR +C[AO2D.root] --> A((FemtoUniverseProducer)) --> D[FemtoAOD.root] --> B((FemtoUniverseTask)) + +``` From e54a839699679f6e3b795ee1b5a616f87499c021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Thu, 14 Dec 2023 13:59:34 +0100 Subject: [PATCH 064/156] DPG: Fix v0 eff (#4167) - move V0 and cascade to dedicated dir. --- DPG/Tasks/AOTTrack/CMakeLists.txt | 21 +------------ DPG/Tasks/AOTTrack/V0Cascades/CMakeLists.txt | 31 +++++++++++++++++++ .../{ => V0Cascades}/perfK0sResolution.cxx | 0 .../AOTTrack/{ => V0Cascades}/qaCascades.cxx | 0 .../{ => V0Cascades}/qaEfficiencyV0s.cxx | 12 +++---- .../qaK0sTrackingEfficiency.cxx | 0 6 files changed, 38 insertions(+), 26 deletions(-) create mode 100644 DPG/Tasks/AOTTrack/V0Cascades/CMakeLists.txt rename DPG/Tasks/AOTTrack/{ => V0Cascades}/perfK0sResolution.cxx (100%) rename DPG/Tasks/AOTTrack/{ => V0Cascades}/qaCascades.cxx (100%) rename DPG/Tasks/AOTTrack/{ => V0Cascades}/qaEfficiencyV0s.cxx (92%) rename DPG/Tasks/AOTTrack/{ => V0Cascades}/qaK0sTrackingEfficiency.cxx (100%) diff --git a/DPG/Tasks/AOTTrack/CMakeLists.txt b/DPG/Tasks/AOTTrack/CMakeLists.txt index 0c9eebff180..866dfbc5546 100644 --- a/DPG/Tasks/AOTTrack/CMakeLists.txt +++ b/DPG/Tasks/AOTTrack/CMakeLists.txt @@ -10,6 +10,7 @@ # or submit itself to any jurisdiction. add_subdirectory(PID) +add_subdirectory(V0Cascades) o2physics_add_dpl_workflow(qa-trackselection SOURCES qaTrackSelection.cxx @@ -36,11 +37,6 @@ o2physics_add_dpl_workflow(qa-efficiency PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(qa-efficiency-v0s - SOURCES qaEfficiencyV0s.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(qa-match-eff SOURCES qaMatchEff.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -54,21 +50,6 @@ o2physics_add_dpl_workflow(qa-impact-parameter O2::DetectorsVertexing COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(qa-k0s-tracking-efficiency - SOURCES qaK0sTrackingEfficiency.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(perf-k0s-resolution - SOURCES perfK0sResolution.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(qa-cascades - SOURCES qaCascades.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(monitorfilterbit SOURCES MonitorFilterBit.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/DPG/Tasks/AOTTrack/V0Cascades/CMakeLists.txt b/DPG/Tasks/AOTTrack/V0Cascades/CMakeLists.txt new file mode 100644 index 00000000000..826f1af6a04 --- /dev/null +++ b/DPG/Tasks/AOTTrack/V0Cascades/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2physics_add_dpl_workflow(qa-efficiency-v0s + SOURCES qaEfficiencyV0s.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(qa-k0s-tracking-efficiency + SOURCES qaK0sTrackingEfficiency.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(perf-k0s-resolution + SOURCES perfK0sResolution.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(qa-cascades + SOURCES qaCascades.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + diff --git a/DPG/Tasks/AOTTrack/perfK0sResolution.cxx b/DPG/Tasks/AOTTrack/V0Cascades/perfK0sResolution.cxx similarity index 100% rename from DPG/Tasks/AOTTrack/perfK0sResolution.cxx rename to DPG/Tasks/AOTTrack/V0Cascades/perfK0sResolution.cxx diff --git a/DPG/Tasks/AOTTrack/qaCascades.cxx b/DPG/Tasks/AOTTrack/V0Cascades/qaCascades.cxx similarity index 100% rename from DPG/Tasks/AOTTrack/qaCascades.cxx rename to DPG/Tasks/AOTTrack/V0Cascades/qaCascades.cxx diff --git a/DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx b/DPG/Tasks/AOTTrack/V0Cascades/qaEfficiencyV0s.cxx similarity index 92% rename from DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx rename to DPG/Tasks/AOTTrack/V0Cascades/qaEfficiencyV0s.cxx index 0476d724b22..a728b252007 100644 --- a/DPG/Tasks/AOTTrack/qaEfficiencyV0s.cxx +++ b/DPG/Tasks/AOTTrack/V0Cascades/qaEfficiencyV0s.cxx @@ -69,14 +69,14 @@ struct QaEfficiencyV0s { for (int i = 0; i < nSpecies; i++) { // MC efficiency (PDG code - histograms[i][kHistoPtNum] = registry.add(Form("Pt/Num_%i", PDGs[i]), Form("Num %i", PDGs[i]), kTH1F, {axisPt}); - histograms[i][kHistoPtDen] = registry.add(Form("Pt/Den_%i", PDGs[i]), Form("Den %i", PDGs[i]), kTH1F, {axisPt}); + histograms[i][kHistoPtNum] = registry.add(Form("Pt/Num_pdg%i", PDGs[i]), Form("Num %i", PDGs[i]), kTH1F, {axisPt}); + histograms[i][kHistoPtDen] = registry.add(Form("Pt/Den_pdg%i", PDGs[i]), Form("Den %i", PDGs[i]), kTH1F, {axisPt}); - histogramsPrm[i][kHistoPtNum] = registry.add(Form("Pt/Prm/Num_%i", PDGs[i]), Form("Pt Prm Num %i", PDGs[i]), kTH1F, {axisPt}); - histogramsPrm[i][kHistoPtDen] = registry.add(Form("Pt/Prm/Den_%i", PDGs[i]), Form("Pt Prm Den %i", PDGs[i]), kTH1F, {axisPt}); + histogramsPrm[i][kHistoPtNum] = registry.add(Form("Pt/Prm/Num_pdg%i", PDGs[i]), Form("Pt Prm Num %i", PDGs[i]), kTH1F, {axisPt}); + histogramsPrm[i][kHistoPtDen] = registry.add(Form("Pt/Prm/Den_pdg%i", PDGs[i]), Form("Pt Prm Den %i", PDGs[i]), kTH1F, {axisPt}); - histogramsPrmRap[i][kHistoPtNum] = registry.add(Form("Pt/Prm/Rap/PtNum_%i", PDGs[i]), Form("Pt Prm Rap Num %i", PDGs[i]), kTH1F, {axisPt}); - histogramsPrmRap[i][kHistoPtDen] = registry.add(Form("Pt/Prm/Rap/PtDen_%i", PDGs[i]), Form("Pt Prm Rap Den %i", PDGs[i]), kTH1F, {axisPt}); + histogramsPrmRap[i][kHistoPtNum] = registry.add(Form("Pt/Prm/Rap/PtNum_pdg%i", PDGs[i]), Form("Pt Prm Rap Num %i", PDGs[i]), kTH1F, {axisPt}); + histogramsPrmRap[i][kHistoPtDen] = registry.add(Form("Pt/Prm/Rap/PtDen_pdg%i", PDGs[i]), Form("Pt Prm Rap Den %i", PDGs[i]), kTH1F, {axisPt}); TAxis* axis = histograms[i][0]->GetXaxis(); listEfficiencyMC->Add(new TEfficiency(Form("efficiencyPt_pdg%d", PDGs[i]), Form("efficiencyPt_pdg%d", PDGs[i]), axis->GetNbins(), axis->GetXmin(), axis->GetXmax())); diff --git a/DPG/Tasks/AOTTrack/qaK0sTrackingEfficiency.cxx b/DPG/Tasks/AOTTrack/V0Cascades/qaK0sTrackingEfficiency.cxx similarity index 100% rename from DPG/Tasks/AOTTrack/qaK0sTrackingEfficiency.cxx rename to DPG/Tasks/AOTTrack/V0Cascades/qaK0sTrackingEfficiency.cxx From 9983f4a98d251c26239c518d1a5bcb4b50f696b3 Mon Sep 17 00:00:00 2001 From: eloviyo <38348689+Eloviyo@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:29:38 +0100 Subject: [PATCH 065/156] updated TaskV0 info and modified its name (#4168) Co-authored-by: Shirajum Monira --- PWGCF/FemtoUniverse/Tasks/CMakeLists.txt | 4 ++-- PWGCF/FemtoUniverse/Tasks/Femto.md | 2 +- ...0.cxx => femtoUniversePairTaskTrackV0Extended.cxx} | 11 +++++------ 3 files changed, 8 insertions(+), 9 deletions(-) rename PWGCF/FemtoUniverse/Tasks/{femtoUniversePairTaskTrackV0.cxx => femtoUniversePairTaskTrackV0Extended.cxx} (97%) diff --git a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt index 88a89cd7f43..42fd16acda3 100644 --- a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt @@ -34,8 +34,8 @@ o2physics_add_dpl_workflow(femtouniverse-debug-track PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(femtouniverse-pair-track-v0 - SOURCES femtoUniversePairTaskTrackV0.cxx +o2physics_add_dpl_workflow(femtouniverse-pair-track-v0-extended + SOURCES femtoUniversePairTaskTrackV0Extended.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/PWGCF/FemtoUniverse/Tasks/Femto.md b/PWGCF/FemtoUniverse/Tasks/Femto.md index 68028b6028e..d2c6926a52d 100644 --- a/PWGCF/FemtoUniverse/Tasks/Femto.md +++ b/PWGCF/FemtoUniverse/Tasks/Femto.md @@ -7,7 +7,7 @@ Here you can find a summary of the tasks and information about who is developing | femtoUniversePairTaskTrackTrack.cxx | | | | femtoUniversePairTaskTrackTrackExtended.cxx | | | | femtoUniversePairTaskTrackPhi.cxx | Angular correlations of h--$\Phi$ | Zuzanna Chochulska | - +| femtoUniversePairTaskTrackV0Extended.cxx | Angular correlations of h--V0 | Shirajum Monira > **Note:** If you have any issues or questions feel free to contact us via mattermost ;) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx similarity index 97% rename from PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx rename to PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index edb0b5abb7c..64a824f1cbb 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -9,8 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file femtoUniversePairTaskTrackTrack.cxx -/// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks +/// \brief Tasks that build pairs of track particles and v0s /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zuzanna.chochulska.stud@pw.edu.pl /// \author Shirajum Monira, WUT Warsaw, shirajum.monira.dokt@pw.edu.pl @@ -37,7 +36,7 @@ using namespace o2::framework::expressions; using namespace o2::analysis::femtoUniverse; using namespace o2::aod::pidutils; -struct femtoUniversePairTaskTrackV0 { +struct femtoUniversePairTaskTrackV0Extended { SliceCache cache; // using FemtoFullParticles = soa::Join; @@ -208,7 +207,7 @@ struct femtoUniversePairTaskTrackV0 { } } - PROCESS_SWITCH(femtoUniversePairTaskTrackV0, processSameEvent, "Enable processing same event", true); + PROCESS_SWITCH(femtoUniversePairTaskTrackV0Extended, processSameEvent, "Enable processing same event", true); /// This function processes the mixed event void processMixedEvent(o2::aod::FDCollisions& cols, FemtoFullParticles& parts) @@ -251,13 +250,13 @@ struct femtoUniversePairTaskTrackV0 { } } - PROCESS_SWITCH(femtoUniversePairTaskTrackV0, processMixedEvent, "Enable processing mixed events", true); + PROCESS_SWITCH(femtoUniversePairTaskTrackV0Extended, processMixedEvent, "Enable processing mixed events", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } From de54b642b6955f8ba74841fdf9725babb3e68930 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Fri, 15 Dec 2023 08:24:08 +0100 Subject: [PATCH 066/156] fixed calculation of Rmax (#4171) --- PWGLF/Tasks/nuclei_in_jets.cxx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 924a5821757..2c334d585b1 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -124,13 +124,13 @@ struct nuclei_in_jets { registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("pt_leading", "pt leading", HistType::kTH1F, {{500, 0, 50, "#it{p}_{T} (GeV/#it{c})"}}); - registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, 0.0, TMath::Pi(), "#Delta#phi"}}); - registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, 0.0, TMath::Pi(), "#Delta#phi"}}); - registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{100, 0.0, 2.0, "#it{R}_{max}"}}); - registryQC.add("r_jet", "R jet", HistType::kTH1F, {{100, 0.0, 0.8, "#it{R}"}}); - registryQC.add("r_ue", "R ue", HistType::kTH1F, {{100, 0.0, 0.8, "#it{R}"}}); + registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, -TMath::Pi(), TMath::Pi(), "#Delta#phi"}}); + registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, -TMath::Pi(), TMath::Pi(), "#Delta#phi"}}); + registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{200, 0.0, 6.0, "#it{R}_{max}"}}); + registryQC.add("r_jet", "R jet", HistType::kTH1F, {{200, 0.0, 1.0, "#it{R}"}}); + registryQC.add("r_ue", "R ue", HistType::kTH1F, {{200, 0.0, 1.0, "#it{R}"}}); registryQC.add("eta_leading", "eta_leading", HistType::kTH1F, {{100, -1, 1, "#eta"}}); - registryQC.add("phi_leading", "phi_leading", HistType::kTH1F, {{100, 0, TMath::Pi(), "#phi"}}); + registryQC.add("phi_leading", "phi_leading", HistType::kTH1F, {{100, -TMath::Pi(), TMath::Pi(), "#phi"}}); // Antiprotons registryData.add("antiproton_jet_tpc", "antiproton_jet_tpc", HistType::kTH3F, {{20, 0.0, 1.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); @@ -465,7 +465,7 @@ struct nuclei_in_jets { float one_over_pt2_part = 1.0 / (p_particle.Pt() * p_particle.Pt()); float one_over_pt2_lead = 1.0 / (p_leading.Pt() * p_leading.Pt()); float deltaEta = p_particle.Eta() - p_leading.Eta(); - float deltaPhi = TVector2::Phi_0_2pi(p_particle.Phi() - p_leading.Phi()); + float deltaPhi = p_particle.Phi() - p_leading.Phi(); float min = Minimum(one_over_pt2_part, one_over_pt2_lead); float Delta2 = deltaEta * deltaEta + deltaPhi * deltaPhi; @@ -518,7 +518,7 @@ struct nuclei_in_jets { // QA Plots registryQC.fill(HIST("eta_leading"), p_leading.Eta()); - registryQC.fill(HIST("phi_leading"), TVector2::Phi_0_2pi(p_leading.Phi())); + registryQC.fill(HIST("phi_leading"), p_leading.Phi()); // Find Maximum Distance from Jet Axis float Rmax(0); @@ -529,7 +529,7 @@ struct nuclei_in_jets { TVector3 p_i(jet_track.px(), jet_track.py(), jet_track.pz()); float deltaEta = p_i.Eta() - p_leading.Eta(); - float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); + float deltaPhi = (p_i.Phi() - p_leading.Phi()); float R = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); if (R > Rmax) Rmax = R; @@ -577,7 +577,7 @@ struct nuclei_in_jets { // Variables float deltaEta = ue_track.eta() - ue_axis.Eta(); - float deltaPhi = TVector2::Phi_0_2pi(ue_track.phi() - ue_axis.Phi()); + float deltaPhi = ue_track.phi() - ue_axis.Phi(); float dr = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); // Store Particles in the UE @@ -603,7 +603,7 @@ struct nuclei_in_jets { TVector3 p_i(jet_track.px(), jet_track.py(), jet_track.pz()); float deltaEta = p_i.Eta() - p_leading.Eta(); - float deltaPhi = TVector2::Phi_0_2pi(p_i.Phi() - p_leading.Phi()); + float deltaPhi = p_i.Phi() - p_leading.Phi(); if (deltaEta != 0 && deltaPhi != 0) { registryQC.fill(HIST("eta_phi_jet"), deltaEta, deltaPhi); registryQC.fill(HIST("r_jet"), TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi)); From e26cdac7f6f5c88ce67bfcff2358d1b475b0d776 Mon Sep 17 00:00:00 2001 From: vbarbaso <146095385+vbarbaso@users.noreply.github.com> Date: Fri, 15 Dec 2023 08:46:04 +0100 Subject: [PATCH 067/156] [PWGLF] MC histograms are not produced for data (#4154) Co-authored-by: Veronika Barbasova --- PWGLF/Tasks/phianalysisTHnSparse.cxx | 195 +++++++++++++-------------- 1 file changed, 95 insertions(+), 100 deletions(-) diff --git a/PWGLF/Tasks/phianalysisTHnSparse.cxx b/PWGLF/Tasks/phianalysisTHnSparse.cxx index 48219fc2e7f..a72a318204a 100644 --- a/PWGLF/Tasks/phianalysisTHnSparse.cxx +++ b/PWGLF/Tasks/phianalysisTHnSparse.cxx @@ -34,6 +34,7 @@ struct phianalysisTHnSparse { SliceCache cache; + Configurable produceTrue{"produce-true", false, "Produce True and Gen histograms."}; Configurable verboselevel{"verbose-level", 0, "Verbose level"}; Configurable refresh{"print-refresh", 0, "Freqency of print event information."}; Configurable refresh_index{"print-refresh-index", 0, "Freqency of print event information index."}; @@ -47,7 +48,7 @@ struct phianalysisTHnSparse { ConfigurableAxis invaxis{"invAxis", {130, 0.97, 1.1}, "Invariant mass axis binning."}; ConfigurableAxis ptaxis{"ptAxis", {20, 0., 20.}, "Pt axis binning."}; - ConfigurableAxis mcposZ{"mcposZ", {40, -20., 20.}, "Z vertex position axis binning."}; + ConfigurableAxis posZ{"posZ", {40, -20., 20.}, "Z vertex position axis binning."}; ConfigurableAxis multiplicityaxis{"multiplicityAxis", {50, 0., 5000.}, "Multiplicity axis binning."}; ConfigurableAxis rapidityaxis{"rapidityAxis", {10., -1.0 * rapidityCut, rapidityCut}, "Rapidity axis binning."}; ConfigurableAxis nsigmatrackaxis{"nsigmatrackaxis", {300, -15., 15.}, "NSigma axis binning."}; @@ -55,13 +56,9 @@ struct phianalysisTHnSparse { ConfigurableAxis nsigmaaxis2{"nsigmaAxis2", {1, 0., tpcnSigma2}, "NSigma axis binning in THnSparse."}; HistogramRegistry registry{"registry", - {{"hNsigmaPos", "hNsigmaPos", {HistType::kTH1F, {nsigmatrackaxis}}}, - {"hNsigmaNeg", "hNsigmaNeg", {HistType::kTH1F, {nsigmatrackaxis}}}, - {"motherGen", "motherGen", {HistType::kTH1F, {ptaxis}}}, - {"motherTrue", "motherTrue", {HistType::kTH1F, {ptaxis}}}, - {"motherBgr", "motherBgr", {HistType::kTH1F, {ptaxis}}}, - {"mcTrueposZ", "mcTrueposZ", {HistType::kTH1F, {mcposZ}}}, - {"mcGenposZ", "mcGenposZ", {HistType::kTH1F, {mcposZ}}}}}; + { + {"hVz", "Z Vertex", {HistType::kTH1F, {posZ}}}, + }}; // defined in DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h float mass1 = o2::track::PID::getMass(dauther1); @@ -101,12 +98,14 @@ struct phianalysisTHnSparse { AxisSpec nsigmatrackaxis1 = {nsigmaaxis1, fmt::format("nSigma particle 1({})", mass1), "ns1"}; AxisSpec nsigmatrackaxis2 = {nsigmaaxis1, fmt::format("nSigma particle 2({})", mass2), "ns2"}; HistogramConfigSpec pairHisto({HistType::kTHnSparseF, {invAxis, ptAxis, mAxis, nsigmatrackaxis1, nsigmatrackaxis2, yAxis}}); - registry.add("unlike", "Unlike", pairHisto); - registry.add("likep", "Likep", pairHisto); - registry.add("liken", "Liken", pairHisto); - registry.add("unlikeTrue", "UnlikeTrue", pairHisto); - registry.add("unlikeGen", "UnlikeGen", pairHisto); + registry.add("unlikepm", "Unlike PM", pairHisto); + registry.add("likepp", "Like PP", pairHisto); + registry.add("likemm", "Like MM", pairHisto); + if (produceTrue) { + registry.add("unlikepmTrue", "Unlike True PM", pairHisto); + registry.add("unlikepmGen", "Unlike Gen PM", pairHisto); + } } template @@ -149,13 +148,9 @@ struct phianalysisTHnSparse { LOGF(info, "pos=%lld neg=%lld, Z vertex position: %f [cm], %d, mult:%f.0", posDauthers.size(), negDauthers.size(), collision.posZ(), collision.globalIndex(), multiplicity); - for (const auto& trk : posDauthers) { - registry.fill(HIST("hNsigmaPos"), trk.tpcNSigmaKa()); - } - - for (const auto& trk : negDauthers) { - registry.fill(HIST("hNsigmaNeg"), trk.tpcNSigmaKa()); - } + if (std::abs(collision.posZ()) > zVertex) + return; + registry.fill(HIST("hVz"), collision.posZ()); for (auto& [track1, track2] : combinations(o2::soa::CombinationsUpperIndexPolicy(posDauthers, negDauthers))) { @@ -170,7 +165,7 @@ struct phianalysisTHnSparse { if (verboselevel > 1) LOGF(info, "Unlike-sign: d1=%ld , d2=%ld , mother=%f", track1.globalIndex(), track2.globalIndex(), mother.Mag()); - registry.fill(HIST("unlike"), mother.Mag(), mother.Pt(), multiplicity, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); + registry.fill(HIST("unlikepm"), mother.Mag(), mother.Pt(), multiplicity, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); } for (auto& [track1, track2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posDauthers, posDauthers))) { @@ -186,7 +181,7 @@ struct phianalysisTHnSparse { if (verboselevel > 1) LOGF(info, "Like-sign positive: d1=%ld , d2=%ld , mother=%f", track1.globalIndex(), track2.globalIndex(), mother.Mag()); - registry.fill(HIST("likep"), mother.Mag(), mother.Pt(), multiplicity, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); + registry.fill(HIST("likepp"), mother.Mag(), mother.Pt(), multiplicity, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); } for (auto& [track1, track2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negDauthers, negDauthers))) { @@ -202,7 +197,7 @@ struct phianalysisTHnSparse { if (verboselevel > 1) LOGF(info, "Like-sign negative: d1=%ld , d2=%ld , mother=%f", track1.globalIndex(), track2.globalIndex(), mother.Mag()); - registry.fill(HIST("liken"), mother.Mag(), mother.Pt(), multiplicity, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); + registry.fill(HIST("likemm"), mother.Mag(), mother.Pt(), multiplicity, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); } } @@ -210,6 +205,9 @@ struct phianalysisTHnSparse { void processTrue(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const& mcParticles, aod::McCollisions const& mcCollisions) { + if (!produceTrue) + return; + auto posDauthersMC = positiveMC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negDauthersMC = negativeMC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -218,63 +216,61 @@ struct phianalysisTHnSparse { return; } - if (std::abs(collision.posZ()) < zVertex) { - registry.fill(HIST("mcTrueposZ"), collision.posZ()); + if (std::abs(collision.posZ()) > zVertex) + return; - multiplicityMC = collision.multFT0A() + collision.multFT0C(); + multiplicityMC = collision.multFT0A() + collision.multFT0C(); - for (auto& [track1, track2] : combinations(o2::soa::CombinationsUpperIndexPolicy(posDauthersMC, negDauthersMC))) { + for (auto& [track1, track2] : combinations(o2::soa::CombinationsUpperIndexPolicy(posDauthersMC, negDauthersMC))) { - if (!track1.has_mcParticle()) { - LOGF(warning, "No MC particle for track, skip..."); - continue; - } + if (!track1.has_mcParticle()) { + LOGF(warning, "No MC particle for track, skip..."); + continue; + } - if (!track2.has_mcParticle()) { - LOGF(warning, "No MC particle for track, skip..."); - continue; - } + if (!track2.has_mcParticle()) { + LOGF(warning, "No MC particle for track, skip..."); + continue; + } - if (!selectedTrack(track1)) - continue; + if (!selectedTrack(track1)) + continue; - if (!selectedTrack(track2)) - continue; + if (!selectedTrack(track2)) + continue; - const auto mctrack1 = track1.mcParticle(); - const auto mctrack2 = track2.mcParticle(); - int track1PDG = std::abs(mctrack1.pdgCode()); - int track2PDG = std::abs(mctrack2.pdgCode()); + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); - if (!(track1PDG == 321 && track2PDG == 321)) { - continue; - } - for (auto& mothertrack1 : mctrack1.mothers_as()) { - for (auto& mothertrack2 : mctrack2.mothers_as()) { - if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) - continue; + if (!(track1PDG == 321 && track2PDG == 321)) { + continue; + } + for (auto& mothertrack1 : mctrack1.mothers_as()) { + for (auto& mothertrack2 : mctrack2.mothers_as()) { + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) + continue; - if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) - continue; + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) + continue; - if (std::abs(mothertrack1.y()) > rapidityCut) - continue; + if (std::abs(mothertrack1.y()) > rapidityCut) + continue; - if (std::abs(mothertrack2.y()) > rapidityCut) - continue; + if (std::abs(mothertrack2.y()) > rapidityCut) + continue; - if (std::abs(mothertrack1.pdgCode()) != 333) - continue; + if (std::abs(mothertrack1.pdgCode()) != 333) + continue; - registry.fill(HIST("motherTrue"), mothertrack1.pt()); - n++; - if (verboselevel > 1) - LOGF(info, "True: %d, d1=%d (%ld), d2=%d (%ld), mother=%d (%ld)", n, mctrack1.pdgCode(), mctrack1.globalIndex(), mctrack2.pdgCode(), mctrack2.globalIndex(), mothertrack1.pdgCode(), mothertrack1.globalIndex()); + n++; + if (verboselevel > 1) + LOGF(info, "True: %d, d1=%d (%ld), d2=%d (%ld), mother=%d (%ld)", n, mctrack1.pdgCode(), mctrack1.globalIndex(), mctrack2.pdgCode(), mctrack2.globalIndex(), mothertrack1.pdgCode(), mothertrack1.globalIndex()); - if (!selectedPair(mother, mctrack1, mctrack2)) - continue; - registry.fill(HIST("unlikeTrue"), mother.Mag(), mother.Pt(), multiplicityMC, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); - } + if (!selectedPair(mother, mctrack1, mctrack2)) + continue; + registry.fill(HIST("unlikepmTrue"), mother.Mag(), mother.Pt(), multiplicityMC, std::abs(track1.tpcNSigmaKa()), std::abs(track2.tpcNSigmaKa()), mother.Rapidity()); } } } @@ -286,51 +282,50 @@ struct phianalysisTHnSparse { void processGen(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) { - if (std::abs(mcCollision.posZ()) < zVertex) { - registry.fill(HIST("mcGenposZ"), mcCollision.posZ()); + if (!produceTrue) + return; - int nuberofPhi = 0; + if (std::abs(mcCollision.posZ()) > zVertex) + return; - for (auto& particle : mcParticles) { - if (std::abs(particle.y()) > rapidityCut) - continue; + int nuberofPhi = 0; - if (particle.pdgCode() == 333) { - auto daughters = particle.daughters_as(); - if (daughters.size() != 2) - continue; + for (auto& particle : mcParticles) { + if (std::abs(particle.y()) > rapidityCut) + continue; - auto daup = false; - auto daun = false; + if (particle.pdgCode() == 333) { + auto daughters = particle.daughters_as(); + if (daughters.size() != 2) + continue; - for (auto& dau : daughters) { - if (!dau.isPhysicalPrimary()) - continue; + auto daup = false; + auto daun = false; - if (dau.pdgCode() == +321) { - daup = true; - d1.SetXYZM(dau.px(), dau.py(), dau.pz(), mass1); - } else if (dau.pdgCode() == -321) { - daun = true; - d2.SetXYZM(dau.px(), dau.py(), dau.pz(), mass2); - } - } - if (!daup && !daun) + for (auto& dau : daughters) { + if (!dau.isPhysicalPrimary()) continue; - mother = d1 + d2; + if (dau.pdgCode() == +321) { + daup = true; + d1.SetXYZM(dau.px(), dau.py(), dau.pz(), mass1); + } else if (dau.pdgCode() == -321) { + daun = true; + d2.SetXYZM(dau.px(), dau.py(), dau.pz(), mass2); + } + } + if (!daup && !daun) + continue; - registry.fill(HIST("unlikeGen"), mother.Mag(), mother.Pt(), multiplicityMC, tpcnSigma1 / 2.0, tpcnSigma2 / 2.0, mother.Rapidity()); - registry.fill(HIST("motherGen"), particle.pt()); + mother = d1 + d2; - nuberofPhi++; - numberofEntries++; + registry.fill(HIST("unlikepmGen"), mother.Mag(), mother.Pt(), multiplicityMC, tpcnSigma1 / 2.0, tpcnSigma2 / 2.0, mother.Rapidity()); - if (verboselevel > 1) - LOGF(info, "Gen: %d, #Phi =%d, mother=%d (%ld), Inv.mass:%f, Pt= %f", numberofEntries, nuberofPhi, particle.pdgCode(), particle.globalIndex(), mother.Mag(), mother.Pt()); - } else { - registry.fill(HIST("motherBgr"), particle.pt()); - } + nuberofPhi++; + numberofEntries++; + + if (verboselevel > 1) + LOGF(info, "Gen: %d, #Phi =%d, mother=%d (%ld), Inv.mass:%f, Pt= %f", numberofEntries, nuberofPhi, particle.pdgCode(), particle.globalIndex(), mother.Mag(), mother.Pt()); } } } From a9c93235ee044da0d32c9a2bd3dc4c6306d65946 Mon Sep 17 00:00:00 2001 From: JBae <110481228+joonsukbae@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:44:56 +0900 Subject: [PATCH 068/156] PWGJE: Broader area range for larger R (#4112) * PWGJE: Broader area range for larger R * broaden jet area range for all QA tasks with proper bins --- PWGJE/Tasks/jetfinderQA.cxx | 2 +- PWGJE/Tasks/jetfinderfullQA.cxx | 2 +- PWGJE/Tasks/jetfinderhfQA.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PWGJE/Tasks/jetfinderQA.cxx b/PWGJE/Tasks/jetfinderQA.cxx index e27fee89222..8a164639ded 100644 --- a/PWGJE/Tasks/jetfinderQA.cxx +++ b/PWGJE/Tasks/jetfinderQA.cxx @@ -83,7 +83,7 @@ struct JetFinderQATask { registry.add("h3_jet_r_jet_pt_jet_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_eta_jet_phi", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, 0., 1.}}}); + registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); registry.add("h3_jet_r_jet_pt_track_pt", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_jet_pt_track_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); diff --git a/PWGJE/Tasks/jetfinderfullQA.cxx b/PWGJE/Tasks/jetfinderfullQA.cxx index 85cc7e7060d..3058e3f4028 100644 --- a/PWGJE/Tasks/jetfinderfullQA.cxx +++ b/PWGJE/Tasks/jetfinderfullQA.cxx @@ -93,7 +93,7 @@ struct JetFinderFullQATask { registry.add("h3_jet_r_jet_eta_jet_phi", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); registry.add("h3_jet_r_jet_pt_jet_nclusters", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet clusters}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, 0., 1.}}}); + registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); registry.add("h3_jet_r_jet_pt_track_pt", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_jet_pt_track_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); diff --git a/PWGJE/Tasks/jetfinderhfQA.cxx b/PWGJE/Tasks/jetfinderhfQA.cxx index 1a64ff6d627..47ffd673fe9 100644 --- a/PWGJE/Tasks/jetfinderhfQA.cxx +++ b/PWGJE/Tasks/jetfinderhfQA.cxx @@ -104,7 +104,7 @@ struct JetFinderHFQATask { registry.add("h3_jet_r_jet_pt_jet_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_eta_jet_phi", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, 0., 1.}}}); + registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); registry.add("h3_jet_r_jet_pt_track_pt", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_jet_pt_track_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); From 71ec725c20973ebbd67a384c820179e7d4f9ff8f Mon Sep 17 00:00:00 2001 From: "Maja Karwowska (Kabus)" Date: Fri, 15 Dec 2023 12:06:28 +0100 Subject: [PATCH 069/156] Rename candidateSelectorLcMl (#4169) --- PWGHF/TableProducer/CMakeLists.txt | 4 ++-- ...candidateSelectorLcMl.cxx => candidateSelectorLcPidMl.cxx} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename PWGHF/TableProducer/{candidateSelectorLcMl.cxx => candidateSelectorLcPidMl.cxx} (100%) diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index 0468776625b..36653de5807 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -125,8 +125,8 @@ o2physics_add_dpl_workflow(candidate-selector-lc PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(candidate-selector-lc-ml - SOURCES candidateSelectorLcMl.cxx +o2physics_add_dpl_workflow(candidate-selector-lc-pid-ml + SOURCES candidateSelectorLcPidMl.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) diff --git a/PWGHF/TableProducer/candidateSelectorLcMl.cxx b/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx similarity index 100% rename from PWGHF/TableProducer/candidateSelectorLcMl.cxx rename to PWGHF/TableProducer/candidateSelectorLcPidMl.cxx From a181b6c8646f63f21d3330e08eb11fb66acc7619 Mon Sep 17 00:00:00 2001 From: nzardosh Date: Fri, 15 Dec 2023 12:07:35 +0000 Subject: [PATCH 070/156] PWGJE : Adding the ability to cut on pT hat in the QA tasks (#4173) Co-authored-by: Nima Zardoshti --- PWGJE/Tasks/jetfinderQA.cxx | 23 +++++++++++++++++++++++ PWGJE/Tasks/jetfinderfullQA.cxx | 26 ++++++++++++++++++++++++++ PWGJE/Tasks/jetfinderhfQA.cxx | 25 +++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/PWGJE/Tasks/jetfinderQA.cxx b/PWGJE/Tasks/jetfinderQA.cxx index 8a164639ded..5d8aa9d7be7 100644 --- a/PWGJE/Tasks/jetfinderQA.cxx +++ b/PWGJE/Tasks/jetfinderQA.cxx @@ -52,6 +52,10 @@ struct JetFinderQATask { Configurable trackPtMin{"trackPtMin", 0.15, "minimum pT acceptance for tracks"}; Configurable trackPtMax{"trackPtMax", 100.0, "maximum pT acceptance for tracks"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; + Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; + Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; + Configurable pTHatExponent{"pTHatExponent", 0.1666, "exponent of the event weight for the calculation of pTHat"}; + std::vector filledJetR; std::vector jetRadiiValues; @@ -176,6 +180,11 @@ struct JetFinderQATask { void fillHistograms(T const& jet, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (jet.pt() > pTHatMaxMCD * pTHat) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_jet_eta"), jet.eta(), weight); @@ -201,6 +210,11 @@ struct JetFinderQATask { void fillMCPHistograms(T const& jet, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (jet.pt() > pTHatMaxMCP * pTHat) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); registry.fill(HIST("h_jet_eta_part"), jet.eta(), weight); @@ -224,8 +238,17 @@ struct JetFinderQATask { template void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (mcdjet.pt() > pTHatMaxMCD * pTHat) { + return; + } + for (auto& mcpjet : mcdjet.template matchedJetGeo_as>()) { + if (mcpjet.pt() > pTHatMaxMCP * pTHat) { + continue; + } + registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt"), mcdjet.r() / 100.0, mcpjet.pt(), mcdjet.pt(), weight); registry.fill(HIST("h3_jet_r_jet_eta_part_jet_eta"), mcdjet.r() / 100.0, mcpjet.eta(), mcdjet.eta(), weight); registry.fill(HIST("h3_jet_r_jet_phi_part_jet_phi"), mcdjet.r() / 100.0, mcpjet.phi(), mcdjet.phi(), weight); diff --git a/PWGJE/Tasks/jetfinderfullQA.cxx b/PWGJE/Tasks/jetfinderfullQA.cxx index 3058e3f4028..be3eb984981 100644 --- a/PWGJE/Tasks/jetfinderfullQA.cxx +++ b/PWGJE/Tasks/jetfinderfullQA.cxx @@ -61,6 +61,10 @@ struct JetFinderFullQATask { Configurable clusterTimeMax{"clusterTimeMax", 999., "maximum Cluster time (ns)"}; Configurable clusterRejectExotics{"clusterRejectExotics", true, "Reject exotic clusters"}; + Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; + Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; + Configurable pTHatExponent{"pTHatExponent", 0.1666, "exponent of the event weight for the calculation of pTHat"}; + std::vector filledJetR; std::vector jetRadiiValues; @@ -171,6 +175,12 @@ struct JetFinderFullQATask { template void fillHistograms(T const& jet, float weight = 1.0) { + + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (jet.pt() > pTHatMaxMCD * pTHat) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_jet_eta"), jet.eta(), weight); @@ -205,6 +215,12 @@ struct JetFinderFullQATask { template void fillMCPHistograms(T const& jet, float weight = 1.0) { + + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (jet.pt() > pTHatMaxMCP * pTHat) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); registry.fill(HIST("h_jet_eta_part"), jet.eta(), weight); @@ -228,8 +244,18 @@ struct JetFinderFullQATask { template void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) { + + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (mcdjet.pt() > pTHatMaxMCD * pTHat) { + return; + } + for (auto& mcpjet : mcdjet.template matchedJetGeo_as>()) { + if (mcpjet.pt() > pTHatMaxMCP * pTHat) { + continue; + } + registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt"), mcdjet.r() / 100.0, mcpjet.pt(), mcdjet.pt(), weight); registry.fill(HIST("h3_jet_r_jet_eta_part_jet_eta"), mcdjet.r() / 100.0, mcpjet.eta(), mcdjet.eta(), weight); registry.fill(HIST("h3_jet_r_jet_phi_part_jet_phi"), mcdjet.r() / 100.0, mcpjet.phi(), mcdjet.phi(), weight); diff --git a/PWGJE/Tasks/jetfinderhfQA.cxx b/PWGJE/Tasks/jetfinderhfQA.cxx index 47ffd673fe9..9ec10903cd4 100644 --- a/PWGJE/Tasks/jetfinderhfQA.cxx +++ b/PWGJE/Tasks/jetfinderhfQA.cxx @@ -58,6 +58,9 @@ struct JetFinderHFQATask { Configurable selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc->PKPi"}; Configurable selectionFlagLcToPiPK{"selectionFlagLcToPiPK", 1, "Selection Flag for Lc->PiPK"}; Configurable selectionFlagBplus{"selectionFlagBplus", 1, "Selection Flag for B+"}; + Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; + Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; + Configurable pTHatExponent{"pTHatExponent", 0.1666, "exponent of the event weight for the calculation of pTHat"}; HfHelper hfHelper; std::vector filledJetR; @@ -230,6 +233,12 @@ struct JetFinderHFQATask { template void fillHistograms(T const& jet, float weight = 1.0) { + + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (jet.pt() > pTHatMaxMCD * pTHat) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_jet_eta"), jet.eta(), weight); @@ -293,6 +302,12 @@ struct JetFinderHFQATask { template void fillMCPHistograms(T const& jet, float weight = 1.0) { + + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (jet.pt() > pTHatMaxMCP * pTHat) { + return; + } + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); registry.fill(HIST("h_jet_eta_part"), jet.eta(), weight); @@ -328,8 +343,18 @@ struct JetFinderHFQATask { template void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) { + + float pTHat = 10. / (std::pow(weight, pTHatExponent)); + if (mcdjet.pt() > pTHatMaxMCD * pTHat) { + return; + } + for (auto& mcpjet : mcdjet.template matchedJetCand_as>()) { + if (mcpjet.pt() > pTHatMaxMCP * pTHat) { + continue; + } + auto mcdCandPt = 0.0; auto mcdCandPhi = 0.0; auto mcdCandEta = 0.0; From d475a2a3d59122c4f363a2442992741c8b890b73 Mon Sep 17 00:00:00 2001 From: "Maja Karwowska (Kabus)" Date: Fri, 15 Dec 2023 14:24:36 +0100 Subject: [PATCH 071/156] PWGHF: Adjust code to rename candidateSelectorLcMl -> candidateSelectorLcPidMl (#4172) * Rename candidateSelectorLcMl * Adjust CMakeLists * Adjust code to rename --- PWGHF/TableProducer/candidateSelectorLcPidMl.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx b/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx index f133daa65ac..c8b2c06cdef 100644 --- a/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx +++ b/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file candidateSelectorLcMl.cxx +/// \file candidateSelectorLcPidMl.cxx /// \brief Λc± → p± K∓ π± selection task using BDT /// /// \author Luigi Dello Stritto , University and INFN SALERNO @@ -36,7 +36,7 @@ using namespace o2::framework; using namespace o2::ml; /// Struct for applying Lc selection cuts -struct HfCandidateSelectorLcMl { +struct HfCandidateSelectorLcPidMl { Produces hfSelLcCandidate; Configurable usePid{"usePid", true, "Bool to use or not the PID based on nSigma cut at filtering level"}; @@ -323,5 +323,5 @@ struct HfCandidateSelectorLcMl { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } From 4074ef63d41cefdc2682a747f4c6018c462b9142 Mon Sep 17 00:00:00 2001 From: Jochen Klein Date: Fri, 15 Dec 2023 20:06:13 +0100 Subject: [PATCH 072/156] Add ITS cluster map for pions (#4177) --- PWGHF/TableProducer/treeCreatorOmegacSt.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index 9ae7aa1d7ec..46ef2b333fe 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -68,6 +68,7 @@ DECLARE_SOA_COLUMN(PxPion, pxPion, float); DECLARE_SOA_COLUMN(PyPion, pyPion, float); DECLARE_SOA_COLUMN(PzPion, pzPion, float); DECLARE_SOA_COLUMN(IsPositivePion, isPositivePion, bool); +DECLARE_SOA_COLUMN(ITSClusterMapPion, itsClusterMapPion, uint8_t); DECLARE_SOA_COLUMN(CpaOmegac, cpaOmegac, float); DECLARE_SOA_COLUMN(CpaOmega, cpaOmega, float); DECLARE_SOA_COLUMN(DcaXYOmega, dcaXYOmega, float); @@ -126,6 +127,7 @@ DECLARE_SOA_TABLE(HfOmegacSt, "AOD", "HFOMEGACST", st_omegac::PyPion, st_omegac::PzPion, st_omegac::IsPositivePion, + st_omegac::ITSClusterMapPion, st_omegac::CpaOmegac, st_omegac::CpaOmega, st_omegac::DcaXYOmega, @@ -457,6 +459,7 @@ struct HfTreeCreatorOmegacSt { momenta[1][1], momenta[1][2], track.sign() > 0 ? true : false, + track.itsClusterMap(), cpaOmegaC, cpaOmega, impactParameterTrk.getY(), From e69dcf137c72c70e35fc9227998b5c418101e1b2 Mon Sep 17 00:00:00 2001 From: Yash Patley <52608802+yashpatley@users.noreply.github.com> Date: Sat, 16 Dec 2023 01:24:55 +0530 Subject: [PATCH 073/156] PWGLF: Lambda1520 sph update (#4176) * PWGLF: Update lambda1520SpherocityAnalysis.cxx * Update lambda1520SpherocityAnalysis.cxx * PWGLF: Update lambda1520SpherocityAnalysis.cxx --- PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx | 306 +++++++++---------- 1 file changed, 142 insertions(+), 164 deletions(-) diff --git a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx index fbc9118c01d..0472d0fb481 100644 --- a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx +++ b/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx @@ -41,27 +41,25 @@ struct lambdaAnalysis { // Configurables. Configurable nBinsPt{"nBinsPt", 100, "N bins in pT histogram"}; Configurable nBinsInvM{"nBinsInvM", 120, "N bins in InvMass histogram"}; - Configurable nBinsSp{"nBinsSp", 100, "N bins in spherocity histogram"}; + Configurable nBinsSp{"nBinsSp", 120, "N bins in spherocity histogram"}; Configurable doRotate{"doRotate", true, "rotated inv mass spectra"}; // Tracks - Configurable cfgPtMin{"ptMin", 0.15, "Minimum Track pT"}; - Configurable cfgEtaCut{"etaCut", 0.8, "Pseudorapidity cut"}; - Configurable cfgDcaz{"dcazMin", 1., "Minimum DCAz"}; - Configurable cfgDcaxy{"dcaxyMin", 0.1, "Minimum DCAxy"}; - Configurable cfgPIDprecut{"cfgPIDprecut", 5, "Preselection PID TPC TOF cut"}; - Configurable cfgKinCuts{"cfgKinCuts", false, "Kinematic Cuts for p-K pair opening angle"}; - Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz - Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) - Configurable cfgPVContributor{"cfgPVContributor", true, "PV contributor track selection"}; // PV Contriuibutor + Configurable cPtMin{"cPtMin", 0.15, "Minimum Track pT"}; + Configurable cEtaCut{"cEtaCut", 0.8, "Pseudorapidity cut"}; + Configurable cDcaz{"cDcazMin", 1., "Minimum DCAz"}; + Configurable cDcaxy{"cDcaxyMin", 0.1, "Minimum DCAxy"}; + Configurable cPIDprecut{"cPIDprecut", 5, "Preselection PID TPC TOF cut"}; + Configurable cKinCuts{"cKinCuts", false, "Kinematic Cuts for p-K pair opening angle"}; + Configurable cPrimaryTrack{"cPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cGlobalWoDCATrack{"cGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cPVContributor{"cPVContributor", true, "PV contributor track selection"}; // PV Contriuibutor // PID Selections Configurable cUseOnlyTOFTrackPr{"cUseOnlyTOFTrackPr", false, "Use only TOF track for PID selection"}; // Use only TOF track for Proton PID selection Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection - Configurable cUseTpcAndTof{"cUseTpcAndTof", true, "Use TPC and TOF PID selection"}; // TPC And TOF tracks - Configurable cUseTpcOnly{"cUseTpcOnly", false, "Use TPC Only tracks (No TOF Veto)"}; // TPC only selection - Configurable cRejNsigma{"cRejNsigma", 3.0, "Reject tracks to improve purity of PID"}; - Configurable cMaxPtpc{"cMaxPtpc", 1.8, "Maximum p for tracks without TOF"}; + Configurable cUseTpcOnly{"cUseTpcOnly", false, "Use TPC Only selection"}; // TPC And TOF tracks + Configurable cRejNsigma{"cRejNsigma", 1.0, "Reject tracks to improve purity of PID"}; // Reject missidentified particles when tpc bands merge // Proton Configurable cMaxTPCnSigmaProton{"cMaxTPCnSigmaProton", 3.0, "TPC nSigma cut for Proton"}; // TPC Configurable cMaxTOFnSigmaProton{"cMaxTOFnSigmaProton", 3.0, "TOF nSigma cut for Proton"}; // TOF @@ -75,11 +73,11 @@ struct lambdaAnalysis { Configurable> kaonTPCPIDp{"kaonTPCPIDp", {0., 0.25, 0.3, 0.45}, "pT dependent TPC cuts kaons"}; Configurable> kaonTPCPIDcut{"kaonTPCPIDcut", {6, 3.5, 2.5}, "TPC nsigma cuts kaons"}; // Event Mixing. - Configurable doSphMix{"doSphMix", true, "Include Sph Bins to be mixed"}; - Configurable nMix{"nMix", 10, "Number of Events to be mixed"}; - ConfigurableAxis cfgVtxBins{"cfgVtxBins", {VARIABLE_WIDTH, -10.0f, -9.f, -8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis cfgMultBins{"cfgMultBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 200.0f}, "Mixing bins - multiplicity"}; - ConfigurableAxis cfgSphBins{"cfgSphBins", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f}, "Mixing bins - spherocity"}; + Configurable cMixSph{"cMixSph", true, "Include Sph Bins to be mixed"}; + Configurable cNumMixEv{"cNumMixEv", 20, "Number of Events to be mixed"}; + ConfigurableAxis cMixVtxBins{"cMixVtxBins", {VARIABLE_WIDTH, -10.0f, -9.f, -8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f}, "Mixing bins - z-vertex"}; + ConfigurableAxis cMixMultBins{"cMixMultBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 200.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis cMixSphBins{"cMixSphBins", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f}, "Mixing bins - spherocity"}; // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -91,6 +89,7 @@ struct lambdaAnalysis { const AxisSpec axisSp(nBinsSp, 0., 1., "S_{0}"); const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); const AxisSpec axisP_pid(400, 0., 4., "p (GeV/c)"); + const AxisSpec axisPt_pid(400, 0., 4., "p_{T} (GeV/c)"); const AxisSpec axisPt(nBinsPt, 0., 10., "p_{T} (GeV/c)"); const AxisSpec axisEta(40, -1, 1, "#eta"); const AxisSpec axisDCAz(500, -0.5, 0.5, {"DCA_{z} (cm)"}); @@ -98,71 +97,68 @@ struct lambdaAnalysis { const AxisSpec axisTPCNCls(200, 0, 200, {"TPCNCls"}); const AxisSpec axisTPCNsigma(120, -6, 6, {"n#sigma^{TPC}"}); const AxisSpec axisTOFNsigma(120, -6, 6, {"n#sigma^{TOF}"}); - const AxisSpec axisInvM(nBinsInvM, 1.44, 2.44, {"M_{inv} (GeV/c^{2})"}); + const AxisSpec axisdEdx(380, 10, 200, {"#frac{dE}{dx}"}); + const AxisSpec axisInvM(nBinsInvM, 1.44, 2.04, {"M_{inv} (GeV/c^{2})"}); // Create Histograms. // Event - histos.add("Event/hCent", "FT0M (%)", kTH1F, {axisCent}); - histos.add("Event/hSph", "Event Spherocity", kTH1F, {axisSp}); - histos.add("Event/hSpCent", "Spherocity vs FT0M(%)", kTH2F, {axisCent, axisSp}); + histos.add("Event/h1d_ft0m_mult_percentile", "FT0M (%)", kTH1F, {axisCent}); + histos.add("Event/h1d_spherocity", "Event Spherocity", kTH1F, {axisSp}); + histos.add("Event/h2d_sph_vs_multpercentile", "Spherocity vs FT0M(%)", kTH2F, {axisCent, axisSp}); // QA Before - histos.add("QAbefore/Proton/hTPCNsigma", "n#sigma^{TPC} Protons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAbefore/Proton/hTOFNsigma", "n#sigma^{TOF} Protons", kTH2F, {axisP_pid, axisTOFNsigma}); - histos.add("QAbefore/Proton/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); - histos.add("QAbefore/Kaon/hTPCNsigma", "n#sigma^{TPC} Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAbefore/Kaon/hTOFNsigma", "n#sigma^{TOF} Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); - histos.add("QAbefore/Kaon/hTpcTofNsigma", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAbefore/Proton/h2d_pr_nsigma_tpc_p", "n#sigma^{TPC} Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAbefore/Proton/h2d_pr_nsigma_tof_p", "n#sigma^{TOF} Protons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAbefore/Proton/h2d_pr_nsigma_tof_vs_tpc", "n#sigma^{TPC} vs n#sigma^{TOF} Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAbefore/Kaon/h2d_ka_nsigma_tpc_p", "n#sigma^{TPC} Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAbefore/Kaon/h2d_ka_nsigma_tof_p", "n#sigma^{TOF} Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAbefore/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // QA After - histos.add("QAafter/Proton/hPt", "p_{T}-spectra Protons", kTH1F, {axisPt}); - histos.add("QAafter/Proton/hDcaZ", "dca_{z} Protons", kTH2F, {axisP_pid, axisDCAz}); - histos.add("QAafter/Proton/hDcaXY", "dca_{xy} Protons", kTH2F, {axisP_pid, axisDCAxy}); - histos.add("QAafter/Proton/hTPCNsigmaFull", "n#sigma(TPC) Protons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAafter/Proton/hTPCNsigma", "n#sigma(TPC) Protons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAafter/Proton/hTPCNsigmaTOF", "n#sigma(TPC) Protons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAafter/Proton/hTOFNsigma", "n#sigma(TOF) Protons", kTH2F, {axisP_pid, axisTOFNsigma}); - histos.add("QAafter/Proton/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); - histos.add("QAafter/Kaon/hPt", "p_{T}-spectra Kaons", kTH1F, {axisPt}); - histos.add("QAafter/Kaon/hDcaZ", "dca_{z} Kaons", kTH2F, {axisP_pid, axisDCAz}); - histos.add("QAafter/Kaon/hDcaXY", "dca_{xy} Kaons", kTH2F, {axisP_pid, axisDCAxy}); - histos.add("QAafter/Kaon/hTPCNsigmaFull", "n#sigma(TPC) Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTPCNsigma", "n#sigma(TPC) Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTPCNsigmaTOF", "n#sigma(TPC) Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); - histos.add("QAafter/Kaon/hTOFNsigma", "n#sigma(TOF) Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); - histos.add("QAafter/Kaon/hTpcTofNsigma", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Proton/h1d_pr_pt", "p_{T}-spectra Protons", kTH1F, {axisPt}); + histos.add("QAafter/Proton/h2d_pr_dca_z", "dca_{z} Protons", kTH2F, {axisPt_pid, axisDCAz}); + histos.add("QAafter/Proton/h2d_pr_dca_xy", "dca_{xy} Protons", kTH2F, {axisPt_pid, axisDCAxy}); + histos.add("QAafter/Proton/h2d_pr_dEdx_p", "TPC Signal Protons", kTH2F, {axisP_pid, axisdEdx}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tpc_pt", " Protons", kTH2F, {axisPt_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tpc_p", " Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tof_pt", " Protons", kTH2F, {axisPt_pid, axisTOFNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tof_p", " Protons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Kaon/h1d_ka_pt", "p_{T}-spectra Kaons", kTH1F, {axisPt}); + histos.add("QAafter/Kaon/h2d_ka_dca_z", "dca_{z} Kaons", kTH2F, {axisPt_pid, axisDCAz}); + histos.add("QAafter/Kaon/h2d_ka_dca_xy", "dca_{xy} Kaons", kTH2F, {axisPt_pid, axisDCAxy}); + histos.add("QAafter/Kaon/h2d_ka_dEdx_p", "TPC Signal Kaon", kTH2F, {axisP_pid, axisdEdx}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tpc_pt", " Kaons", kTH2F, {axisPt_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tpc_p", " Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_pt", " Kaons", kTH2F, {axisPt_pid, axisTOFNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_p", " Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // Analysis // Lambda Invariant Mass - histos.add("Analysis/hInvMass", "#Lambda(1520) M_{inv}", kTH1D, {axisInvM}); - histos.add("Analysis/hInvMassLS1", "Like Signs M_{inv} p K^{+}", kTH1D, {axisInvM}); - histos.add("Analysis/hInvMassLS2", "Like Signs M_{inv} #bar{p} K^{-}", kTH1D, {axisInvM}); - histos.add("Analysis/hInvMassR", "Rotated Spectra", kTH1D, {axisInvM}); - histos.add("Analysis/hInvMassMix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); - histos.add("Analysis/hInvMassMixLS", "Mixed Events M_{inv}", kTH1D, {axisInvM}); - histos.add("Analysis/h4InvMass", "THn #Lambda(1520)", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); - histos.add("Analysis/h4InvMassLS1", "THn Like Signs p K^{+}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); - histos.add("Analysis/h4InvMassLS2", "THn Like Signs #bar{p} K^{-}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); - histos.add("Analysis/h4InvMassR", "THn Rotated", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); - histos.add("Analysis/h4InvMassMix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); - histos.add("Analysis/h4InvMassMixLS", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h1d_lstar_invm_US", "#Lambda(1520) M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_PP", "Like Signs M_{inv} p K^{+}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_MM", "Like Signs M_{inv} #bar{p} K^{-}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_rot", "Rotated Spectra", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_US_mix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_LS_mix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/h4d_lstar_invm_US", "THn #Lambda(1520)", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4d_lstar_invm_PP", "THn Like Signs p K^{+}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4d_lstar_invm_MM", "THn Like Signs #bar{p} K^{-}", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4d_lstar_invm_rot", "THn Rotated", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4d_lstar_invm_US_mix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Analysis/h4d_lstar_invm_LS_mix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); // MC if (doprocessMC) { - histos.add("Event/hSphRec", "Reconstructed S_{0}", kTH1F, {axisSp}); - histos.add("Event/hSpCentRec", "Reconstructed S_{0} vs FT0M(%)", kTH2F, {axisCent, axisSp}); - histos.add("QAMCTrue/DcaZ_pr", "dca_{z}^{MC} Protons", kTH2F, {axisP_pid, axisDCAz}); - histos.add("QAMCTrue/DcaZ_ka", "dca_{z}^{MC} Kaons", kTH2F, {axisP_pid, axisDCAz}); - histos.add("QAMCTrue/DcaXY_pr", "dca_{xy}^{MC} Protons", kTH2F, {axisP_pid, axisDCAxy}); - histos.add("QAMCTrue/DcaXY_ka", "dca_{xy}^{MC} Kaons", kTH2F, {axisP_pid, axisDCAxy}); - histos.add("Analysis/hLambdaGen", "Generated #Lambda(1520) p_{T}", kTH1D, {axisPt}); - histos.add("Analysis/hLambdaGenAnti", "Generated #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); - histos.add("Analysis/hLambdaRec", "Reconstructed #Lambda(1520) p_{T}", kTH1D, {axisPt}); - histos.add("Analysis/hLambdaRecAnti", "Reconstructed #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); - histos.add("Analysis/hInvMassLambdaRec", "Recostructed #Lambda(1520)", kTH1D, {axisInvM}); - histos.add("Analysis/hInvMassLambdaRecAnti", "Recostructed #bar{#Lambda}(1520)", kTH1D, {axisInvM}); - histos.add("Analysis/h4InvMassLambdaRec", "Recostructed #Lambda(1520)", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); - histos.add("Analysis/h4InvMassLambdaRecAnti", "Recostructed #bar{#Lambda}(1520)", kTHnSparseD, {axisInvM, axisPt, axisSp, axisCent}); + histos.add("Event/h1d_rec_sph", "Reconstructed S_{0}", kTH1F, {axisSp}); + histos.add("Event/h1d_rec_sph_vs_cent", "Reconstructed S_{0} vs FT0M(%)", kTH2F, {axisCent, axisSp}); + histos.add("Analysis/h1d_gen_lstar", "Generated #Lambda(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_gen_lstar_anti", "Generated #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_rec_lstar", "Reconstructed #Lambda(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_rec_lstar_anti", "Reconstructed #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_rec_invm_lstar", "Recostructed #Lambda(1520)", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_rec_invm_lstar_anti", "Recostructed #bar{#Lambda}(1520)", kTH1D, {axisInvM}); } } @@ -170,22 +166,25 @@ struct lambdaAnalysis { bool selTracks(T const& track) { - if (track.pt() < cfgPtMin) + if (track.pt() < cPtMin) return false; - if (std::abs(track.dcaZ()) > cfgDcaz) + if (std::abs(track.eta()) > cEtaCut) return false; - if (std::abs(track.dcaXY()) > cfgDcaxy) + if (std::abs(track.dcaZ()) > cDcaz) return false; - if (cfgPrimaryTrack && !track.isPrimaryTrack()) + if (std::abs(track.dcaXY()) > cDcaxy) return false; - if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + if (cPrimaryTrack && !track.isPrimaryTrack()) return false; - if (cfgPVContributor && !track.isPVContributor()) + if (cGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + return false; + + if (cPVContributor && !track.isPVContributor()) return false; return true; @@ -236,9 +235,6 @@ struct lambdaAnalysis { if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaPr < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma)) { tpcPIDPassed = true; } - if (!cUseTpcAndTof && p >= tpcPIDp[nitr - 1] && p < cMaxPtpc && (tpcNsigmaPr < tpcPIDcut[nitr - 2] && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma)) { - tpcPIDPassed = true; - } } } } @@ -292,9 +288,6 @@ struct lambdaAnalysis { if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaKa < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma)) { tpcPIDPassed = true; } - if (!cUseTpcAndTof && p >= tpcPIDp[nitr - 1] && p < cMaxPtpc && (tpcNsigmaKa < tpcPIDcut[nitr - 2] && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma)) { - tpcPIDPassed = true; - } } } } @@ -320,27 +313,20 @@ struct lambdaAnalysis { if (!selTracks(trkPr) || !selTracks(trkKa)) continue; - // PID preselection - if ((std::abs(trkPr.tpcNSigmaPr()) > cfgPIDprecut) || (std::abs(trkKa.tpcNSigmaKa()) > cfgPIDprecut)) - continue; - - if ((trkPr.hasTOF() && std::abs(trkPr.tofNSigmaPr()) > cfgPIDprecut) || (trkKa.hasTOF() && std::abs(trkKa.tofNSigmaKa()) > cfgPIDprecut)) - continue; - - p_ptot = TMath::Sqrt(trkPr.px() * trkPr.px() + trkPr.py() * trkPr.py() + trkPr.py() * trkPr.py()); - k_ptot = TMath::Sqrt(trkKa.px() * trkKa.px() + trkKa.py() * trkKa.py() + trkKa.py() * trkKa.py()); + p_ptot = TMath::Sqrt(trkPr.px() * trkPr.px() + trkPr.py() * trkPr.py() + trkPr.pz() * trkPr.pz()); + k_ptot = TMath::Sqrt(trkKa.px() * trkKa.px() + trkKa.py() * trkKa.py() + trkKa.pz() * trkKa.pz()); // Fill QA before track selection. if (!mix) { - histos.fill(HIST("QAbefore/Proton/hTPCNsigma"), p_ptot, trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAbefore/Proton/h2d_pr_nsigma_tpc_p"), p_ptot, trkPr.tpcNSigmaPr()); if (trkPr.hasTOF()) { - histos.fill(HIST("QAbefore/Proton/hTOFNsigma"), p_ptot, trkPr.tofNSigmaPr()); - histos.fill(HIST("QAbefore/Proton/hTpcTofNsigma"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); + histos.fill(HIST("QAbefore/Proton/h2d_pr_nsigma_tof_p"), p_ptot, trkPr.tofNSigmaPr()); + histos.fill(HIST("QAbefore/Proton/h2d_pr_nsigma_tof_vs_tpc"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); } - histos.fill(HIST("QAbefore/Kaon/hTPCNsigma"), k_ptot, trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAbefore/Kaon/h2d_ka_nsigma_tpc_p"), k_ptot, trkKa.tpcNSigmaKa()); if (trkKa.hasTOF()) { - histos.fill(HIST("QAbefore/Kaon/hTOFNsigma"), k_ptot, trkKa.tofNSigmaKa()); - histos.fill(HIST("QAbefore/Kaon/hTpcTofNsigma"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); + histos.fill(HIST("QAbefore/Kaon/h2d_ka_nsigma_tof_p"), k_ptot, trkKa.tofNSigmaKa()); + histos.fill(HIST("QAbefore/Kaon/h2d_ka_nsigma_tof_vs_tpc"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); } } @@ -353,28 +339,30 @@ struct lambdaAnalysis { continue; // Fill QA after track selection. - if (!mix) { - histos.fill(HIST("QAafter/Proton/hPt"), trkPr.pt()); - histos.fill(HIST("QAafter/Proton/hDcaZ"), p_ptot, trkPr.dcaZ()); - histos.fill(HIST("QAafter/Proton/hDcaXY"), p_ptot, trkPr.dcaXY()); - histos.fill(HIST("QAafter/Proton/hTPCNsigmaFull"), p_ptot, trkPr.tpcNSigmaPr()); + if constexpr (!mix) { + // Proton + histos.fill(HIST("QAafter/Proton/h1d_pr_pt"), trkPr.pt()); + histos.fill(HIST("QAafter/Proton/h2d_pr_dca_z"), trkPr.pt(), trkPr.dcaZ()); + histos.fill(HIST("QAafter/Proton/h2d_pr_dca_xy"), trkPr.pt(), trkPr.dcaXY()); + histos.fill(HIST("QAafter/Proton/h2d_pr_dEdx_p"), p_ptot, trkPr.tpcSignal()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tpc_p"), p_ptot, trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tpc_pt"), trkPr.pt(), trkPr.tpcNSigmaPr()); if (!cUseTpcOnly && trkPr.hasTOF()) { - histos.fill(HIST("QAafter/Proton/hTPCNsigmaTOF"), p_ptot, trkPr.tpcNSigmaPr()); - histos.fill(HIST("QAafter/Proton/hTOFNsigma"), p_ptot, trkPr.tofNSigmaPr()); - histos.fill(HIST("QAafter/Proton/hTpcTofNsigma"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); - } else { - histos.fill(HIST("QAafter/Proton/hTPCNsigma"), p_ptot, trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tof_p"), p_ptot, trkPr.tofNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tof_pt"), trkPr.pt(), trkPr.tofNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tof_vs_tpc"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); } - histos.fill(HIST("QAafter/Kaon/hPt"), trkKa.pt()); - histos.fill(HIST("QAafter/Kaon/hDcaZ"), k_ptot, trkKa.dcaZ()); - histos.fill(HIST("QAafter/Kaon/hDcaXY"), k_ptot, trkKa.dcaXY()); - histos.fill(HIST("QAafter/Kaon/hTPCNsigmaFull"), k_ptot, trkKa.tpcNSigmaKa()); + // Kaon + histos.fill(HIST("QAafter/Kaon/h1d_ka_pt"), trkKa.pt()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_dca_z"), trkKa.pt(), trkKa.dcaZ()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_dca_xy"), trkKa.pt(), trkKa.dcaXY()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_dEdx_p"), k_ptot, trkKa.tpcSignal()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tpc_p"), k_ptot, trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tpc_pt"), trkKa.pt(), trkKa.tpcNSigmaKa()); if (!cUseTpcOnly && trkKa.hasTOF()) { - histos.fill(HIST("QAafter/Kaon/hTPCNsigmaTOF"), k_ptot, trkKa.tpcNSigmaKa()); - histos.fill(HIST("QAafter/Kaon/hTOFNsigma"), k_ptot, trkKa.tofNSigmaKa()); - histos.fill(HIST("QAafter/Kaon/hTpcTofNsigma"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); - } else { - histos.fill(HIST("QAafter/Kaon/hTPCNsigma"), k_ptot, trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tof_p"), k_ptot, trkKa.tofNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tof_pt"), trkKa.pt(), trkKa.tofNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tof_vs_tpc"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); } } @@ -387,7 +375,7 @@ struct lambdaAnalysis { continue; // Apply kinematic cuts. - if (cfgKinCuts) { + if (cKinCuts) { TVector3 v1(trkPr.px(), trkPr.py(), trkPr.pz()); TVector3 v2(trkKa.px(), trkKa.py(), trkKa.pz()); float alpha = v1.Angle(v2); @@ -398,28 +386,38 @@ struct lambdaAnalysis { // Fill Invariant Mass Histograms. if constexpr (!mix && !mc) { if (trkPr.sign() * trkKa.sign() < 0) { - histos.fill(HIST("Analysis/hInvMass"), p.M()); - histos.fill(HIST("Analysis/h4InvMass"), p.M(), p.Pt(), sph, mult); + histos.fill(HIST("Analysis/h1d_lstar_invm_US"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_US"), p.M(), p.Pt(), sph, mult); if (doRotate) { - float theta = rn->Uniform(3.12, 3.16); + float theta = rn->Uniform(1.56, 1.58); p1.RotateZ(theta); p = p1 + p2; if (std::abs(p.Rapidity()) < 0.5) { - histos.fill(HIST("Analysis/hInvMassR"), p.M()); - histos.fill(HIST("Analysis/h4InvMassR"), p.M(), p.Pt(), sph, mult); + histos.fill(HIST("Analysis/h1d_lstar_invm_rot"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_rot"), p.M(), p.Pt(), sph, mult); } } } else { if (trkPr.sign() == 1) { - histos.fill(HIST("Analysis/hInvMassLS1"), p.M()); - histos.fill(HIST("Analysis/h4InvMassLS1"), p.M(), p.Pt(), sph, mult); + histos.fill(HIST("Analysis/h1d_lstar_invm_PP"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_PP"), p.M(), p.Pt(), sph, mult); } else { - histos.fill(HIST("Analysis/hInvMassLS2"), p.M()); - histos.fill(HIST("Analysis/h4InvMassLS2"), p.M(), p.Pt(), sph, mult); + histos.fill(HIST("Analysis/h1d_lstar_invm_MM"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_MM"), p.M(), p.Pt(), sph, mult); } } } + if constexpr (mix) { + if (trkPr.sign() * trkKa.sign() < 0) { + histos.fill(HIST("Analysis/h1d_lstar_invm_US_mix"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_US_mix"), p.M(), p.Pt(), sph, mult); + } else { + histos.fill(HIST("Analysis/h1d_lstar_invm_LS_mix"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_LS_mix"), p.M(), p.Pt(), sph, mult); + } + } + if constexpr (mc) { if (abs(trkPr.pdgCode()) != 2212 || abs(trkKa.pdgCode()) != 321) continue; @@ -427,34 +425,16 @@ struct lambdaAnalysis { if (trkPr.motherId() != trkKa.motherId()) continue; - if (abs(trkPr.motherPDG()) != 3124) + if (abs(trkPr.motherPDG()) != 3124) // L* pdg_code = 3124 continue; - // Track selection check. - histos.fill(HIST("QAMCTrue/DcaXY_pr"), p_ptot, trkPr.dcaXY()); - histos.fill(HIST("QAMCTrue/DcaXY_ka"), k_ptot, trkKa.dcaXY()); - histos.fill(HIST("QAMCTrue/DcaZ_pr"), p_ptot, trkPr.dcaZ()); - histos.fill(HIST("QAMCTrue/DcaZ_ka"), k_ptot, trkKa.dcaZ()); - // MC histograms if (trkPr.motherPDG() > 0) { - histos.fill(HIST("Analysis/hLambdaRec"), p.Pt()); - histos.fill(HIST("Analysis/hInvMassLambdaRec"), p.M()); - histos.fill(HIST("Analysis/h4InvMassLambdaRec"), p.M(), p.Pt(), sph, mult); + histos.fill(HIST("Analysis/h1d_rec_lstar"), p.Pt()); + histos.fill(HIST("Analysis/h1d_rec_invm_lstar"), p.M()); } else { - histos.fill(HIST("Analysis/hLambdaRecAnti"), p.Pt()); - histos.fill(HIST("Analysis/hInvMassLambdaRecAnti"), p.M()); - histos.fill(HIST("Analysis/h4InvMassLambdaRecAnti"), p.M(), p.Pt(), sph, mult); - } - } - - if constexpr (mix) { - if (trkPr.sign() * trkKa.sign() < 0) { - histos.fill(HIST("Analysis/hInvMassMix"), p.M()); - histos.fill(HIST("Analysis/h4InvMassMix"), p.M(), p.Pt(), sph, mult); - } else { - histos.fill(HIST("Analysis/hInvMassMixLS"), p.M()); - histos.fill(HIST("Analysis/h4InvMassMixLS"), p.M(), p.Pt(), sph, mult); + histos.fill(HIST("Analysis/h1d_rec_lstar_anti"), p.Pt()); + histos.fill(HIST("Analysis/h1d_rec_invm_lstar_anti"), p.M()); } } } @@ -466,9 +446,9 @@ struct lambdaAnalysis { void processData(resoCols::iterator const& collision, resoTracks const& tracks) { - histos.fill(HIST("Event/hCent"), collision.cent()); - histos.fill(HIST("Event/hSph"), collision.spherocity()); - histos.fill(HIST("Event/hSpCent"), collision.cent(), collision.spherocity()); + histos.fill(HIST("Event/h1d_ft0m_mult_percentile"), collision.cent()); + histos.fill(HIST("Event/h1d_spherocity"), collision.spherocity()); + histos.fill(HIST("Event/h2d_sph_vs_multpercentile"), collision.cent(), collision.spherocity()); fillDataHistos(tracks, tracks, collision.spherocity(), collision.cent()); } @@ -478,9 +458,7 @@ struct lambdaAnalysis { void processMC(resoCols::iterator const& collision, soa::Join const& tracks) { - - histos.fill(HIST("Event/hSphRec"), collision.spherocity()); - histos.fill(HIST("Event/hSpCentRec"), collision.cent(), collision.spherocity()); + histos.fill(HIST("Event/h1d_rec_sph"), collision.spherocity()); fillDataHistos(tracks, tracks, collision.spherocity(), collision.cent()); } PROCESS_SWITCH(lambdaAnalysis, processMC, "Process Event for MC", false); @@ -490,7 +468,7 @@ struct lambdaAnalysis { for (auto const& part : resoParents) { - if (abs(part.pdgCode()) != 3124) // #Lambda(1520) PDGCode = 3124 + if (abs(part.pdgCode()) != 3124) // // L* pdg_code = 3124 continue; if (abs(part.y()) > 0.5) { // rapidity cut continue; @@ -510,9 +488,9 @@ struct lambdaAnalysis { continue; if (part.pdgCode() > 0) - histos.fill(HIST("Analysis/hLambdaGen"), part.pt()); + histos.fill(HIST("Analysis/h1d_gen_lstar"), part.pt()); else - histos.fill(HIST("Analysis/hLambdaGenAnti"), part.pt()); + histos.fill(HIST("Analysis/h1d_gen_lstar_anti"), part.pt()); } } PROCESS_SWITCH(lambdaAnalysis, processMCTrue, "Process Event for MC", false); @@ -524,16 +502,16 @@ struct lambdaAnalysis { { LOGF(debug, "Event Mixing Started"); - BinningType1 binningPositions1{{cfgVtxBins, cfgMultBins, cfgSphBins}, true}; - BinningType2 binningPositions2{{cfgVtxBins, cfgMultBins}, true}; + BinningType1 binningPositions1{{cMixVtxBins, cMixMultBins, cMixSphBins}, true}; + BinningType2 binningPositions2{{cMixVtxBins, cMixMultBins}, true}; auto tracksTuple = std::make_tuple(tracks); - if (doSphMix) { - SameKindPair pairs{binningPositions1, nMix, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + if (cMixSph) { + SameKindPair pairs{binningPositions1, cNumMixEv, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto& [c1, t1, c2, t2] : pairs) { fillDataHistos(t1, t2, c1.spherocity(), c1.cent()); } } else { - SameKindPair pairs{binningPositions2, nMix, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + SameKindPair pairs{binningPositions2, cNumMixEv, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto& [c1, t1, c2, t2] : pairs) { fillDataHistos(t1, t2, c1.spherocity(), c1.cent()); } From 298b225c4c2b15c24f27502839bf4f5d3a38e35f Mon Sep 17 00:00:00 2001 From: basiach <74355517+basiach@users.noreply.github.com> Date: Sun, 17 Dec 2023 11:45:37 +0100 Subject: [PATCH 074/156] [PWGCF]: FemtoUniverse - Adding centrality to producer, renaming trackMultKt to trackMultKtExtended; FemtoWorld - adding TOF beta histograms and sel7 to EfficiencyTask (#4182) * Adding TOFbeta histograms * Revoking changes to TOFbeta histograms * Revoking changes to TOFnSigmaPr ranges * Adding TOFbeta histograms * Commenting TOF Beta histogram * Adding sel7 * Adding process function for centrality analysis to producer, renaming TrackMultKt to TrackMultKtExtended * Revoking changes to TOFnSigmaPr ranges * Revoking comment for adding TOF beta histograms * MegaLinter fixes --------- Co-authored-by: Barbara Chytla Co-authored-by: ALICE Action Bot --- .../femtoUniverseProducerTask.cxx | 125 +++++++++++++----- PWGCF/FemtoUniverse/Tasks/CMakeLists.txt | 4 +- ...versePairTaskTrackTrackMultKtExtended.cxx} | 20 +-- .../Tasks/femtoWorldEfficiencyTask.cxx | 3 + 4 files changed, 109 insertions(+), 43 deletions(-) rename PWGCF/FemtoUniverse/Tasks/{femtoUniversePairTaskTrackTrackMultKt.cxx => femtoUniversePairTaskTrackTrackMultKtExtended.cxx} (97%) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 22ee91cca79..f1866086ac1 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -21,6 +21,7 @@ #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "DataFormatsParameters/GRPMagField.h" @@ -55,6 +56,10 @@ namespace o2::aod using FemtoFullCollision = soa::Join::iterator; +using FemtoFullCollisionCentRun2 = + soa::Join::iterator; +using FemtoFullCollisionCentRun3 = + soa::Join::iterator; using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullTracks = @@ -301,10 +306,10 @@ struct femtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackD0mesonData) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackD0mesonData || doprocessTrackCentRun2Data || doprocessTrackCentRun3Data) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackD0mesonData) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackD0mesonData || doprocessTrackCentRun2Data || doprocessTrackCentRun3Data) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); @@ -529,21 +534,28 @@ struct femtoUniverseProducerTask { template void fillMCTruthCollisions(CollisionType const& col, TrackType const& tracks) + { + for (auto& c : col) { + const auto vtxZ = c.posZ(); + const auto spher = 0; // colCuts.computeSphericity(col, tracks); + int mult = 0; + int multNtr = 0; + + // colCuts.fillQA(c); //for now, TODO: create a configurable so in the FemroUniverseCollisionSelection.h there is an option to plot QA just for the posZ + outputCollision(vtxZ, mult, multNtr, spher, mMagField); + } + } + + template + void fillCollisionsCentRun2(CollisionType const& col, TrackType const& tracks) { const auto vtxZ = col.posZ(); - const auto spher = 0; // colCuts.computeSphericity(col, tracks); - int mult = 0; + const auto spher = colCuts.computeSphericity(col, tracks); + int cent = 0; int multNtr = 0; - if (ConfIsRun3) { - mult = col.multFV0M(); - multNtr = col.multNTracksPV(); - } else { - mult = 0.5 * (col.multFV0M()); /// For benchmarking on Run 2, V0M in - /// FemtoUniverseRun2 is defined V0M/2 - multNtr = col.multTracklets(); - } - if (ConfEvtUseTPCmult) { - multNtr = col.multTPC(); + if (!ConfIsRun3) { + cent = col.centRun2V0M(); + multNtr = col.centRun2V0M(); } // check whether the basic event selection criteria are fulfilled @@ -551,17 +563,43 @@ struct femtoUniverseProducerTask { // in case of skimming run - don't store such collisions // in case of trigger run - store such collisions but don't store any // particle candidates for such collisions + if (!colCuts.isSelected(col)) { + if (ConfIsTrigger) { + outputCollision(vtxZ, cent, multNtr, spher, mMagField); ////// + } + return; + } - // CHECK WHAT CUTS SHOULD BE USED FOR MC TRUTH - // if (!colCuts.isSelected(col)) { - // if (ConfIsTrigger) { - // outputCollision(vtxZ, mult, multNtr, spher, mMagField); - // } - // return; - // } + // colCuts.fillQA(col); //for now, TODO: create a configurable so in the FemroUniverseCollisionSelection.h there is an option to plot QA just for the posZ + outputCollision(vtxZ, cent, multNtr, spher, mMagField); + } - colCuts.fillQA(col); - outputCollision(vtxZ, mult, multNtr, spher, mMagField); + template + void fillCollisionsCentRun3(CollisionType const& col, TrackType const& tracks) + { + const auto vtxZ = col.posZ(); + const auto spher = colCuts.computeSphericity(col, tracks); + int cent = 0; + int multNtr = 0; + if (ConfIsRun3) { + multNtr = col.centFT0M(); + cent = col.centFT0M(); + } + + // check whether the basic event selection criteria are fulfilled + // if the basic selection is NOT fulfilled: + // in case of skimming run - don't store such collisions + // in case of trigger run - store such collisions but don't store any + // particle candidates for such collisions + if (!colCuts.isSelected(col)) { + if (ConfIsTrigger) { + outputCollision(vtxZ, cent, multNtr, spher, mMagField); ////// + } + return; + } + + // colCuts.fillQA(col); //for now, TODO: create a configurable so in the FemroUniverseCollisionSelection.h there is an option to plot QA just for the posZ + outputCollision(vtxZ, cent, multNtr, spher, mMagField); } template @@ -929,8 +967,7 @@ struct femtoUniverseProducerTask { if (ConfMCTruthAnalysisWithPID) { bool pass = false; - std::vector tmpPDGCodes = ConfMCTruthPDGCodes; - ; // necessary due to some features of the Configurable + std::vector tmpPDGCodes = ConfMCTruthPDGCodes; // necessary due to some features of the Configurable for (uint32_t pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { if (pdgCode == 333) { // ATTENTION: workaround for now, because all Phi mesons are NOT primary particles for now. @@ -1053,7 +1090,7 @@ struct femtoUniverseProducerTask { fillTracks(tracks); } PROCESS_SWITCH(femtoUniverseProducerTask, processTrackData, - "Provide experimental data for track track", false); + "Provide experimental data for track track", true); // using FilteredFemtoFullTracks = soa::Filtered; void processTrackPhiData(aod::FemtoFullCollision const& col, @@ -1087,17 +1124,43 @@ struct femtoUniverseProducerTask { "Provide experimental data for track D0 meson", false); void - processTrackMCTruth(aod::FemtoFullCollisionMC const& col, - aod::BCsWithTimestamps const&, - aod::McCollisions const& mcCollisions, - aod::McParticles const& mcParticles) + processTrackMCTruth(aod::McCollision const& mcCol, + soa::SmallGroups> const& collisions, + aod::McParticles const& mcParticles, + aod::BCsWithTimestamps const&) { // magnetic field for run not needed for mc truth // fill the tables - fillMCTruthCollisions(col, mcParticles); + fillMCTruthCollisions(collisions, mcParticles); fillParticles(mcParticles); } PROCESS_SWITCH(femtoUniverseProducerTask, processTrackMCTruth, "Provide MC data for MC truth track analysis", false); + + void + processTrackCentRun2Data(aod::FemtoFullCollisionCentRun2 const& col, + aod::BCsWithTimestamps const&, + aod::FemtoFullTracks const& tracks) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + // fill the tables + fillCollisionsCentRun2(col, tracks); + fillTracks(tracks); + } + PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCentRun2Data, "Provide experimental data for Run 2 with centrality for track track", false); + + void + processTrackCentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, + aod::BCsWithTimestamps const&, + aod::FemtoFullTracks const& tracks) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + // fill the tables + fillCollisionsCentRun3(col, tracks); + fillTracks(tracks); + } + PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCentRun3Data, "Provide experimental data for Run 3 with centrality for track track", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt index 42fd16acda3..cdb28b6501a 100644 --- a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt @@ -24,8 +24,8 @@ o2physics_add_dpl_workflow(femtouniverse-pair-track-track-extended PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(femtouniverse-pair-track-track-mult-kt - SOURCES femtoUniversePairTaskTrackTrackMultKt.cxx +o2physics_add_dpl_workflow(femtouniverse-pair-track-track-mult-kt-extended + SOURCES femtoUniversePairTaskTrackTrackMultKtExtended.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKt.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx similarity index 97% rename from PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKt.cxx rename to PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index 1803183735c..8fe38d3e784 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKt.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file femtoUniversePairTaskTrackTrackMultKt.cxx +/// \file femtoUniversePairTaskTrackTrackMultKtExtended.cxx /// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de @@ -57,7 +57,7 @@ static const float cutsTable[nPart][nCuts]{ {4.05f, 1.f, 3.f, 3.f, 100.f}}; } // namespace -struct femtoUniversePairTaskTrackTrackMultKt { +struct femtoUniversePairTaskTrackTrackMultKtExtended { Service pdg; @@ -134,7 +134,7 @@ struct femtoUniversePairTaskTrackTrackMultKt { /// Event part Configurable ConfV0MLow{"ConfV0MLow", 0.0, "Lower limit for V0M multiplicity"}; - Configurable ConfV0MHigh{"ConfV0MHigh", 1000.0, "Upper limit for V0M multiplicity"}; + Configurable ConfV0MHigh{"ConfV0MHigh", 25000.0, "Upper limit for V0M multiplicity"}; Filter collV0Mfilter = ((o2::aod::femtouniversecollision::multV0M > ConfV0MLow) && (o2::aod::femtouniversecollision::multV0M < ConfV0MHigh)); // Filter trackAdditionalfilter = (nabs(aod::femtouniverseparticle::eta) < twotracksconfigs.ConfEtaMax); // example filtering on configurable @@ -144,8 +144,8 @@ struct femtoUniversePairTaskTrackTrackMultKt { ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; /// Correlation part - ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task - ConfigurableAxis ConfMultKstarBins{"ConfMultKstarBins", {VARIABLE_WIDTH, 0.0f, 13.0f, 20.0f, 30.0f, 40.0f, 50.0f, 100.0f, 99999.f}, "Bins for kstar analysis in multiplicity bins (10 is maximum)"}; + ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity or centrality"}; // \todo to be obtained from the hash task + ConfigurableAxis ConfMultKstarBins{"ConfMultKstarBins", {VARIABLE_WIDTH, 0.0f, 13.0f, 20.0f, 30.0f, 40.0f, 50.0f, 100.0f, 99999.f}, "Bins for kstar analysis in multiplicity or centrality bins (10 is maximum)"}; ConfigurableAxis ConfKtKstarBins{"ConfKtKstarBins", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 2.0f, 99999.f}, "Bins for kstar analysis in kT bins (10 is maximum)"}; 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"}; @@ -540,7 +540,7 @@ struct femtoUniversePairTaskTrackTrackMultKt { if (cfgProcessMM) doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); } - PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKt, processSameEvent, "Enable processing same event", true); + PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKtExtended, processSameEvent, "Enable processing same event", true); /// process function for to call doSameEvent with Monte Carlo /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) @@ -565,7 +565,7 @@ struct femtoUniversePairTaskTrackTrackMultKt { if (cfgProcessMM) doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); } - PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKt, processSameEventMC, "Enable processing same event for Monte Carlo", false); + PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKtExtended, processSameEventMC, "Enable processing same event for Monte Carlo", false); /// This function processes the mixed event /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... @@ -664,7 +664,7 @@ struct femtoUniversePairTaskTrackTrackMultKt { } } } - PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKt, processMixedEvent, "Enable processing mixed events", true); + PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKtExtended, processMixedEvent, "Enable processing mixed events", true); /// brief process function for to call doMixedEvent with Monte Carlo /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) @@ -705,13 +705,13 @@ struct femtoUniversePairTaskTrackTrackMultKt { } } } - PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKt, processMixedEventMC, "Enable processing mixed events MC", false); + PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMultKtExtended, processMixedEventMC, "Enable processing mixed events MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx index 935e7e21e24..141fb5e9ef6 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx @@ -216,6 +216,9 @@ struct femtoWorldEficiencyTask { if (ConfIsRun3) { if (!collision.sel8()) return; + } else { + if (!collision.sel7()) + return; } // auto bc = collision.bc_as(); /// adding timestamp to access magnetic field later From bca3f9c51e5cd4e9f4b4dde60f1e12c4781ce460 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Sun, 17 Dec 2023 14:37:27 +0100 Subject: [PATCH 075/156] fixed deltaPhi calculation (smallest angle taken) (#4178) * fixed deltaPhi calculation (smallest angle taken) * Introduced cut on jet and UE area --- PWGLF/Tasks/nuclei_in_jets.cxx | 65 +++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 2c334d585b1..016746bc4be 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -79,7 +79,8 @@ struct nuclei_in_jets { // Global Parameters Configurable min_pt_leading{"min_pt_leading", 5.0f, "minimum pt of leading particle"}; - Configurable max_jet_radius{"max_jet_radius", 0.1f, "maximum jet resolution parameter R"}; + Configurable Rparameter_jet{"Rparameter_jet", 0.3f, "jet resolution parameter R"}; + Configurable Rmax_jet_ue{"Rmax_jet_ue", 0.3f, "Maximum radius"}; Configurable particle_of_interest{"particle_of_interest", 0, "0=antiproton, 1=antideuteron, 2=antihelium3"}; // Track Parameters @@ -305,6 +306,24 @@ struct nuclei_in_jets { return x_min; } + // Deltaphi + double GetDeltaPhi(double a1, double a2) + { + + double delta_phi(0); + + double phi1 = TVector2::Phi_0_2pi(a1); + double phi2 = TVector2::Phi_0_2pi(a2); + double diff = TMath::Abs(phi1 - phi2); + + if (diff <= TMath::Pi()) + delta_phi = diff; + if (diff > TMath::Pi()) + delta_phi = TMath::TwoPi() - diff; + + return delta_phi; + } + float Weight(float pt, int event_region, int nucleus_of_interest) { @@ -413,16 +432,16 @@ struct nuclei_in_jets { // Histogram with pt_leading registryQC.fill(HIST("pt_leading"), pt_max); + // Event Counter: Skip Events with pt(particle_ID.size()); // Event Counter: Skip Events with less than 2 Particles - if (nParticles < 3) - return; - registryQC.fill(HIST("number_of_events_data"), 3.5); - - // Event Counter: Skip Events with pt Rmax) Rmax = R; } @@ -544,12 +565,12 @@ struct nuclei_in_jets { // Event Counter: Skip Events with jet not fully inside acceptance float eta_jet_axis = p_leading.Eta(); - if ((TMath::Abs(eta_jet_axis) + max_jet_radius) > max_eta) + if ((TMath::Abs(eta_jet_axis) + Rmax_jet_ue) > max_eta) return; registryQC.fill(HIST("number_of_events_data"), 8.5); // Fill Jet Multiplicity - registryQC.fill(HIST("jet_plus_ue_multiplicity"), nParticlesJetUE); + registryQC.fill(HIST("jet_plus_ue_multiplicity"), nParticlesJetAndUE); // Perpendicular Cones for UE Estimate TVector3 z(0.0, 0.0, p_leading.Mag()); @@ -560,7 +581,7 @@ struct nuclei_in_jets { double angle = gRandom->Uniform(0.0, TMath::TwoPi()); ue_axis.Rotate(angle, p_leading); double eta_ue_axis = ue_axis.Eta(); - dEta = (TMath::Abs(eta_ue_axis) + max_jet_radius); + dEta = (TMath::Abs(eta_ue_axis) + Rmax_jet_ue); } while (dEta > max_eta); // Store UE @@ -577,11 +598,11 @@ struct nuclei_in_jets { // Variables float deltaEta = ue_track.eta() - ue_axis.Eta(); - float deltaPhi = ue_track.phi() - ue_axis.Phi(); + float deltaPhi = GetDeltaPhi(ue_track.phi(), ue_axis.Phi()); float dr = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); // Store Particles in the UE - if (dr < max_jet_radius) { + if (dr < Rmax_jet_ue) { registryQC.fill(HIST("eta_phi_ue"), deltaEta, deltaPhi); registryQC.fill(HIST("r_ue"), dr); ue_particle_ID.push_back(particle_ID[i]); @@ -593,7 +614,7 @@ struct nuclei_in_jets { registryQC.fill(HIST("ue_multiplicity"), nParticlesUE); // Jet Multiplicity - int jet_Nch = nParticlesJetUE - nParticlesUE; + int jet_Nch = nParticlesJetAndUE - nParticlesUE; registryQC.fill(HIST("jet_multiplicity"), jet_Nch); // Loop over particles inside Jet @@ -603,7 +624,11 @@ struct nuclei_in_jets { TVector3 p_i(jet_track.px(), jet_track.py(), jet_track.pz()); float deltaEta = p_i.Eta() - p_leading.Eta(); - float deltaPhi = p_i.Phi() - p_leading.Phi(); + float deltaPhi = GetDeltaPhi(p_i.Phi(), p_leading.Phi()); + float R = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); + if (R > Rmax_jet_ue) + continue; + if (deltaEta != 0 && deltaPhi != 0) { registryQC.fill(HIST("eta_phi_jet"), deltaEta, deltaPhi); registryQC.fill(HIST("r_jet"), TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi)); From 9cb92e42f85e7bf6b5bcc7a5d6dd6cede268717e Mon Sep 17 00:00:00 2001 From: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Date: Sun, 17 Dec 2023 18:56:04 +0100 Subject: [PATCH 076/156] PWGCF: Masked Mixing in FemtoDream (#4181) * Feat: Change PID selection in femtodream * Feat: add collision masker When mixing particles, it is not guranteed that the events used for the mixing even contain the particles of interest. To solve this the collision masker is introduced. The collision masker runs before the pair task and generates a bit mask indiciating if particle one/two/three/... is contained in the collision or not. Only the collisions whose bit is set for a specific particle is used in the mixing. * Feat: add support for masked collisions to pair task * Feat: finalize collision masker * Fix: fix bug in collision masker in PID selection * Feat: finalizing masked processing * Fix: fix final bugs and renames * Fix: undo comments prepare removal of unneeded producer tasks in upcoming commit * Fix: fix copyright header * Fix: fix formatting * Fix: fix whitespace * Fix: remove commented code --- PWGCF/DataModel/FemtoDerived.h | 10 + PWGCF/FemtoDream/CMakeLists.txt | 7 +- PWGCF/FemtoDream/FemtoDreamCutculator.h | 38 +- PWGCF/FemtoDream/FemtoUtils.h | 16 + .../FemtoDream/femtoDreamCollisionMasker.cxx | 292 ++++++++++++++ PWGCF/FemtoDream/femtoDreamDebugTrack.cxx | 41 +- PWGCF/FemtoDream/femtoDreamDebugV0.cxx | 60 +-- .../femtoDreamPairTaskTrackTrack.cxx | 368 +++++++++--------- .../FemtoDream/femtoDreamPairTaskTrackV0.cxx | 335 +++++++++------- 9 files changed, 775 insertions(+), 392 deletions(-) create mode 100644 PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 036f69775a6..989405e5239 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -32,6 +32,11 @@ DECLARE_SOA_COLUMN(MultNtr, multNtr, int); //! multiplicity of charged t DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event DECLARE_SOA_COLUMN(MagField, magField, float); //! Magnetic field of the event +using BitMaskType = uint32_t; //! Definition of the data type for the collision masks + +DECLARE_SOA_COLUMN(BitMaskTrackOne, bitmaskTrackOne, BitMaskType); //! Bit for track one +DECLARE_SOA_COLUMN(BitMaskTrackTwo, bitmaskTrackTwo, BitMaskType); //! Bit for track two +DECLARE_SOA_COLUMN(BitMaskTrackThree, bitmaskTrackThree, BitMaskType); //! Bit for track three } // namespace femtodreamcollision DECLARE_SOA_TABLE(FDCollisions, "AOD", "FDCOLLISION", @@ -43,6 +48,11 @@ DECLARE_SOA_TABLE(FDCollisions, "AOD", "FDCOLLISION", femtodreamcollision::MagField); using FDCollision = FDCollisions::iterator; +DECLARE_SOA_TABLE(FDColMasks, "AOD", "FDCOLMASK", + femtodreamcollision::BitMaskTrackOne, + femtodreamcollision::BitMaskTrackTwo, + femtodreamcollision::BitMaskTrackThree); + /// FemtoDreamTrack namespace femtodreamparticle { diff --git a/PWGCF/FemtoDream/CMakeLists.txt b/PWGCF/FemtoDream/CMakeLists.txt index 383f229439d..8a4e2aa9e15 100644 --- a/PWGCF/FemtoDream/CMakeLists.txt +++ b/PWGCF/FemtoDream/CMakeLists.txt @@ -14,6 +14,11 @@ o2physics_add_dpl_workflow(femtodream-producer PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femtodream-collision-masker + SOURCES femtoDreamCollisionMasker.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femtodream-producer-reduced SOURCES femtoDreamProducerReducedTask.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -57,4 +62,4 @@ o2physics_add_executable(femtodream-cutculator o2physics_add_dpl_workflow(femtodream-producer-v0 SOURCES femtoDreamProducerTaskV0Only.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGCF/FemtoDream/FemtoDreamCutculator.h b/PWGCF/FemtoDream/FemtoDreamCutculator.h index fbc6fcaad67..1f7ecab464d 100644 --- a/PWGCF/FemtoDream/FemtoDreamCutculator.h +++ b/PWGCF/FemtoDream/FemtoDreamCutculator.h @@ -22,6 +22,7 @@ #include "FemtoDreamTrackSelection.h" #include "FemtoDreamV0Selection.h" #include +#include #include #include #include @@ -322,20 +323,29 @@ class FemtoDreamCutculator << " not recognized - available options are (T/V)" << std::endl; return; } - std::bitset<8 * sizeof(aod::femtodreamparticle::cutContainerType)> - bitOutput = output; + std::bitset<8 * sizeof(aod::femtodreamparticle::cutContainerType)> bitOutput = output; std::cout << "+++++++++++++++++++++++++++++++++" << std::endl; std::cout << "CutCulator has spoken - your selection bit is" << std::endl; std::cout << bitOutput << " (bitwise)" << std::endl; std::cout << output << " (number representation)" << std::endl; - std::cout << "PID for these species is stored:" << std::endl; - int index = 0; + std::cout << "+++++++++++++++++++++++++++++++++" << std::endl; + std::cout << "PID bits for these species are available:" << std::endl; int randomIndex = 0; std::random_device rd; std::mt19937 rng(rd()); std::uniform_int_distribution uni(0, mPIDValues.size() - 1); - for (auto id : mPIDspecies) { - std::cout << o2::track::PID::getName(id) << " : " << index++ << std::endl; + std::sort(mPIDValues.begin(), mPIDValues.end(), std::greater<>()); + int Bit = 0; + + std::cout << "+++++++++++++++++++++++++++++++++" << std::endl; + for (std::size_t i = 0; i < mPIDspecies.size(); i++) { + for (std::size_t j = 0; j < mPIDValues.size(); j++) { + std::cout << "Species " << o2::track::PID::getName(mPIDspecies.at(i)) << " with |NSigma|<" << mPIDValues.at(j) << std::endl; + Bit = (2 * mPIDspecies.size() * (mPIDValues.size() - (j + 1)) + 1) + (mPIDspecies.size() - (1 + i)) * 2; + std::cout << "Bit for Nsigma TPC: " << (1 << (Bit + 1)) << std::endl; + std::cout << "Bit for Nsigma TPCTOF: " << (1 << Bit) << std::endl; + std::cout << "+++++++++++++++++++++++++++++++++" << std::endl; + } if (SysChecks) { // Seed the random number generator // Select a random element @@ -345,20 +355,14 @@ class FemtoDreamCutculator std::cout << "Nsigma TPCTOF: " << mPIDValues[randomIndex] << std::endl; } } - std::cout << "+++++++++++++++++++++++++++++++++" << std::endl; } private: - boost::property_tree::ptree - mConfigTree; ///< the dpl-config.json buffered into a ptree - FemtoDreamTrackSelection - mTrackSel; ///< for setting up the bit-wise selection container for tracks - FemtoDreamV0Selection - mV0Sel; ///< for setting up the bit-wise selection container for V0s - std::vector - mPIDspecies; ///< list of particle species for which PID is stored - std::vector - mPIDValues; ///< list of nsigma values for which PID is stored + boost::property_tree::ptree mConfigTree; ///< the dpl-config.json buffered into a ptree + FemtoDreamTrackSelection mTrackSel; ///< for setting up the bit-wise selection container for tracks + FemtoDreamV0Selection mV0Sel; ///< for setting up the bit-wise selection container for V0s + std::vector mPIDspecies; ///< list of particle species for which PID is stored + std::vector mPIDValues; ///< list of nsigma values for which PID is stored }; } // namespace o2::analysis::femtoDream diff --git a/PWGCF/FemtoDream/FemtoUtils.h b/PWGCF/FemtoDream/FemtoUtils.h index 8b2047cbb90..54e3d168a8b 100644 --- a/PWGCF/FemtoDream/FemtoUtils.h +++ b/PWGCF/FemtoDream/FemtoUtils.h @@ -17,6 +17,7 @@ #define PWGCF_FEMTODREAM_FEMTOUTILS_H_ #include +#include #include #include #include "Framework/ASoAHelpers.h" @@ -25,6 +26,8 @@ namespace o2::analysis::femtoDream { +// TODO: remove all these functions pertaining to PID selection for the next tutorial session they have been removed from femtodream tasks but are still present in tutorial files + enum kDetector { kTPC, kTPCTOF, kNdetectors }; @@ -133,5 +136,18 @@ int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int mo return partOrigin; }; +template +bool containsNameValuePair(const std::vector& myVector, const std::string& name, R value) +{ + for (const auto& obj : myVector) { + if (obj.name == name) { + if (std::abs(static_cast((obj.defaultValue.template get() - value))) < 1e-2) { + return true; // Found a match + } + } + } + return false; // No match found +} + } // namespace o2::analysis::femtoDream #endif // PWGCF_FEMTODREAM_FEMTOUTILS_H_ diff --git a/PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx b/PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx new file mode 100644 index 00000000000..614c9427b64 --- /dev/null +++ b/PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx @@ -0,0 +1,292 @@ +// Copyright 2019-2023 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoDreamCollisionMasker.cxx +/// \brief Tasks creates bitmasks for femtodream collisions +/// \author Anton Riedel, TU München, anton.riedel@tum.de + +#include +#include +#include + +#include "fairlogger/Logger.h" +#include "Framework/Configurable.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" + +#include "PWGCF/DataModel/FemtoDerived.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; + +namespace CollisionMasks +{ +enum Parts { + kPartOne, + kPartTwo, + kPartThree, + kNParts, +}; +enum Tasks { + kTrackTrack, + kTrackV0, + kNTasks, +}; +} // namespace CollisionMasks + +struct femoDreamCollisionMasker { + Produces Masks; + + // particle selection bits + std::array, CollisionMasks::kNParts> TrackCutBits; + // particle tpc pid bits + std::array, CollisionMasks::kNParts> TrackPIDTPCBits; + // particle tpctof pid bits + std::array, CollisionMasks::kNParts> TrackPIDTPCTOFBits; + // particle momemtum threshold for PID + std::array, CollisionMasks::kNParts> TrackPIDThreshold; + + // particle selection for v0 + std::array, CollisionMasks::kNParts> V0CutBits; + + // particle selection bits for v0 children + std::array, CollisionMasks::kNParts> PosChildCutBits; + std::array, CollisionMasks::kNParts> NegChildCutBits; + + // particle tpc pid bits for v0 children + std::array, CollisionMasks::kNParts> PosChildPIDTPCBits; + std::array, CollisionMasks::kNParts> NegChildPIDTPCBits; + + // cuts from filters on the pair task + std::array, CollisionMasks::kNParts> FilterPtMin; + std::array, CollisionMasks::kNParts> FilterPtMax; + std::array, CollisionMasks::kNParts> FilterEtaMin; + std::array, CollisionMasks::kNParts> FilterEtaMax; + std::array, CollisionMasks::kNParts> FilterInvMassMin; + std::array, CollisionMasks::kNParts> FilterInvMassMax; + std::array, CollisionMasks::kNParts> FilterInvMassAntiMin; + std::array, CollisionMasks::kNParts> FilterInvMassAntiMax; + + int TaskFinder = -1; + + void init(InitContext& context) + { + std::vector MatchedWorkflows; + LOG(info) << "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"; + LOG(info) << " Collision masker self-configuration "; + LOG(info) << "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"; + auto& workflows = context.services().get(); + for (DeviceSpec const& device : workflows.devices) { + if (device.name.find("femto-dream-pair-task-track-track") != std::string::npos) { + LOG(info) << "Matched workflow: " << device.name; + TaskFinder = CollisionMasks::kTrackTrack; + for (auto const& option : device.options) { + if (option.name.compare(std::string("ConfTrk1_CutBit")) == 0) { + TrackCutBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_TPCBit")) == 0) { + TrackPIDTPCBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_TPCTOFBit")) == 0) { + TrackPIDTPCTOFBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_PIDThres")) == 0) { + TrackPIDThreshold.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_minPt")) == 0) { + FilterPtMin.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_maxPt")) == 0) { + FilterPtMax.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_minEta")) == 0) { + FilterEtaMin.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_maxEta")) == 0) { + FilterEtaMax.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_CutBit")) == 0) { + TrackCutBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_TPCBit")) == 0) { + TrackPIDTPCBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_TPCTOFBit")) == 0) { + TrackPIDTPCTOFBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_PIDThres")) == 0) { + TrackPIDThreshold.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_minPt")) == 0) { + FilterPtMin.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_maxPt")) == 0) { + FilterPtMax.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_minEta")) == 0) { + FilterEtaMin.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk2_maxEta")) == 0) { + FilterEtaMax.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } + } + } else if (device.name.find(std::string("femto-dream-pair-task-track-v0")) != std::string::npos) { + LOG(info) << "Matched workflow: " << device.name; + TaskFinder = CollisionMasks::kTrackV0; + for (auto const& option : device.options) { + if (option.name.compare(std::string("ConfTrk1_CutBit")) == 0) { + TrackCutBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_TPCBit")) == 0) { + TrackPIDTPCBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_TPCTOFBit")) == 0) { + TrackPIDTPCTOFBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_PIDThres")) == 0) { + TrackPIDThreshold.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_minPt")) == 0) { + FilterPtMin.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_maxPt")) == 0) { + FilterPtMax.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_minEta")) == 0) { + FilterEtaMin.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTrk1_maxEta")) == 0) { + FilterEtaMax.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_CutBit")) == 0) { + V0CutBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_minPt")) == 0) { + FilterPtMin.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_maxPt")) == 0) { + FilterPtMax.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_minEta")) == 0) { + FilterEtaMin.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_maxEta")) == 0) { + FilterEtaMax.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_minInvMass")) == 0) { + FilterInvMassMin.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_maxInvMass")) == 0) { + FilterInvMassMax.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_minInvMassAnti")) == 0) { + FilterInvMassAntiMin.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_maxInvMassAnti")) == 0) { + FilterInvMassAntiMax.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_ChildPos_CutBit")) == 0) { + PosChildCutBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_ChildPos_TPCBit")) == 0) { + PosChildPIDTPCBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_ChildNeg_CutBit")) == 0) { + NegChildCutBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfV02_ChildNeg_TPCBit")) == 0) { + NegChildPIDTPCBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); + } + } + } + } + + if (8 * sizeof(femtodreamcollision::BitMaskType) < TrackCutBits.at(CollisionMasks::kPartOne).size() || + 8 * sizeof(femtodreamcollision::BitMaskType) < TrackCutBits.at(CollisionMasks::kPartTwo).size() || + 8 * sizeof(femtodreamcollision::BitMaskType) < TrackCutBits.at(CollisionMasks::kPartThree).size()) { + LOG(fatal) << "Too many variations!"; + LOG(fatal) << "Collision masker only supports up to " << 8 * sizeof(femtodreamcollision::BitMaskType) << " variations!"; + } + } + + // make bitmask for a track + template + void MaskForTrack(T& BitSet, CollisionMasks::Parts P, R& track) + { + if (track.partType() != static_cast(femtodreamparticle::kTrack)) { + return; + } + for (size_t index = 0; index < TrackCutBits.at(P).size(); index++) { + // check filter cuts + if (track.pt() < FilterPtMin.at(P).at(index) || track.pt() > FilterPtMax.at(P).at(index) || + track.eta() < FilterEtaMin.at(P).at(index) || track.eta() > FilterEtaMax.at(P).at(index)) { + // if they are not passed, skip the particle + continue; + } + // set the bit at the index of the selection equal to one if the track passes all selections + // check track cuts + if ((track.cut() & TrackCutBits.at(P).at(index)) == TrackCutBits.at(P).at(index)) { + // check pid cuts + if (track.p() <= TrackPIDThreshold.at(P).at(index)) { + if ((track.pidcut() & TrackPIDTPCBits.at(P).at(index)) == TrackPIDTPCBits.at(P).at(index)) { + BitSet.at(P).set(index); + } + } else { + if ((track.pidcut() & TrackPIDTPCTOFBits.at(P).at(index)) == TrackPIDTPCTOFBits.at(P).at(index)) { + BitSet.at(P).set(index); + } + } + } + } + } + + // make bit mask for v0 + template + void MaskForV0(T& BitSet, CollisionMasks::Parts P, R& v0, S& parts) + { + if (v0.partType() != static_cast(femtodreamparticle::kV0)) { + return; + } + for (size_t index = 0; index < V0CutBits.at(P).size(); index++) { + // check filter cuts + if (v0.pt() < FilterPtMin.at(P).at(index) || v0.pt() > FilterPtMax.at(P).at(index) || + v0.eta() < FilterEtaMin.at(P).at(index) || v0.eta() > FilterEtaMax.at(P).at(index) || + v0.mLambda() < FilterInvMassMin.at(P).at(index) || v0.mLambda() > FilterInvMassMax.at(P).at(index) || + v0.mAntiLambda() < FilterInvMassAntiMin.at(P).at(index) || v0.mAntiLambda() > FilterInvMassAntiMax.at(P).at(index)) { + // if they are not passed, skip the particle + continue; + } + // check cut bit of v0 + if ((v0.cut() & V0CutBits.at(P).at(index)) == V0CutBits.at(P).at(index)) { + const auto& posChild = parts.iteratorAt(v0.index() - 2); + const auto& negChild = parts.iteratorAt(v0.index() - 1); + // This is how it is supposed to work but there seems to be an issue + // for now, keep in sync with femtodreampairtasktrackv0 + // auto posChild = v0.template children_as().front(); + // auto negChild = v0.template children_as().back(); + // check cut on v0 children + if ((posChild.cut() & PosChildCutBits.at(P).at(index)) == PosChildCutBits.at(P).at(index) && + (posChild.pidcut() & PosChildPIDTPCBits.at(P).at(index)) == PosChildPIDTPCBits.at(P).at(index) && + (negChild.cut() & NegChildCutBits.at(P).at(index)) == NegChildCutBits.at(P).at(index) && + (negChild.pidcut() & NegChildPIDTPCBits.at(P).at(index)) == NegChildPIDTPCBits.at(P).at(index)) { + BitSet.at(P).set(index); + } + } + } + } + + void process(FDCollision const& col, FDParticles const& parts) + { + // create a bit mask for particle one, particle two and particle three + std::array, CollisionMasks::kNParts> Mask = {{0}}; + + switch (TaskFinder) { + case CollisionMasks::kTrackTrack: + // pair-track-track task + // create mask for track 1 and track 2 + for (auto const& part : parts) { + MaskForTrack(Mask, CollisionMasks::kPartOne, part); + MaskForTrack(Mask, CollisionMasks::kPartTwo, part); + } + break; + case CollisionMasks::kTrackV0: + // pair-track-v0 task + // create mask for track 1 and v0 2 + for (auto const& part : parts) { + MaskForTrack(Mask, CollisionMasks::kPartOne, part); + MaskForV0(Mask, CollisionMasks::kPartTwo, part, parts); + } + // TODO: add all supported pair/triplet tasks + break; + default: + LOG(fatal) << "No femtodream pair task found!"; + } + // fill bitmask for each collision + Masks(static_cast(Mask.at(CollisionMasks::kPartOne).to_ulong()), + static_cast(Mask.at(CollisionMasks::kPartTwo).to_ulong()), + static_cast(Mask.at(CollisionMasks::kPartThree).to_ulong())); + }; +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +}; diff --git a/PWGCF/FemtoDream/femtoDreamDebugTrack.cxx b/PWGCF/FemtoDream/femtoDreamDebugTrack.cxx index a1845090d9d..515ed97a83d 100644 --- a/PWGCF/FemtoDream/femtoDreamDebugTrack.cxx +++ b/PWGCF/FemtoDream/femtoDreamDebugTrack.cxx @@ -13,6 +13,7 @@ /// \brief Tasks that reads the particle tables and fills QA histograms for tracks /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch +#include #include "DataFormatsParameters/GRPObject.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisTask.h" @@ -32,24 +33,15 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -namespace -{ -static constexpr int nCuts = 5; -static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; -static const float cutsTable[1][nCuts] = {{4.05f, 0.75f, 3.f, 3.f, 100.f}}; - -} // namespace - struct femtoDreamDebugTrack { SliceCache cache; - Configurable> ConfCutTable{"ConfCutTable", {cutsTable[0], nCuts, cutNames}, "Particle selections"}; - Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 2212, "Particle 1 - PDG code"}; - Configurable ConfCutPartOne{"ConfCutPartOne", 5542474, "Particle 1 - Selection bit from cutCulator"}; - Configurable ConfPIDPartOne{"ConfPIDPartOne", 1, "Particle 1 - Read from cutCulator"}; - Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{3.5f, 3.f, 2.5f}, "This configurable needs to be the same as the one used in the producer task"}; + Configurable ConfTrk1_PDGCode{"ConfTrk1_PDGCode", 2212, "Particle 1 - PDG code"}; + Configurable ConfTrk1_CutBit{"ConfTrk1_CutBit", 5542474, "Particle 1 - Selection bit from cutCulator"}; + Configurable ConfTrk1_TPCBit{"ConfTrk1_TPCBit", 1, "Particle 1 - Read from cutCulator"}; + Configurable ConfTrk1_TPCTOFBit{"ConfTrk1_TPCTOFBit", 1, "Particle 1 - Read from cutCulator"}; + Configurable ConfTrk1_PIDThres{"ConfTrk1_PIDThres", 0.75, "Particle 1 - Read from cutCulator"}; ConfigurableAxis ConfTempFitVarBins{"ConfTempFitVarBins", {300, -0.15, 0.15}, "Binning of the TempFitVar"}; ConfigurableAxis ConfNsigmaTPCBins{"ConfNsigmaTPCBins", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; ConfigurableAxis ConfNsigmaTOFBins{"ConfNsigmaTOFBins", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; @@ -59,11 +51,14 @@ struct femtoDreamDebugTrack { ConfigurableAxis ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis for inv mass"}; using FemtoFullParticles = soa::Join; - Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ((aod::femtodreamparticle::cut & ConfCutPartOne) == ConfCutPartOne); + + Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)); + Preslice perColReco = aod::femtodreamparticle::fdCollisionId; using FemtoFullParticlesMC = soa::Join; - Partition partsOneMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ((aod::femtodreamparticle::cut & ConfCutPartOne) == ConfCutPartOne); + Partition partsOneMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit); Preslice perColGen = aod::femtodreamparticle::fdCollisionId; /// Histogramming for Event @@ -71,19 +66,13 @@ struct femtoDreamDebugTrack { FemtoDreamParticleHisto trackHisto; - /// The configurables need to be passed to an std::vector - int vPIDPartOne; - std::vector kNsigma; - /// Histogram output HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { eventHisto.init(&qaRegistry); - trackHisto.init(&qaRegistry, ConfTempFitVarMomentumBins, ConfTempFitVarBins, ConfNsigmaTPCBins, ConfNsigmaTOFBins, ConfNsigmaTPCTOFBins, ConfDummy, ConfIsMC, ConfPDGCodePartOne.value, true); - vPIDPartOne = ConfPIDPartOne.value; - kNsigma = ConfTrkPIDnSigmaMax.value; + trackHisto.init(&qaRegistry, ConfTempFitVarMomentumBins, ConfTempFitVarBins, ConfNsigmaTPCBins, ConfNsigmaTOFBins, ConfNsigmaTPCTOFBins, ConfDummy, ConfIsMC, ConfTrk1_PDGCode.value, true); } /// Porduce QA plots for sigle track selection in FemtoDream framework @@ -92,12 +81,6 @@ struct femtoDreamDebugTrack { { eventHisto.fillQA(col); for (auto& part : groupPartsOne) { - if (part.p() > ConfCutTable->get("MaxP") || part.pt() > ConfCutTable->get("MaxPt")) { - continue; - } - if (!isFullPIDSelected(part.pidcut(), part.p(), ConfCutTable->get("PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfCutTable->get("nSigmaTPC"), ConfCutTable->get("nSigmaTPCTOF"))) { - continue; - } trackHisto.fillQA(part, static_cast(ConfTempFitVarMomentum.value)); } } diff --git a/PWGCF/FemtoDream/femtoDreamDebugV0.cxx b/PWGCF/FemtoDream/femtoDreamDebugV0.cxx index d193bfe05ec..538e58e2352 100644 --- a/PWGCF/FemtoDream/femtoDreamDebugV0.cxx +++ b/PWGCF/FemtoDream/femtoDreamDebugV0.cxx @@ -13,7 +13,6 @@ /// \brief Tasks that reads the particle tables and fills QA histograms for V0s /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch -#include #include #include #include @@ -24,6 +23,7 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" #include "DataFormatsParameters/GRPObject.h" +#include "fairlogger/Logger.h" #include "PWGCF/DataModel/FemtoDerived.h" #include "FemtoDreamParticleHisto.h" @@ -39,35 +39,30 @@ using namespace o2::soa; struct femtoDreamDebugV0 { SliceCache cache; - Configurable ConfPDGCodeV0{"ConfPDGCodePartOne", 3122, "V0 - PDG code"}; - Configurable ConfPDGCodeChildPos{"ConfPDGCodeChildPos", 2212, "Positive Child - PDG code"}; - Configurable ConfPDGCodeChildNeg{"ConfPDGCodeChildNeg", 211, "Negative Child- PDG code"}; - Configurable ConfCutV0{"ConfCutV0", 338, "V0 - Selection bit from cutCulator"}; + Configurable ConfV01_PDGCode{"ConfV01_PDGCode", 3122, "V0 - PDG code"}; + Configurable ConfV01_ChildPos_PDGCode{"ConfV01_PosChild_PDGCode", 2212, "Positive Child - PDG code"}; + Configurable ConfV01_NegChild_PDGCode{"ConfV01_NegChild_PDGCode", 211, "Negative Child- PDG code"}; + Configurable ConfV01_CutBit{"ConfV01_CutBit", 338, "V0 - Selection bit from cutCulator"}; ConfigurableAxis ConfV0TempFitVarBins{"ConfV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfV0TempFitVarMomentumBins{"ConfV0TempFitVarMomentumBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; - Configurable ConfTempFitVarMomentum{"ConfTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; + Configurable ConfV0TempFitVarMomentum{"ConfV0TempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; ConfigurableAxis ConfV0InvMassBins{"ConfV0InvMassBins", {200, 1, 1.2}, "V0: InvMass binning"}; - ConfigurableAxis ConfChildTempFitVarMomentumBins{"ConfChildTempFitVarMomentumBins", {600, 0, 6}, "p binning for the p vs Nsigma TPC/TOF plot"}; - ConfigurableAxis ConfChildNsigmaTPCBins{"ConfChildNsigmaTPCBins", {1600, -8, 8}, "binning of Nsigma TPC plot"}; - ConfigurableAxis ConfChildNsigmaTOFBins{"ConfChildNsigmaTOFBins", {3000, -15, 15}, "binning of the Nsigma TOF plot"}; - ConfigurableAxis ConfChildNsigmaTPCTOFBins{"ConfChildNsigmaTPCTOFBins", {1000, 0, 10}, "binning of the Nsigma TPC+TOF plot"}; - - Configurable ConfCutChildPos{"ConfCutChildPos", 150, "Positive Child of V0 - Selection bit from cutCulator"}; - Configurable ConfCutChildNeg{"ConfCutChildNeg", 149, "Negative Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildPosPidnSigmaMax{"ConfChildPosPidnSigmaMax", 3.f, "Positive Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildNegPidnSigmaMax{"ConfChildNegPidnSigmaMax", 3.f, "Negative Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildPosIndex{"ConfChildPosIndex", 1, "Positive Child of V0 - Index from cutCulator"}; - Configurable ConfChildNegIndex{"ConfChildNegIndex", 0, "Negative Child of V0 - Index from cutCulator"}; - Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child sel: Max. PID nSigma TPC"}; - Configurable ConfChildnSpecies{"ConfChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; + ConfigurableAxis ConfV0ChildTempFitVarMomentumBins{"ConfV0ChildTempFitVarMomentumBins", {600, 0, 6}, "p binning for the p vs Nsigma TPC/TOF plot"}; + ConfigurableAxis ConfV0ChildNsigmaTPCBins{"ConfV0ChildNsigmaTPCBins", {1600, -8, 8}, "binning of Nsigma TPC plot"}; + ConfigurableAxis ConfV0ChildNsigmaTOFBins{"ConfV0ChildNsigmaTOFBins", {3000, -15, 15}, "binning of the Nsigma TOF plot"}; + ConfigurableAxis ConfV0ChildNsigmaTPCTOFBins{"ConfV0ChildNsigmaTPCTOFBins", {1000, 0, 10}, "binning of the Nsigma TPC+TOF plot"}; + + Configurable ConfV01_ChildPos_CutBit{"ConfV01_ChildPos_CutBit", 150, "Positive Child of V0 - Selection bit from cutCulator"}; + Configurable ConfV01_ChildPos_TPCBit{"ConfV01_ChildPos_TPCBit", 4, "Positive Child of V0 - PID bit from cutCulator"}; + Configurable ConfV01_ChildNeg_TPCBit{"ConfV01_ChildNeg_TPCBit", 8, "Negative Child of V0 - PID bit from cutCulator"}; ConfigurableAxis ConfChildTempFitVarBins{"ConfChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfChildTempFitVarpTBins{"ConfChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; using FemtoFullParticles = soa::Join; - Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && ((aod::femtodreamparticle::cut & ConfCutV0) == ConfCutV0); + Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && (ncheckbit(aod::femtodreamparticle::cut, ConfV01_CutBit)); Preslice perCol = aod::femtodreamparticle::fdCollisionId; /// Histogramming @@ -83,9 +78,9 @@ struct femtoDreamDebugV0 { void init(InitContext&) { eventHisto.init(&EventRegistry); - posChildHistos.init(&V0Registry, ConfChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfChildNsigmaTPCBins, ConfChildNsigmaTOFBins, ConfChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfPDGCodeChildPos.value, true); - negChildHistos.init(&V0Registry, ConfChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfChildNsigmaTPCBins, ConfChildNsigmaTOFBins, ConfChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfPDGCodeChildNeg, true); - V0Histos.init(&V0Registry, ConfV0TempFitVarMomentumBins, ConfV0TempFitVarBins, ConfChildNsigmaTPCBins, ConfChildNsigmaTOFBins, ConfChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfPDGCodeV0.value, true); + posChildHistos.init(&V0Registry, ConfV0ChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_ChildPos_PDGCode.value, true); + negChildHistos.init(&V0Registry, ConfV0ChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_NegChild_PDGCode, true); + V0Histos.init(&V0Registry, ConfV0TempFitVarMomentumBins, ConfV0TempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_PDGCode.value, true); } /// Porduce QA plots for V0 selection in FemtoDream framework @@ -97,6 +92,10 @@ struct femtoDreamDebugV0 { if (!part.has_children()) { continue; } + // check cut on v0 children + // TODO: check if this should be possible + // auto posChild = part.template children_as().front(); + // auto negChild = part.template children_as().back(); const auto& posChild = parts.iteratorAt(part.index() - 2); const auto& negChild = parts.iteratorAt(part.index() - 1); if (posChild.globalIndex() != part.childrenIds()[0] || negChild.globalIndex() != part.childrenIds()[1]) { @@ -104,12 +103,15 @@ struct femtoDreamDebugV0 { continue; } // check cuts on V0 children - if ((posChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kV0Child) && (posChild.cut() & ConfCutChildPos) == ConfCutChildPos) && - (negChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kV0Child) && (negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) && - isFullPIDSelected(posChild.pidcut(), posChild.p(), 999.f, ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfChildPosPidnSigmaMax.value, 1.f) && isFullPIDSelected(negChild.pidcut(), negChild.p(), 999.f, ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfChildNegPidnSigmaMax.value, 1.f)) { - V0Histos.fillQA(part, static_cast(ConfTempFitVarMomentum.value)); - posChildHistos.fillQA(posChild, static_cast(ConfTempFitVarMomentum.value)); - negChildHistos.fillQA(negChild, static_cast(ConfTempFitVarMomentum.value)); + if (posChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kV0Child) && + (posChild.cut() & ConfV01_ChildPos_CutBit) == ConfV01_ChildPos_CutBit && + (posChild.pidcut() & ConfV01_ChildPos_TPCBit) == ConfV01_ChildPos_TPCBit && + negChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kV0Child) && + (negChild.cut() & ConfV01_ChildNeg_TPCBit) == ConfV01_ChildNeg_TPCBit && + (negChild.pidcut() & ConfV01_ChildNeg_TPCBit) == ConfV01_ChildNeg_TPCBit) { + V0Histos.fillQA(part, static_cast(ConfV0TempFitVarMomentum.value)); + posChildHistos.fillQA(posChild, static_cast(ConfV0TempFitVarMomentum.value)); + negChildHistos.fillQA(negChild, static_cast(ConfV0TempFitVarMomentum.value)); } } } diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx b/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx index 69106ff6635..48dc654b816 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx @@ -15,7 +15,11 @@ /// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de /// \author Anton Riedel, TU München, anton.riedel@tum.de +#include +#include +#include #include +#include #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" @@ -33,89 +37,87 @@ #include "FemtoDreamDetaDphiStar.h" #include "FemtoUtils.h" -using namespace o2; -using namespace o2::analysis::femtoDream; +using namespace o2::aod; +using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; -using namespace o2::soa; - -namespace -{ -static constexpr int nPart = 2; -static constexpr int nCuts = 3; -static const std::vector partNames{"PartOne", "PartTwo"}; -static const std::vector cutNames{"PIDthr", "nSigmaTPC", "nSigmaTPCTOF"}; -static const float cutsTable[nPart][nCuts]{ - {0.75f, 3.f, 3.f}, - {0.75f, 3.f, 3.f}}; -} // namespace +using namespace o2::analysis::femtoDream; struct femtoDreamPairTaskTrackTrack { SliceCache cache; Preslice perCol = aod::femtodreamparticle::fdCollisionId; - /// Particle selection part + using MaskedCollisions = soa::Join; + using MaskedCollision = MaskedCollisions::iterator; + femtodreamcollision::BitMaskType MaskBit = -1; /// Table for both particles - Configurable> ConfCutTable{"ConfCutTable", {cutsTable[0], nPart, nCuts, partNames, cutNames}, "Particle selections"}; - Configurable ConfNspecies{"ConfNspecies", 1, "Number of particle spieces with PID info"}; Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; - Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; Configurable ConfExtendedPlots{"ConfExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; Configurable ConfHighkstarCut{"ConfHighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; - /// Particle 1 - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 2212, "Particle 1 - PDG code"}; - Configurable ConfCutPartOne{"ConfCutPartOne", 3191978, "Particle 1 - Selection bit from cutCulator"}; - Configurable ConfPIDPartOne{"ConfPIDPartOne", 0, "Particle 1 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector>int>> + /// Particle selection part - Configurable ConfTrk1_minPt{"ConfTrk1_minPt", 0., "Minimum pT of Partricle 1 (Track)"}; - Configurable ConfTrk1_maxPt{"ConfTrk1_maxPt", 999., "Maximum pT of Partricle 1 (Track)"}; - Configurable ConfTrk1_minEta{"ConfTrk1_minEta", -10., "Minimum eta of Partricle 1 (Track)"}; - Configurable ConfTrk1_maxEta{"ConfTrk1_maxEta", 10., "Maximum eta of Partricle 1 (Track)"}; + /// Particle 1 + Configurable ConfTrk1_PDGCode{"ConfTrk1_PDGCode", 2212, "PDG code of particle 1 (Track)"}; + Configurable ConfTrk1_CutBit{"ConfTrk1_CutBit", 3191978, "Selection bit from cutCulator for particle 1 (Track)"}; + Configurable ConfTrk1_TPCBit{"ConfTrk1_TPCBit", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; + Configurable ConfTrk1_TPCTOFBit{"ConfTrk1_TPCTOFBit", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; + Configurable ConfTrk1_PIDThres{"ConfTrk1_PIDThres", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; + Configurable ConfTrk1_minPt{"ConfTrk1_minPt", 0., "Minimum pT of partricle 1 (Track)"}; + Configurable ConfTrk1_maxPt{"ConfTrk1_maxPt", 999., "Maximum pT of partricle 1 (Track)"}; + Configurable ConfTrk1_minEta{"ConfTrk1_minEta", -10., "Minimum eta of partricle 1 (Track)"}; + Configurable ConfTrk1_maxEta{"ConfTrk1_maxEta", 10., "Maximum eta of partricle 1 (Track)"}; /// Partition for particle 1 - Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - ((aod::femtodreamparticle::cut & ConfCutPartOne) == ConfCutPartOne) && - (aod::femtodreamparticle::pt > ConfTrk1_minPt) && - (aod::femtodreamparticle::pt < ConfTrk1_maxPt) && - (aod::femtodreamparticle::eta > ConfTrk1_minEta) && - (aod::femtodreamparticle::eta < ConfTrk1_maxEta); - Partition> partsOneMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - ((aod::femtodreamparticle::cut & ConfCutPartOne) == ConfCutPartOne) && - (aod::femtodreamparticle::pt > ConfTrk1_minPt) && - (aod::femtodreamparticle::pt < ConfTrk1_maxPt) && - (aod::femtodreamparticle::eta > ConfTrk1_minEta) && - (aod::femtodreamparticle::eta < ConfTrk1_maxEta); + Partition PartitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)) && + (aod::femtodreamparticle::pt > ConfTrk1_minPt) && + (aod::femtodreamparticle::pt < ConfTrk1_maxPt) && + (aod::femtodreamparticle::eta > ConfTrk1_minEta) && + (aod::femtodreamparticle::eta < ConfTrk1_maxEta); + + Partition> PartitionMCTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)) && + (aod::femtodreamparticle::pt > ConfTrk1_minPt) && + (aod::femtodreamparticle::pt < ConfTrk1_maxPt) && + (aod::femtodreamparticle::eta > ConfTrk1_minEta) && + (aod::femtodreamparticle::eta < ConfTrk1_maxEta); /// Histogramming for particle 1 FemtoDreamParticleHisto trackHistoPartOne; /// Particle 2 - Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 2212, "Particle 2 - PDG code"}; - Configurable ConfCutPartTwo{"ConfCutPartTwo", 3191978, "Particle 2 - Selection bit"}; - Configurable ConfPIDPartTwo{"ConfPIDPartTwo", 0, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> - - Configurable ConfTrk2_minPt{"ConfTrk2_minPt", 0., "Minimum pT of Partricle 2 (Track)"}; - Configurable ConfTrk2_maxPt{"ConfTrk2_maxPt", 999., "Maximum pT of Partricle 2 (Track)"}; - Configurable ConfTrk2_minEta{"ConfTrk2_minEta", -10., "Minimum eta of Partricle 2 (Track)"}; - Configurable ConfTrk2_maxEta{"ConfTrk2_maxEta", 10., "Maximum eta of Partricle 2 (Track)"}; + Configurable ConfIsSame{"ConfIsSame", false, "Set to true if particle 1 and particle 2 are the same species"}; + Configurable ConfTrk2_PDGCode{"ConfTrk2_PDGCode", 2212, "PDG code of particle 2 (Track)"}; + Configurable ConfTrk2_CutBit{"ConfTrk2_CutBit", 3191978, "Selection bit from cutCulator for particle 2 (Track)"}; + Configurable ConfTrk2_TPCBit{"ConfTrk2_TPCBit", 4, "PID TPC bit from cutCulator for particle 2 (Track)"}; + Configurable ConfTrk2_TPCTOFBit{"ConfTrk2_TPCTOFBit", 2, "PID TPCTOF bit from cutCulator for particle 2 (Track)"}; + Configurable ConfTrk2_PIDThres{"ConfTrk2_PIDThres", 0.75, "Momentum threshold for PID selection for particle 2 (Track)"}; + Configurable ConfTrk2_minPt{"ConfTrk2_minPt", 0., "Minimum pT of partricle 2 (Track)"}; + Configurable ConfTrk2_maxPt{"ConfTrk2_maxPt", 999., "Maximum pT of partricle 2 (Track)"}; + Configurable ConfTrk2_minEta{"ConfTrk2_minEta", -10., "Minimum eta of partricle 2 (Track)"}; + Configurable ConfTrk2_maxEta{"ConfTrk2_maxEta", 10., "Maximum eta of partricle 2 (Track)"}; /// Partition for particle 2 - Partition partsTwo = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - ((aod::femtodreamparticle::cut & ConfCutPartTwo) == ConfCutPartTwo) && - (aod::femtodreamparticle::pt > ConfTrk2_minPt) && - (aod::femtodreamparticle::pt < ConfTrk2_maxPt) && - (aod::femtodreamparticle::eta > ConfTrk2_minEta) && - (aod::femtodreamparticle::eta < ConfTrk2_maxEta); - Partition> partsTwoMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - ((aod::femtodreamparticle::cut & ConfCutPartTwo) == ConfCutPartTwo) && - (aod::femtodreamparticle::pt > ConfTrk2_minPt) && - (aod::femtodreamparticle::pt < ConfTrk2_maxPt) && - (aod::femtodreamparticle::eta > ConfTrk2_minEta) && - (aod::femtodreamparticle::eta < ConfTrk2_maxEta); + Partition PartitionTrk2 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfTrk2_CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk2_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk2_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk2_TPCTOFBit)) && + (aod::femtodreamparticle::pt > ConfTrk2_minPt) && + (aod::femtodreamparticle::pt < ConfTrk2_maxPt) && + (aod::femtodreamparticle::eta > ConfTrk2_minEta) && + (aod::femtodreamparticle::eta < ConfTrk2_maxEta); + + Partition> PartitionMCTrk2 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfTrk2_CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk2_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk2_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk2_TPCTOFBit)) && + (aod::femtodreamparticle::pt > ConfTrk2_minPt) && + (aod::femtodreamparticle::pt < ConfTrk2_maxPt) && + (aod::femtodreamparticle::eta > ConfTrk2_minEta) && + (aod::femtodreamparticle::eta < ConfTrk2_maxEta); /// Histogramming for particle 2 FemtoDreamParticleHisto trackHistoPartTwo; @@ -123,22 +125,16 @@ struct femtoDreamPairTaskTrackTrack { /// Histogramming for Event FemtoDreamEventHisto eventHisto; - /// The configurables need to be passed to an std::vector - int vPIDPartOne, vPIDPartTwo; - std::vector kNsigma; - /// particle part - ConfigurableAxis ConfTempFitVarBins{"ConfDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfTempFitVarBins{"ConfTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; /// Correlation part ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task - // ConfigurableAxis ConfMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; 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 ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; ConfigurableAxis ConfmultBins3D{"ConfmultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; @@ -160,13 +156,12 @@ struct femtoDreamPairTaskTrackTrack { HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(InitContext& context) { - eventHisto.init(&qaRegistry); - trackHistoPartOne.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfPDGCodePartOne); + trackHistoPartOne.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrk1_PDGCode); if (!ConfIsSame) { - trackHistoPartTwo.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfPDGCodePartTwo); + trackHistoPartTwo.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrk2_PDGCode); } MixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); @@ -174,17 +169,50 @@ struct femtoDreamPairTaskTrackTrack { sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); - sameEventCont.setPDGCodes(ConfPDGCodePartOne, ConfPDGCodePartTwo); - mixedEventCont.setPDGCodes(ConfPDGCodePartOne, ConfPDGCodePartTwo); + sameEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfTrk2_PDGCode); + mixedEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfTrk2_PDGCode); pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); } - vPIDPartOne = ConfPIDPartOne.value; - vPIDPartTwo = ConfPIDPartTwo.value; - kNsigma = ConfTrkPIDnSigmaMax.value; - } + // get bit for the collision mask + std::bitset<8 * sizeof(femtodreamcollision::BitMaskType)> mask; + int index = 0; + auto& workflows = context.services().get(); + for (DeviceSpec const& device : workflows.devices) { + if (device.name.find("femto-dream-pair-task-track-track") != std::string::npos) { + if (containsNameValuePair(device.options, "ConfTrk1_CutBit", ConfTrk1_CutBit.value) && + containsNameValuePair(device.options, "ConfTrk1_TPCBit", ConfTrk1_TPCBit.value) && + containsNameValuePair(device.options, "ConfTrk1_TPCTOFBit", ConfTrk1_TPCTOFBit.value) && + containsNameValuePair(device.options, "ConfTrk1_PIDThres", ConfTrk1_PIDThres.value) && + containsNameValuePair(device.options, "ConfTrk1_minPt", ConfTrk1_minPt.value) && + containsNameValuePair(device.options, "ConfTrk1_maxPt", ConfTrk1_maxPt.value) && + containsNameValuePair(device.options, "ConfTrk1_minEta", ConfTrk1_minEta.value) && + containsNameValuePair(device.options, "ConfTrk1_maxEta", ConfTrk1_maxEta.value) && + containsNameValuePair(device.options, "ConfTrk2_CutBit", ConfTrk2_CutBit.value) && + containsNameValuePair(device.options, "ConfTrk2_TPCBit", ConfTrk2_TPCBit.value) && + containsNameValuePair(device.options, "ConfTrk2_TPCTOFBit", ConfTrk2_TPCTOFBit.value) && + containsNameValuePair(device.options, "ConfTrk2_PIDThres", ConfTrk2_PIDThres.value) && + containsNameValuePair(device.options, "ConfTrk2_minPt", ConfTrk2_minPt.value) && + containsNameValuePair(device.options, "ConfTrk2_maxPt", ConfTrk2_maxPt.value) && + containsNameValuePair(device.options, "ConfTrk2_minEta", ConfTrk2_minEta.value) && + containsNameValuePair(device.options, "ConfTrk2_maxEta", ConfTrk2_maxEta.value)) { + mask.set(index); + MaskBit = static_cast(mask.to_ulong()); + LOG(info) << "Device name matched: " << device.name; + LOG(info) << "Bitmask for collisions: " << mask.to_string(); + break; + } else { + index++; + } + } + } + if ((doprocessSameEvent && doprocessSameEventMasked) || + (doprocessMixedEvent && doprocessMixedEventMasked)) { + LOG(fatal) << "Normal and masked processing cannot be activated simultaneously!"; + } + }; template void fillCollision(CollisionType col) @@ -204,104 +232,93 @@ struct femtoDreamPairTaskTrackTrack { /// @param magFieldTesla magnetic field of the collision /// @param multCol multiplicity of the collision template - void doSameEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartType parts, float magFieldTesla, int multCol) + void doSameEvent(PartitionType SliceTrk1, PartitionType SliceTrk2, PartType parts, float magFieldTesla, int multCol) { - /// Histogramming same event - for (auto& part : groupPartsOne) { - if (!isFullPIDSelected(part.pidcut(), - part.p(), - ConfCutTable->get("PartOne", "PIDthr"), - vPIDPartOne, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartOne", "nSigmaTPC"), - ConfCutTable->get("PartOne", "nSigmaTPCTOF"))) { - continue; - } - + for (auto& part : SliceTrk1) { trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt); } - if (!ConfIsSame) { - for (auto& part : groupPartsTwo) { - if (!isFullPIDSelected(part.pidcut(), - part.p(), - ConfCutTable->get("PartTwo", "PIDthr"), - vPIDPartTwo, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartTwo", "nSigmaTPC"), - ConfCutTable->get("PartTwo", "nSigmaTPCTOF"))) { - continue; - } + if (!ConfIsSame.value) { + for (auto& part : SliceTrk2) { trackHistoPartTwo.fillQA(part, aod::femtodreamparticle::kPt); } } - /// Now build the combinations - for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (!isFullPIDSelected(p1.pidcut(), - p1.p(), - ConfCutTable->get("PartOne", "PIDthr"), - vPIDPartOne, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartOne", "nSigmaTPC"), - ConfCutTable->get("PartOne", "nSigmaTPCTOF")) || - !isFullPIDSelected(p2.pidcut(), - p2.p(), - ConfCutTable->get("PartTwo", "PIDthr"), - vPIDPartTwo, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartTwo", "nSigmaTPC"), - ConfCutTable->get("PartTwo", "nSigmaTPCTOF"))) { - continue; - } - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + /// Now build the combinations + if (ConfIsSame.value) { + for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(SliceTrk1, SliceTrk2))) { + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + } + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } - - // track cleaning - if (!pairCleaner.isCleanPair(p1, p2, parts)) { - continue; + } else { + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + } + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } - sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } } /// process function for to call doSameEvent with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoDreamParticleTable - void processSameEvent(o2::aod::FDCollision& col, - o2::aod::FDParticles& parts) + void processSameEvent(o2::aod::FDCollision& col, o2::aod::FDParticles& parts) { fillCollision(col); - - auto thegroupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - - doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr()); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceTrk1, SliceTrk2, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEvent, "Enable processing same event", true); + void processSameEventMasked(MaskedCollision& col, o2::aod::FDParticles& parts) + { + if (ConfIsSame.value) { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit) { + return; + } + } else { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + return; + } + } + fillCollision(col); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceTrk1.size() == 0 || SliceTrk2.size() == 0) { + return; + } + doSameEvent(SliceTrk1, SliceTrk2, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMasked, "Enable processing same event with masks", false); + /// process function for to call doSameEvent with Monte Carlo /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) /// \param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth /// \param FemtoDreamMCParticles subscribe to the Monte Carlo truth table - void processSameEventMC(o2::aod::FDCollision& col, - soa::Join& parts, + void processSameEventMC(o2::aod::FDCollision& col, soa::Join& parts, o2::aod::FDMCParticles&) { fillCollision(col); - - auto thegroupPartsOne = partsOneMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsTwo = partsTwoMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - - doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr()); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMC, "Enable processing same event for Monte Carlo", false); @@ -316,35 +333,14 @@ struct femtoDreamPairTaskTrackTrack { /// \param magFieldTesla magnetic field of the collision /// \param multCol multiplicity of the collision template - void doMixedEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartType parts, float magFieldTesla, int multCol) + void doMixedEvent(PartitionType SliceTrk1, PartitionType SliceTrk2, PartType parts, float magFieldTesla, int multCol) { - - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (!isFullPIDSelected(p1.pidcut(), - p1.p(), - ConfCutTable->get("PartOne", "PIDthr"), - vPIDPartOne, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartOne", "nSigmaTPC"), - ConfCutTable->get("PartOne", "nSigmaTPCTOF")) || - !isFullPIDSelected(p2.pidcut(), - p2.p(), - ConfCutTable->get("PartTwo", "PIDthr"), - vPIDPartTwo, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartTwo", "nSigmaTPC"), - ConfCutTable->get("PartTwo", "nSigmaTPCTOF"))) { - continue; - } - + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { if (ConfIsCPR.value) { if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { continue; } } - mixedEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } } @@ -352,16 +348,15 @@ struct femtoDreamPairTaskTrackTrack { /// process function for to call doMixedEvent with Data /// @param cols subscribe to the collisions table (Data) /// @param parts subscribe to the femtoDreamParticleTable - void processMixedEvent(o2::aod::FDCollisions& cols, - o2::aod::FDParticles& parts) + void processMixedEvent(o2::aod::FDCollisions& cols, o2::aod::FDParticles& parts) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { + for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { const int multiplicityCol = collision1.multNtr(); MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto groupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); @@ -372,26 +367,43 @@ struct femtoDreamPairTaskTrackTrack { /// \todo before mixing we should check whether both collisions contain a pair of particles! // if (partsOne.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTwo.size() == 0 ) continue; - doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol); + doMixedEvent(SliceTrk1, SliceTrk2, parts, magFieldTesla1, multiplicityCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEvent, "Enable processing mixed events", true); + void processMixedEventMasked(MaskedCollisions& cols, o2::aod::FDParticles& parts) + { + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; + Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; + + PartitionMaskedCol1.bindTable(cols); + PartitionMaskedCol2.bindTable(cols); + + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { + const auto multiplicityCol = collision1.multNtr(); + const auto magFieldTesla1 = collision1.magField(); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(SliceTrk1, SliceTrk2, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMasked, "Enable processing mixed events", false); + /// brief process function for to call doMixedEvent with Monte Carlo /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) /// @param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth /// @param FemtoDreamMCParticles subscribe to the Monte Carlo truth table - void processMixedEventMC(o2::aod::FDCollisions& cols, - soa::Join& parts, - o2::aod::FDMCParticles&) + void processMixedEventMC(o2::aod::FDCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { const int multiplicityCol = collision1.multNtr(); MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto groupPartsOne = partsOneMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); @@ -402,7 +414,7 @@ struct femtoDreamPairTaskTrackTrack { /// \todo before mixing we should check whether both collisions contain a pair of particles! // if (partsOne.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTwo.size() == 0 ) continue; - doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol); + doMixedEvent(SliceMCTrk1, SliceMCTrk2, parts, magFieldTesla1, multiplicityCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMC, "Enable processing mixed events MC", false); diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx b/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx index 18b7cc2d087..36379c6870e 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx +++ b/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx @@ -13,6 +13,9 @@ /// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +#include +#include +#include #include #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -30,88 +33,76 @@ #include "FemtoUtils.h" using namespace o2; +using namespace o2::aod; using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::femtoDream; -namespace -{ -static constexpr int nTrack = 1; -static constexpr int nV0Children = 2; -static constexpr int nCuts = 3; -static const std::vector TrackName{"Track"}; -static const std::vector V0ChildrenName{"PosChild", "NegChild"}; -static const std::vector cutNames{"PIDthr", "nSigmaTPC", "nSigmaTPCTOF"}; -static const float cutsTableTrack[nTrack][nCuts]{{0.75f, 3.f, 3.f}}; -static const float cutsTableV0Children[nV0Children][nCuts]{ - {99.f, 5.f, 5.f}, - {99.f, 5.f, 5.f}}; -} // namespace - struct femtoDreamPairTaskTrackV0 { SliceCache cache; Preslice perCol = aod::femtodreamparticle::fdCollisionId; + using MaskedCollisions = soa::Join; + using MaskedCollision = MaskedCollisions::iterator; + femtodreamcollision::BitMaskType MaskBit = -1; + /// Particle 1 (track) - Configurable> ConfTrkCutTable{"ConfTrkCutTable", {cutsTableTrack[0], nTrack, nCuts, TrackName, cutNames}, "Particle selections"}; - Configurable ConfTrkPDGCodePartOne{"ConfTrkPDGCodePartOne", 2212, "Particle 1 (Track) - PDG code"}; - Configurable ConfTrkCutPartOne{"ConfTrkCutPartOne", 5542474, "Particle 1 (Track) - Selection bit from cutCulator"}; - Configurable ConfTrkPIDPartOne{"ConfTrkPIDPartOne", 2, "Particle 1 - Read from cutCulator"}; - Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; - Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; - ConfigurableAxis ConfTrkTempFitVarBins{"ConfTrkDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + Configurable ConfTrk1_PDGCode{"ConfTrk1_PDGCode", 2212, "PDG code of Particle 1 (Track)"}; + Configurable ConfTrk1_CutBit{"ConfTrk1_CutBit", 5542474, "Particle 1 (Track) - Selection bit from cutCulator"}; + Configurable ConfTrk1_TPCBit{"ConfTrk1_TPCBit", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; + Configurable ConfTrk1_TPCTOFBit{"ConfTrk1_TPCTOFBit", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; + Configurable ConfTrk1_PIDThres{"ConfTrk1_PIDThres", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; + Configurable ConfTrk1_minPt{"ConfTrk1_minPt", 0., "Minimum pT of partricle 1 (Track)"}; + Configurable ConfTrk1_maxPt{"ConfTrk1_maxPt", 999., "Maximum pT of partricle 1 (Track)"}; + Configurable ConfTrk1_minEta{"ConfTrk1_minEta", -10., "Minimum eta of partricle 1 (Track)"}; + Configurable ConfTrk1_maxEta{"ConfTrk1_maxEta", 10., "Maximum eta of partricle 1 (Track)"}; + + ConfigurableAxis ConfTrkTempFitVarBins{"ConfTrkTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfTrkTempFitVarpTBins{"ConfTrkTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; - Configurable ConfTrkminPt{"ConfTrkminPt", 0., "Minimum pT of Partricle 1 (Track)"}; - Configurable ConfTrkmaxPt{"ConfTrkmaxPt", 999., "Maximum pT of Partricle 1 (Track)"}; - Configurable ConfTrkminEta{"ConfTrkminEta", -10., "Minimum eta of Partricle 1 (Track)"}; - Configurable ConfTrkmaxEta{"ConfTrkmaxEta", 10., "Maximum eta of Partricle 1 (Track)"}; - - Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ConfTrkminPt, true); - Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ConfTrkmaxPt, true); - Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > ConfTrkminEta, true); - Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < ConfTrkmaxEta, true); + Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ConfTrk1_minPt, true); + Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ConfTrk1_maxPt, true); + Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > ConfTrk1_minEta, true); + Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < ConfTrk1_maxEta, true); /// Histogramming for particle 1 FemtoDreamParticleHisto trackHistoPartOne; /// Particle 2 (V0) - Configurable> ConfV0ChildrenCutTable{"ConfV0ChildrenCutTable", {cutsTableV0Children[0], nV0Children, nCuts, V0ChildrenName, cutNames}, "V0 Children selections"}; - Configurable ConfV0PDGCodePartTwo{"ConfV0PDGCodePartTwo", 3122, "Particle 2 (V0) - PDG code"}; - Configurable ConfV0CutPartTwo{"ConfV0CutPartTwo", 338, "Particle 2 (V0) - Selection bit"}; + Configurable ConfV02_PDGCode{"ConfV02_PDGCode", 3122, "PDG code of particle 2 (V0)"}; + Configurable ConfV02_CutBit{"ConfV02_CutBit", 338, "Selection bit for particle 2 (V0)"}; + Configurable ConfV02_ChildPos_CutBit{"ConfV02_ChildPos_CutBit", 149, "Selection bit for positive child of V0"}; + Configurable ConfV02_ChildPos_TPCBit{"ConfV02_ChildPos_TPCBit", 2, "PID TPC bit for positive child of V0"}; + Configurable ConfV02_ChildNeg_CutBit{"ConfV02_ChildNeg_CutBit", 149, "Selection bit for negative child of V0"}; + Configurable ConfV02_ChildNeg_TPCBit{"ConfV02_ChildNeg_TPCBit", 2, "PID TPC bit for negative child of V0"}; + ConfigurableAxis ConfV0TempFitVarBins{"ConfV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfV0TempFitVarpTBins{"ConfV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; ConfigurableAxis ConfV0TempFitVarInvMassBins{"ConfV0TempFitVarInvMassBins", {200, 1, 1.2}, "V0: InvMass binning"}; - Configurable ConfCutChildPos{"ConfCutChildPos", 150, "Positive Child of V0 - Selection bit from cutCulator"}; - Configurable ConfCutChildNeg{"ConfCutChildNeg", 149, "Negative Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildPosIndex{"ConfChildPosIndex", 1, "Positive Child of V0 - Index from cutCulator"}; - Configurable ConfChildNegIndex{"ConfChildNegIndex", 0, "Negative Child of V0 - Index from cutCulator"}; - Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child sel: Max. PID nSigma TPC"}; - Configurable ConfChildnSpecies{"ConfChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; - ConfigurableAxis ConfChildTempFitVarBins{"ConfChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfChildTempFitVarpTBins{"ConfChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; - - Configurable ConfV0minMass{"ConfV0minMass", 1.08, "Minimum invariant mass of Partricle 2 (particle) (V0)"}; - Configurable ConfV0maxMass{"ConfV0maxMass", 1.15, "Maximum invariant mass of Partricle 2 (particle) (V0)"}; - Configurable ConfV0minMassAnti{"ConfV0minMassAnti", 0., "Minimum invariant mass of Partricle 2 (antiparticle) (V0)"}; - Configurable ConfV0maxMassAnti{"ConfV0maxMassAnti", 999., "Maximum invariant mass of Partricle 2 (antiparticle) (V0)"}; - - Configurable ConfV0minPt{"ConfV0minPt", 0., "Minimum pT of Partricle 2 (V0)"}; - Configurable ConfV0maxPt{"ConfV0maxPt", 999., "Maximum pT of Partricle 2 (V0)"}; - Configurable ConfV0minEta{"ConfV0minEta", -10., "Minimum eta of Partricle 2 (V0)"}; - Configurable ConfV0maxEta{"ConfV0maxEta", 10., "Maximum eta of Partricle 2 (V0)"}; - - Filter v0MassFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mLambda > ConfV0minMass, true); - Filter v0MassFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mLambda < ConfV0maxMass, true); - Filter antiv0MassFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mAntiLambda > ConfV0minMassAnti, true); - Filter antiv0MassFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mAntiLambda < ConfV0maxMassAnti, true); - - Filter v0PtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::pt > ConfV0minPt, true); - Filter v0PtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::pt < ConfV0maxPt, true); - Filter v0EtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::eta > ConfV0minEta, true); - Filter v0EtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::eta < ConfV0maxEta, true); + ConfigurableAxis ConfV0ChildTempFitVarBins{"ConfV0ChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfV0ChildTempFitVarpTBins{"ConfV0ChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; + + Configurable ConfV02_minInvMass{"ConfV02_minInvMass", 1.08, "Minimum invariant mass of Partricle 2 (particle) (V0)"}; + Configurable ConfV02_maxInvMass{"ConfV02_maxInvMass", 1.15, "Maximum invariant mass of Partricle 2 (particle) (V0)"}; + Configurable ConfV02_minInvMassAnti{"ConfV02_minInvMassAnti", 0., "Minimum invariant mass of Partricle 2 (antiparticle) (V0)"}; + Configurable ConfV02_maxInvMassAnti{"ConfV02_maxInvMassAnti", 999., "Maximum invariant mass of Partricle 2 (antiparticle) (V0)"}; + + Configurable ConfV02_minPt{"ConfV02_minPt", 0., "Minimum pT of Partricle 2 (V0)"}; + Configurable ConfV02_maxPt{"ConfV02_maxPt", 999., "Maximum pT of Partricle 2 (V0)"}; + Configurable ConfV02_minEta{"ConfV02_minEta", -10., "Minimum eta of Partricle 2 (V0)"}; + Configurable ConfV02_maxEta{"ConfV02_maxEta", 10., "Maximum eta of Partricle 2 (V0)"}; + + Filter v0MassFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mLambda > ConfV02_minInvMass, true); + Filter v0MassFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mLambda < ConfV02_maxInvMass, true); + Filter antiv0MassFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mAntiLambda > ConfV02_minInvMassAnti, true); + Filter antiv0MassFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::mAntiLambda < ConfV02_maxInvMassAnti, true); + + Filter v0PtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::pt > ConfV02_minPt, true); + Filter v0PtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::pt < ConfV02_maxPt, true); + Filter v0EtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::eta > ConfV02_minEta, true); + Filter v0EtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0), aod::femtodreamparticle::eta < ConfV02_maxEta, true); /// Histogramming for particle 2 FemtoDreamParticleHisto trackHistoPartTwo; @@ -125,19 +116,20 @@ struct femtoDreamPairTaskTrackV0 { using FilteredFDMCPart = FilteredFDMCParts::iterator; /// Partition for particle 1 - Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ((aod::femtodreamparticle::cut & ConfTrkCutPartOne) == ConfTrkCutPartOne); - Partition partsOneMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ((aod::femtodreamparticle::cut & ConfTrkCutPartOne) == ConfTrkCutPartOne); + Partition PartitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)); + Partition PartitionMCTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)); /// Partition for particle 2 - Partition partsTwo = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && ((aod::femtodreamparticle::cut & ConfV0CutPartTwo) == ConfV0CutPartTwo); - Partition partsTwoMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && ((aod::femtodreamparticle::cut & ConfV0CutPartTwo) == ConfV0CutPartTwo); + Partition PartitionV02 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && ((aod::femtodreamparticle::cut & ConfV02_CutBit) == ConfV02_CutBit); + Partition PartitionMCV02 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && ((aod::femtodreamparticle::cut & ConfV02_CutBit) == ConfV02_CutBit); /// Histogramming for Event FemtoDreamEventHisto eventHisto; - int vPIDPartOne; - std::vector kNsigma; - /// Correlation part Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; @@ -169,117 +161,163 @@ struct femtoDreamPairTaskTrackV0 { HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(InitContext& context) { eventHisto.init(&qaRegistry); - trackHistoPartOne.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrkPDGCodePartOne); - trackHistoPartTwo.init(&qaRegistry, ConfV0TempFitVarpTBins, ConfV0TempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfV0TempFitVarInvMassBins, ConfIsMC, ConfV0PDGCodePartTwo); - posChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, false, false); - negChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, false, false); + trackHistoPartOne.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrk1_PDGCode); + trackHistoPartTwo.init(&qaRegistry, ConfV0TempFitVarpTBins, ConfV0TempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfV0TempFitVarInvMassBins, ConfIsMC, ConfV02_PDGCode); + posChildHistos.init(&qaRegistry, ConfV0ChildTempFitVarpTBins, ConfV0ChildTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, false, false); + negChildHistos.init(&qaRegistry, ConfV0ChildTempFitVarpTBins, ConfV0ChildTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, false, false); sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); - sameEventCont.setPDGCodes(ConfTrkPDGCodePartOne, ConfV0PDGCodePartTwo); + sameEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfV02_PDGCode); mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); - mixedEventCont.setPDGCodes(ConfTrkPDGCodePartOne, ConfV0PDGCodePartTwo); + mixedEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfV02_PDGCode); pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); } - vPIDPartOne = ConfTrkPIDPartOne.value; - kNsigma = ConfTrkPIDnSigmaMax.value; + + // get bit for the collision mask + std::bitset<8 * sizeof(femtodreamcollision::BitMaskType)> mask; + int index = 0; + auto& workflows = context.services().get(); + for (DeviceSpec const& device : workflows.devices) { + if (device.name.find("femto-dream-pair-task-track-v0") != std::string::npos) { + if (containsNameValuePair(device.options, "ConfTrk1_CutBit", ConfTrk1_CutBit.value) && + containsNameValuePair(device.options, "CnfTrk1_TPCBit", ConfTrk1_TPCBit.value) && + containsNameValuePair(device.options, "ConfTrk1_TPCTOFBit", ConfTrk1_TPCTOFBit.value) && + containsNameValuePair(device.options, "ConfTrk1_PIDThres", ConfTrk1_PIDThres.value) && + containsNameValuePair(device.options, "ConfTrk1_minPt", ConfTrk1_minPt.value) && + containsNameValuePair(device.options, "ConfTrk1_maxPt", ConfTrk1_maxPt.value) && + containsNameValuePair(device.options, "ConfTrk1_minEta", ConfTrk1_minEta.value) && + containsNameValuePair(device.options, "ConfTrk1_maxEta", ConfTrk1_maxEta.value) && + containsNameValuePair(device.options, "ConfV02_CutBit", ConfV02_CutBit.value) && + containsNameValuePair(device.options, "ConfV02_ChildPos_CutBit", ConfV02_ChildPos_CutBit.value) && + containsNameValuePair(device.options, "ConfV02_ChildPos_TPCBit", ConfV02_ChildPos_TPCBit.value) && + containsNameValuePair(device.options, "ConfV02_ChildNeg_CutBit", ConfV02_ChildNeg_CutBit.value) && + containsNameValuePair(device.options, "ConfV02_ChildNeg_TPCBit", ConfV02_ChildNeg_TPCBit.value) && + containsNameValuePair(device.options, "ConfV02_minInvMass", ConfV02_minInvMass.value) && + containsNameValuePair(device.options, "ConfV02_maxInvMass", ConfV02_maxInvMass.value) && + containsNameValuePair(device.options, "ConfV02_minInvMassAnti", ConfV02_minInvMassAnti.value) && + containsNameValuePair(device.options, "ConfV02_maxInvMassAnti", ConfV02_maxInvMassAnti.value) && + containsNameValuePair(device.options, "ConfV02_minPt", ConfV02_minPt.value) && + containsNameValuePair(device.options, "ConfV02_maxPt", ConfV02_maxPt.value) && + containsNameValuePair(device.options, "ConfV02_minEta", ConfV02_minEta.value) && + containsNameValuePair(device.options, "ConfV02_maxEta", ConfV02_maxEta.value)) { + mask.set(index); + MaskBit = static_cast(mask.to_ulong()); + LOG(info) << "Device name matched: " << device.name; + LOG(info) << "Bitmask for collisions: " << mask.to_string(); + break; + } else { + index++; + } + } + } + if ((doprocessSameEvent && doprocessSameEventMasked) || + (doprocessMixedEvent && doprocessMixedEventMasked)) { + LOG(fatal) << "Normal and masked processing cannot be activated simultaneously!"; + } } /// This function processes the same event and takes care of all the histogramming - /// \todo the trivial loops over the tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... - template - void doSameEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartType parts, float magFieldTesla, int multCol) + template + void doSameEvent(T& SliceTrk1, R& SliceV02, S& parts, float magFieldTesla, int multCol) { - /// Histogramming same event - for (auto& part : groupPartsOne) { - if (!isFullPIDSelected(part.pidcut(), part.p(), ConfTrkCutTable->get("Track", "PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfTrkCutTable->get("Track", "nSigmaTPC"), ConfTrkCutTable->get("Track", "nSigmaTPCTOF"))) { - continue; - } + for (auto& part : SliceTrk1) { trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt); } - for (auto& part : groupPartsTwo) { - const auto& posChild = parts.iteratorAt(part.index() - 2); - const auto& negChild = parts.iteratorAt(part.index() - 1); + + for (auto& v0 : SliceV02) { + const auto& posChild = parts.iteratorAt(v0.index() - 2); + const auto& negChild = parts.iteratorAt(v0.index() - 1); + // This is how it is supposed to work but there seems to be an issue + // with partitions and accessing elements in tables that have been + // with an SELF_INDEX column. Under investigation. Maybe need to change + // femtdream dataformat to take special care of v0 candidates + // auto posChild = v0.template children_as().front(); + // auto negChild = v0.template children_as().back(); // check cuts on V0 children - if (!((posChild.cut() & ConfCutChildPos) == ConfCutChildPos) || !((negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) || - !isFullPIDSelected(posChild.pidcut(), posChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPCTOF")) || - !isFullPIDSelected(negChild.pidcut(), negChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPCTOF"))) { - continue; + if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && + ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && + ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && + ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { + trackHistoPartTwo.fillQA(v0, aod::femtodreamparticle::kPt); + posChildHistos.fillQA(posChild, aod::femtodreamparticle::kPt); + negChildHistos.fillQA(negChild, aod::femtodreamparticle::kPt); } - trackHistoPartTwo.fillQA(part, aod::femtodreamparticle::kPt); - posChildHistos.fillQA(posChild, aod::femtodreamparticle::kPt); - negChildHistos.fillQA(negChild, aod::femtodreamparticle::kPt); } /// Now build the combinations - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (!isFullPIDSelected(p1.pidcut(), p1.p(), ConfTrkCutTable->get("Track", "PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfTrkCutTable->get("Track", "nSigmaTPC"), ConfTrkCutTable->get("Track", "nSigmaTPCTOF"))) { - continue; - } + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { const auto& posChild = parts.iteratorAt(p2.index() - 2); const auto& negChild = parts.iteratorAt(p2.index() - 1); // check cuts on V0 children - if (!((posChild.cut() & ConfCutChildPos) == ConfCutChildPos) || !((negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) || - !isFullPIDSelected(posChild.pidcut(), posChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPCTOF")) || - !isFullPIDSelected(negChild.pidcut(), negChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPCTOF"))) { - continue; - } - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && + ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && + ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && + ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + } + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } - // track cleaning - if (!pairCleaner.isCleanPair(p1, p2, parts)) { - continue; - } - sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } } - void processSameEvent(o2::aod::FDCollision& col, - FilteredFDParticles& parts) + void processSameEvent(o2::aod::FDCollision const& col, FilteredFDParticles const& parts) { eventHisto.fillQA(col); - - auto thegroupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - - doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr()); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceTrk1, SliceV02, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEvent, "Enable processing same event", true); + void processSameEventMasked(MaskedCollision const& col, FilteredFDParticles const& parts) + { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + return; + } + eventHisto.fillQA(col); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceTrk1, SliceV02, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMasked, "Enable processing same event with masks", false); + void processSameEventMC(o2::aod::FDCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) // void processSameEventMC(o2::aod::FDCollision& col, soa::Join& parts, o2::aod::FDMCParticles&) { eventHisto.fillQA(col); - auto thegroupPartsOne = partsOneMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsTwo = partsTwoMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr()); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceMCTrk1, SliceMCV02, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMC, "Enable processing same event MC", false); /// This function processes the mixed event /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... template - void doMixedEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartType parts, float magFieldTesla, int multCol) + void doMixedEvent(PartitionType SliceTrk1, PartitionType SliceV02, PartType parts, float magFieldTesla, int multCol) { - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (!isFullPIDSelected(p1.pidcut(), p1.p(), ConfTrkCutTable->get("Track", "PIDthr"), vPIDPartOne, ConfNspecies, kNsigma, ConfTrkCutTable->get("Track", "nSigmaTPC"), ConfTrkCutTable->get("Track", "nSigmaTPCTOF"))) { - continue; - } + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { const auto& posChild = parts.iteratorAt(p2.index() - 2); const auto& negChild = parts.iteratorAt(p2.index() - 1); // check cuts on V0 children - if (!((posChild.cut() & ConfCutChildPos) == ConfCutChildPos) || !((negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) || - !isFullPIDSelected(posChild.pidcut(), posChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("PosChild", "nSigmaTPCTOF")) || - !isFullPIDSelected(negChild.pidcut(), negChild.p(), ConfV0ChildrenCutTable->get("PosChild", "PIDthr"), ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPC"), ConfV0ChildrenCutTable->get("NegChild", "nSigmaTPCTOF"))) { + if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && + ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && + ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && + ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { continue; } if (ConfIsCPR.value) { @@ -295,14 +333,13 @@ struct femtoDreamPairTaskTrackV0 { } } - void processMixedEvent(o2::aod::FDCollisions& cols, - FilteredFDParticles& parts) + void processMixedEvent(o2::aod::FDCollisions& cols, FilteredFDParticles& parts) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { const int multCol = collision1.multNtr(); - auto groupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); @@ -310,20 +347,42 @@ struct femtoDreamPairTaskTrackV0 { if (magFieldTesla1 != magFieldTesla2) { continue; } - - doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multCol); + doMixedEvent(SliceTrk1, SliceV02, parts, magFieldTesla1, multCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEvent, "Enable processing mixed events", true); + void processMixedEventMasked(MaskedCollisions const& cols, FilteredFDParticles const& parts) + { + + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; + Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; + + PartitionMaskedCol1.bindTable(cols); + PartitionMaskedCol2.bindTable(cols); + + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { + const int multCol = collision1.multNtr(); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + doMixedEvent(SliceTrk1, SliceV02, parts, magFieldTesla1, multCol); + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMasked, "Enable processing mixed events with masks", false); + void processMixedEventMC(o2::aod::FDCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) // void processMixedEventMC(o2::aod::FDCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { const int multCol = collision1.multNtr(); - auto groupPartsOne = partsOneMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); @@ -332,7 +391,7 @@ struct femtoDreamPairTaskTrackV0 { continue; } - doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multCol); + doMixedEvent(SliceMCTrk1, SliceMCV02, parts, magFieldTesla1, multCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMC, "Enable processing mixed events MC", false); From a0cb0e8333d2be213c9134175b2dd1386fc028e1 Mon Sep 17 00:00:00 2001 From: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Date: Mon, 18 Dec 2023 10:08:30 +0100 Subject: [PATCH 077/156] Fix: fix typo (#4185) --- PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx b/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx index 36379c6870e..bc0cb0a1903 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx +++ b/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx @@ -185,7 +185,7 @@ struct femtoDreamPairTaskTrackV0 { for (DeviceSpec const& device : workflows.devices) { if (device.name.find("femto-dream-pair-task-track-v0") != std::string::npos) { if (containsNameValuePair(device.options, "ConfTrk1_CutBit", ConfTrk1_CutBit.value) && - containsNameValuePair(device.options, "CnfTrk1_TPCBit", ConfTrk1_TPCBit.value) && + containsNameValuePair(device.options, "ConfTrk1_TPCBit", ConfTrk1_TPCBit.value) && containsNameValuePair(device.options, "ConfTrk1_TPCTOFBit", ConfTrk1_TPCTOFBit.value) && containsNameValuePair(device.options, "ConfTrk1_PIDThres", ConfTrk1_PIDThres.value) && containsNameValuePair(device.options, "ConfTrk1_minPt", ConfTrk1_minPt.value) && From 6fb1c6f1bb3a92f687cabfe0bcf5a58e71ba16a6 Mon Sep 17 00:00:00 2001 From: EmilGorm <50658075+EmilGorm@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:06:49 +0100 Subject: [PATCH 078/156] Generic Framework changes (#4141) * Changes to GFW folder structure, added GFWConfig core class, changes to flowGenericFramework task - uses GFWConfig, MC reco/gen * Linter * Linter + whitespace * Linter --------- Co-authored-by: Emil Gorm Nielsen --- PWGCF/GenericFramework/CMakeLists.txt | 20 +- PWGCF/GenericFramework/Core/CMakeLists.txt | 29 ++ .../{ => Core}/FlowContainer.cxx | 291 ++++++------ .../{ => Core}/FlowContainer.h | 7 +- PWGCF/GenericFramework/{ => Core}/GFW.cxx | 0 PWGCF/GenericFramework/{ => Core}/GFW.h | 6 +- PWGCF/GenericFramework/Core/GFWConfig.h | 223 +++++++++ .../{ => Core}/GFWCumulant.cxx | 0 .../GenericFramework/{ => Core}/GFWCumulant.h | 12 +- .../{ => Core}/GFWPowerArray.cxx | 0 .../{ => Core}/GFWPowerArray.h | 6 +- .../{ => Core}/GFWWeights.cxx | 0 .../GenericFramework/{ => Core}/GFWWeights.h | 6 +- .../{ => Core}/GenericFrameworkLinkDef.h | 9 +- .../{ => Core}/ProfileSubset.cxx | 6 +- .../{ => Core}/ProfileSubset.h | 10 +- .../GenericFramework/DataModel/CMakeLists.txt | 10 + .../TableProducer/CMakeLists.txt | 10 + PWGCF/GenericFramework/Tasks/CMakeLists.txt | 15 + .../Tasks/flowGenericFramework.cxx | 445 ++++++++++++++++++ PWGCF/Tasks/CMakeLists.txt | 5 - PWGCF/Tasks/flowGenericFramework.cxx | 305 ------------ PWGDQ/Tasks/dqFlow.cxx | 8 +- 23 files changed, 920 insertions(+), 503 deletions(-) mode change 100755 => 100644 PWGCF/GenericFramework/CMakeLists.txt create mode 100755 PWGCF/GenericFramework/Core/CMakeLists.txt rename PWGCF/GenericFramework/{ => Core}/FlowContainer.cxx (87%) rename PWGCF/GenericFramework/{ => Core}/FlowContainer.h (97%) rename PWGCF/GenericFramework/{ => Core}/GFW.cxx (100%) rename PWGCF/GenericFramework/{ => Core}/GFW.h (97%) create mode 100644 PWGCF/GenericFramework/Core/GFWConfig.h rename PWGCF/GenericFramework/{ => Core}/GFWCumulant.cxx (100%) rename PWGCF/GenericFramework/{ => Core}/GFWCumulant.h (88%) rename PWGCF/GenericFramework/{ => Core}/GFWPowerArray.cxx (100%) rename PWGCF/GenericFramework/{ => Core}/GFWPowerArray.h (87%) rename PWGCF/GenericFramework/{ => Core}/GFWWeights.cxx (100%) rename PWGCF/GenericFramework/{ => Core}/GFWWeights.h (95%) rename PWGCF/GenericFramework/{ => Core}/GenericFrameworkLinkDef.h (68%) rename PWGCF/GenericFramework/{ => Core}/ProfileSubset.cxx (99%) rename PWGCF/GenericFramework/{ => Core}/ProfileSubset.h (81%) create mode 100644 PWGCF/GenericFramework/DataModel/CMakeLists.txt create mode 100644 PWGCF/GenericFramework/TableProducer/CMakeLists.txt create mode 100644 PWGCF/GenericFramework/Tasks/CMakeLists.txt create mode 100644 PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx delete mode 100644 PWGCF/Tasks/flowGenericFramework.cxx diff --git a/PWGCF/GenericFramework/CMakeLists.txt b/PWGCF/GenericFramework/CMakeLists.txt old mode 100755 new mode 100644 index 9fabc616f60..0d3bb13ae7b --- a/PWGCF/GenericFramework/CMakeLists.txt +++ b/PWGCF/GenericFramework/CMakeLists.txt @@ -9,20 +9,6 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2physics_add_library(GFWCore - SOURCES GFWPowerArray.cxx - GFWCumulant.cxx - GFW.cxx - ProfileSubset.cxx - FlowContainer.cxx - GFWWeights.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore) - -o2physics_target_root_dictionary(GFWCore - HEADERS GFWPowerArray.h - GFWCumulant.h - GFW.h - ProfileSubset.h - FlowContainer.h - GFWWeights.h - LINKDEF GenericFrameworkLinkDef.h) \ No newline at end of file +add_subdirectory(Core) +add_subdirectory(Tasks) +add_subdirectory(TableProducer) diff --git a/PWGCF/GenericFramework/Core/CMakeLists.txt b/PWGCF/GenericFramework/Core/CMakeLists.txt new file mode 100755 index 00000000000..0d53a69f45e --- /dev/null +++ b/PWGCF/GenericFramework/Core/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2physics_add_library(GFWCore + SOURCES GFWPowerArray.cxx + GFWCumulant.cxx + GFW.cxx + ProfileSubset.cxx + FlowContainer.cxx + GFWWeights.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore) + +o2physics_target_root_dictionary(GFWCore + HEADERS GFWPowerArray.h + GFWCumulant.h + GFW.h + ProfileSubset.h + FlowContainer.h + GFWWeights.h + GFWConfig.h + LINKDEF GenericFrameworkLinkDef.h) diff --git a/PWGCF/GenericFramework/FlowContainer.cxx b/PWGCF/GenericFramework/Core/FlowContainer.cxx similarity index 87% rename from PWGCF/GenericFramework/FlowContainer.cxx rename to PWGCF/GenericFramework/Core/FlowContainer.cxx index 3a51fbe93e6..3d27a13169d 100644 --- a/PWGCF/GenericFramework/FlowContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowContainer.cxx @@ -25,7 +25,7 @@ FlowContainer::FlowContainer() : TNamed("", ""), fXAxis(0), fNbinsPt(0), fbinsPt(0), - fPropagateErrors(kFALSE){}; + fPropagateErrors(kFALSE) {} FlowContainer::FlowContainer(const char* name) : TNamed(name, name), fProf(0), fProfRand(0), @@ -38,7 +38,7 @@ FlowContainer::FlowContainer(const char* name) : TNamed(name, name), fXAxis(0), fNbinsPt(0), fbinsPt(0), - fPropagateErrors(kFALSE){}; + fPropagateErrors(kFALSE) {} FlowContainer::~FlowContainer() { delete fProf; @@ -57,11 +57,11 @@ void FlowContainer::Initialize(TObjArray* inputList, const o2::framework::AxisSp if (!inputList) { printf("Input list not specified\n"); return; - }; + } if (inputList->GetEntries() < 1) { printf("Input list empty!\n"); return; - }; + } fProf = new TProfile2D(Form("%s_CorrProfile", this->GetName()), "CorrProfile", nMultiBins, &multiBins[0], inputList->GetEntries(), 0.5, inputList->GetEntries() + 0.5); for (int i = 0; i < inputList->GetEntries(); i++) fProf->GetYaxis()->SetBinLabel(i + 1, inputList->At(i)->GetName()); @@ -71,21 +71,21 @@ void FlowContainer::Initialize(TObjArray* inputList, const o2::framework::AxisSp fProfRand = new TObjArray(); fProfRand->SetOwner(kTRUE); for (int i = 0; i < nRandom; i++) { - fProfRand->Add((TProfile2D*)fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i))); - ((TProfile2D*)fProfRand->At(i))->Sumw2(); - }; - }; + fProfRand->Add(reinterpret_cast(fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i)))); + reinterpret_cast(fProfRand->At(i))->Sumw2(); + } + } }; void FlowContainer::Initialize(TObjArray* inputList, int nMultiBins, double MultiMin, double MultiMax, int nRandom) { if (!inputList) { printf("Input list not specified\n"); return; - }; + } if (inputList->GetEntries() < 1) { printf("Input list empty!\n"); return; - }; + } fProf = new TProfile2D(Form("%s_CorrProfile", this->GetName()), "CorrProfile", nMultiBins, MultiMin, MultiMax, inputList->GetEntries(), 0.5, inputList->GetEntries() + 0.5); fProf->SetDirectory(0); fProf->Sumw2(); @@ -96,10 +96,10 @@ void FlowContainer::Initialize(TObjArray* inputList, int nMultiBins, double Mult fProfRand = new TObjArray(); fProfRand->SetOwner(kTRUE); for (int i = 0; i < nRandom; i++) { - fProfRand->Add((TProfile2D*)fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i))); - ((TProfile2D*)fProfRand->At(i))->Sumw2(); - }; - }; + fProfRand->Add(reinterpret_cast(fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i)))); + reinterpret_cast(fProfRand->At(i))->Sumw2(); + } + } }; bool FlowContainer::CreateBinsFromAxis(TAxis* inax) { @@ -113,7 +113,7 @@ bool FlowContainer::CreateBinsFromAxis(TAxis* inax) } void FlowContainer::SetXAxis(TAxis* inax) { - fXAxis = (TAxis*)inax->Clone("pTAxis"); + fXAxis = reinterpret_cast(inax->Clone("pTAxis")); bool success = CreateBinsFromAxis(fXAxis); if (!success) printf("Something went wrong setting the x axis!\n"); @@ -141,12 +141,12 @@ int FlowContainer::FillProfile(const char* hname, double multi, double corr, dou if (!yin) { printf("Could not find bin %s\n", hname); return -1; - }; + } fProf->Fill(multi, yin, corr, w); if (fNRandom) { double rnind = rn * fNRandom; - ((TProfile2D*)fProfRand->At((int)rnind))->Fill(multi, yin, corr, w); - }; + reinterpret_cast(fProfRand->At(static_cast(rnind)))->Fill(multi, yin, corr, w); + } return 0; }; void FlowContainer::OverrideProfileErrors(TProfile2D* inpf) @@ -156,7 +156,7 @@ void FlowContainer::OverrideProfileErrors(TProfile2D* inpf) if ((inpf->GetNbinsX() != nBinsX) || (inpf->GetNbinsY() != nBinsY)) { printf("Number of bins in two profiles do not match, not doing anything\n"); return; - }; + } if (!inpf->GetBinSumw2()->fArray) { printf("Input profile has no BinSumw2()! Returning\n"); return; @@ -188,14 +188,15 @@ Long64_t FlowContainer::Merge(TCollection* collist) Long64_t nmerged = 0; FlowContainer* l_FC = 0; TIter all_FC(collist); - while ((l_FC = ((FlowContainer*)all_FC()))) { + while ((l_FC = reinterpret_cast(all_FC()))) { TProfile2D* tpro = GetProfile(); TProfile2D* spro = l_FC->GetProfile(); if (!tpro) { - fProf = (TProfile2D*)spro->Clone(spro->GetName()); + fProf = reinterpret_cast(spro->Clone(spro->GetName())); fProf->SetDirectory(0); - } else + } else { tpro->Add(spro); + } nmerged++; TObjArray* tarr = l_FC->GetSubProfiles(); if (!tarr) @@ -203,16 +204,16 @@ Long64_t FlowContainer::Merge(TCollection* collist) if (!fProfRand) { fProfRand = new TObjArray(); fProfRand->SetOwner(kTRUE); - }; + } for (int i = 0; i < tarr->GetEntries(); i++) { if (!(fProfRand->FindObject(tarr->At(i)->GetName()))) { - fProfRand->Add((TProfile2D*)tarr->At(i)->Clone(tarr->At(i)->GetName())); - ((TProfile2D*)fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); + fProfRand->Add(reinterpret_cast(tarr->At(i)->Clone(tarr->At(i)->GetName()))); + reinterpret_cast(fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); } else { - ((TProfile2D*)fProfRand->FindObject(tarr->At(i)->GetName()))->Add((TProfile2D*)tarr->At(i)); - }; - }; - }; + reinterpret_cast(fProfRand->FindObject(tarr->At(i)->GetName()))->Add(reinterpret_cast(tarr->At(i))); + } + } + } return nmerged; }; void FlowContainer::ReadAndMerge(const char* filelist) @@ -226,7 +227,7 @@ void FlowContainer::ReadAndMerge(const char* filelist) if (nFiles == 0) { printf("No files to read!\n"); return; - }; + } for (int i = 0; i < nFiles; i++) { auto retVal = fscanf(flist, "%s\n", str); (void)retVal; @@ -235,41 +236,42 @@ void FlowContainer::ReadAndMerge(const char* filelist) printf("Could not open file %s!\n", str); tf->Close(); continue; - }; + } PickAndMerge(tf); tf->Close(); - }; + } }; void FlowContainer::PickAndMerge(TFile* tfi) { - FlowContainer* lfc = (FlowContainer*)tfi->Get(this->GetName()); + FlowContainer* lfc = reinterpret_cast(tfi->Get(this->GetName())); if (!lfc) { printf("Could not pick up the %s from %s\n", this->GetName(), tfi->GetName()); return; - }; + } TProfile2D* spro = lfc->GetProfile(); TProfile2D* tpro = GetProfile(); if (!tpro) { - fProf = (TProfile2D*)spro->Clone(spro->GetName()); + fProf = reinterpret_cast(spro->Clone(spro->GetName())); fProf->SetDirectory(0); - } else + } else { tpro->Add(spro); + } TObjArray* tarr = lfc->GetSubProfiles(); if (!tarr) { return; - }; + } if (!fProfRand) { fProfRand = new TObjArray(); fProfRand->SetOwner(kTRUE); - }; + } for (int i = 0; i < tarr->GetEntries(); i++) { if (!(fProfRand->FindObject(tarr->At(i)->GetName()))) { - fProfRand->Add((TProfile2D*)tarr->At(i)->Clone(tarr->At(i)->GetName())); - ((TProfile2D*)fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); + fProfRand->Add(reinterpret_cast(tarr->At(i)->Clone(tarr->At(i)->GetName()))); + reinterpret_cast(fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); } else { - ((TProfile2D*)fProfRand->FindObject(tarr->At(i)->GetName()))->Add((TProfile2D*)tarr->At(i)); - }; - }; + reinterpret_cast(fProfRand->FindObject(tarr->At(i)->GetName()))->Add(reinterpret_cast(tarr->At(i))); + } + } }; bool FlowContainer::OverrideBinsWithZero(int xb1, int yb1, int xb2, int yb2) { @@ -277,9 +279,9 @@ bool FlowContainer::OverrideBinsWithZero(int xb1, int yb1, int xb2, int yb2) if (!t_apf->OverrideBinsWithZero(xb1, yb1, xb2, yb2)) { delete t_apf; return kFALSE; - }; + } delete fProf; - fProf = (TProfile2D*)t_apf; + fProf = reinterpret_cast(t_apf); return kTRUE; } bool FlowContainer::OverrideMainWithSub(int ind, bool ExcludeChosen) @@ -287,16 +289,16 @@ bool FlowContainer::OverrideMainWithSub(int ind, bool ExcludeChosen) if (!fProfRand) { printf("Cannot override main profile with a randomized one. Random profile array does not exist.\n"); return kFALSE; - }; + } if (!ExcludeChosen) { - TProfile2D* tarprof = (TProfile2D*)fProfRand->At(ind); + TProfile2D* tarprof = reinterpret_cast(fProfRand->At(ind)); if (!tarprof) { printf("Target random histogram does not exist.\n"); return kFALSE; - }; + } TString ts(fProf->GetName()); delete fProf; - fProf = (TProfile2D*)tarprof->Clone(ts.Data()); + fProf = reinterpret_cast(tarprof->Clone(ts.Data())); return kTRUE; } else { TString ts(fProf->GetName()); @@ -305,21 +307,21 @@ bool FlowContainer::OverrideMainWithSub(int ind, bool ExcludeChosen) for (int i = 0; i < fProfRand->GetEntries(); i++) { if (i == ind) continue; - TProfile2D* tarprof = (TProfile2D*)fProfRand->At(i); + TProfile2D* tarprof = reinterpret_cast(fProfRand->At(i)); if (!fProf) - fProf = (TProfile2D*)tarprof->Clone(ts.Data()); + fProf = reinterpret_cast(tarprof->Clone(ts.Data())); else fProf->Add(tarprof); - }; + } return kTRUE; - }; -}; + } +} bool FlowContainer::RandomizeProfile(int nSubsets) { if (!fProfRand) { printf("Cannot randomize profile, random array does not exist.\n"); return kFALSE; - }; + } int l_Subsets = nSubsets ? nSubsets : fProfRand->GetEntries(); TRandom* rndm = new TRandom(0); for (int i = 0; i < l_Subsets; i++) { @@ -327,9 +329,10 @@ bool FlowContainer::RandomizeProfile(int nSubsets) if (!i) { TString ts(fProf->GetName()); delete fProf; - fProf = (TProfile2D*)fProfRand->At(rInd)->Clone(ts.Data()); - } else - fProf->Add((TProfile2D*)fProfRand->At(rInd)); + fProf = reinterpret_cast(fProfRand->At(rInd)->Clone(ts.Data())); + } else { + fProf->Add(reinterpret_cast(fProfRand->At(rInd))); + } } return kTRUE; } @@ -348,7 +351,7 @@ bool FlowContainer::CreateStatisticsProfile(StatisticsType StatType, int arg) default: return kFALSE; break; - }; + } } void FlowContainer::SetIDName(TString newname) { @@ -366,21 +369,21 @@ TProfile* FlowContainer::GetCorrXXVsMulti(const char* order, int l_pti) if (ybinno < 0) { printf("Could not find %s!\n", ybinlab); return 0; - }; - TProfile* rethist = (TProfile*)fProf->ProfileX("temp_prof", ybinno, ybinno); + } + TProfile* rethist = reinterpret_cast(fProf->ProfileX("temp_prof", ybinno, ybinno)); rethist->SetTitle(Form(";multi.;#LT#LT%s#GT#GT", order)); if (!retSubset) { - retSubset = (TProfile*)rethist->Clone(Form("corr_%s", order)); + retSubset = reinterpret_cast(rethist->Clone(Form("corr_%s", order))); } else { retSubset->Add(rethist); - }; + } delete rethist; - }; + } if (fMultiRebin > 0) { TString temp_name(retSubset->GetName()); - TProfile* tempprof = (TProfile*)retSubset->Clone("tempProfile"); + TProfile* tempprof = reinterpret_cast(retSubset->Clone("tempProfile")); delete retSubset; - retSubset = (TProfile*)tempprof->Rebin(fMultiRebin, temp_name.Data(), fMultiRebinEdges); + retSubset = reinterpret_cast(tempprof->Rebin(fMultiRebin, temp_name.Data(), fMultiRebinEdges)); delete tempprof; } return retSubset; @@ -394,7 +397,7 @@ TProfile* FlowContainer::GetCorrXXVsPt(const char* order, double lminmulti, doub if (lminmulti > 0) { minm = fProf->GetXaxis()->FindBin(lminmulti + 0.001); maxm = minm; - }; + } if (lmaxmulti > lminmulti) maxm = fProf->GetXaxis()->FindBin(lmaxmulti - 0.001); ProfileSubset* rhProfSub = new ProfileSubset(*fProf); @@ -410,20 +413,22 @@ TProfile* FlowContainer::GetCorrXXVsPt(const char* order, double lminmulti, doub TProfile* tempprof = rhProfSub->GetSubset(kFALSE, "tempprof", minm, maxm, fNbinsPt, fbinsPt); if (!retSubset) { TString profname = Form("%s_MultiB_%i_%i", order, minm, maxm); - retSubset = (TProfile*)tempprof->Clone(profname.Data()); - } else + retSubset = reinterpret_cast(tempprof->Clone(profname.Data())); + } else { retSubset->Add(tempprof); + } delete tempprof; - }; + } delete rhProfSub; if (fPtRebinEdges) { TString pnbu(retSubset->GetName()); retSubset->SetName("TempName"); - TProfile* tempprof = (TProfile*)retSubset->Rebin(fPtRebin, pnbu.Data(), fPtRebinEdges); + TProfile* tempprof = reinterpret_cast(retSubset->Rebin(fPtRebin, pnbu.Data(), fPtRebinEdges)); delete retSubset; retSubset = tempprof; - } else + } else { retSubset->RebinX(fPtRebin); + } return retSubset; }; TH1D* FlowContainer::ProfToHist(TProfile* inpf) @@ -437,8 +442,8 @@ TH1D* FlowContainer::ProfToHist(TProfile* inpf) if (inpf->GetBinContent(i) != 0) { rethist->SetBinContent(i, inpf->GetBinContent(i)); rethist->SetBinError(i, inpf->GetBinError(i)); - }; - }; + } + } return rethist; }; TH1D* FlowContainer::GetHistCorrXXVsMulti(const char* order, int l_pti) @@ -462,7 +467,7 @@ TH1D* FlowContainer::GetHistCorrXXVsPt(const char* order, double lminmulti, doub }; TH1D* FlowContainer::GetVN2(TH1D* cn2) { - TH1D* rethist = (TH1D*)cn2->Clone(Form("vn2_%s", cn2->GetName())); + TH1D* rethist = reinterpret_cast(cn2->Clone(Form("vn2_%s", cn2->GetName()))); rethist->Reset(); double rf2 = cn2->GetBinContent(0); double rf2e = cn2->GetBinError(0); @@ -473,17 +478,17 @@ TH1D* FlowContainer::GetVN2(TH1D* cn2) if (d2 > 0) { rethist->SetBinContent(i, OnPt ? VDN2Value(d2, rf2) : VN2Value(d2)); rethist->SetBinError(i, OnPt ? VDN2Error(d2, d2e, rf2, rf2e) : VN2Error(d2, d2e)); - }; - }; + } + } return rethist; -}; +} TH1D* FlowContainer::GetCN2VsX(int n, bool onPt, double arg1, double arg2) { TH1D* corrN2; if (onPt) corrN2 = GetHistCorrXXVsPt(Form("%i2", n), arg1, arg2); else - corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), (int)arg1); + corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), static_cast(arg1)); corrN2->SetName(Form("Corr_%s", corrN2->GetName())); TH1D* rethist = GetCN2(corrN2); TString* nam = new TString(corrN2->GetName()); @@ -497,9 +502,9 @@ TH1D* FlowContainer::GetCN2VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); c_{%i}{2}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};c_{%i}{2}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN2VsX(int n, bool onPt, double arg1, double arg2) { @@ -516,7 +521,7 @@ TH1D* FlowContainer::GetVN2VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); v_{%i}{2}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};v_{%i}{2}", n)); - }; + } delete nam; return rethist; }; @@ -526,21 +531,21 @@ TH1D* FlowContainer::GetCN2(TH1D* corrN2) double rf2 = corrN2->GetBinContent(0); double rf2e = corrN2->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = (TH1D*)corrN2->Clone(Form("cN2_%s", corrN2->GetName())); + TH1D* rethist = reinterpret_cast(corrN2->Clone(Form("cN2_%s", corrN2->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor2v = corrN2->GetBinContent(i); double cor2e = corrN2->GetBinError(i); rethist->SetBinContent(i, cor2v); rethist->SetBinError(i, cor2e); - }; + } if (OnPt) { rethist->SetBinContent(0, rf2); rethist->SetBinError(0, rf2e); } else { rethist->SetBinContent(0, 0); rethist->SetBinError(0, 0); - }; + } return rethist; }; @@ -551,7 +556,7 @@ TH1D* FlowContainer::GetCN4(TH1D* corrN4, TH1D* corrN2) double rf4 = corrN4->GetBinContent(0); double rf4e = corrN4->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = (TH1D*)corrN4->Clone(Form("cN4_%s", corrN4->GetName())); + TH1D* rethist = reinterpret_cast(corrN4->Clone(Form("cN4_%s", corrN4->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor4v = corrN4->GetBinContent(i); @@ -560,22 +565,22 @@ TH1D* FlowContainer::GetCN4(TH1D* corrN4, TH1D* corrN2) double cor2e = corrN2->GetBinError(i); rethist->SetBinContent(i, OnPt ? DN4Value(cor4v, cor2v, rf2) : CN4Value(cor4v, cor2v)); rethist->SetBinError(i, OnPt ? DN4Error(cor4e, cor2v, cor2e, rf2, rf2e) : CN4Error(cor4e, cor2v, cor2e)); - }; + } if (OnPt) { rethist->SetBinContent(0, CN4Value(rf4, rf2)); rethist->SetBinError(0, CN4Error(rf4e, rf2, rf2e)); } else { rethist->SetBinContent(0, 0); rethist->SetBinError(0, 0); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetCN6(TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) { - TH1D* tn2 = (TH1D*)corrN2->Clone(Form("tn2_%s", corrN2->GetName())); - TH1D* tn4 = (TH1D*)corrN4->Clone(Form("tn4_%s", corrN4->GetName())); - TH1D* tn6 = (TH1D*)corrN6->Clone(Form("tn6_%s", corrN6->GetName())); + TH1D* tn2 = reinterpret_cast(corrN2->Clone(Form("tn2_%s", corrN2->GetName()))); + TH1D* tn4 = reinterpret_cast(corrN4->Clone(Form("tn4_%s", corrN4->GetName()))); + TH1D* tn6 = reinterpret_cast(corrN6->Clone(Form("tn6_%s", corrN6->GetName()))); double rf2 = corrN2->GetBinContent(0); double rf2e = corrN2->GetBinError(0); @@ -584,7 +589,7 @@ TH1D* FlowContainer::GetCN6(TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) double rf6 = corrN6->GetBinContent(0); double rf6e = corrN6->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = (TH1D*)corrN6->Clone(Form("cN6_%s", corrN6->GetName())); + TH1D* rethist = reinterpret_cast(corrN6->Clone(Form("cN6_%s", corrN6->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor6v = corrN6->GetBinContent(i); @@ -595,25 +600,25 @@ TH1D* FlowContainer::GetCN6(TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) double cor2e = corrN2->GetBinError(i); rethist->SetBinContent(i, OnPt ? DN6Value(cor6v, cor4v, cor2v, rf4, rf2) : CN6Value(cor6v, cor4v, cor2v)); rethist->SetBinError(i, OnPt ? DN6Error(cor6e, cor4v, cor4e, cor2v, cor2e, rf4, rf4e, rf2, rf2e) : CN6Error(cor6e, cor4v, cor4e, cor2v, cor2e)); - }; + } if (OnPt) { rethist->SetBinContent(0, CN6Value(rf6, rf4, rf2)); rethist->SetBinError(0, CN6Error(rf6e, rf4, rf4e, rf2, rf2e)); } else { rethist->SetBinContent(0, 0); rethist->SetBinError(0, 0); - }; + } delete tn2; delete tn4; delete tn6; return rethist; -}; +} TH1D* FlowContainer::GetCN8(TH1D* corrN8, TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) { - TH1D* tn2 = (TH1D*)corrN2->Clone(Form("tn2_%s", corrN2->GetName())); - TH1D* tn4 = (TH1D*)corrN4->Clone(Form("tn4_%s", corrN4->GetName())); - TH1D* tn6 = (TH1D*)corrN6->Clone(Form("tn6_%s", corrN6->GetName())); - TH1D* tn8 = (TH1D*)corrN8->Clone(Form("tn8_%s", corrN6->GetName())); + TH1D* tn2 = reinterpret_cast(corrN2->Clone(Form("tn2_%s", corrN2->GetName()))); + TH1D* tn4 = reinterpret_cast(corrN4->Clone(Form("tn4_%s", corrN4->GetName()))); + TH1D* tn6 = reinterpret_cast(corrN6->Clone(Form("tn6_%s", corrN6->GetName()))); + TH1D* tn8 = reinterpret_cast(corrN8->Clone(Form("tn8_%s", corrN6->GetName()))); double rf2 = corrN2->GetBinContent(0); double rf2e = corrN2->GetBinError(0); @@ -624,7 +629,7 @@ TH1D* FlowContainer::GetCN8(TH1D* corrN8, TH1D* corrN6, TH1D* corrN4, TH1D* corr double rf8 = corrN8->GetBinContent(0); double rf8e = corrN8->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = (TH1D*)corrN8->Clone(Form("cN8_%s", corrN8->GetName())); + TH1D* rethist = reinterpret_cast(corrN8->Clone(Form("cN8_%s", corrN8->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor8v = corrN8->GetBinContent(i); @@ -637,20 +642,20 @@ TH1D* FlowContainer::GetCN8(TH1D* corrN8, TH1D* corrN6, TH1D* corrN4, TH1D* corr double cor2e = corrN2->GetBinError(i); rethist->SetBinContent(i, OnPt ? DN8Value(cor8v, cor6v, cor4v, cor2v, rf6, rf4, rf2) : CN8Value(cor8v, cor6v, cor4v, cor2v)); rethist->SetBinError(i, OnPt ? DN8Error(cor8e, cor6v, cor6e, cor4v, cor4e, cor2v, cor2e, rf6, rf6e, rf4, rf4e, rf2, rf2e) : CN8Error(cor8e, cor6v, cor6e, cor4v, cor4e, cor2v, cor2e)); - }; + } if (OnPt) { rethist->SetBinContent(0, CN8Value(rf8, rf6, rf4, rf2)); rethist->SetBinError(0, CN8Error(rf8e, rf6, rf6e, rf4, rf4e, rf2, rf2e)); } else { rethist->SetBinContent(0, 0); rethist->SetBinError(0, 0); - }; + } delete tn2; delete tn4; delete tn6; delete tn8; return rethist; -}; +} TH1D* FlowContainer::GetCN4VsX(int n, bool onPt, double arg1, double arg2) { @@ -661,11 +666,11 @@ TH1D* FlowContainer::GetCN4VsX(int n, bool onPt, double arg1, double arg2) corrN4 = GetHistCorrXXVsPt(Form("%i4", n), arg1, arg2); corrN4->SetName(Form("Corr_%s", corrN4->GetName())); } else { - corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), (int)arg1); + corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), static_cast(arg1)); corrN2->SetName(Form("Corr_%s", corrN2->GetName())); - corrN4 = GetHistCorrXXVsMulti(Form("%i4", n), (int)arg1); + corrN4 = GetHistCorrXXVsMulti(Form("%i4", n), static_cast(arg1)); corrN4->SetName(Form("Corr_%s", corrN4->GetName())); - }; + } TH1D* rethist = GetCN4(corrN4, corrN2); TString* nam = new TString(corrN4->GetName()); delete corrN2; @@ -679,12 +684,12 @@ TH1D* FlowContainer::GetCN4VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); c_{%i}{4}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};c_{%i}{4}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN4(TH1D* inh) { - TH1D* rethist = (TH1D*)inh->Clone(Form("v24_%s", inh->GetName())); + TH1D* rethist = reinterpret_cast(inh->Clone(Form("v24_%s", inh->GetName()))); double c4 = inh->GetBinContent(0); double c4e = inh->GetBinError(0); bool OnPt = ((!c4) == 0); @@ -697,12 +702,12 @@ TH1D* FlowContainer::GetVN4(TH1D* inh) // if(d4>=0) continue; rethist->SetBinContent(i, OnPt ? VDN4Value(d4, c4) : VN4Value(d4)); rethist->SetBinError(i, OnPt ? VDN4Error(d4, d4e, c4, c4e) : VN4Error(d4, d4e)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN6(TH1D* inh) { - TH1D* rethist = (TH1D*)inh->Clone(Form("v26_%s", inh->GetName())); + TH1D* rethist = reinterpret_cast(inh->Clone(Form("v26_%s", inh->GetName()))); double c6 = inh->GetBinContent(0); double c6e = inh->GetBinError(0); bool OnPt = ((!c6) == 0); @@ -715,12 +720,12 @@ TH1D* FlowContainer::GetVN6(TH1D* inh) // if(d6<=0) continue; rethist->SetBinContent(i, OnPt ? VDN6Value(d6, c6) : VN6Value(d6)); rethist->SetBinError(i, OnPt ? VDN6Error(d6, d6e, c6, c6e) : VN6Error(d6, d6e)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN8(TH1D* inh) { - TH1D* rethist = (TH1D*)inh->Clone(Form("v28_%s", inh->GetName())); + TH1D* rethist = reinterpret_cast(inh->Clone(Form("v28_%s", inh->GetName()))); double c8 = inh->GetBinContent(0); double c8e = inh->GetBinError(0); bool OnPt = ((!c8) == 0); @@ -733,9 +738,9 @@ TH1D* FlowContainer::GetVN8(TH1D* inh) // if(d8>0) continue; rethist->SetBinContent(i, OnPt ? VDN8Value(d8, c8) : VN8Value(d8)); rethist->SetBinError(i, OnPt ? VDN8Error(d8, d8e, c8, c8e) : VN8Error(d8, d8e)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN4VsX(int n, bool onPt, double arg1, double arg2) { @@ -752,9 +757,9 @@ TH1D* FlowContainer::GetVN4VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); v_{%i}{4}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};v_{%i}{4}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetCN6VsX(int n, bool onPt, double arg1, double arg2) { TH1D *corrN2, *corrN4, *corrN6; @@ -766,10 +771,10 @@ TH1D* FlowContainer::GetCN6VsX(int n, bool onPt, double arg1, double arg2) corrN6 = GetHistCorrXXVsPt(Form("%i6", n), arg1, arg2); corrN6->SetName(Form("Corr_%s", corrN6->GetName())); } else { - corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), (int)arg1); - corrN4 = GetHistCorrXXVsMulti(Form("%i4", n), (int)arg1); - corrN6 = GetHistCorrXXVsMulti(Form("%i6", n), (int)arg1); - }; + corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), static_cast(arg1)); + corrN4 = GetHistCorrXXVsMulti(Form("%i4", n), static_cast(arg1)); + corrN6 = GetHistCorrXXVsMulti(Form("%i6", n), static_cast(arg1)); + } TH1D* rethist = GetCN6(corrN6, corrN4, corrN2); delete corrN2; delete corrN4; @@ -784,9 +789,9 @@ TH1D* FlowContainer::GetCN6VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); c_{%i}{6}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};c_{%i}{6}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN6VsX(int n, bool onPt, double arg1, double arg2) { TH1D* temph = GetCN6VsX(n, onPt, arg1, arg2); @@ -802,9 +807,9 @@ TH1D* FlowContainer::GetVN6VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); v_{%i}{6}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};v_{%i}{6}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetCN8VsX(int n, bool onPt, double arg1, double arg2) { TH1D *corrN2, *corrN4, *corrN6, *corrN8; @@ -818,11 +823,11 @@ TH1D* FlowContainer::GetCN8VsX(int n, bool onPt, double arg1, double arg2) corrN8 = GetHistCorrXXVsPt(Form("%i8", n), arg1, arg2); corrN8->SetName(Form("Corr_%s", corrN8->GetName())); } else { - corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), (int)arg1); - corrN4 = GetHistCorrXXVsMulti(Form("%i4", n), (int)arg1); - corrN6 = GetHistCorrXXVsMulti(Form("%i6", n), (int)arg1); - corrN8 = GetHistCorrXXVsMulti(Form("%i8", n), (int)arg1); - }; + corrN2 = GetHistCorrXXVsMulti(Form("%i2", n), static_cast(arg1)); + corrN4 = GetHistCorrXXVsMulti(Form("%i4", n), static_cast(arg1)); + corrN6 = GetHistCorrXXVsMulti(Form("%i6", n), static_cast(arg1)); + corrN8 = GetHistCorrXXVsMulti(Form("%i8", n), static_cast(arg1)); + } TH1D* rethist = GetCN8(corrN8, corrN6, corrN4, corrN2); delete corrN2; delete corrN4; @@ -838,9 +843,9 @@ TH1D* FlowContainer::GetCN8VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); c_{%i}{8}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};c_{%i}{8}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetVN8VsX(int n, bool onPt, double arg1, double arg2) { TH1D* temph = GetCN8VsX(n, onPt, arg1, arg2); @@ -856,9 +861,9 @@ TH1D* FlowContainer::GetVN8VsX(int n, bool onPt, double arg1, double arg2) rethist->SetTitle(Form("%2.0f - %4.0f;#it{p}_{T} (GeV/#it{c}); v_{%i}{8}", bv1, bv2, n)); } else { rethist->SetTitle(Form(";#it{N}_{tr};v_{%i}{8}", n)); - }; + } return rethist; -}; +} TH1D* FlowContainer::GetCNN(int n, int c, bool onPt, double arg1, double arg2) { if (c == 8) @@ -901,11 +906,11 @@ TProfile* FlowContainer::GetRefFlowProfile(const char* order, double m1, double int ybin = fProf->GetYaxis()->FindBin(l_name.Data()); TProfile* tempprof = rhSubset->GetSubset(kTRUE, "tempprof", ybin, ybin, nBins, l_bins); if (!retpf) - retpf = (TProfile*)tempprof->Clone("RefFlowProf"); + retpf = reinterpret_cast(tempprof->Clone("RefFlowProf")); else retpf->Add(tempprof); delete tempprof; - }; + } delete rhSubset; retpf->RebinX(nBins); return retpf; @@ -1187,11 +1192,11 @@ void FlowContainer::SetMultiRebin(int nbins, double* binedges) if (fMultiRebinEdges) { delete[] fMultiRebinEdges; fMultiRebinEdges = 0; - }; + } if (nbins <= 0) { fMultiRebin = 0; return; - }; + } fMultiRebin = nbins; fMultiRebinEdges = new double[nbins + 1]; for (int i = 0; i <= fMultiRebin; i++) @@ -1202,10 +1207,10 @@ double* FlowContainer::GetMultiRebin(int& nbins) if (fMultiRebin <= 0) { nbins = 0; return 0; - }; + } nbins = fMultiRebin; double* retBins = new double[fMultiRebin + 1]; for (int i = 0; i <= nbins; i++) retBins[i] = fMultiRebinEdges[i]; return fMultiRebinEdges; -} \ No newline at end of file +} diff --git a/PWGCF/GenericFramework/FlowContainer.h b/PWGCF/GenericFramework/Core/FlowContainer.h similarity index 97% rename from PWGCF/GenericFramework/FlowContainer.h rename to PWGCF/GenericFramework/Core/FlowContainer.h index abafb105e26..40a379e01a8 100644 --- a/PWGCF/GenericFramework/FlowContainer.h +++ b/PWGCF/GenericFramework/Core/FlowContainer.h @@ -9,8 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef PWGCF_GENERICFRAMEWORK_FLOWCONTAINER_H_ -#define PWGCF_GENERICFRAMEWORK_FLOWCONTAINER_H_ +#ifndef PWGCF_GENERICFRAMEWORK_CORE_FLOWCONTAINER_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_FLOWCONTAINER_H_ +#include #include "TH3F.h" #include "TProfile2D.h" #include "TProfile.h" @@ -165,4 +166,4 @@ class FlowContainer : public TNamed ClassDef(FlowContainer, 2); }; -#endif // PWGCF_GENERICFRAMEWORK_FLOWCONTAINER_H_ +#endif // PWGCF_GENERICFRAMEWORK_CORE_FLOWCONTAINER_H_ diff --git a/PWGCF/GenericFramework/GFW.cxx b/PWGCF/GenericFramework/Core/GFW.cxx similarity index 100% rename from PWGCF/GenericFramework/GFW.cxx rename to PWGCF/GenericFramework/Core/GFW.cxx diff --git a/PWGCF/GenericFramework/GFW.h b/PWGCF/GenericFramework/Core/GFW.h similarity index 97% rename from PWGCF/GenericFramework/GFW.h rename to PWGCF/GenericFramework/Core/GFW.h index 2b20ff7f2ad..629731bea85 100644 --- a/PWGCF/GenericFramework/GFW.h +++ b/PWGCF/GenericFramework/Core/GFW.h @@ -16,8 +16,8 @@ Class steers the initialization and calculation of n-particle correlations. Uses Latest version includes the calculation of any number of gaps and any combination of harmonics (including eg symmetric cumulants, etc.) If used, modified, or distributed, please aknowledge the author of this code. */ -#ifndef PWGCF_GENERICFRAMEWORK_GFW_H_ -#define PWGCF_GENERICFRAMEWORK_GFW_H_ +#ifndef PWGCF_GENERICFRAMEWORK_CORE_GFW_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_GFW_H_ #include "GFWCumulant.h" #include "GFWPowerArray.h" @@ -88,4 +88,4 @@ class GFW void s_replace_all(std::string& instr, const std::string& pattern1, const std::string& pattern2); bool s_tokenize(std::string& instr, std::string& substr, int& spos, const std::string& delim); }; -#endif // PWGCF_GENERICFRAMEWORK_GFW_H_ +#endif // PWGCF_GENERICFRAMEWORK_CORE_GFW_H_ diff --git a/PWGCF/GenericFramework/Core/GFWConfig.h b/PWGCF/GenericFramework/Core/GFWConfig.h new file mode 100644 index 00000000000..e626c37a79f --- /dev/null +++ b/PWGCF/GenericFramework/Core/GFWConfig.h @@ -0,0 +1,223 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ + +#include +#include +#include +#include +#include +#include +#include "GFW.h" + +namespace o2 +{ + +namespace analysis::genericframework +{ + +template +int CheckSameSize(const std::vector& first) +{ + return first.size(); +} + +template +int CheckSameSize(const std::vector& first, const std::vector&... rest) +{ + int size = first.size(); + bool allSameSize = ((size == rest.size()) && ...); + + return allSameSize ? size : -1; +} + +/// \class GFWBinningCuts +/// \brief Class which implements configurable acceptance cuts +/// +class GFWBinningCuts +{ + public: + GFWBinningCuts(int vtxzbins = 40, float vtxzmin = -10., float vtxzmax = 10, float ptpoimin = 0.2, float ptpoimax = 10., + std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, + 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, + 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, + 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, + int etabins = 16, float etamin = -0.8, float etamax = 0.8, int phibins = 72, float ptrefmin = 0.2, float ptrefmax = 3., int nchbins = 300, + float nchmin = 0.5, float nchmax = 3000.5, std::vector centbinning = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0}) : mVtxZbins{vtxzbins}, mVtxZmin{vtxzmin}, mVtxZmax{vtxzmax}, mPTpoimin{ptpoimin}, mPTpoimax{ptpoimax}, mPTbinning{std::move(ptbinning)}, mEtabins{etabins}, mEtamin{etamin}, mEtamax{etamax}, mPhibins{phibins}, mPTrefmin{ptrefmin}, mPTrefmax{ptrefmax}, mNchbins{nchbins}, mNchmin{nchmin}, mNchmax{nchmax}, mCentbinning{std::move(centbinning)} {}; + void SetVtxZBinning(int vtxbins, float vtxmin, float vtxmax) + { + mVtxZbins = vtxbins; + mVtxZmin = vtxmin; + mVtxZmax = vtxmax; + } + const auto& GetVtxZbins() const { return mVtxZbins; } + const auto& GetVtxZmin() const { return mVtxZmin; } + const auto& GetVtxZmax() const { return mVtxZmax; } + + void SetPtPOI(float ptpoimin, float ptpoimax) + { + mPTpoimin = ptpoimin; + mPTpoimax = ptpoimax; + } + const auto& GetPtPOImin() const { return mPTpoimin; } + const auto& GetPtPOImax() const { return mPTpoimax; } + + void SetPtBinning(std::vector ptbinning) { mPTbinning = std::move(ptbinning); } + const auto& GetPtBinning() const { return mPTbinning; } + + void SetEtaBinning(int etabins, float etamin, float etamax) + { + mEtabins = etabins; + mEtamin = etamin; + mEtamax = etamax; + } + const auto& GetEtaBins() const { return mEtabins; } + const auto& GetEtaMin() const { return mEtamin; } + const auto& GetEtaMax() const { return mEtamax; } + + void SetPhiBins(int phibins) { mPhibins = phibins; } + const auto& GetPhiBins() const { return mPhibins; } + + void SetPtRef(float ptrefmin, float ptrefmax) + { + mPTrefmin = ptrefmin; + mPTrefmax = ptrefmax; + } + const auto& GetPtRefMin() const { return mPTrefmin; } + const auto& GetPtRefMax() const { return mPTrefmax; } + + void SetNchBinning(int nchbins, float nchmin, float nchmax) + { + mNchbins = nchbins; + mNchmin = nchmin; + mNchmax = nchmax; + } + const auto& GetNchBins() const { return mNchbins; } + const auto& GetNchMin() const { return mNchmin; } + const auto& GetNchMax() const { return mNchmax; } + + void SetCentBinning(std::vector centbinning) { mCentbinning = std::move(centbinning); } + const auto& GetCentBinning() const { return mCentbinning; } + + private: + int mVtxZbins; + float mVtxZmin; + float mVtxZmax; + float mPTpoimin; + float mPTpoimax; + std::vector mPTbinning; + int mEtabins; + float mEtamin; + float mEtamax; + int mPhibins; + float mPTrefmin; + float mPTrefmax; + int mNchbins; + float mNchmin; + float mNchmax; + std::vector mCentbinning; + ClassDefNV(GFWBinningCuts, 1); +}; + +/// \class GFWRegions +/// \brief Class which implements configurable regions for the GFW +/// + +class GFWRegions +{ + public: + GFWRegions(std::vector names_ = {"refN", "refP", "refFull"}, std::vector etaminvals_ = {-0.8, 0.4, -0.8}, + std::vector etamaxvals_ = {-0.4, 0.8, 0.8}, + std::vector pTDifs_ = {0, 0, 0}, + std::vector bitmasks_ = {1, 1, 1}) : names{std::move(names_)}, etaminvals{std::move(etaminvals_)}, etamaxvals{std::move(etamaxvals_)}, pTDifs{std::move(pTDifs_)}, bitmasks{std::move(bitmasks_)} {}; + + auto Print() const + { + std::stringstream ss; + for (auto i = 0; i < names.size(); ++i) { + ss << "{" << names[i] << ", " << etaminvals[i] << ", " << etamaxvals[i] << ", " << pTDifs[i] << ", " << bitmasks[i] << "}"; + if (i != names.size() - 1) + ss << "\n"; + } + return ss.str(); + } + + auto GetSize() const { return CheckSameSize(names, etaminvals, etamaxvals, pTDifs, bitmasks); } + + void SetNames(std::vector names_) { names = std::move(names_); } + const auto& GetNames() const { return names; } + + void SetEtaMin(std::vector etaminvals_) { etaminvals = std::move(etaminvals_); } + const auto& GetEtaMin() const { return etaminvals; } + + void SetEtaMax(std::vector etamaxvals_) { etamaxvals = std::move(etamaxvals_); } + const auto& GetEtaMax() const { return etamaxvals; } + + void SetpTDifs(std::vector pTDifs_) { pTDifs = std::move(pTDifs_); } + const auto& GetpTDifs() const { return pTDifs; } + + void SetBitmasks(std::vector bitmasks_) { bitmasks = std::move(bitmasks_); } + const auto& GetBitmasks() const { return bitmasks; } + + private: + std::vector names; + std::vector etaminvals; + std::vector etamaxvals; + std::vector pTDifs; + std::vector bitmasks; + ClassDefNV(GFWRegions, 1); +}; + +/// \class GFWCorrConfigs +/// \brief Class which implements configurable correlations for GFW +/// +class GFWCorrConfigs +{ + public: + GFWCorrConfigs(std::vector corrs_ = {"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", + "refFull {2 2 -2 -2}"}, + std::vector heads_ = {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, + std::vector pTDifs_ = {0, 0, 0, 0, 0}) : corrs{std::move(corrs_)}, heads{std::move(heads_)}, pTDifs{std::move(pTDifs_)} {}; + + auto Print() const + { + std::stringstream ss; + for (auto i = 0; i < corrs.size(); ++i) { + ss << "{" << heads[i] << ", " << corrs[i] << ", " << pTDifs[i] << "}"; + if (i != corrs.size() - 1) + ss << "\n"; + } + return ss.str(); + } + + auto GetSize() const { return CheckSameSize(corrs, heads, pTDifs); } + + void SetCorrs(std::vector corrs_) { corrs = std::move(corrs_); } + const auto& GetCorrs() const { return corrs; } + + void SetHeads(std::vector heads_) { heads = std::move(heads_); } + const auto& GetHeads() const { return heads; } + + void SetpTDifs(std::vector pTDifs_) { pTDifs = std::move(pTDifs_); } + const auto& GetpTDifs() const { return pTDifs; } + + private: + std::vector corrs; + std::vector heads; + std::vector pTDifs; + ClassDefNV(GFWCorrConfigs, 1); +}; + +} // namespace analysis::genericframework +} // namespace o2 +#endif // PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ diff --git a/PWGCF/GenericFramework/GFWCumulant.cxx b/PWGCF/GenericFramework/Core/GFWCumulant.cxx similarity index 100% rename from PWGCF/GenericFramework/GFWCumulant.cxx rename to PWGCF/GenericFramework/Core/GFWCumulant.cxx diff --git a/PWGCF/GenericFramework/GFWCumulant.h b/PWGCF/GenericFramework/Core/GFWCumulant.h similarity index 88% rename from PWGCF/GenericFramework/GFWCumulant.h rename to PWGCF/GenericFramework/Core/GFWCumulant.h index 70341e8e625..f8cf6624542 100644 --- a/PWGCF/GenericFramework/GFWCumulant.h +++ b/PWGCF/GenericFramework/Core/GFWCumulant.h @@ -16,8 +16,8 @@ A part of A container to store Q vectors for one subevent with an extra layer to recursively calculate particle correlations. If used, modified, or distributed, please aknowledge the author of this code. */ -#ifndef PWGCF_GENERICFRAMEWORK_GFWCUMULANT_H_ -#define PWGCF_GENERICFRAMEWORK_GFWCUMULANT_H_ +#ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWCUMULANT_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_GFWCUMULANT_H_ #include #include @@ -51,13 +51,13 @@ class GFWCumulant uint fUsed; int fNEntries; // Q-vectors. Could be done recursively, but maybe defining each one of them explicitly is easier to read - int fN; //! Harmonics - int fPow; //! Power + int fN; //! Harmonics + int fPow; //! Power std::vector fPowVec; //! Powers array - int fPt; //! fPt bins + int fPt; //! fPt bins bool* fFilledPts; bool fInitialized; // Arrays are initialized std::complex fNullQ = 0; }; -#endif // PWGCF_GENERICFRAMEWORK_GFWCUMULANT_H_ +#endif // PWGCF_GENERICFRAMEWORK_CORE_GFWCUMULANT_H_ diff --git a/PWGCF/GenericFramework/GFWPowerArray.cxx b/PWGCF/GenericFramework/Core/GFWPowerArray.cxx similarity index 100% rename from PWGCF/GenericFramework/GFWPowerArray.cxx rename to PWGCF/GenericFramework/Core/GFWPowerArray.cxx diff --git a/PWGCF/GenericFramework/GFWPowerArray.h b/PWGCF/GenericFramework/Core/GFWPowerArray.h similarity index 87% rename from PWGCF/GenericFramework/GFWPowerArray.h rename to PWGCF/GenericFramework/Core/GFWPowerArray.h index 12d7361fbc2..82314374e00 100644 --- a/PWGCF/GenericFramework/GFWPowerArray.h +++ b/PWGCF/GenericFramework/Core/GFWPowerArray.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef PWGCF_GENERICFRAMEWORK_GFWPOWERARRAY_H_ -#define PWGCF_GENERICFRAMEWORK_GFWPOWERARRAY_H_ +#ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWPOWERARRAY_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_GFWPOWERARRAY_H_ #include #include @@ -31,4 +31,4 @@ class GFWPowerArray static void RecursiveFunction(HarSet& masterVector, HarSet hars, int offset, const int& MaxPower); static void PrintVector(const HarSet& singleSet); }; -#endif // PWGCF_GENERICFRAMEWORK_GFWPOWERARRAY_H_ +#endif // PWGCF_GENERICFRAMEWORK_CORE_GFWPOWERARRAY_H_ diff --git a/PWGCF/GenericFramework/GFWWeights.cxx b/PWGCF/GenericFramework/Core/GFWWeights.cxx similarity index 100% rename from PWGCF/GenericFramework/GFWWeights.cxx rename to PWGCF/GenericFramework/Core/GFWWeights.cxx diff --git a/PWGCF/GenericFramework/GFWWeights.h b/PWGCF/GenericFramework/Core/GFWWeights.h similarity index 95% rename from PWGCF/GenericFramework/GFWWeights.h rename to PWGCF/GenericFramework/Core/GFWWeights.h index 67fb3d8f116..c5176cdc64c 100644 --- a/PWGCF/GenericFramework/GFWWeights.h +++ b/PWGCF/GenericFramework/Core/GFWWeights.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef PWGCF_GENERICFRAMEWORK_GFWWEIGHTS_H_ -#define PWGCF_GENERICFRAMEWORK_GFWWEIGHTS_H_ +#ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTS_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTS_H_ #include "TObjArray.h" #include "TNamed.h" #include "TH3D.h" @@ -75,4 +75,4 @@ class GFWWeights : public TNamed ClassDef(GFWWeights, 1); }; -#endif // PWGCF_GENERICFRAMEWORK_GFWWEIGHTS_H_ +#endif // PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTS_H_ diff --git a/PWGCF/GenericFramework/GenericFrameworkLinkDef.h b/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h similarity index 68% rename from PWGCF/GenericFramework/GenericFrameworkLinkDef.h rename to PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h index 17eb7db8587..ae931455101 100755 --- a/PWGCF/GenericFramework/GenericFrameworkLinkDef.h +++ b/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef PWGCF_GENERICFRAMEWORK_GENERICFRAMEWORKLINKDEF_H_ -#define PWGCF_GENERICFRAMEWORK_GENERICFRAMEWORKLINKDEF_H_ +#ifndef PWGCF_GENERICFRAMEWORK_CORE_GENERICFRAMEWORKLINKDEF_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_GENERICFRAMEWORKLINKDEF_H_ #pragma link off all globals; #pragma link off all classes; @@ -22,5 +22,8 @@ #pragma link C++ class ProfileSubset + ; #pragma link C++ class FlowContainer + ; #pragma link C++ class GFWWeights + ; +#pragma link C++ class o2::analysis::genericframework::GFWBinningCuts + ; +#pragma link C++ class o2::analysis::genericframework::GFWRegions + ; +#pragma link C++ class o2::analysis::genericframework::GFWCorrConfigs + ; -#endif // PWGCF_GENERICFRAMEWORK_GENERICFRAMEWORKLINKDEF_H_ +#endif // PWGCF_GENERICFRAMEWORK_CORE_GENERICFRAMEWORKLINKDEF_H_ diff --git a/PWGCF/GenericFramework/ProfileSubset.cxx b/PWGCF/GenericFramework/Core/ProfileSubset.cxx similarity index 99% rename from PWGCF/GenericFramework/ProfileSubset.cxx rename to PWGCF/GenericFramework/Core/ProfileSubset.cxx index fd1b3165465..be5795f1252 100644 --- a/PWGCF/GenericFramework/ProfileSubset.cxx +++ b/PWGCF/GenericFramework/Core/ProfileSubset.cxx @@ -97,11 +97,11 @@ bool ProfileSubset::OverrideBinsWithZero(int xb1, int yb1, int xb2, int yb2) if (GetNbinsX() < xb1 || GetNbinsX() < xb2) { lHaveToQuit = kTRUE; printf("xBins out of range! (%i-%i vs %i)\n", xb1, xb2, GetNbinsX()); - }; + } if (GetNbinsY() < yb1 || GetNbinsY() < yb2) { lHaveToQuit = kTRUE; printf("yBins out of range! (%i-%i vs %i)\n", yb1, yb2, GetNbinsY()); - }; + } if (lHaveToQuit) return kFALSE; for (int ix = xb1; ix <= xb2; ix++) { @@ -115,4 +115,4 @@ bool ProfileSubset::OverrideBinsWithZero(int xb1, int yb1, int xb2, int yb2) } } return kTRUE; -} \ No newline at end of file +} diff --git a/PWGCF/GenericFramework/ProfileSubset.h b/PWGCF/GenericFramework/Core/ProfileSubset.h similarity index 81% rename from PWGCF/GenericFramework/ProfileSubset.h rename to PWGCF/GenericFramework/Core/ProfileSubset.h index 1548bc592b0..3d749e06b0e 100644 --- a/PWGCF/GenericFramework/ProfileSubset.h +++ b/PWGCF/GenericFramework/Core/ProfileSubset.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef ProfileSubset__H -#define ProfileSubset__H +#ifndef PWGCF_GENERICFRAMEWORK_CORE_PROFILESUBSET_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_PROFILESUBSET_H_ // Helper function to select a subrange of a TProfile #include "TProfile.h" #include "TProfile2D.h" @@ -19,8 +19,8 @@ class ProfileSubset : public TProfile2D { public: - ProfileSubset(TProfile2D& inpf) : TProfile2D(inpf){}; - ~ProfileSubset(){}; + explicit ProfileSubset(TProfile2D& inpf) : TProfile2D(inpf) {} + ~ProfileSubset() {} TProfile* GetSubset(bool onx, const char* name, int fb, int lb, int l_nbins = 0, double* l_binarray = 0); void OverrideBinContent(double x, double y, double x2, double y2, double val); void OverrideBinContent(double x, double y, double x2, double y2, TProfile2D* sourceProf); @@ -28,4 +28,4 @@ class ProfileSubset : public TProfile2D ClassDef(ProfileSubset, 2); }; -#endif \ No newline at end of file +#endif // PWGCF_GENERICFRAMEWORK_CORE_PROFILESUBSET_H_ diff --git a/PWGCF/GenericFramework/DataModel/CMakeLists.txt b/PWGCF/GenericFramework/DataModel/CMakeLists.txt new file mode 100644 index 00000000000..bbfd7adac2b --- /dev/null +++ b/PWGCF/GenericFramework/DataModel/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. diff --git a/PWGCF/GenericFramework/TableProducer/CMakeLists.txt b/PWGCF/GenericFramework/TableProducer/CMakeLists.txt new file mode 100644 index 00000000000..bbfd7adac2b --- /dev/null +++ b/PWGCF/GenericFramework/TableProducer/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. diff --git a/PWGCF/GenericFramework/Tasks/CMakeLists.txt b/PWGCF/GenericFramework/Tasks/CMakeLists.txt new file mode 100644 index 00000000000..ee71394c4cb --- /dev/null +++ b/PWGCF/GenericFramework/Tasks/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2physics_add_dpl_workflow(flow-generic-framework + SOURCES flowGenericFramework.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx new file mode 100644 index 00000000000..ea910808f3c --- /dev/null +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -0,0 +1,445 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/DataModel/EventSelection.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" + +#include "GFWPowerArray.h" +#include "GFW.h" +#include "GFWCumulant.h" +#include "FlowContainer.h" +#include "GFWConfig.h" +#include "GFWWeights.h" +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis; + +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +namespace o2::analysis::genericframework +{ +std::vector ptbinning = { + 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, + 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, + 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, + 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; +float ptpoilow = 0.2, ptpoiup = 10.0; +float ptreflow = 0.2, ptrefup = 3.0; +float ptlow = 0.2, ptup = 3.0; +int etabins = 16; +float etalow = -0.8, etaup = 0.8; +int vtxZbins = 40; +float vtxZlow = -10.0, vtxZup = 10.0; +int phibins = 72; +float philow = 0.0; +float phiup = constants::math::TwoPI; +int nchbins = 300; +float nchlow = 0.5; +float nchup = 3000.5; +std::vector centbinning(90); +int nBootstrap = 10; +GFWRegions regions; +GFWCorrConfigs configs; +} // namespace o2::analysis::genericframework + +using namespace o2::analysis::genericframework; + +struct GenericFramework { + + O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") + O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Do correlations as function of Nch") + O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") + O2_DEFINE_CONFIGURABLE(cfgFillQA, bool, false, "Fill QA histograms") + O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") + + Configurable cfgBinning{"cfgBinning", + {40, -10.0, 10.0, 0.2, 2.0, {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, 16, -0.8, 0.8, 72, 0.2, 5.0, 300, 0.5, 3000.5, {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}}, + "triplets - nbins, min, max - for z_vtx, PtPOI, eta - nbins for phi - ptRef min and max"}; + + Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; + + Configurable cfgCorrConfig{"cfgCorrConfig", {{"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, {0, 0, 0, 0, 0}}, "Configurations for each correlation to calculate"}; + +#include "PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.cxx" // NOLINT + // Connect to ccdb + Service ccdb; + + struct Config { + TH1D* mEfficiency = nullptr; + GFWWeights* mAcceptance = nullptr; + bool correctionsLoaded = false; + } cfg; + + // Define output + OutputObj fFC{FlowContainer("FlowContainer")}; + OutputObj fFC_gen{FlowContainer("FlowContainer_gen")}; + OutputObj fFC_reco{FlowContainer("FlowContainer_reco")}; + OutputObj fWeights{GFWWeights("weights")}; + HistogramRegistry registry{"registry"}; + HistogramRegistry QAregistry{"QAregistry", {}, OutputObjHandlingPolicy::QAObject}; + + // define global variables + GFW* fGFW = new GFW(); + std::vector corrconfigs; + TRandom3* fRndm = new TRandom3(0); + TAxis* fPtAxis; + + void init(InitContext const&) + { + LOGF(info, "flowGenericFramework::init()"); + regions.SetNames(cfgRegions->GetNames()); + regions.SetEtaMin(cfgRegions->GetEtaMin()); + regions.SetEtaMax(cfgRegions->GetEtaMax()); + regions.SetpTDifs(cfgRegions->GetpTDifs()); + regions.SetBitmasks(cfgRegions->GetBitmasks()); + configs.SetCorrs(cfgCorrConfig->GetCorrs()); + configs.SetHeads(cfgCorrConfig->GetHeads()); + configs.SetpTDifs(cfgCorrConfig->GetpTDifs()); + LOGF(info, "Regions:\n%s", regions.Print()); + LOGF(info, "CorrConfigs:\n%s", configs.Print()); + ptbinning = cfgBinning->GetPtBinning(); + ptpoilow = cfgBinning->GetPtPOImin(); + ptpoiup = cfgBinning->GetPtPOImax(); + ptreflow = cfgBinning->GetPtRefMin(); + ptrefup = cfgBinning->GetPtRefMax(); + ptlow = static_cast(std::min(ptpoilow, ptreflow)); + ptup = static_cast(std::max(ptpoiup, ptrefup)); + etabins = cfgBinning->GetEtaBins(); + etalow = cfgBinning->GetEtaMin(); + etaup = cfgBinning->GetEtaMax(); + vtxZbins = cfgBinning->GetVtxZbins(); + vtxZlow = cfgBinning->GetVtxZmin(); + vtxZup = cfgBinning->GetVtxZmax(); + phibins = cfgBinning->GetPhiBins(); + philow = 0.0f; + phiup = constants::math::TwoPI; + nchbins = cfgBinning->GetNchBins(); + nchlow = cfgBinning->GetNchMin(); + nchup = cfgBinning->GetNchMax(); + centbinning = cfgBinning->GetCentBinning(); + + AxisSpec phiAxis = {phibins, philow, phiup, "#phi"}; + AxisSpec etaAxis = {etabins, etalow, etaup, "#eta"}; + AxisSpec vtxAxis = {vtxZbins, vtxZlow, vtxZup, "Vtx_{z} (cm)"}; + AxisSpec ptAxis = {ptbinning, "#it{p}_{T} GeV/#it{c}"}; + AxisSpec centAxis = {centbinning, "Centrality (%)"}; + AxisSpec nchAxis = {nchbins, nchlow, nchup}; + AxisSpec multAxis = (cfgUseNch) ? nchAxis : centAxis; + AxisSpec dcaZAXis = {200, -2, 2, "DCA_{z} (cm)"}; + AxisSpec dcaXYAXis = {200, -1, 1, "DCA_{xy} (cm)"}; + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + int ptbins = ptbinning.size() - 1; + fPtAxis = new TAxis(ptbins, &ptbinning[0]); + + if (cfgFillWeights) { + fWeights->SetPtBins(ptbins, &ptbinning[0]); + fWeights->Init(true, false); + } + + if (doprocessGen || doprocessReco) { + if (doprocessGen) { + QAregistry.add("pt_gen", "", {HistType::kTH1D, {ptAxis}}); + QAregistry.add("phi_gen", "", {HistType::kTH1D, {phiAxis}}); + QAregistry.add("eta_gen", "", {HistType::kTH1D, {etaAxis}}); + QAregistry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); + } + if (doprocessReco) { + QAregistry.add("pt_reco", "", {HistType::kTH1D, {ptAxis}}); + QAregistry.add("phi_reco", "", {HistType::kTH1D, {phiAxis}}); + QAregistry.add("eta_reco", "", {HistType::kTH1D, {etaAxis}}); + QAregistry.add("vtxZ_reco", "", {HistType::kTH1D, {vtxAxis}}); + } + } else { + QAregistry.add("phi", "", {HistType::kTH1D, {phiAxis}}); + QAregistry.add("eta", "", {HistType::kTH1D, {etaAxis}}); + QAregistry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); + + QAregistry.add("pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); + registry.add("phi_eta_vtxZ_corrected", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + QAregistry.add("cent_nch", "", {HistType::kTH2D, {nchAxis, centAxis}}); + QAregistry.add("globalTracks_PVTracks", "", {HistType::kTH2D, {nchAxis, nchAxis}}); + } + + if (regions.GetSize() < 0) + LOGF(error, "Configuration contains vectors of different size - check the GFWRegions configurable"); + for (auto i(0); i < regions.GetSize(); ++i) { + fGFW->AddRegion(regions.GetNames()[i], regions.GetEtaMin()[i], regions.GetEtaMax()[i], (regions.GetpTDifs()[i]) ? ptbins + 1 : 1, regions.GetBitmasks()[i]); + } + for (auto i = 0; i < configs.GetSize(); ++i) { + corrconfigs.push_back(fGFW->GetCorrelatorConfig(configs.GetCorrs()[i], configs.GetHeads()[i], configs.GetpTDifs()[i])); + } + if (corrconfigs.empty()) + LOGF(error, "Configuration contains vectors of different size - check the GFWCorrConfig configurable"); + fGFW->CreateRegions(); + TObjArray* oba = new TObjArray(); + AddConfigObjectsToObjArray(oba, corrconfigs); + if (!doprocessGen && !doprocessReco) { + fFC->SetName("FlowContainer"); + fFC->SetXAxis(fPtAxis); + fFC->Initialize(oba, multAxis, cfgNbootstrap); + } + if (doprocessGen) { + fFC_gen->SetName("FlowContainer_gen"); + fFC_gen->SetXAxis(fPtAxis); + fFC_gen->Initialize(oba, multAxis, cfgNbootstrap); + } + if (doprocessReco) { + fFC_reco->SetName("FlowContainer_reco"); + fFC_reco->SetXAxis(fPtAxis); + fFC_reco->Initialize(oba, multAxis, cfgNbootstrap); + } + delete oba; + } + + void AddConfigObjectsToObjArray(TObjArray* oba, const std::vector& configs) + { + for (auto it = configs.begin(); it != configs.end(); ++it) { + if (it->pTDif) { + std::string suffix = "_ptDiff"; + for (auto i = 0; i < fPtAxis->GetNbins(); ++i) { + std::string index = Form("_pt_%i", i + 1); + oba->Add(new TNamed(it->Head.c_str() + index, it->Head.c_str() + suffix)); + } + } else { + oba->Add(new TNamed(it->Head.c_str(), it->Head.c_str())); + } + } + } + + void loadCorrections(uint64_t timestamp) + { + if (cfg.correctionsLoaded) + return; + if (cfgAcceptance.value.empty() == false) { + cfg.mAcceptance = ccdb->getForTimeStamp(cfgAcceptance, timestamp); + if (cfg.mAcceptance) + LOGF(info, "Loaded acceptance weights from %s (%p)", cfgAcceptance.value.c_str(), (void*)cfg.mAcceptance); + else + LOGF(warning, "Could not load acceptance weights from %s (%p)", cfgAcceptance.value.c_str(), (void*)cfg.mAcceptance); + } + if (cfgEfficiency.value.empty() == false) { + cfg.mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + if (cfg.mEfficiency == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)cfg.mEfficiency); + } + cfg.correctionsLoaded = true; + } + + void FillFC(OutputObj fc, const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) + { + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fc->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + return; + } + for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { + dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); + if (dnx == 0) + continue; + val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fc->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + } + return; + } + + Filter collisionFilter = aod::collision::posZ < vtxZup && aod::collision::posZ > vtxZlow; + Filter trackFilter = aod::track::eta < etaup && aod::track::eta > etalow&& aod::track::pt > ptlow&& aod::track::pt < ptup && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < 0.2f; + using myTracks = soa::Filtered>; + + enum datatype { + kRaw, + kDerived + }; + + template + void processData(TCollision collision, TTracks tracks, float centrality) + { + if (tracks.size() < 1) + return; + if (centrality < centbinning.front() || centrality > centbinning.back()) + return; + float vtxz = collision.posZ(); + + if (cfgFillQA) { + QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); + QAregistry.fill(HIST("vtxZ"), vtxz); + } + fGFW->Clear(); + float l_Random = fRndm->Rndm(); + float weff = 1, wacc = 1; + + for (auto& track : tracks) { + if (cfgFillWeights) + fWeights->Fill(track.phi(), track.eta(), vtxz, track.pt(), centrality, 0); + if (cfg.mEfficiency) + weff = cfg.mEfficiency->GetBinContent(cfg.mEfficiency->FindBin(track.pt())); + else + weff = 1.0; + if (weff == 0) + continue; + weff = 1. / weff; + if (cfg.mAcceptance) + wacc = cfg.mAcceptance->GetNUA(track.phi(), track.eta(), vtxz); + else + wacc = 1; + registry.fill(HIST("phi_eta_vtxZ_corrected"), track.phi(), track.eta(), vtxz, wacc); + bool WithinPtPOI = (ptpoilow < track.pt()) && (track.pt() < ptpoiup); // within POI pT range + bool WithinPtRef = (ptreflow < track.pt()) && (track.pt() < ptrefup); // within RF pT range + if (WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt() - 1), track.phi(), wacc * weff, 1); + if (WithinPtPOI) + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), wacc * weff, 2); + if (WithinPtPOI && WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), wacc * weff, 4); + + if (cfgFillQA) { + QAregistry.fill(HIST("phi"), track.phi()); + QAregistry.fill(HIST("eta"), track.eta()); + QAregistry.fill(HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); + } + } + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + FillFC(fFC, corrconfigs.at(l_ind), centrality, l_Random); + } + } + + void processRawData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) + { + const auto centrality = collision.centFT0C(); + auto bc = collision.bc_as(); + if (!collision.sel8()) + return; + QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + loadCorrections(bc.timestamp()); + processData(collision, tracks, centrality); + } + PROCESS_SWITCH(GenericFramework, processRawData, "Process analysis for derived data", true); + + void processGen(soa::Filtered>::iterator const& collision, aod::McParticles const& particles) + { + if (collision.has_mcCollision()) { + float centrality = collision.centFT0C(); + if (particles.size() < 1) + return; + if (centrality < centbinning.front() || centrality > centbinning.back()) + return; + float vtxz = collision.posZ(); + if (cfgFillQA) { + QAregistry.fill(HIST("vtxZ_gen"), vtxz); + } + fGFW->Clear(); + float l_Random = fRndm->Rndm(); + + for (auto& particle : particles) { + if (!particle.isPhysicalPrimary() || particle.eta() < etalow || particle.eta() > etaup || particle.pt() < ptlow || particle.pt() > ptup) + continue; + bool WithinPtPOI = (ptpoilow < particle.pt()) && (particle.pt() < ptpoiup); // within POI pT range + bool WithinPtRef = (ptreflow < particle.pt()) && (particle.pt() < ptrefup); // within RF pT range + if (WithinPtRef) + fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 1); + if (WithinPtPOI) + fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 2); + if (WithinPtPOI && WithinPtRef) + fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 4); + if (cfgFillQA) { + QAregistry.fill(HIST("phi_gen"), particle.phi()); + QAregistry.fill(HIST("eta_gen"), particle.eta()); + QAregistry.fill(HIST("pt_gen"), particle.pt()); + } + } + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + FillFC(fFC_gen, corrconfigs.at(l_ind), centrality, l_Random); + } + } + } + PROCESS_SWITCH(GenericFramework, processGen, "Process analysis for MC generated events", false); + + Filter dcaFilter = nabs(aod::track::dcaXY) < 0.2f; + void processReco(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles const&) + { + float centrality = collision.centFT0C(); + if (tracks.size() < 1) + return; + if (centrality < centbinning.front() || centrality > centbinning.back()) + return; + float vtxz = collision.posZ(); + if (cfgFillQA) { + QAregistry.fill(HIST("vtxZ_reco"), vtxz); + } + fGFW->Clear(); + float l_Random = fRndm->Rndm(); + + for (auto& track : tracks) { + if (track.has_mcParticle()) { + auto particle = track.mcParticle(); + if (!particle.isPhysicalPrimary() || particle.eta() < etalow || particle.eta() > etaup || particle.pt() < ptlow || particle.pt() > ptup) + continue; + bool WithinPtPOI = (ptpoilow < particle.pt()) && (particle.pt() < ptpoiup); // within POI pT range + bool WithinPtRef = (ptreflow < particle.pt()) && (particle.pt() < ptrefup); // within RF pT range + if (WithinPtRef) + fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 1); + if (WithinPtPOI) + fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 2); + if (WithinPtPOI && WithinPtRef) + fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 4); + if (cfgFillQA) { + QAregistry.fill(HIST("phi_reco"), particle.phi()); + QAregistry.fill(HIST("eta_reco"), particle.eta()); + QAregistry.fill(HIST("pt_reco"), particle.pt()); + } + } + } + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + FillFC(fFC_reco, corrconfigs.at(l_ind), centrality, l_Random); + } + } + PROCESS_SWITCH(GenericFramework, processReco, "Process analysis for MC reconstructed events", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGCF/Tasks/CMakeLists.txt b/PWGCF/Tasks/CMakeLists.txt index e1bf473ab31..fdc35cf2ef6 100644 --- a/PWGCF/Tasks/CMakeLists.txt +++ b/PWGCF/Tasks/CMakeLists.txt @@ -28,8 +28,3 @@ o2physics_add_dpl_workflow(correlations SOURCES correlations.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(flow-generic-framework - SOURCES flowGenericFramework.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore - COMPONENT_NAME Analysis) diff --git a/PWGCF/Tasks/flowGenericFramework.cxx b/PWGCF/Tasks/flowGenericFramework.cxx deleted file mode 100644 index 8aaff20ea6b..00000000000 --- a/PWGCF/Tasks/flowGenericFramework.cxx +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" - -#include "GFWPowerArray.h" -#include "GFW.h" -#include "GFWCumulant.h" -#include "FlowContainer.h" -#include "GFWWeights.h" -#include -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; - -struct GenericFramework { - - O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range") - O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "Minimal pT for tracks") - O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 3.0f, "Maximal pT for tracks") - O2_DEFINE_CONFIGURABLE(cfgCutPtRefMin, float, 0.2f, "Minimal pT for reference tracks") - O2_DEFINE_CONFIGURABLE(cfgCutPtRefMax, float, 3.0f, "Maximal pT for reference tracks") - O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") - O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") - O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "Number of chi2 per TPC cluster") - O2_DEFINE_CONFIGURABLE(cfgCutDCAxy, float, 0.1f, "Maximum DCA xy") - O2_DEFINE_CONFIGURABLE(cfgEtaSep, float, 0.4f, "Eta gap for flow calculations") - O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") - O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") - - ConfigurableAxis axisVertex{"axisVertex", {22, -11, 11}, "vertex axis for histograms"}; - ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; - ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, "pt axis for histograms"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.1}, "multiplicity / centrality axis for histograms"}; - - Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (aod::track::dcaXY < cfgCutDCAxy); - using myTracks = soa::Filtered>; - - // Connect to ccdb - Service ccdb; - - struct Config { - TH1D* mEfficiency = nullptr; - GFWWeights* mAcceptance = nullptr; - bool correctionsLoaded = false; - } cfg; - - // Define output - OutputObj fFC{FlowContainer("FlowContainer")}; - OutputObj fWeights{GFWWeights("weights")}; - HistogramRegistry registry{"registry"}; - - // define global variables - GFW* fGFW = new GFW(); - std::vector corrconfigs; - TRandom3* fRndm = new TRandom3(0); - TAxis* fPtAxis; - - void init(InitContext const&) - { - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - - int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - ccdb->setCreatedNotAfter(now); - - o2::framework::AxisSpec axis = axisPt; - int nPtBins = axis.binEdges.size() - 1; - double* PtBins = &(axis.binEdges)[0]; - fPtAxis = new TAxis(nPtBins, PtBins); - - if (doprocessWeights) { - fWeights->SetPtBins(nPtBins, PtBins); - fWeights->Init(true, false); - } - - if (doprocessData) { - registry.add("hPhi", "", {HistType::kTH1D, {axisPhi}}); - registry.add("hEta", "", {HistType::kTH1D, {axisEta}}); - registry.add("hPt", "", {HistType::kTH1D, {axisPt}}); - registry.add("hVtxZ", "", {HistType::kTH1D, {axisVertex}}); - registry.add("hPhiEtaVtxZ_corrected", "", {HistType::kTH3D, {axisPhi, axisEta, axisVertex}}); - registry.add("hCent", "", {HistType::kTH1D, {axisMultiplicity}}); - - TObjArray* oba = new TObjArray(); - // Reference flow - oba->Add(new TNamed("ChGapP22", "ChGapP22")); // for positive gap case - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGapP22_pt_%i", i + 1), "ChGapP22_pTDiff")); - oba->Add(new TNamed("ChGapP32", "ChGapP32")); - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGapP32_pt_%i", i + 1), "ChGapP32_pTDiff")); - oba->Add(new TNamed("ChGapP42", "ChGapP42")); - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGapP42_pt_%i", i + 1), "ChGapP42_pTDiff")); - - oba->Add(new TNamed("ChGapN22", "ChGapN22")); // for negative gap case - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGapN22_pt_%i", i + 1), "ChGapN22_pTDiff")); - oba->Add(new TNamed("ChGapN32", "ChGapN32")); - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGapN32_pt_%i", i + 1), "ChGapN32_pTDiff")); - oba->Add(new TNamed("ChGapN42", "ChGapN42")); - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGapN42_pt_%i", i + 1), "ChGapN42_pTDiff")); - - oba->Add(new TNamed("ChFull22", "ChFull22")); // no-gap case - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChFull22_pt_%i", i + 1), "ChFull22_pTDiff")); - oba->Add(new TNamed("ChFull24", "ChFull24")); // no-gap case - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChFull24_pt_%i", i + 1), "ChFull24_pTDiff")); - oba->Add(new TNamed("ChFull26", "ChFull26")); // no-gap case - oba->Add(new TNamed("ChFull28", "ChFull28")); // no-gap case - oba->Add(new TNamed("ChFull210", "ChFull210")); // no-gap case - fFC->SetName("FlowContainer"); - fFC->SetXAxis(fPtAxis); - fFC->Initialize(oba, axisMultiplicity, cfgNbootstrap); - delete oba; - - fGFW->AddRegion("refN", -cfgCutEta, cfgEtaSep, 1, 1); - fGFW->AddRegion("refP", cfgEtaSep, cfgCutEta, 1, 1); - fGFW->AddRegion("refFull", -cfgCutEta, cfgCutEta, 1, 1); - - fGFW->AddRegion("poiN", -cfgCutEta, -cfgEtaSep, nPtBins + 1, 2); - fGFW->AddRegion("poiP", cfgEtaSep, cfgCutEta, nPtBins + 1, 2); - fGFW->AddRegion("poiFull", -cfgCutEta, cfgCutEta, nPtBins + 1, 2); - - fGFW->AddRegion("olN", -cfgCutEta, -cfgEtaSep, nPtBins + 1, 4); - fGFW->AddRegion("olP", cfgEtaSep, cfgCutEta, nPtBins + 1, 4); - fGFW->AddRegion("olFull", -cfgCutEta, cfgCutEta, nPtBins + 1, 4); - - CreateCorrConfigs(); - fGFW->CreateRegions(); - } - } - - void loadCorrections(uint64_t timestamp) - { - if (cfg.correctionsLoaded) - return; - if (cfgAcceptance.value.empty() == false) { - cfg.mAcceptance = ccdb->getForTimeStamp(cfgAcceptance, timestamp); - if (cfg.mAcceptance) - LOGF(info, "Loaded acceptance weights from %s (%p)", cfgAcceptance.value.c_str(), (void*)cfg.mAcceptance); - else - LOGF(warning, "Could not load acceptance weights from %s (%p)", cfgAcceptance.value.c_str(), (void*)cfg.mAcceptance); - } - if (cfgEfficiency.value.empty() == false) { - cfg.mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); - if (cfg.mEfficiency == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); - } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)cfg.mEfficiency); - } - cfg.correctionsLoaded = true; - } - - void CreateCorrConfigs() - { - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP {2} refN {-2}", "ChGapP22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiP refP | olP {2} refN {-2}", "ChGapP22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN {2} refP {-2}", "ChGapN22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN | olN {2} refP {-2}", "ChGapN22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP {3} refN {-3}", "ChGapP32", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiP refP | olP {3} refN {-3}", "ChGapP32", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN {3} refP {-3}", "ChGapN32", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN | olN {3} refP {-3}", "ChGapN32", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP {4} refN {-4}", "ChGapP42", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiP refP | olP {4} refN {-4}", "ChGapP42", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN {4} refP {-4}", "ChGapN42", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN | olN {4} refP {-4}", "ChGapN42", kTRUE)); - - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refFull {2 -2}", "ChFull22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiFull refFull | olFull {2 -2}", "ChFull22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refFull {2 2 -2 -2}", "ChFull24", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiFull refFull | olFull {2 2 -2 -2}", "ChFull24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refFull {2 2 2 -2 -2 -2}", "ChFull26", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refFull {2 2 2 2 -2 -2 -2 -2}", "ChFull28", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refFull {2 2 2 2 2 -2 -2 -2 -2 -2}", "ChFull210", kFALSE)); - } - - void FillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) - { - double dnx, val; - dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); - if (dnx == 0) - return; - if (!corrconf.pTDif) { - val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; - if (TMath::Abs(val) < 1) - fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); - return; - } - for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { - dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); - if (dnx == 0) - continue; - val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; - if (TMath::Abs(val) < 1) - fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); - } - return; - } - - void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) - { - - auto bc = collision.bc_as(); - loadCorrections(bc.timestamp()); - - if (tracks.size() < 1) - return; - - float vtxz = collision.posZ(); - registry.fill(HIST("hVtxZ"), vtxz); - - fGFW->Clear(); - const auto centrality = collision.centFT0C(); - registry.fill(HIST("hCent"), centrality); - if (centrality > 100) - return; - float l_Random = fRndm->Rndm(); - float weff = 1, wacc = 1; - - for (auto& track : tracks) { - registry.fill(HIST("hPhi"), track.phi()); - registry.fill(HIST("hEta"), track.eta()); - - double pt = track.pt(); - if (cfg.mEfficiency) - weff = cfg.mEfficiency->GetBinContent(cfg.mEfficiency->FindBin(pt)); - else - weff = 1.0; - if (weff == 0) - continue; - weff = 1. / weff; - if (cfg.mAcceptance) - wacc = cfg.mAcceptance->GetNUA(track.phi(), track.eta(), vtxz); - else - wacc = 1; - registry.fill(HIST("hPhiEtaVtxZ_corrected"), track.phi(), track.eta(), vtxz, wacc); - registry.fill(HIST("hPt"), pt); - bool WithinPtPOI = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within POI pT range - bool WithinPtRef = (cfgCutPtRefMin < pt) && (pt < cfgCutPtRefMax); // within RF pT range - if (WithinPtRef) - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 1); - if (WithinPtPOI) - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 2); - if (WithinPtPOI && WithinPtRef) - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 4); - } - for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - FillFC(corrconfigs.at(l_ind), centrality, l_Random); - } - } - PROCESS_SWITCH(GenericFramework, processData, "Process analysis for data", true); - - void processWeights(soa::Filtered>::iterator const& collision, myTracks const& tracks) - { - const auto centrality = collision.centFT0C(); - if (centrality > 100) - return; - for (auto& track : tracks) { - if (track.tpcNClsCrossedRows() < 70) - continue; - if (track.dcaXY() > 7 * (0.0026 + 0.0050 / pow(track.pt(), 1.01))) - continue; - fWeights->Fill(track.phi(), track.eta(), collision.posZ(), track.pt(), centrality, 0); - } - } - PROCESS_SWITCH(GenericFramework, processWeights, "Process weights for acceptance corrections", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGDQ/Tasks/dqFlow.cxx b/PWGDQ/Tasks/dqFlow.cxx index 07ea30e70e7..4e73e69ad5f 100644 --- a/PWGDQ/Tasks/dqFlow.cxx +++ b/PWGDQ/Tasks/dqFlow.cxx @@ -36,10 +36,10 @@ #include "PWGDQ/Core/HistogramsLibrary.h" #include "PWGDQ/Core/CutsLibrary.h" #include "PWGDQ/Core/MixingLibrary.h" -#include "PWGCF/GenericFramework/GFW.h" -#include "PWGCF/GenericFramework/GFWCumulant.h" -#include "PWGCF/GenericFramework/FlowContainer.h" -#include "PWGCF/GenericFramework/GFWWeights.h" +#include "PWGCF/GenericFramework/Core/GFW.h" +#include "PWGCF/GenericFramework/Core/GFWCumulant.h" +#include "PWGCF/GenericFramework/Core/FlowContainer.h" +#include "PWGCF/GenericFramework/Core/GFWWeights.h" #include "Common/DataModel/EventSelection.h" #include "Common/Core/TrackSelection.h" #include "Common/DataModel/TrackSelectionTables.h" From 6435c00b8b802eec3869f20258dcce73efd167da Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:49:49 +0100 Subject: [PATCH 079/156] Adding missing process function (#4188) Co-authored-by: Lucamicheletti93 --- PWGDQ/Tasks/tableReader.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 0ed46426cfd..8790cd66878 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -1189,6 +1189,7 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithColl, "Run electron-electron pairing, with skimmed tracks and with collision information", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmed, "Run muon-muon pairing, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuVertexingSkimmed, "Run muon-muon pairing and vertexing, with skimmed muons", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmedWithColl, "Run muon-muon pairing keeping the info of AO2D collision, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processVnDecayToEESkimmed, "Run electron-electron pairing, with skimmed tracks for vn", false); PROCESS_SWITCH(AnalysisSameEventPairing, processVnDecayToMuMuSkimmed, "Run muon-muon pairing, with skimmed tracks for vn", false); PROCESS_SWITCH(AnalysisSameEventPairing, processElectronMuonSkimmed, "Run electron-muon pairing, with skimmed tracks/muons", false); From 82bbba6277518bdfbf15b7a215a9022a38afcc5c Mon Sep 17 00:00:00 2001 From: kgwizdzi <116073883+kgwizdzi@users.noreply.github.com> Date: Mon, 18 Dec 2023 17:37:53 +0100 Subject: [PATCH 080/156] Changes in invMass histograms (#4184) * Changes in invMass histograms * Fixing clang --- .../Tasks/femtoUniversePairTaskTrackD0.cxx | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index ff893fabc63..a338c9ddca2 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -82,7 +82,6 @@ struct femtoUniversePairTaskTrackD0 { struct : o2::framework::ConfigurableGroup { Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; Configurable ConfPDGCodeTrack{"ConfPDGCodeTrack", 2212, "Particle 2 - PDG code"}; - // Configurable ConfCutTrack{"ConfCutTrack", 5542474, "Particle 2 - Selection bit"}; Configurable ConfPIDTrack{"ConfPIDTrack", 2, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> Configurable ConfTrackSign{"ConfTrackSign", 1, "Track sign"}; Configurable ConfIsTrackIdentified{"ConfIsTrackIdentified", true, "Enable PID for the track"}; @@ -92,6 +91,8 @@ struct femtoUniversePairTaskTrackD0 { struct : o2::framework::ConfigurableGroup { Configurable ConfPDGCodeD0{"ConfPDGCodeD0", 421, "D0 meson - PDG code"}; Configurable ConfPDGCodeD0bar{"ConfPDGCodeD0bar", -421, "D0bar meson - PDG code"}; + Configurable ConfMinInvMassD0D0bar{"ConfMinInvMassD0D0bar", 1.65, "D0/D0bar sel. - min. invMass"}; + Configurable ConfMaxInvMassD0D0bar{"ConfMaxInvMassD0D0bar", 2.05, "D0/D0bar sel. - max. invMass"}; } ConfDmesons; /// Partitions for particle 1 @@ -99,7 +100,8 @@ struct femtoUniversePairTaskTrackD0 { Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)); /// Partitions for particle 2 - Partition partsD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); + Partition partsD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f); + // Partition partsD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); Partition> partsD0D0barMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); /// Histogramming for particle 1 @@ -151,10 +153,12 @@ struct femtoUniversePairTaskTrackD0 { HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry registry{"registry", - {{"hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{300, 1.75, 2.05}}}}, - {"hInvMassD0bar", ";#it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{300, 1.75, 2.05}}}}, - {"hPtD0", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 15.}}}}, - {"hPtD0bar", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 15.}}}}, + {{"hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{400, 1.65, 2.05}}}}, + {"hInvMassD0bar", ";#it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{400, 1.65, 2.05}}}}, + {"hMassVsPt", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {{500, 0.0, 5.0}, {400, 0., 20.}}}}, + {"hInvMassVsPt", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {{400, 1.65, 2.05}, {400, 0., 20.}}}}, + {"hPtD0", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{400, 0., 20.}}}}, + {"hPtD0bar", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{400, 0., 20.}}}}, {"hPhiD0", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, {"hPhiD0bar", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, {"hEtaD0", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, @@ -326,14 +330,21 @@ struct femtoUniversePairTaskTrackD0 { // auto groupPartsD0D0barDaugh = partsD0D0barDaughters->sliceByCached(aod::femtoworldparticle::femtoWorldCollisionId, col.globalIndex(), cache); for (auto& d0d0bar : groupPartsD0D0bar) { - if (d0d0bar.mLambda() > 0 && d0d0bar.mAntiLambda() < 0) { - registry.fill(HIST("hInvMassD0"), d0d0bar.mLambda()); + registry.fill(HIST("hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); + if (d0d0bar.mLambda() > 0.0f && d0d0bar.mAntiLambda() < 0.0f) { + if (d0d0bar.mLambda() > ConfDmesons.ConfMinInvMassD0D0bar && d0d0bar.mLambda() < ConfDmesons.ConfMaxInvMassD0D0bar) { + registry.fill(HIST("hInvMassD0"), d0d0bar.mLambda()); + } + registry.fill(HIST("hInvMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); registry.fill(HIST("hPtD0"), d0d0bar.pt()); registry.fill(HIST("hPhiD0"), d0d0bar.phi()); registry.fill(HIST("hEtaD0"), d0d0bar.eta()); } - if (d0d0bar.mLambda() < 0 && d0d0bar.mAntiLambda() > 0) { - registry.fill(HIST("hInvMassD0bar"), d0d0bar.mAntiLambda()); + if (d0d0bar.mLambda() < 0.0f && d0d0bar.mAntiLambda() > 0.0f) { + if (d0d0bar.mAntiLambda() > ConfDmesons.ConfMinInvMassD0D0bar && d0d0bar.mAntiLambda() < ConfDmesons.ConfMaxInvMassD0D0bar) { + registry.fill(HIST("hInvMassD0bar"), d0d0bar.mAntiLambda()); + } + registry.fill(HIST("hInvMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); From 858131b4c2997cdfc6c016091ef9b477d8f39801 Mon Sep 17 00:00:00 2001 From: vfeuilla <71069003+vfeuilla@users.noreply.github.com> Date: Mon, 18 Dec 2023 18:23:34 +0100 Subject: [PATCH 081/156] Also include LS pairs in filter (#4193) --- PWGDQ/Tasks/filterPPwithAssociation.cxx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/PWGDQ/Tasks/filterPPwithAssociation.cxx b/PWGDQ/Tasks/filterPPwithAssociation.cxx index 48c7ff249ea..81ac67482b5 100644 --- a/PWGDQ/Tasks/filterPPwithAssociation.cxx +++ b/PWGDQ/Tasks/filterPPwithAssociation.cxx @@ -989,6 +989,8 @@ struct DQFilterPPTask { Configurable fConfigBarrelSelections{"cfgBarrelSels", "jpsiPID1:pairMassLow:1", ":[]:,[:[]:],..."}; Configurable fConfigMuonSelections{"cfgMuonSels", "muonQualityCuts:pairNoCut:1", ":[]:"}; Configurable fConfigQA{"cfgWithQA", false, "If true, fill QA histograms"}; + Configurable fConfigFilterLsBarrelTracksPairs{"cfgWithBarrelLS", false, "If true, also select like sign (--/++) barrel track pairs"}; + Configurable fConfigFilterLsMuonsPairs{"cfgWithMuonLS", false, "If true, also select like sign (--/++) muon pairs"}; int fNBarrelCuts; // number of barrel selections int fNMuonCuts; // number of muon selections @@ -1140,8 +1142,10 @@ struct DQFilterPPTask { auto t1 = a1.template track_as(); auto t2 = a2.template track_as(); // keep just opposite-sign pairs - if (t1.sign() * t2.sign() > 0) { - continue; + if (!fConfigFilterLsBarrelTracksPairs) { + if (t1.sign() * t2.sign() > 0) { + continue; + } } // construct the pair and apply pair cuts @@ -1198,8 +1202,10 @@ struct DQFilterPPTask { auto t1 = a1.template fwdtrack_as(); auto t2 = a2.template fwdtrack_as(); // keep just opposite-sign pairs - if (t1.sign() * t2.sign() > 0) { - continue; + if (!fConfigFilterLsMuonsPairs) { + if (t1.sign() * t2.sign() > 0) { + continue; + } } // construct the pair and apply cuts From 517122a94592564ef885efefc5ab8e30e717ba77 Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Mon, 18 Dec 2023 18:35:56 +0100 Subject: [PATCH 082/156] toggle search of missing tpc segment across collisions (#4190) * fix issues in binning * fill histo with found tpc segments including fake * toggle tpc segment search without association to collision --- PWGLF/Tasks/QC/efficiencyQA.cxx | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/PWGLF/Tasks/QC/efficiencyQA.cxx b/PWGLF/Tasks/QC/efficiencyQA.cxx index 7a6b34970e6..b47385d3a1c 100644 --- a/PWGLF/Tasks/QC/efficiencyQA.cxx +++ b/PWGLF/Tasks/QC/efficiencyQA.cxx @@ -105,6 +105,7 @@ struct efficiencyQA { Configurable v0cosPaMin{"v0cosPaMin", 0.99f, "minimum cosine of pointing angle of V0"}; Configurable findTpcLeg{"findTpcLeg", false, "toggle search of missing tpc segment"}; + Configurable useTpcTracksFromSameColl{"useTpcTracksFromSameColl", true, "toggle post-matching to tpc segment associated to collision"}; Configurable propToTPCinnerWall{"propToTPCinnerWall", false, "toggle propagation of tracks to the TPC inner wall"}; Configurable refitVertex{"refitVertex", false, "toggle refit of decay vertex using tag and tpc prolongation"}; Configurable ptWindow{"ptWindow", 0.05f, "pt window to search tpc segment"}; @@ -126,7 +127,7 @@ struct efficiencyQA { ConfigurableAxis massResAxis{"massResAxis", {400, -0.1f, 0.1f}, "binning for the invariant-mass resolution"}; ConfigurableAxis zVtxAxis{"zVtxAxis", {200, -10.f, 10.f}, "binning for the z coordinate of the primary vertex"}; ConfigurableAxis recAxis{"recAxis", {8, 0.f, 8.f}, "binning for the reconstruction flag"}; - ConfigurableAxis tpcAxis{"tpcAxis", {3, 0.f, 3.f}, "binning for the matching of tpc segment"}; + ConfigurableAxis tpcAxis{"tpcAxis", {4, 0.f, 4.f}, "binning for the matching of tpc segment"}; ConfigurableAxis ptAxis{"ptAxis", {100, -5.f, 5.f}, "binning for the pt of V0 daughter tracks"}; ConfigurableAxis ptResAxis{"ptResAxis", {200, -1.f, 1.f}, "binning for the pt resolution of V0 daughter tracks"}; ConfigurableAxis etaAxis{"etaAxis", {900, -.9f, .9f}, "binning for the eta of V0 daughter tracks"}; @@ -153,15 +154,15 @@ struct efficiencyQA { histos.add("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); hPiRec = histos.add("piRec", ";;#it{p}_{T} (GeV/#it{c});Entries", HistType::kTH2F, {recAxis, ptAxis}); std::string binLabels[]{"Decays", "ITS", "ITS only", "TPC", "TPC only", "ITS+TPC", "TPC+TOF", " "}; - for (int iB{0}; iB < 8; ++iB) { + for (int iB{0}; iB < hPiRec->GetNbinsX(); ++iB) { hPiRec->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); } if (doprocessMcTracks) { hPiRec->GetXaxis()->SetBinLabel(1, "Generated"); hPtRes = histos.add("ptRes", ";;#it{p}_{T}^{rec} (GeV/#it{c});#it{p}_{T}^{rec} - #it{p}_{T}^{MC} (GeV/#it{c})", HistType::kTH3F, {recAxis, ptAxis, ptResAxis}); - hEtaRes = histos.add("etaRes", ";;#eta^{rec};#eta^{rec} - #eta^{MC} (rad)", HistType::kTH3F, {recAxis, etaAxis, etaResAxis}); - hPhiRes = histos.add("phiRes", ";;#phi^{rec} (rad);#phi^{rec} - #phi^{MC} (rad)", HistType::kTH3F, {recAxis, phiAxis, phiResAxis}); - for (int iB{1}; iB < 8; ++iB) { + hEtaRes = histos.add("etaRes", ";;#it{p}_{T}^{rec} (GeV/#it{c});#eta^{rec} - #eta^{MC} (rad)", HistType::kTH3F, {recAxis, ptAxis, etaResAxis}); + hPhiRes = histos.add("phiRes", ";;#it{p}_{T}^{rec} (GeV/#it{c});#phi^{rec} - #phi^{MC} (rad)", HistType::kTH3F, {recAxis, ptAxis, phiResAxis}); + for (int iB{1}; iB < hPtRes->GetNbinsX(); ++iB) { hPtRes->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); hEtaRes->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); hPhiRes->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); @@ -197,18 +198,18 @@ struct efficiencyQA { histos.add("phiItsTpcSel", ";#it{p} (GeV/#it{c});#phi^{TPC} - #phi^{ITS} (rad)", HistType::kTH2F, {ptAxis, ptResAxis}); std::string binLabelsTag[]{"hasITS && hasTPC", "tracking", "PID", "v0 mass", "dcaV0dau", "cosPA", "dcaXYZ", "V0radius"}; - for (int iB{0}; iB < 8; ++iB) { + for (int iB{0}; iB < hTagCuts->GetNbinsX(); ++iB) { hTagCuts->GetXaxis()->SetBinLabel(iB + 1, binLabelsTag[iB].data()); } - for (int iB{0}; iB < 7; ++iB) { + for (int iB{0}; iB < hPiRecMass->GetNbinsX(); ++iB) { hPiRecMass->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); } hPiRecMass->GetXaxis()->SetBinLabel(8, "ITS w/ TPC leg"); if (doprocessTagAndProbeMC) { - std::string binLabelsTpc[]{"hasTPCsegment", "foundTPCsegment", "allFoundTPCsegment"}; + std::string binLabelsTpc[]{"hasTPCsegment", "foundTPCsegment", "allFoundTPCsegment", "foundTPCsegment (w/ fake)"}; hTpcSegment = histos.add("tpcSegment", ";;#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {tpcAxis, ptAxis}); - for (int iB{0}; iB < 3; ++iB) { + for (int iB{0}; iB < hTpcSegment->GetNbinsX(); ++iB) { hTpcSegment->GetXaxis()->SetBinLabel(iB + 1, binLabelsTpc[iB].data()); } histos.add("pTpcIts", ";#it{p}^{ITS} (GeV/#it{c});#it{p}^{TPC} - #it{p}^{ITS} (GeV/#it{c});Entries", HistType::kTH2F, {ptAxis, ptResAxis}); @@ -287,7 +288,7 @@ struct efficiencyQA { template void fillTagAndProbe(soa::Join::iterator const& collision, aod::V0s const& V0s, TracksFull const& tracks) { - auto tpcTracks = tracks.sliceBy(perCollisionTracks, collision.globalIndex()); + auto tpcTracks = useTpcTracksFromSameColl ? tracks.sliceBy(perCollisionTracks, collision.globalIndex()) : tracks; for (auto& v0 : V0s) { auto posTrack = v0.posTrack_as(); auto negTrack = v0.negTrack_as(); @@ -530,7 +531,7 @@ struct efficiencyQA { void fillProbeMC(soa::Join::iterator const& collision, TracksFull const& tracks, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) { - auto tracks_thisEvent = tracks.sliceBy(perCollisionTracks, collision.globalIndex()); + auto tracks_thisEvent = useTpcTracksFromSameColl ? tracks.sliceBy(perCollisionTracks, collision.globalIndex()) : tracks; for (const auto& probeTrack : probeTracks) { auto mcLab = trackLabelsMC.rawIteratorAt(probeTrack.globalIndex); @@ -564,6 +565,9 @@ struct efficiencyQA { } if (mcLabTpc.mcParticleId() == mcLab.mcParticleId()) { hTpcSegment->Fill(0., probeTrack.pt); + if (probeTrack.globalIndexTpc > 0) { + hTpcSegment->Fill(3., probeTrack.pt); + } auto trackCov = getTrackParCov(tpcTrack); gpu::gpustd::array dcaInfo; From 8e277ae90360f4883d37a85d52a760c9301f7900 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Tue, 19 Dec 2023 02:44:53 +0900 Subject: [PATCH 083/156] PWGEM/PhotonMeson: update efficiency for primary muon (#4195) * PWGEM/PhotonMeson: remove unnecessary dep. * PWGEM/PhotonMeson: change default value in TAP * PWGEM/PhotonMeson: update efficiency for primary muon --- .../TableProducer/skimmerPrimaryMuon.cxx | 54 +++++++++++-------- PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx | 2 +- PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx | 6 +-- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx index 1930b5f713c..4ac362d71e3 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx @@ -89,8 +89,8 @@ struct skimmerPrimaryMuon { {"Track/hTOFNsigmaPi_after", "TOF n sigma #pi vs. p_{in};p_{in} (GeV/c);n #sigma_{#pi}^{TOF}", {HistType::kTH2F, {{1000, 0.f, 1.f}, {100, -5.f, +5.f}}}}, {"Pair/hMmumuPtmumu", "ULS m_{#mu#mu} vs. p_{T,#mu#mu};m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c)", {HistType::kTH2F, {{100, 0.2f, 1.2f}, {120, 0.f, 1.2f}}}}, // for MC primary muon - {"MC/Primary/hP_Pin", "p vs. p_{in};p (GeV/c);p_{in} (GeV/c)", {HistType::kTH2F, {{1000, 0.f, 1.f}, {1000, 0.f, 1.f}}}}, - {"MC/Primary/hRelDiffP", "p vs. rel diff p;p (GeV/c);(p_{in} - p)/p", {HistType::kTH2F, {{1000, 0.f, 1.f}, {200, -1.f, 1.f}}}}, + {"MC/Primary/hPt_Gen", "generated pT;p_{T,#mu}^{gen} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, + {"MC/Primary/hPt_Rec", "reconstructed pT;p_{T,#mu}^{rec} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, {"MC/Primary/hTPCdEdx_Pin", "TPC dE/dx vs. p_{in};p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 1.f}, {200, 0.f, 200.f}}}}, {"MC/Primary/hTOFbeta_Pin", "TOF beta vs. p_{in};p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 1.f}, {250, 0.6f, 1.1f}}}}, {"MC/Primary/hNclsITS", "Ncls ITS;N_{cls}^{ITS}", {HistType::kTH1F, {{8, -0.5f, +7.5f}}}}, @@ -99,8 +99,6 @@ struct skimmerPrimaryMuon { {"MC/Primary/hNcrTPC", "Ncr TPC;N_{cr}^{TPC}", {HistType::kTH1F, {{161, -0.5f, +160.5f}}}}, {"MC/Primary/hNfTPC", "Nfindable TPC;N_{f}^{TPC}", {HistType::kTH1F, {{161, -0.5f, +160.5f}}}}, {"MC/Primary/hChi2TPC", "chi2 TPC;#chi^{2}/N_{cls}^{TPC}", {HistType::kTH1F, {{100, 0.f, 10.f}}}}, - {"MC/Primary/hChi2TPC_NclsTPC", "chi2 TPC;N_{cls}^{TPC};#chi^{2}/N_{cls}^{TPC}", {HistType::kTH2F, {{161, -0.5, 160.5}, {100, 0.f, 10.f}}}}, - {"MC/Primary/hDCAxy_NclsTPC", "DCA xy vs. N_{cls}^{TPC};DCA_{xy} (cm);N_{cls}^{TPC}", {HistType::kTH2F, {{200, -1.f, +1.f}, {161, -0.5f, +160.5f}}}}, {"MC/Primary/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", {HistType::kTH2F, {{200, -1.f, +1.f}, {200, -1.f, +1.f}}}}, {"MC/Primary/hDCA3D", "DCA;DCA_{3D} (cm)", {HistType::kTH1F, {{100, 0.f, +1.f}}}}, {"MC/Primary/hDCAxy_resolution", "DCA xy resolution;DCA_{xy} resolution (cm)", {HistType::kTH1F, {{100, 0.f, +0.1f}}}}, @@ -109,8 +107,8 @@ struct skimmerPrimaryMuon { {"MC/Primary/hDCA3D_sigma", "DCA;DCA_{3D} (#sigma)", {HistType::kTH1F, {{100, 0.f, +10.f}}}}, {"MC/Primary/hProdVtx", "#mu production vtx;X_{MC} (cm);Y_{MC} (cm)", {HistType::kTH2F, {{200, -100.f, +100.f}, {200, -100.f, +100.f}}}}, // for MC seconday muon - {"MC/Secondary/hP_Pin", "p vs. p_{in};p (GeV/c);p_{in} (GeV/c)", {HistType::kTH2F, {{1000, 0.f, 1.f}, {1000, 0.f, 1.f}}}}, - {"MC/Secondary/hRelDiffP", "p vs. rel diff p;p (GeV/c);(p_{in} - p)/p", {HistType::kTH2F, {{1000, 0.f, 1.f}, {200, -1.f, 1.f}}}}, + {"MC/Secondary/hPt_Gen", "generated pT;p_{T,#mu}^{gen} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, + {"MC/Secondary/hPt_Rec", "reconstructed pT;p_{T,#mu}^{rec} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, {"MC/Secondary/hTPCdEdx_Pin", "TPC dE/dx vs. p_{in};p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 1.f}, {200, 0.f, 200.f}}}}, {"MC/Secondary/hTOFbeta_Pin", "TOF beta vs. p_{in};p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 1.f}, {250, 0.6f, 1.1f}}}}, {"MC/Secondary/hNclsITS", "Ncls ITS;N_{cls}^{ITS}", {HistType::kTH1F, {{8, -0.5f, +7.5f}}}}, @@ -119,8 +117,6 @@ struct skimmerPrimaryMuon { {"MC/Secondary/hNcrTPC", "Ncr TPC;N_{cr}^{TPC}", {HistType::kTH1F, {{161, -0.5f, +160.5f}}}}, {"MC/Secondary/hNfTPC", "Nfindable TPC;N_{f}^{TPC}", {HistType::kTH1F, {{161, -0.5f, +160.5f}}}}, {"MC/Secondary/hChi2TPC", "chi2 TPC;#chi^{2}/N_{cls}^{TPC}", {HistType::kTH1F, {{100, 0.f, 10.f}}}}, - {"MC/Secondary/hChi2TPC_NclsTPC", "chi2 TPC;N_{cls}^{TPC};#chi^{2}/N_{cls}^{TPC}", {HistType::kTH2F, {{161, -0.5, 160.5}, {100, 0.f, 10.f}}}}, - {"MC/Secondary/hDCAxy_NclsTPC", "DCA xy vs. N_{cls}^{TPC};DCA_{xy} (cm);N_{cls}^{TPC}", {HistType::kTH2F, {{200, -1.f, +1.f}, {161, -0.5f, +160.5f}}}}, {"MC/Secondary/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", {HistType::kTH2F, {{200, -1.f, +1.f}, {200, -1.f, +1.f}}}}, {"MC/Secondary/hDCA3D", "DCA;DCA_{3D} (cm)", {HistType::kTH1F, {{100, 0.f, +1.f}}}}, {"MC/Secondary/hDCAxy_resolution", "DCA xy resolution;DCA_{xy} resolution (cm)", {HistType::kTH1F, {{100, 0.f, +0.1f}}}}, @@ -213,11 +209,12 @@ struct skimmerPrimaryMuon { if constexpr (isMC) { auto mctrack = track.template mcParticle_as(); - if (abs(mctrack.pdgCode()) == 13 && mctrack.has_mothers()) { - auto mp = mctrack.template mothers_first_as(); - if (abs(mp.pdgCode()) == 221 || abs(mp.pdgCode()) == 223 || abs(mp.pdgCode()) == 333 || abs(mp.pdgCode()) == 113 || abs(mp.pdgCode()) == 331) { - fRegistry.fill(HIST("MC/Primary/hP_Pin"), track.p(), track.tpcInnerParam()); - fRegistry.fill(HIST("MC/Primary/hRelDiffP"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + if (abs(mctrack.pdgCode()) == 13 /* && mctrack.has_mothers()*/) { + // auto mp = mctrack.template mothers_first_as(); + if (mctrack.isPhysicalPrimary()) { + if (isMuon(track)) { + fRegistry.fill(HIST("MC/Primary/hPt_Rec"), track.pt()); + } fRegistry.fill(HIST("MC/Primary/hTPCdEdx_Pin"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("MC/Primary/hTOFbeta_Pin"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("MC/Primary/hNclsITS"), track.itsNCls()); @@ -226,8 +223,6 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Primary/hNclsTPC"), track.tpcNClsFound()); fRegistry.fill(HIST("MC/Primary/hNfTPC"), track.tpcNClsFindable()); fRegistry.fill(HIST("MC/Primary/hChi2TPC"), track.tpcChi2NCl()); - fRegistry.fill(HIST("MC/Primary/hChi2TPC_NclsTPC"), track.tpcNClsFound(), track.tpcChi2NCl()); - fRegistry.fill(HIST("MC/Primary/hDCAxy_NclsTPC"), track.dcaXY(), track.tpcNClsFound()); fRegistry.fill(HIST("MC/Primary/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("MC/Primary/hDCA3D"), sqrt(pow(track.dcaXY(), 2) + pow(track.dcaZ(), 2))); fRegistry.fill(HIST("MC/Primary/hDCAxy_resolution"), sqrt(track.cYY())); @@ -235,9 +230,10 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Primary/hDCAxyz_sigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); fRegistry.fill(HIST("MC/Primary/hDCA3D_sigma"), sqrt(pow(track.dcaXY() / sqrt(track.cYY()), 2) + pow(track.dcaZ() / sqrt(track.cZZ()), 2))); fRegistry.fill(HIST("MC/Primary/hProdVtx"), mctrack.vx(), mctrack.vy()); - } else if (abs(mp.pdgCode()) == 211 || abs(mp.pdgCode()) == 321) { - fRegistry.fill(HIST("MC/Secondary/hP_Pin"), track.p(), track.tpcInnerParam()); - fRegistry.fill(HIST("MC/Secondary/hRelDiffP"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + } else { + if (isMuon(track)) { + fRegistry.fill(HIST("MC/Secondary/hPt_Rec"), track.pt()); + } fRegistry.fill(HIST("MC/Secondary/hTPCdEdx_Pin"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("MC/Secondary/hTOFbeta_Pin"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("MC/Secondary/hNclsITS"), track.itsNCls()); @@ -246,8 +242,6 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Secondary/hNclsTPC"), track.tpcNClsFound()); fRegistry.fill(HIST("MC/Secondary/hNfTPC"), track.tpcNClsFindable()); fRegistry.fill(HIST("MC/Secondary/hChi2TPC"), track.tpcChi2NCl()); - fRegistry.fill(HIST("MC/Secondary/hChi2TPC_NclsTPC"), track.tpcNClsFound(), track.tpcChi2NCl()); - fRegistry.fill(HIST("MC/Secondary/hDCAxy_NclsTPC"), track.dcaXY(), track.tpcNClsFound()); fRegistry.fill(HIST("MC/Secondary/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("MC/Secondary/hDCA3D"), sqrt(pow(track.dcaXY(), 2) + pow(track.dcaZ(), 2))); fRegistry.fill(HIST("MC/Secondary/hDCAxy_resolution"), sqrt(track.cYY())); @@ -364,7 +358,7 @@ struct skimmerPrimaryMuon { using MyFilteredTracksMC = soa::Filtered; Partition posTracksMC = o2::aod::track::signed1Pt > 0.f; Partition negTracksMC = o2::aod::track::signed1Pt < 0.f; - void processMC(soa::Join const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks, aod::McParticles const&) + void processMC(soa::Join const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks, aod::McParticles const& mcparticles) { stored_trackIds.reserve(tracks.size()); for (auto& collision : collisions) { @@ -386,7 +380,25 @@ struct skimmerPrimaryMuon { stored_trackIds.clear(); stored_trackIds.shrink_to_fit(); + + // for generated info + for (auto& mcparticle : mcparticles) { + if (abs(mcparticle.pdgCode()) != 13) { + continue; + } + + if (abs(mcparticle.eta()) > maxeta) { + continue; + } + + if (mcparticle.isPhysicalPrimary()) { + fRegistry.fill(HIST("MC/Primary/hPt_Gen"), mcparticle.pt()); + } else { + fRegistry.fill(HIST("MC/Secondary/hPt_Gen"), mcparticle.pt()); + } + } } + PROCESS_SWITCH(skimmerPrimaryMuon, processMC, "process reconstructed and MC info ", false); }; diff --git a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx index 05ea3174187..707e8030cef 100644 --- a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx +++ b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx @@ -50,7 +50,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; diff --git a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx index fc22b3a3283..58c92a0ea83 100644 --- a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx +++ b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx @@ -60,9 +60,9 @@ struct TagAndProbe { Configurable maxY{"maxY", 0.9, "maximum rapidity for reconstructed particles"}; Configurable fConfigTagPCMCut{"cfgTagPCMCuts", "tag_track", "Tag PCM photon cut. 1 per wagon"}; - Configurable fConfigTagPHOSCut{"cfgTagPHOSCuts", "tag", "Tag PHOS photon cuts. 1 per wagon"}; - Configurable fConfigTagEMCCut{"cfgTagEMCCuts", "tag", "Tag EMCal photon cuts. 1 per wagon"}; - Configurable fConfigProbePCMCuts{"cfgProbePCMCuts", "analysis,analysis_wo_mee,qc,qc_w_mee", "Comma separated list of V0 photon cuts"}; + Configurable fConfigTagPHOSCut{"cfgTagPHOSCuts", "test03", "Tag PHOS photon cuts. 1 per wagon"}; + Configurable fConfigTagEMCCut{"cfgTagEMCCuts", "standard", "Tag EMCal photon cuts. 1 per wagon"}; + Configurable fConfigProbePCMCuts{"cfgProbePCMCuts", "analysis,qc", "Comma separated list of V0 photon cuts"}; Configurable fConfigProbePHOSCuts{"cfgProbePHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; Configurable fConfigProbeEMCCuts{"cfgProbeEMCCuts", "standard", "Comma separated list of EMCal photon cuts"}; Configurable minOpenAngle{"minOpenAngle", 0.0202, "apply min opening angle"}; From 82c0efda966f550e98bacee37671b023234a24d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Mon, 18 Dec 2023 22:57:37 +0100 Subject: [PATCH 084/156] PWGHF: Add D0 derived-data creator (#4121) --- PWGHF/DataModel/DerivedTables.h | 348 +++++++++++++++ PWGHF/TableProducer/CMakeLists.txt | 5 + .../derivedDataCreatorD0ToKPi.cxx | 403 ++++++++++++++++++ 3 files changed, 756 insertions(+) create mode 100644 PWGHF/DataModel/DerivedTables.h create mode 100644 PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx diff --git a/PWGHF/DataModel/DerivedTables.h b/PWGHF/DataModel/DerivedTables.h new file mode 100644 index 00000000000..eb12c71a257 --- /dev/null +++ b/PWGHF/DataModel/DerivedTables.h @@ -0,0 +1,348 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file DerivedTables.h.h +/// \brief Definitions of derived tables produced by derived-data creators + +#ifndef PWGHF_DATAMODEL_DERIVEDTABLES_H_ +#define PWGHF_DATAMODEL_DERIVEDTABLES_H_ + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" + +#include "Common/Core/RecoDecay.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +namespace o2::aod +{ +// Basic collision properties +namespace hf_coll_base +{ +DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int8_t); //! collision rejection flag +DECLARE_SOA_COLUMN(MultFT0M, multFT0M, float); //! FT0M multiplicity +} // namespace hf_coll_base + +DECLARE_SOA_TABLE(HfD0CollBases, "AOD1", "HFD0COLLBASE", //! Table with basic collision info + o2::soa::Index<>, + collision::NumContrib, + hf_coll_base::IsEventReject, + bc::RunNumber); + +using HfD0CollBase = HfD0CollBases::iterator; + +DECLARE_SOA_TABLE(StoredHfD0CollBases, "AOD", "HFD0COLLBASE", //! Table with basic collision info (stored version) + o2::soa::Index<>, + collision::NumContrib, + hf_coll_base::IsEventReject, + bc::RunNumber, + soa::Marker<1>); + +using StoredHfD0CollBase = StoredHfD0CollBases::iterator; + +DECLARE_SOA_TABLE(HfD0CollIds, "AOD1", "HFD0COLLID", //! Table with global indices for collisions + hf_cand::CollisionId); + +DECLARE_SOA_TABLE(StoredHfD0CollIds, "AOD", "HFD0COLLID", //! Table with global indices for collisions (stored version) + hf_cand::CollisionId, + soa::Marker<1>); + +// Basic candidate properties +namespace hf_cand_base +{ +DECLARE_SOA_INDEX_COLUMN(HfD0CollBase, hfD0CollBase); //! collision index pointing to the derived collision table for D0 candidates +DECLARE_SOA_INDEX_COLUMN(StoredHfD0CollBase, storedHfD0CollBase); //! collision index pointing to the derived collision table for D0 candidates +DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); //! MC collision of this particle +DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle +DECLARE_SOA_COLUMN(Eta, eta, float); //! pseudorapidity +DECLARE_SOA_COLUMN(M, m, float); //! invariant mass +DECLARE_SOA_COLUMN(Phi, phi, float); //! azimuth +DECLARE_SOA_COLUMN(Pt, pt, float); //! transverse momentum + +namespace functions +{ +/// Rapidity as a function of pT, eta, mass +/// \todo Move to RecoDecay +template +auto y(TPt pt, TEta eta, TM m) +{ + return std::log((RecoDecay::sqrtSumOfSquares(m, pt * std::cosh(eta)) + pt * std::sinh(eta)) / RecoDecay::sqrtSumOfSquares(m, pt)); +} +} // namespace functions +DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! D0 rapidity + [](float pt, float eta) -> float { return functions::y(pt, eta, o2::constants::physics::MassD0); }); +} // namespace hf_cand_base + +// Candidate properties used for selection +namespace hf_cand_par +{ +DECLARE_SOA_COLUMN(CosThetaStar, cosThetaStar, float); //! cosine of theta star +DECLARE_SOA_COLUMN(Cpa, cpa, float); //! cosine of pointing angle +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! cosine of pointing angle in the transverse plane +DECLARE_SOA_COLUMN(Ct, ct, float); //! proper lifetime times c +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! decay length +DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! decay length divided by its uncertainty +DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! decay length in the transverse plane +DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! decay length in the transverse plane divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterNormalised0, impactParameterNormalised0, float); //! impact parameter of prong 0 divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterNormalised1, impactParameterNormalised1, float); //! impact parameter of prong 1 divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterNormalised2, impactParameterNormalised2, float); //! impact parameter of prong 2 divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterProduct, impactParameterProduct, float); //! product of impact parameters of prong 0 and prong 1 +DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! see RecoDecay::maxNormalisedDeltaIP +DECLARE_SOA_COLUMN(PProng0, pProng0, float); //! momentum magnitude of prong 0 +DECLARE_SOA_COLUMN(PProng1, pProng1, float); //! momentum magnitude of prong 1 +DECLARE_SOA_COLUMN(PProng2, pProng2, float); //! momentum magnitude of prong 2 +DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! transverse momentum of prong 0 +DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! transverse momentum of prong 1 +DECLARE_SOA_COLUMN(PtProng2, ptProng2, float); //! transverse momentum of prong 2 +DECLARE_SOA_COLUMN(RSecondaryVertex, rSecondaryVertex, float); //! distance of the secondary vertex from the z axis +// TOF +DECLARE_SOA_COLUMN(NSigTofKa0, nSigTofKa0, float); +DECLARE_SOA_COLUMN(NSigTofKa1, nSigTofKa1, float); +DECLARE_SOA_COLUMN(NSigTofKa2, nSigTofKa2, float); +DECLARE_SOA_COLUMN(NSigTofPi0, nSigTofPi0, float); +DECLARE_SOA_COLUMN(NSigTofPi1, nSigTofPi1, float); +DECLARE_SOA_COLUMN(NSigTofPi2, nSigTofPi2, float); +DECLARE_SOA_COLUMN(NSigTofPr0, nSigTofPr0, float); +DECLARE_SOA_COLUMN(NSigTofPr1, nSigTofPr1, float); +DECLARE_SOA_COLUMN(NSigTofPr2, nSigTofPr2, float); +// TPC +DECLARE_SOA_COLUMN(NSigTpcKa0, nSigTpcKa0, float); +DECLARE_SOA_COLUMN(NSigTpcKa1, nSigTpcKa1, float); +DECLARE_SOA_COLUMN(NSigTpcKa2, nSigTpcKa2, float); +DECLARE_SOA_COLUMN(NSigTpcPi0, nSigTpcPi0, float); +DECLARE_SOA_COLUMN(NSigTpcPi1, nSigTpcPi1, float); +DECLARE_SOA_COLUMN(NSigTpcPi2, nSigTpcPi2, float); +DECLARE_SOA_COLUMN(NSigTpcPr0, nSigTpcPr0, float); +DECLARE_SOA_COLUMN(NSigTpcPr1, nSigTpcPr1, float); +DECLARE_SOA_COLUMN(NSigTpcPr2, nSigTpcPr2, float); +// TPC+TOF +DECLARE_SOA_COLUMN(NSigTpcTofKa0, nSigTpcTofKa0, float); +DECLARE_SOA_COLUMN(NSigTpcTofKa1, nSigTpcTofKa1, float); +DECLARE_SOA_COLUMN(NSigTpcTofKa2, nSigTpcTofKa2, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi0, nSigTpcTofPi0, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi1, nSigTpcTofPi1, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi2, nSigTpcTofPi2, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr0, nSigTpcTofPr0, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr1, nSigTpcTofPr1, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr2, nSigTpcTofPr2, float); +} // namespace hf_cand_par + +// Candidate selection flags +namespace hf_cand_sel +{ +DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! bitmap of the selected candidate type +} + +// MC flags +namespace hf_cand_mc +{ +DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! flag for reconstruction level matching +DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! flag for generator level matching +DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); //! particle origin, reconstruction level +DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); //! particle origin, generator level +DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int8_t); //! swapping of the prongs order +DECLARE_SOA_COLUMN(FlagMcDecayChanRec, flagMcDecayChanRec, int8_t); //! resonant decay channel flag, reconstruction level +DECLARE_SOA_COLUMN(FlagMcDecayChanGen, flagMcDecayChanGen, int8_t); //! resonant decay channel flag, generator level +DECLARE_SOA_COLUMN(MlScoreBkg, mlScoreBkg, float); //! ML score for background class +DECLARE_SOA_COLUMN(MlScorePrompt, mlScorePrompt, float); //! ML score for prompt class +DECLARE_SOA_COLUMN(MlScoreNonPrompt, mlScoreNonPrompt, float); //! ML score for non-prompt class +} // namespace hf_cand_mc + +DECLARE_SOA_TABLE(HfD0Bases, "AOD1", "HFD0BASE", //! Table with basic candidate properties used in the analyses + o2::soa::Index<>, + hf_cand_base::HfD0CollBaseId, + hf_cand_base::Pt, + hf_cand_base::Eta, + hf_cand_base::Phi, + hf_cand_base::M, + hf_cand_base::Y); + +DECLARE_SOA_TABLE(StoredHfD0Bases, "AOD", "HFD0BASE", //! Table with basic candidate properties used in the analyses (stored version) + o2::soa::Index<>, + hf_cand_base::StoredHfD0CollBaseId, + hf_cand_base::Pt, + hf_cand_base::Eta, + hf_cand_base::Phi, + hf_cand_base::M, + hf_cand_base::Y, + soa::Marker<1>); + +// candidates for removal: +// PxProng0, PyProng0, PzProng0,... (same for 1, 2), we can keep Pt, Eta, Phi instead +// XY: CpaXY, DecayLengthXY, ErrorDecayLengthXY +// normalised: DecayLengthNormalised, DecayLengthXYNormalised, ImpactParameterNormalised0 +DECLARE_SOA_TABLE(HfD0Pars, "AOD1", "HFD0PAR", //! Table with candidate properties used for selection + hf_cand::Chi2PCA, + hf_cand_par::DecayLength, + hf_cand_par::DecayLengthXY, + hf_cand_par::DecayLengthNormalised, + hf_cand_par::DecayLengthXYNormalised, + hf_cand_par::PtProng0, + hf_cand_par::PtProng1, + hf_cand::ImpactParameter0, + hf_cand::ImpactParameter1, + hf_cand_par::ImpactParameterNormalised0, + hf_cand_par::ImpactParameterNormalised1, + hf_cand_par::NSigTpcPi0, + hf_cand_par::NSigTpcKa0, + hf_cand_par::NSigTofPi0, + hf_cand_par::NSigTofKa0, + hf_cand_par::NSigTpcTofPi0, + hf_cand_par::NSigTpcTofKa0, + hf_cand_par::NSigTpcPi1, + hf_cand_par::NSigTpcKa1, + hf_cand_par::NSigTofPi1, + hf_cand_par::NSigTofKa1, + hf_cand_par::NSigTpcTofPi1, + hf_cand_par::NSigTpcTofKa1, + hf_cand_par::Cpa, + hf_cand_par::CpaXY, + hf_cand_par::MaxNormalisedDeltaIP, + hf_cand_par::ImpactParameterProduct); + +DECLARE_SOA_TABLE(StoredHfD0Pars, "AOD", "HFD0PAR", //! Table with candidate properties used for selection (stored version) + hf_cand::Chi2PCA, + hf_cand_par::DecayLength, + hf_cand_par::DecayLengthXY, + hf_cand_par::DecayLengthNormalised, + hf_cand_par::DecayLengthXYNormalised, + hf_cand_par::PtProng0, + hf_cand_par::PtProng1, + hf_cand::ImpactParameter0, + hf_cand::ImpactParameter1, + hf_cand_par::ImpactParameterNormalised0, + hf_cand_par::ImpactParameterNormalised1, + hf_cand_par::NSigTpcPi0, + hf_cand_par::NSigTpcKa0, + hf_cand_par::NSigTofPi0, + hf_cand_par::NSigTofKa0, + hf_cand_par::NSigTpcTofPi0, + hf_cand_par::NSigTpcTofKa0, + hf_cand_par::NSigTpcPi1, + hf_cand_par::NSigTpcKa1, + hf_cand_par::NSigTofPi1, + hf_cand_par::NSigTofKa1, + hf_cand_par::NSigTpcTofPi1, + hf_cand_par::NSigTpcTofKa1, + hf_cand_par::Cpa, + hf_cand_par::CpaXY, + hf_cand_par::MaxNormalisedDeltaIP, + hf_cand_par::ImpactParameterProduct, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfD0ParEs, "AOD1", "HFD0PARE", //! Table with additional candidate properties used for selection + collision::PosX, + collision::PosY, + collision::PosZ, + hf_cand::XSecondaryVertex, + hf_cand::YSecondaryVertex, + hf_cand::ZSecondaryVertex, + hf_cand::ErrorDecayLength, + hf_cand::ErrorDecayLengthXY, + hf_cand::KfTopolChi2OverNdf, + hf_cand_par::RSecondaryVertex, + hf_cand_par::PProng0, + hf_cand_par::PProng1, + hf_cand::PxProng0, + hf_cand::PyProng0, + hf_cand::PzProng0, + hf_cand::PxProng1, + hf_cand::PyProng1, + hf_cand::PzProng1, + hf_cand::ErrorImpactParameter0, + hf_cand::ErrorImpactParameter1, + hf_cand_par::CosThetaStar, + hf_cand_par::Ct); + +DECLARE_SOA_TABLE(StoredHfD0ParEs, "AOD", "HFD0PARE", //! Table with additional candidate properties used for selection (stored version) + collision::PosX, + collision::PosY, + collision::PosZ, + hf_cand::XSecondaryVertex, + hf_cand::YSecondaryVertex, + hf_cand::ZSecondaryVertex, + hf_cand::ErrorDecayLength, + hf_cand::ErrorDecayLengthXY, + hf_cand::KfTopolChi2OverNdf, + hf_cand_par::RSecondaryVertex, + hf_cand_par::PProng0, + hf_cand_par::PProng1, + hf_cand::PxProng0, + hf_cand::PyProng0, + hf_cand::PzProng0, + hf_cand::PxProng1, + hf_cand::PyProng1, + hf_cand::PzProng1, + hf_cand::ErrorImpactParameter0, + hf_cand::ErrorImpactParameter1, + hf_cand_par::CosThetaStar, + hf_cand_par::Ct, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfD0Sels, "AOD1", "HFD0SEL", //! Table with candidate selection flags + hf_cand_sel::CandidateSelFlag); + +DECLARE_SOA_TABLE(StoredHfD0Sels, "AOD", "HFD0SEL", //! Table with candidate selection flags (stored version) + hf_cand_sel::CandidateSelFlag, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfD0Ids, "AOD1", "HFD0ID", //! Table with global indices for candidates + hf_cand::CollisionId, + hf_track_index::Prong0Id, + hf_track_index::Prong1Id); + +DECLARE_SOA_TABLE(StoredHfD0Ids, "AOD", "HFD0ID", //! Table with global indices for candidates (stored version) + hf_cand::CollisionId, + hf_track_index::Prong0Id, + hf_track_index::Prong1Id, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfD0Mcs, "AOD1", "HFD0MC", //! Table with MC candidate info + hf_cand_mc::FlagMcMatchRec, + hf_cand_mc::OriginMcRec); + +DECLARE_SOA_TABLE(StoredHfD0Mcs, "AOD", "HFD0MC", //! Table with MC candidate info (stored version) + hf_cand_mc::FlagMcMatchRec, + hf_cand_mc::OriginMcRec, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfD0PBases, "AOD1", "HFD0PBASE", //! Table with MC particle info + o2::soa::Index<>, + hf_cand_base::Pt, + hf_cand_base::Eta, + hf_cand_base::Phi, + hf_cand_mc::FlagMcMatchGen, + hf_cand_mc::OriginMcGen, + hf_cand_base::Y); + +DECLARE_SOA_TABLE(StoredHfD0PBases, "AOD", "HFD0PBASE", //! Table with MC particle info (stored version) + o2::soa::Index<>, + hf_cand_base::Pt, + hf_cand_base::Eta, + hf_cand_base::Phi, + hf_cand_mc::FlagMcMatchGen, + hf_cand_mc::OriginMcGen, + hf_cand_base::Y, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfD0PIds, "AOD1", "HFD0PID", //! Table with global indices for MC particles + hf_cand_base::McCollisionId, + hf_cand_base::McParticleId); + +DECLARE_SOA_TABLE(StoredHfD0PIds, "AOD", "HFD0PID", //! Table with global indices for MC particles (stored version) + hf_cand_base::McCollisionId, + hf_cand_base::McParticleId, + soa::Marker<1>); +} // namespace o2::aod + +#endif // PWGHF_DATAMODEL_DERIVEDTABLES_H_ diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index 36653de5807..fe7ee5c6222 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -217,4 +217,9 @@ o2physics_add_dpl_workflow(tree-creator-xicc-to-p-k-pi-pi PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +# Derived-data creators +o2physics_add_dpl_workflow(derived-data-creator-d0-to-k-pi + SOURCES derivedDataCreatorD0ToKPi.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx new file mode 100644 index 00000000000..e1416f07ddd --- /dev/null +++ b/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx @@ -0,0 +1,403 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file derivedDataCreatorD0ToKPi.cxx +/// \brief Producer of derived tables of D0 candidates, collisions and MC particles +/// \note Based on treeCreatorD0ToKPi.cxx +/// +/// \author Vít Kučera , Inha University + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/RecoDecay.h" + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/DerivedTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +/// Writes the full information in an output TTree +struct HfDerivedDataCreatorD0ToKPi { + Produces rowCandidateBase; + Produces rowCandidatePar; + Produces rowCandidateParE; + Produces rowCandidateSel; + Produces rowCandidateId; + Produces rowCandidateMc; + Produces rowCollBase; + Produces rowCollId; + Produces rowParticleBase; + Produces rowParticleId; + + // Switches for filling tables + Configurable fillCandidateBase{"fillCandidateBase", true, "Fill candidate base properties"}; + Configurable fillCandidatePar{"fillCandidatePar", true, "Fill candidate parameters"}; + Configurable fillCandidateParE{"fillCandidateParE", true, "Fill candidate extended parameters"}; + Configurable fillCandidateSel{"fillCandidateSel", true, "Fill candidate selection flags"}; + Configurable fillCandidateId{"fillCandidateId", true, "Fill candidate indices"}; + Configurable fillCandidateMc{"fillCandidateMc", true, "Fill candidate MC info"}; + Configurable fillCollBase{"fillCollBase", true, "Fill collision base properties"}; + Configurable fillCollId{"fillCollId", true, "Fill collision indices"}; + Configurable fillParticleBase{"fillParticleBase", true, "Fill particle properties"}; + Configurable fillParticleId{"fillParticleId", true, "Fill particle indices"}; + // Parameters for production of training samples + Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + + HfHelper hfHelper; + SliceCache cache; + + using TracksWPid = soa::Join; + using SelectedCandidates = soa::Filtered>; + using SelectedCandidatesKf = soa::Filtered>; + using SelectedCandidatesMc = soa::Filtered>; + using SelectedCandidatesMcKf = soa::Filtered>; + using MatchedGenCandidatesMc = soa::Filtered>; + + Filter filterSelectCandidates = aod::hf_sel_candidate_d0::isSelD0 >= 1 || aod::hf_sel_candidate_d0::isSelD0bar >= 1; + Filter filterMcGenMatching = nabs(aod::hf_cand_2prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_2prong::DecayType::D0ToPiK)); + + Preslice candidatesPerCollision = aod::hf_cand::collisionId; + Preslice candidatesKfPerCollision = aod::hf_cand::collisionId; + Preslice candidatesMcPerCollision = aod::hf_cand::collisionId; + Preslice candidatesMcKfPerCollision = aod::hf_cand::collisionId; + + // trivial partitions for all candidates to allow "->sliceByCached" inside processCandidates + Partition candidatesAll = aod::hf_sel_candidate_d0::isSelD0 >= 0; + Partition candidatesKfAll = aod::hf_sel_candidate_d0::isSelD0 >= 0; + Partition candidatesMcAll = aod::hf_sel_candidate_d0::isSelD0 >= 0; + Partition candidatesMcKfAll = aod::hf_sel_candidate_d0::isSelD0 >= 0; + // partitions for signal and background + Partition candidatesMcSig = nabs(aod::hf_cand_2prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_2prong::DecayType::D0ToPiK)); + Partition candidatesMcBkg = nabs(aod::hf_cand_2prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_2prong::DecayType::D0ToPiK)); + Partition candidatesMcKfSig = nabs(aod::hf_cand_2prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_2prong::DecayType::D0ToPiK)); + Partition candidatesMcKfBkg = nabs(aod::hf_cand_2prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_2prong::DecayType::D0ToPiK)); + + void init(InitContext const&) + { + std::array doprocess{doprocessDataWithDCAFitterN, doprocessDataWithKFParticle, doprocessMcWithDCAFitterSig, doprocessMcWithDCAFitterBkg, doprocessMcWithDCAFitterAll, doprocessMcWithKFParticleSig, doprocessMcWithKFParticleBkg, doprocessMcWithKFParticleAll}; + if (std::accumulate(doprocess.begin(), doprocess.end(), 0) != 1) { + LOGP(fatal, "Only one process function can be enabled at a time."); + } + } + + template + void reserveTable(T& table, const Configurable& enabled, const uint64_t size) + { + if (enabled.value) { + table.reserve(size); + } + }; + + template + void fillTablesCollision(const T& collision, int isEventReject, int runNumber) + { + if (fillCollBase) { + rowCollBase( + collision.numContrib(), + isEventReject, + runNumber); + } + if (fillCollId) { + rowCollId( + collision.globalIndex()); + } + } + + template + auto fillTablesCandidate(const T& candidate, const U& prong0, const U& prong1, int candFlag, double invMass, double cosThetaStar, double topoChi2, + double ct, int8_t flagMc, int8_t origin) + { + if (fillCandidateBase) { + rowCandidateBase( + rowCollBase.lastIndex(), + candidate.pt(), + candidate.eta(), + candidate.phi(), + invMass); + } + if (fillCandidatePar) { + rowCandidatePar( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + prong0.tpcNSigmaPi(), + prong0.tpcNSigmaKa(), + prong0.tofNSigmaPi(), + prong0.tofNSigmaKa(), + prong0.tpcTofNSigmaPi(), + prong0.tpcTofNSigmaKa(), + prong1.tpcNSigmaPi(), + prong1.tpcNSigmaKa(), + prong1.tofNSigmaPi(), + prong1.tofNSigmaKa(), + prong1.tpcTofNSigmaPi(), + prong1.tpcTofNSigmaKa(), + candidate.cpa(), + candidate.cpaXY(), + candidate.maxNormalisedDeltaIP(), + candidate.impactParameterProduct()); + } + if (fillCandidateParE) { + rowCandidateParE( + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + topoChi2, + candidate.rSecondaryVertex(), + RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + cosThetaStar, + ct); + } + if (fillCandidateSel) { + rowCandidateSel( + BIT(candFlag)); + } + if (fillCandidateId) { + rowCandidateId( + candidate.collisionId(), + candidate.prong0Id(), + candidate.prong1Id()); + } + if (fillCandidateMc) { + rowCandidateMc( + flagMc, + origin); + } + } + + template + void fillTablesParticle(const T& particle, U mass) + { + if (fillParticleBase) { + rowParticleBase( + particle.pt(), + particle.eta(), + particle.phi(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + if (fillParticleId) { + rowParticleId( + particle.mcCollisionId(), + particle.globalIndex()); + } + } + + template + void processCandidates(aod::Collisions const& collisions, + Partition& candidates, + TracksWPid const&, + aod::BCs const&) + { + // Fill collision properties + auto sizeTableColl = collisions.size(); + reserveTable(rowCollBase, fillCollBase, sizeTableColl); + reserveTable(rowCollId, fillCollId, sizeTableColl); + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + auto sizeTableCand = candidatesThisColl.size(); + // skip collisions without HF candidates + if (sizeTableCand == 0) { + continue; + } + fillTablesCollision(collision, 0, collision.bc().runNumber()); + + // Fill candidate properties + reserveTable(rowCandidateBase, fillCandidateBase, sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (isMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } + int8_t flagMcRec, origin; + for (const auto& candidate : candidatesThisColl) { + if constexpr (isMc) { + flagMcRec = candidate.flagMcMatchRec(); + origin = candidate.originMcRec(); + if constexpr (onlyBkg) { + if (TESTBIT(std::abs(flagMcRec), aod::hf_cand_2prong::DecayType::D0ToPiK)) { + continue; + } + if (downSampleBkgFactor < 1.) { + float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; + } + } + } + if constexpr (onlySig) { + if (!TESTBIT(std::abs(flagMcRec), aod::hf_cand_2prong::DecayType::D0ToPiK)) { + continue; + } + } + } else { + flagMcRec = 0; + origin = 0; + } + auto prong0 = candidate.template prong0_as(); + auto prong1 = candidate.template prong1_as(); + double ctD = hfHelper.ctD0(candidate); + float massD0, massD0bar; + float topolChi2PerNdf = -999.; + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + massD0 = candidate.kfGeoMassD0(); + massD0bar = candidate.kfGeoMassD0bar(); + topolChi2PerNdf = candidate.kfTopolChi2OverNdf(); + } else { + massD0 = hfHelper.invMassD0ToPiK(candidate); + massD0bar = hfHelper.invMassD0barToKPi(candidate); + } + if (candidate.isSelD0()) { + fillTablesCandidate(candidate, prong0, prong1, 0, massD0, hfHelper.cosThetaStarD0(candidate), topolChi2PerNdf, ctD, flagMcRec, origin); + } + if (candidate.isSelD0bar()) { + fillTablesCandidate(candidate, prong0, prong1, 1, massD0bar, hfHelper.cosThetaStarD0bar(candidate), topolChi2PerNdf, ctD, flagMcRec, origin); + } + } + } + } + + template + void processMcParticles(ParticleType const& mcParticles) + { + // Fill MC particle properties + auto sizeTablePart = mcParticles.size(); + reserveTable(rowParticleBase, fillParticleBase, sizeTablePart); + reserveTable(rowParticleId, fillParticleId, sizeTablePart); + for (const auto& particle : mcParticles) { + if (!TESTBIT(std::abs(particle.flagMcMatchGen()), aod::hf_cand_2prong::DecayType::D0ToPiK)) { + continue; + } + fillTablesParticle(particle, o2::constants::physics::MassD0); + } + } + + void processDataWithDCAFitterN(aod::Collisions const& collisions, + SelectedCandidates const&, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesAll, tracks, bcs); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processDataWithDCAFitterN, "Process data with DCAFitterN", true); + + void processDataWithKFParticle(aod::Collisions const& collisions, + SelectedCandidatesKf const&, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesKfAll, tracks, bcs); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processDataWithKFParticle, "Process data with KFParticle", false); + + void processMcWithDCAFitterSig(aod::Collisions const& collisions, + SelectedCandidatesMc const&, + MatchedGenCandidatesMc const& mcParticles, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMcSig, tracks, bcs); + processMcParticles(mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processMcWithDCAFitterSig, "Process MC with DCAFitterN only for signals", false); + + void processMcWithDCAFitterBkg(aod::Collisions const& collisions, + SelectedCandidatesMc const&, + MatchedGenCandidatesMc const& mcParticles, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMcBkg, tracks, bcs); + processMcParticles(mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processMcWithDCAFitterBkg, "Process MC with DCAFitterN only for background", false); + + void processMcWithDCAFitterAll(aod::Collisions const& collisions, + SelectedCandidatesMc const&, + MatchedGenCandidatesMc const& mcParticles, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMcAll, tracks, bcs); + processMcParticles(mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processMcWithDCAFitterAll, "Process MC with DCAFitterN", false); + + void processMcWithKFParticleSig(aod::Collisions const& collisions, + SelectedCandidatesMcKf const&, + MatchedGenCandidatesMc const& mcParticles, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMcKfSig, tracks, bcs); + processMcParticles(mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processMcWithKFParticleSig, "Process MC with KFParticle only for signals", false); + + void processMcWithKFParticleBkg(aod::Collisions const& collisions, + SelectedCandidatesMcKf const&, + MatchedGenCandidatesMc const& mcParticles, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMcKfBkg, tracks, bcs); + processMcParticles(mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processMcWithKFParticleBkg, "Process MC with KFParticle only for background", false); + + void processMcWithKFParticleAll(aod::Collisions const& collisions, + SelectedCandidatesMcKf const&, + MatchedGenCandidatesMc const& mcParticles, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMcKfAll, tracks, bcs); + processMcParticles(mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorD0ToKPi, processMcWithKFParticleAll, "Process MC with KFParticle", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From ef5cb68dfeb33c975d76e605d2b1a30ca1c0a8cb Mon Sep 17 00:00:00 2001 From: Junlee Kim Date: Tue, 19 Dec 2023 17:25:13 +0900 Subject: [PATCH 085/156] [Event plane] fix bug (#4183) * fix bug * Please consider the following formatting changes --------- Co-authored-by: junleekim Co-authored-by: ALICE Action Bot --- Common/Tasks/qVectorsCorrection.cxx | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/Common/Tasks/qVectorsCorrection.cxx b/Common/Tasks/qVectorsCorrection.cxx index f63f260a350..751f4af552d 100644 --- a/Common/Tasks/qVectorsCorrection.cxx +++ b/Common/Tasks/qVectorsCorrection.cxx @@ -162,46 +162,46 @@ struct qVectorsCorrection { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histCent"), vec.cent()); if (vec.qvecAmp()[DetId] > 1e-8) { - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecUncor"), vec.qvecRe()[DetId], vec.qvecIm()[DetId]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRectr"), vec.qvecRe()[DetId + 1], vec.qvecIm()[DetId + 1]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecTwist"), vec.qvecRe()[DetId + 2], vec.qvecIm()[DetId + 2]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFinal"), vec.qvecRe()[DetId + 3], vec.qvecIm()[DetId + 3]); - - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlUncor"), helperEP.GetEventPlane(vec.qvecRe()[DetId], vec.qvecIm()[DetId], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRectr"), helperEP.GetEventPlane(vec.qvecRe()[DetId + 1], vec.qvecIm()[DetId + 1], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlTwist"), helperEP.GetEventPlane(vec.qvecRe()[DetId + 2], vec.qvecIm()[DetId + 2], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFinal"), helperEP.GetEventPlane(vec.qvecRe()[DetId + 3], vec.qvecIm()[DetId + 3], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecUncor"), vec.qvecRe()[DetId * 4], vec.qvecIm()[DetId * 4]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRectr"), vec.qvecRe()[DetId * 4 + 1], vec.qvecIm()[DetId * 4 + 1]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecTwist"), vec.qvecRe()[DetId * 4 + 2], vec.qvecIm()[DetId * 4 + 2]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFinal"), vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3]); + + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlUncor"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4], vec.qvecIm()[DetId * 4], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRectr"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 1], vec.qvecIm()[DetId * 4 + 1], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlTwist"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 2], vec.qvecIm()[DetId * 4 + 2], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFinal"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3], 2)); } if (vec.qvecAmp()[RefAId] > 1e-8) { - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAUncor"), vec.qvecRe()[RefAId], vec.qvecIm()[RefAId]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefARectr"), vec.qvecRe()[RefAId + 1], vec.qvecIm()[RefAId + 1]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefATwist"), vec.qvecRe()[RefAId + 2], vec.qvecIm()[RefAId + 2]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAFinal"), vec.qvecRe()[RefAId + 3], vec.qvecIm()[RefAId + 3]); - - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefAId], vec.qvecIm()[RefAId], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefARectr"), helperEP.GetEventPlane(vec.qvecRe()[RefAId + 1], vec.qvecIm()[RefAId + 1], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefATwist"), helperEP.GetEventPlane(vec.qvecRe()[RefAId + 2], vec.qvecIm()[RefAId + 2], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefAId + 3], vec.qvecIm()[RefAId + 3], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAUncor"), vec.qvecRe()[RefAId * 4], vec.qvecIm()[RefAId * 4]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefARectr"), vec.qvecRe()[RefAId * 4 + 1], vec.qvecIm()[RefAId * 4 + 1]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefATwist"), vec.qvecRe()[RefAId * 4 + 2], vec.qvecIm()[RefAId * 4 + 2]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAFinal"), vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3]); + + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4], vec.qvecIm()[RefAId * 4], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefARectr"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 1], vec.qvecIm()[RefAId * 4 + 1], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefATwist"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 2], vec.qvecIm()[RefAId * 4 + 2], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3], 2)); } if (vec.qvecAmp()[RefBId] > 1e-8) { - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBUncor"), vec.qvecRe()[RefBId], vec.qvecIm()[RefBId]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBRectr"), vec.qvecRe()[RefBId + 1], vec.qvecIm()[RefBId + 1]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBTwist"), vec.qvecRe()[RefBId + 2], vec.qvecIm()[RefBId + 2]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBFinal"), vec.qvecRe()[RefBId + 3], vec.qvecIm()[RefBId + 3]); - - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefBId], vec.qvecIm()[RefBId], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBRectr"), helperEP.GetEventPlane(vec.qvecRe()[RefBId + 1], vec.qvecIm()[RefBId + 1], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBTwist"), helperEP.GetEventPlane(vec.qvecRe()[RefBId + 2], vec.qvecIm()[RefBId + 2], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefBId + 3], vec.qvecIm()[RefBId + 3], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBUncor"), vec.qvecRe()[RefBId * 4], vec.qvecIm()[RefBId * 4]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBRectr"), vec.qvecRe()[RefBId * 4 + 1], vec.qvecIm()[RefBId * 4 + 1]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBTwist"), vec.qvecRe()[RefBId * 4 + 2], vec.qvecIm()[RefBId * 4 + 2]); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBFinal"), vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3]); + + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4], vec.qvecIm()[RefBId * 4], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBRectr"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 1], vec.qvecIm()[RefBId * 4 + 1], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBTwist"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 2], vec.qvecIm()[RefBId * 4 + 2], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3], 2)); } if (vec.qvecAmp()[DetId] > 1e-8 && vec.qvecAmp()[RefAId] > 1e-8 && vec.qvecAmp()[RefBId] > 1e-8) { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlResolution"), helperEP.GetResolution( - helperEP.GetEventPlane(vec.qvecRe()[RefAId + 3], vec.qvecIm()[RefAId + 3], 2), - helperEP.GetEventPlane(vec.qvecRe()[RefBId + 3], vec.qvecIm()[RefBId + 3], 2), - helperEP.GetEventPlane(vec.qvecRe()[DetId + 3], vec.qvecIm()[DetId + 3], 2), 2)); + helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3], 2), + helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3], 2), + helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3], 2), 2)); } } From 96dc5feb5195db13192c16c518750a77634d0cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Jacazio?= Date: Tue, 19 Dec 2023 09:25:46 +0100 Subject: [PATCH 086/156] Extend table helpers (#4166) --- Common/Core/TableHelper.cxx | 29 +++++++++++++++++++++++++---- Common/Core/TableHelper.h | 13 ++++++++++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Common/Core/TableHelper.cxx b/Common/Core/TableHelper.cxx index e8ecb1db9ee..aad65dc6c73 100644 --- a/Common/Core/TableHelper.cxx +++ b/Common/Core/TableHelper.cxx @@ -39,13 +39,13 @@ void printTablesInWorkflow(o2::framework::InitContext& initContext) /// @param table name of the table to check for bool isTableRequiredInWorkflow(o2::framework::InitContext& initContext, const std::string& table) { - LOG(info) << "Checking if table " << table << " is needed"; + LOG(debug) << "Checking if table " << table << " is needed"; bool tableNeeded = false; auto& workflows = initContext.services().get(); for (auto const& device : workflows.devices) { for (auto const& input : device.inputs) { if (input.matcher.binding == table) { - LOG(info) << "Table: " << input.matcher.binding << " is needed in device: " << device.name; + LOG(debug) << "Table: " << input.matcher.binding << " is needed in device: " << device.name; tableNeeded = true; } } @@ -53,6 +53,25 @@ bool isTableRequiredInWorkflow(o2::framework::InitContext& initContext, const st return tableNeeded; } +/// Function to enable or disable a configurable flag, depending on the fact that a table is needed or not +/// @param initContext initContext of the init function +/// @param table name of the table to check for +/// @param flag bool value of flag to set, if the given value is true it will be kept, disregarding the table usage in the workflow. +void enableFlagIfTableRequired(o2::framework::InitContext& initContext, const std::string& table, bool& flag) +{ + if (flag) { + LOG(info) << "Table enabled: " + table; + return; + } + if (isTableRequiredInWorkflow(initContext, table)) { + flag = true; + LOG(info) << "Auto-enabling table: " + table; + return; + } + flag = false; + LOG(info) << "Table disabled and not required: " + table; +} + /// Function to enable or disable a configurable flag, depending on the fact that a table is needed or not /// @param initContext initContext of the init function /// @param table name of the table to check for @@ -68,8 +87,10 @@ void enableFlagIfTableRequired(o2::framework::InitContext& initContext, const st if (flag < 0) { flag = 1; LOG(info) << "Auto-enabling table: " + table; - } else { - LOG(info) << "Table disabled: " + table; + return; } + LOG(info) << "Table disabled but required: " + table; } + flag = 0; + LOG(info) << "Table disabled and not required: " + table; } diff --git a/Common/Core/TableHelper.h b/Common/Core/TableHelper.h index 583c919dd4b..a5935c558f3 100644 --- a/Common/Core/TableHelper.h +++ b/Common/Core/TableHelper.h @@ -32,6 +32,12 @@ void printTablesInWorkflow(o2::framework::InitContext& initContext); /// @param table name of the table to check for bool isTableRequiredInWorkflow(o2::framework::InitContext& initContext, const std::string& table); +/// Function to enable or disable a configurable flag, depending on the fact that a table is needed or not +/// @param initContext initContext of the init function +/// @param table name of the table to check for +/// @param flag bool value of flag to set, if the given value is true it will be kept, disregarding the table usage in the workflow. +void enableFlagIfTableRequired(o2::framework::InitContext& initContext, const std::string& table, bool& flag); + /// Function to enable or disable a configurable flag, depending on the fact that a table is needed or not /// @param initContext initContext of the init function /// @param table name of the table to check for @@ -48,7 +54,12 @@ void enableFlagIfTableRequired(o2::framework::InitContext& initContext, const st enableFlagIfTableRequired(initContext, table, flag.value); } -/// Function to check for a specific configurable in the current workflow +/// Function to check for a specific configurable from another task in the current workflow and fetch its value. Useful for tasks that need to know the value of a configurable in another task. +/// @param initContext initContext of the init function +/// @param taskName name of the task to check for +/// @param optName name of the option to check for +/// @param value value of the option to set +/// @param verbose if true, print debug messages template bool getTaskOptionValue(o2::framework::InitContext& initContext, const std::string& taskName, const std::string& optName, ValueType& value, const bool verbose = true) { From c9bd5aeb517f819d66728b7a39856fe6505a1a6b Mon Sep 17 00:00:00 2001 From: rbailhac Date: Tue, 19 Dec 2023 10:30:05 +0100 Subject: [PATCH 087/156] NoTwoProngFitter (#4197) --- PWGDQ/Tasks/tableReader.cxx | 98 ++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 8790cd66878..a486cd0324c 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -822,7 +822,7 @@ struct AnalysisSameEventPairing { } } - if (context.mOptions.get("processDecayToEESkimmed") || context.mOptions.get("processDecayToEESkimmedWithCov") || context.mOptions.get("processDecayToEEVertexingSkimmed") || context.mOptions.get("processVnDecayToEESkimmed") || context.mOptions.get("processDecayToEEPrefilterSkimmed") || context.mOptions.get("processDecayToEESkimmedWithColl") || context.mOptions.get("processDecayToPiPiSkimmed") || context.mOptions.get("processAllSkimmed")) { + if (context.mOptions.get("processDecayToEESkimmed") || context.mOptions.get("processDecayToEESkimmedNoTwoProngFitter") || context.mOptions.get("processDecayToEESkimmedWithCov") || context.mOptions.get("processDecayToEESkimmedWithCovNoTwoProngFitter") || context.mOptions.get("processDecayToEEVertexingSkimmed") || context.mOptions.get("processVnDecayToEESkimmed") || context.mOptions.get("processDecayToEEPrefilterSkimmed") || context.mOptions.get("processDecayToEEPrefilterSkimmedNoTwoProngFitter") || context.mOptions.get("processDecayToEESkimmedWithColl") || context.mOptions.get("processDecayToEESkimmedWithCollNoTwoProngFitter") || context.mOptions.get("processDecayToPiPiSkimmed") || context.mOptions.get("processAllSkimmed")) { TString cutNames = fConfigTrackCuts.value; if (!cutNames.IsNull()) { // if track cuts std::unique_ptr objArray(cutNames.Tokenize(",")); @@ -930,7 +930,7 @@ struct AnalysisSameEventPairing { } // Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon) - template + template void runSameEventPairing(TEvent const& event, TTracks1 const& tracks1, TTracks2 const& tracks2) { if (fCurrentRun != event.runNumber()) { @@ -941,18 +941,26 @@ struct AnalysisSameEventPairing { } else { LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", event.timestamp()); } - if (fConfigUseKFVertexing.value) { - VarManager::SetupTwoProngKFParticle(mMagField); + if constexpr (TTwoProngFitter == true) { + if (fConfigUseKFVertexing.value) { + VarManager::SetupTwoProngKFParticle(mMagField); + } else { + VarManager::SetupTwoProngDCAFitter(mMagField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables + VarManager::SetupTwoProngFwdDCAFitter(mMagField, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); + } } else { - VarManager::SetupTwoProngDCAFitter(mMagField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables - VarManager::SetupTwoProngFwdDCAFitter(mMagField, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); + VarManager::SetupTwoProngDCAFitter(mMagField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations } } else { - if (fConfigUseKFVertexing.value) { - VarManager::SetupTwoProngKFParticle(fConfigMagField.value); + if constexpr (TTwoProngFitter == true) { + if (fConfigUseKFVertexing.value) { + VarManager::SetupTwoProngKFParticle(fConfigMagField.value); + } else { + VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables + VarManager::SetupTwoProngFwdDCAFitter(fConfigMagField.value, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); + } } else { - VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // TODO: get these parameters from Configurables - VarManager::SetupTwoProngFwdDCAFitter(fConfigMagField.value, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); + VarManager::SetupTwoProngDCAFitter(mMagField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations } } fCurrentRun = event.runNumber(); @@ -998,7 +1006,9 @@ struct AnalysisSameEventPairing { // TODO: FillPair functions need to provide a template argument to discriminate between cases when cov matrix is available or not VarManager::FillPair(t1, t2); if constexpr ((TPairType == pairTypeEE) || (TPairType == pairTypeMuMu)) { // call this just for ee or mumu pairs - VarManager::FillPairVertexing(event, t1, t2, fPropToPCA); + if constexpr (TTwoProngFitter == true) { + VarManager::FillPairVertexing(event, t1, t2, fPropToPCA); + } if constexpr (eventHasQvector) { VarManager::FillPairVn(t1, t2); } @@ -1013,10 +1023,10 @@ struct AnalysisSameEventPairing { } constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); - if constexpr ((TPairType == pairTypeEE) && trackHasCov) { + if constexpr ((TPairType == pairTypeEE) && trackHasCov && (TTwoProngFitter == true)) { dileptonExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauz], VarManager::fgValues[VarManager::kVertexingLz], VarManager::fgValues[VarManager::kVertexingLxy]); } - if constexpr (TPairType == pairTypeMuMu) { + if constexpr ((TPairType == pairTypeMuMu) && (TTwoProngFitter == true)) { // LOGP(info, "mu1 collId = {}, mu2 collId = {}", t1.collisionId(), t2.collisionId()); dileptonExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauz], VarManager::fgValues[VarManager::kVertexingLz], VarManager::fgValues[VarManager::kVertexingLxy]); if (fConfigFlatTables.value) { @@ -1088,93 +1098,121 @@ struct AnalysisSameEventPairing { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); + } + void processDecayToEESkimmedNoTwoProngFitter(soa::Filtered::iterator const& event, soa::Filtered const& tracks) + { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + runSameEventPairing(event, tracks, tracks); } void processDecayToEESkimmedWithCov(soa::Filtered::iterator const& event, soa::Filtered const& tracks) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); + } + void processDecayToEESkimmedWithCovNoTwoProngFitter(soa::Filtered::iterator const& event, soa::Filtered const& tracks) + { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + runSameEventPairing(event, tracks, tracks); } void processDecayToEEVertexingSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& tracks) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); } void processDecayToEEPrefilterSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& tracks) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); + } + void processDecayToEEPrefilterSkimmedNoTwoProngFitter(soa::Filtered::iterator const& event, soa::Filtered const& tracks) + { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + runSameEventPairing(event, tracks, tracks); } void processDecayToEESkimmedWithColl(soa::Filtered::iterator const& event, soa::Filtered const& tracks) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); + } + void processDecayToEESkimmedWithCollNoTwoProngFitter(soa::Filtered::iterator const& event, soa::Filtered const& tracks) + { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + runSameEventPairing(event, tracks, tracks); } void processDecayToMuMuSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& muons) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, muons, muons); + runSameEventPairing(event, muons, muons); } void processDecayToMuMuVertexingSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& muons) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, muons, muons); + runSameEventPairing(event, muons, muons); } void processDecayToMuMuSkimmedWithColl(soa::Filtered::iterator const& event, soa::Filtered const& muons) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, muons, muons); + runSameEventPairing(event, muons, muons); } void processVnDecayToEESkimmed(soa::Filtered::iterator const& event, soa::Filtered const& tracks) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); } void processVnDecayToMuMuSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& muons) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, muons, muons); + runSameEventPairing(event, muons, muons); } void processElectronMuonSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& tracks, soa::Filtered const& muons) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, muons); + runSameEventPairing(event, tracks, muons); } void processDecayToPiPiSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& tracks) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, tracks, tracks); } void processAllSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& tracks, soa::Filtered const& muons) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillEvent(event, VarManager::fgValues); - runSameEventPairing(event, tracks, tracks); - runSameEventPairing(event, muons, muons); - runSameEventPairing(event, tracks, muons); + runSameEventPairing(event, tracks, tracks); + runSameEventPairing(event, muons, muons); + runSameEventPairing(event, tracks, muons); } // TODO: dummy function for the case when no process function is enabled void processDummy(MyEvents&) @@ -1183,10 +1221,14 @@ struct AnalysisSameEventPairing { } PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmed, "Run electron-electron pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedNoTwoProngFitter, "Run electron-electron pairing, with skimmed tracks but no two prong fitter", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithCov, "Run electron-electron pairing, with skimmed covariant tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithCovNoTwoProngFitter, "Run electron-electron pairing, with skimmed covariant tracks but no two prong fitter", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEEVertexingSkimmed, "Run electron-electron pairing and vertexing, with skimmed electrons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEEPrefilterSkimmed, "Run electron-electron pairing, with skimmed tracks and prefilter from AnalysisPrefilterSelection", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEEPrefilterSkimmedNoTwoProngFitter, "Run electron-electron pairing, with skimmed tracks and prefilter from AnalysisPrefilterSelection but no two prong fitter", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithColl, "Run electron-electron pairing, with skimmed tracks and with collision information", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithCollNoTwoProngFitter, "Run electron-electron pairing, with skimmed tracks and with collision information but no two prong fitter", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmed, "Run muon-muon pairing, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuVertexingSkimmed, "Run muon-muon pairing and vertexing, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmedWithColl, "Run muon-muon pairing keeping the info of AO2D collision, with skimmed muons", false); From fce65a1fa5f8db1e3a6ecaf0a6e165fb20053180 Mon Sep 17 00:00:00 2001 From: Nicolas Strangmann <77485327+nstrangm@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:58:16 +0100 Subject: [PATCH 088/156] PWGJE+EM: Add EMCal ambiguous collision table and include in QC task (#4180) * PWGEM/PhotonMeson: Update EMCalQCTask - Introduce configurable axis for invmass-pT histograms - Change required trigger from INT7 to kTVXinEMC - Introduce option to differentiate between gamma-gamma pairs from EMCal and DCal * PWGJE+EM: Add EMCal ambiguous collision option and include in QC task - Add table EMCALMatchedCollisions which for every collision contains a bolean stating, whether multiple collisions were found in the BC - That table is filled in the emcalCorrectionTask for every collision to make it joinable with the collision table - emcalPi0QC task reads this table to enable correct event normalization - Bug fix in emcalPi0QC task NCell cut - Combined event histograms in emcalPi0QC task * PWGJE: Fix clang issues * PWGJE: Fix clang idndef issues --- PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx | 30 ++++++++++------ PWGJE/DataModel/EMCALMatchedCollisions.h | 40 +++++++++++++++++++++ PWGJE/TableProducer/emcalCorrectionTask.cxx | 20 +++++++++-- 3 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 PWGJE/DataModel/EMCALMatchedCollisions.h diff --git a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx index a4e4492d9fe..9c7d6209913 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx @@ -29,6 +29,7 @@ #include "EMCALBase/Geometry.h" #include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/EMCALMatchedCollisions.h" #include "DataFormatsEMCAL/Cell.h" #include "DataFormatsEMCAL/Constants.h" #include "DataFormatsEMCAL/AnalysisCluster.h" @@ -179,10 +180,12 @@ struct Pi0QCTask { const o2Axis bcAxis{3501, -0.5, 3500.5}; const o2Axis energyAxis{makeClusterBinning(), "#it{E} (GeV)"}; - // event properties - mHistManager.add("eventsAll", "Number of events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); - mHistManager.add("eventsEMCTrigg", "Number of EMC triggered events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); - mHistManager.add("eventsSelected", "Number of events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); + mHistManager.add("events", "events;;#it{count}", o2HistType::kTH1F, {{4, 0.5, 4.5}}); + auto heventType = mHistManager.get(HIST("events")); + heventType->GetXaxis()->SetBinLabel(1, "All events"); + heventType->GetXaxis()->SetBinLabel(2, "One collision in BC"); + heventType->GetXaxis()->SetBinLabel(3, "Triggered"); + heventType->GetXaxis()->SetBinLabel(4, "Selected"); mHistManager.add("eventBCAll", "Bunch crossing ID of event (all events)", o2HistType::kTH1F, {bcAxis}); mHistManager.add("eventBCSelected", "Bunch crossing ID of event (selected events)", o2HistType::kTH1F, {bcAxis}); mHistManager.add("eventVertexZAll", "z-vertex of event (all events)", o2HistType::kTH1F, {{200, -20, 20}}); @@ -239,11 +242,17 @@ struct Pi0QCTask { } /// \brief Process EMCAL clusters that are matched to a collisions - void processCollisions(o2::soa::Join::iterator const& collision, selectedClusters const& clusters) + void processCollisions(o2::soa::Join::iterator const& collision, selectedClusters const& clusters) { - // for(const auto & collision : theCollisions){ - mHistManager.fill(HIST("eventsAll"), 1); + mHistManager.fill(HIST("events"), 1); // Fill "All events" bin of event histogram LOG(debug) << "processCollisions"; + + if (collision.ambiguous()) { // Skip ambiguous collisions (those that are in BCs including multiple collisions) + LOG(debug) << "Event not selected becaus there are multiple collisions in this BC, skipping"; + return; + } + mHistManager.fill(HIST("events"), 2); // Fill "One collision in BC" bin of event histogram + // do event selection if mDoEventSel is specified // currently the event selection is hard coded to kTVXinEMC // but other selections are possible that are defined in TriggerAliases.h @@ -251,12 +260,13 @@ struct Pi0QCTask { LOG(debug) << "Event not selected becaus it is not kTVXinEMC, skipping"; return; } + mHistManager.fill(HIST("events"), 3); // Fill "Triggered" bin of event histogram mHistManager.fill(HIST("eventVertexZAll"), collision.posZ()); if (mVertexCut > 0 && std::abs(collision.posZ()) > mVertexCut) { LOG(debug) << "Event not selected because of z-vertex cut z= " << collision.posZ() << " > " << mVertexCut << " cm, skipping"; return; } - mHistManager.fill(HIST("eventsSelected"), 1); + mHistManager.fill(HIST("events"), 4); // Fill "Selected" bin of event histogram mHistManager.fill(HIST("eventVertexZSelected"), collision.posZ()); ProcessClusters(clusters); @@ -381,7 +391,7 @@ struct Pi0QCTask { LOG(debug) << "Cluster rejected because of energy cut"; return true; } - if (cluster.nCells() <= mMinNCellsCut) { + if (cluster.nCells() < mMinNCellsCut) { LOG(debug) << "Cluster rejected because of nCells cut"; return true; } @@ -401,8 +411,6 @@ struct Pi0QCTask { { LOG(debug) << "ProcessMesons " << mPhotons.size(); - mHistManager.fill(HIST("eventsEMCTrigg"), 1); - // if less then 2 clusters are found, skip event if (mPhotons.size() < 2) return; diff --git a/PWGJE/DataModel/EMCALMatchedCollisions.h b/PWGJE/DataModel/EMCALMatchedCollisions.h new file mode 100644 index 00000000000..6fe721ccdfc --- /dev/null +++ b/PWGJE/DataModel/EMCALMatchedCollisions.h @@ -0,0 +1,40 @@ +// Copyright 2019-2023 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \brief Table definitions for defining whether a collision is matched to a buch crossing including either one or multiple collisions +/// \file EMCALMatchedCollisions.h +/// \author Nicolas Strangmann +/// \since 2023-12-16 + +#ifndef PWGJE_DATAMODEL_EMCALMATCHEDCOLLISIONS_H_ +#define PWGJE_DATAMODEL_EMCALMATCHEDCOLLISIONS_H_ + +#include +#include "Framework/AnalysisDataModel.h" +#include "EMCALClusterDefinition.h" + +namespace o2::aod +{ +namespace emcalcollisionmatch +{ +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! collisionID used as index for matched collisions +DECLARE_SOA_COLUMN(Ambiguous, ambiguous, bool); //! boolean stating whether the collision is ambiguous (in a BC with multiple collisions) +} // namespace emcalcollisionmatch + +DECLARE_SOA_TABLE(EMCALMatchedCollisions, "AOD", "EMCALMCS", //! + o2::soa::Index<>, emcalcollisionmatch::CollisionId, emcalcollisionmatch::Ambiguous); // + +using EMCALMatchedCollision = EMCALMatchedCollisions::iterator; + +} // namespace o2::aod + +#endif // PWGJE_DATAMODEL_EMCALMATCHEDCOLLISIONS_H_ diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index 07b1d189fdf..6dfa6020870 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -29,6 +29,7 @@ #include "DetectorsBase/GeometryManager.h" #include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/EMCALMatchedCollisions.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -58,6 +59,7 @@ struct EmcalCorrectionTask { Produces clustercells; // cells belonging to given cluster Produces clustercellsambiguous; Produces matchedTracks; + Produces emcalcollisionmatch; // Preslices Preslice perCollision = o2::aod::track::collisionId; @@ -218,6 +220,7 @@ struct EmcalCorrectionTask { int nBCsProcessed = 0; int nCellsProcessed = 0; + std::unordered_map numberCollsInBC; // Number of collisions mapped to the global BC index of all BCs for (auto bc : bcs) { LOG(debug) << "Next BC"; // Convert aod::Calo to o2::emcal::Cell which can be used with the clusterizer. @@ -227,6 +230,8 @@ struct EmcalCorrectionTask { auto collisionsInFoundBC = collisions.sliceBy(collisionsPerFoundBC, bc.globalIndex()); auto cellsInBC = cells.sliceBy(cellsPerFoundBC, bc.globalIndex()); + numberCollsInBC.insert(std::pair(bc.globalIndex(), collisionsInFoundBC.size())); + if (!cellsInBC.size()) { LOG(debug) << "No cells found for BC"; countBC(collisionsInFoundBC.size(), false); @@ -302,6 +307,18 @@ struct EmcalCorrectionTask { LOG(debug) << "Done with process BC."; nBCsProcessed++; } // end of bc loop + + // Loop through all collisions and fill emcalcollisionmatch with a boolean stating, whether the collision was ambiguous (not the only collision in its BC) + for (const auto& collision : collisions) { + auto globalbcid = collision.foundBC_as().globalIndex(); + auto found = numberCollsInBC.find(globalbcid); + if (found != numberCollsInBC.end()) { + emcalcollisionmatch(collision.globalIndex(), found->second != 1); + } else { + LOG(warning) << "BC not found in map of number of collisions."; + } + } // end of collision loop + LOG(detail) << "Processed " << nBCsProcessed << " BCs with " << nCellsProcessed << " cells"; } PROCESS_SWITCH(EmcalCorrectionTask, processFull, "run full analysis", true); @@ -561,8 +578,7 @@ struct EmcalCorrectionTask { mHistManager.fill(HIST("hClusterE"), cluster.E()); mHistManager.fill(HIST("hClusterEtaPhi"), pos.Eta(), TVector2::Phi_0_2pi(pos.Phi())); if (IndexMapPair && trackGlobalIndex) { - for (unsigned int iTrack = 0; - iTrack < std::get<0>(*IndexMapPair)[iCluster].size(); iTrack++) { + for (unsigned int iTrack = 0; iTrack < std::get<0>(*IndexMapPair)[iCluster].size(); iTrack++) { if (std::get<0>(*IndexMapPair)[iCluster][iTrack] >= 0) { LOG(debug) << "Found track " << (*trackGlobalIndex)[std::get<0>(*IndexMapPair)[iCluster][iTrack]] << " in cluster " << cluster.getID(); matchedTracks(clusters.lastIndex(), (*trackGlobalIndex)[std::get<0>(*IndexMapPair)[iCluster][iTrack]]); From 3827d2892c752bf5ac72e0d9aa078d6dcd4d95bc Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Tue, 19 Dec 2023 21:22:03 +0900 Subject: [PATCH 089/156] PWGEM/PhotonMeson: update material budget study with dalitz ee (#4203) --- PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx | 34 ++-- PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx | 160 ++++++++----------- PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx | 131 +++++++-------- 3 files changed, 133 insertions(+), 192 deletions(-) diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx index 9fb85b461a1..938f88ce7af 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx @@ -326,15 +326,6 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* } if (TString(histClass) == "material_budget_study") { - const int nrxy = 102; - double rxy[nrxy] = {0.f}; - for (int i = 0; i < 90; i++) { - rxy[i] = 1.0 * i; - } - for (int i = 90; i < nrxy; i++) { - rxy[i] = 10.0 * (i - 90) + 90.0; - } - const int npt = 71; double pt[npt] = {0.f}; for (int i = 0; i < 10; i++) { @@ -348,33 +339,28 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* } if (TString(subGroup) == "V0") { const int ndim = 4; // pt, r, phi, eta - const int nbins[ndim] = {npt - 1, nrxy - 1, 72, 40}; + const int nbins[ndim] = {npt - 1, 90, 72, 40}; const double xmin[ndim] = {0.0, 0.0, 0.0, -2.0}; - const double xmax[ndim] = {10.0, 200.0, TMath::TwoPi(), +2.0}; + const double xmax[ndim] = {10.0, 90.0, TMath::TwoPi(), +2.0}; THnSparseF* hs_conv_point = new THnSparseF("hs_conv_point", "hs_conv_point;p_{T,#gamma} (GeV/c);R_{xy} (cm);#varphi (rad.);#eta;", ndim, nbins, xmin, xmax); hs_conv_point->SetBinEdges(0, pt); - hs_conv_point->SetBinEdges(1, rxy); hs_conv_point->Sumw2(); list->Add(hs_conv_point); } else if (TString(subGroup) == "Pair") { - const int ndim = 9; // mgg, pT1, rxy1, eta1, phi1, pT2, rxy2, eta2, phi2 - const int nbins[ndim] = {200, npt - 1, nrxy - 1, 72, 40, npt - 1, nrxy - 1, 72, 40}; - const double xmin[ndim] = {0.0, 0.0, 0, 0, -2, 0.0, 0, 0, -2}; - const double xmax[ndim] = {0.4, 10.0, 200, TMath::TwoPi(), +2, 10.0, 200, TMath::TwoPi(), +2}; + const int ndim = 6; // mgg, pT1, pT2, rxy2, eta2, phi2 + const int nbins[ndim] = {200, npt - 1, npt - 1, 90, 72, 40}; + const double xmin[ndim] = {0.0, 0.0, 0.0, 0, 0, -2}; + const double xmax[ndim] = {0.4, 10.0, 10.0, 90.0, TMath::TwoPi(), +2}; - THnSparseF* hs_conv_point_same = new THnSparseF("hs_conv_point_same", "hs_conv_point;m_{#gamma#gamma} (GeV/c^{2});p_{T,#gamma}^{tag} (GeV/c);R_{xy}^{tag} (cm);#varphi^{tag} (rad.);#eta^{tag};p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); + THnSparseF* hs_conv_point_same = new THnSparseF("hs_conv_point_same", "hs_conv_point;m_{ee#gamma} (GeV/c^{2});p_{T,ee}^{tag} (GeV/c);p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); hs_conv_point_same->SetBinEdges(1, pt); - hs_conv_point_same->SetBinEdges(2, rxy); - hs_conv_point_same->SetBinEdges(5, pt); - hs_conv_point_same->SetBinEdges(6, rxy); + hs_conv_point_same->SetBinEdges(2, pt); hs_conv_point_same->Sumw2(); list->Add(hs_conv_point_same); - THnSparseF* hs_conv_point_mix = new THnSparseF("hs_conv_point_mix", "hs_conv_point;m_{#gamma#gamma} (GeV/c^{2});p_{T,#gamma}^{tag} (GeV/c);R_{xy}^{tag} (cm);#varphi^{tag} (rad.);#eta^{tag};p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); + THnSparseF* hs_conv_point_mix = new THnSparseF("hs_conv_point_mix", "hs_conv_point;m_{ee#gamma} (GeV/c^{2});p_{T,ee}^{tag} (GeV/c);p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); hs_conv_point_mix->SetBinEdges(1, pt); - hs_conv_point_mix->SetBinEdges(2, rxy); - hs_conv_point_mix->SetBinEdges(5, pt); - hs_conv_point_mix->SetBinEdges(6, rxy); + hs_conv_point_mix->SetBinEdges(2, pt); hs_conv_point_mix->Sumw2(); list->Add(hs_conv_point_mix); } // end of pair diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx index 0d1cf34a0c4..cdf1c1bd852 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx @@ -32,6 +32,7 @@ #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" #include "PWGEM/PhotonMeson/Utils/PairUtilities.h" #include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/Core/DalitzEECut.h" #include "PWGEM/PhotonMeson/Core/PairCut.h" #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" @@ -43,7 +44,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; @@ -52,14 +53,17 @@ using MyV0Photon = MyV0Photons::iterator; using MyDalitzEEs = soa::Join; using MyDalitzEE = MyDalitzEEs::iterator; +using MyPrimaryElectrons = soa::Join; +using MyPrimaryElectron = MyPrimaryElectrons::iterator; + struct MaterialBudget { Configurable CentMin{"CentMin", -1, "min. centrality"}; Configurable CentMax{"CentMax", 999, "max. centrality"}; Configurable CentEstimator{"CentEstimator", "FT0M", "centrality estimator"}; - Configurable fConfigTagPCMCuts{"cfgTagPCMCuts", "qc_ITSTPC", "Comma separated list of V0 photon cuts for tag"}; - Configurable fConfigProbePCMCuts{"cfgProbePCMCuts", "qc_ITSTPC,qc_TPConly,qc_ITSonly", "Comma separated list of V0 photon cuts for probe"}; + Configurable fConfigTagCuts{"cfgTagCuts", "mee_0_120_tpconly_lowB", "Comma separated list of DalitzEE cuts for tag"}; + Configurable fConfigProbeCuts{"cfgProbeCuts", "qc,wwire_ib", "Comma separated list of V0 photon cuts for probe"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; Configurable fDoMixing{"DoMixing", false, "do event mixing"}; @@ -68,19 +72,19 @@ struct MaterialBudget { OutputObj fOutputPair{"Pair"}; // 2-photon pair THashList* fMainList = new THashList(); - std::vector fTagPCMCuts; - std::vector fProbePCMCuts; + std::vector fTagCuts; + std::vector fProbeCuts; std::vector fPairCuts; std::vector fPairNames; void init(InitContext& context) { if (context.mOptions.get("processMB")) { - fPairNames.push_back("PCMPCM"); + fPairNames.push_back("PCMDalitzEE"); } - DefineTagPCMCuts(); - DefineProbePCMCuts(); + DefineTagCuts(); + DefineProbeCuts(); DefinePairCuts(); addhistograms(); @@ -97,10 +101,6 @@ struct MaterialBudget { std::string cutname1 = cut1.GetName(); std::string cutname2 = cut2.GetName(); - // if (cutname1 == cutname2) { - // continue; - // } - THashList* list_pair_subsys = reinterpret_cast(list_pair->FindObject(pairname.data())); std::string photon_cut_name = cutname1 + "_" + cutname2; o2::aod::emphotonhistograms::AddHistClass(list_pair_subsys, photon_cut_name.data()); @@ -116,7 +116,7 @@ struct MaterialBudget { } // end of cut1 loop } - static constexpr std::string_view pairnames[6] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PHOSEMC"}; + static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; void addhistograms() { fMainList->SetOwner(true); @@ -133,7 +133,7 @@ struct MaterialBudget { THashList* list_v0 = reinterpret_cast(fMainList->FindObject("V0")); // for V0s - for (const auto& cut : fProbePCMCuts) { + for (const auto& cut : fProbeCuts) { const char* cutname = cut.GetName(); THashList* list_v0_cut = o2::aod::emphotonhistograms::AddHistClass(list_v0, cutname); o2::aod::emphotonhistograms::DefineHistograms(list_v0_cut, "material_budget_study", "V0"); @@ -148,39 +148,39 @@ struct MaterialBudget { o2::aod::emphotonhistograms::AddHistClass(list_pair, pairname.data()); - if (pairname == "PCMPCM") { - add_pair_histograms(list_pair, pairname, fTagPCMCuts, fProbePCMCuts, fPairCuts); + if (pairname == "PCMDalitzEE") { + add_pair_histograms(list_pair, pairname, fTagCuts, fProbeCuts, fPairCuts); } } // end of pair name loop } - void DefineTagPCMCuts() + void DefineTagCuts() { - TString cutNamesStr = fConfigTagPCMCuts.value; + TString cutNamesStr = fConfigTagCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { const char* cutname = objArray->At(icut)->GetName(); LOGF(info, "add cut : %s", cutname); - fTagPCMCuts.push_back(*pcmcuts::GetCut(cutname)); + fTagCuts.push_back(*dalitzeecuts::GetCut(cutname)); } } - LOGF(info, "Number of Tag PCM cuts = %d", fTagPCMCuts.size()); + LOGF(info, "Number of Tag cuts = %d", fTagCuts.size()); } - void DefineProbePCMCuts() + void DefineProbeCuts() { - TString cutNamesStr = fConfigProbePCMCuts.value; + TString cutNamesStr = fConfigProbeCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { const char* cutname = objArray->At(icut)->GetName(); LOGF(info, "add cut : %s", cutname); - fProbePCMCuts.push_back(*pcmcuts::GetCut(cutname)); + fProbeCuts.push_back(*pcmcuts::GetCut(cutname)); } } - LOGF(info, "Number of Probe PCM cuts = %d", fProbePCMCuts.size()); + LOGF(info, "Number of Probe cuts = %d", fProbeCuts.size()); } void DefinePairCuts() @@ -198,13 +198,12 @@ struct MaterialBudget { } Preslice perCollision_pcm = aod::v0photonkf::emreducedeventId; + Preslice perCollision_ee = aod::dalitzee::emreducedeventId; template bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) { - // bool is_selected_pair = false; - // return is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); - return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); + return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } template @@ -226,15 +225,14 @@ struct MaterialBudget { auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { for (auto& photon : photons_coll) { - if (!cut.template IsSelected(photon)) { continue; } - float phi_cp = atan2(photon.recalculatedVtxY(), photon.recalculatedVtxX()); - float eta_cp = std::atanh(photon.recalculatedVtxZ() / sqrt(pow(photon.recalculatedVtxX(), 2) + pow(photon.recalculatedVtxY(), 2) + pow(photon.recalculatedVtxZ(), 2))); + float phi_cp = atan2(photon.vy(), photon.vx()); + float eta_cp = std::atanh(photon.vz() / sqrt(pow(photon.vx(), 2) + pow(photon.vy(), 2) + pow(photon.vz(), 2))); value[0] = photon.pt(); - value[1] = photon.recalculatedVtxR(); + value[1] = photon.v0radius(); value[2] = phi_cp > 0 ? phi_cp : phi_cp + TMath::TwoPi(); value[3] = eta_cp; reinterpret_cast(list_v0->FindObject(cut.GetName())->FindObject("hs_conv_point"))->Fill(value); @@ -245,8 +243,8 @@ struct MaterialBudget { } // end of collision loop } - template - void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs) + template + void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) { THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); @@ -275,47 +273,40 @@ struct MaterialBudget { auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); - double value[9] = {0.f}; - float phi_cp1 = 0.f, eta_cp1 = 0.f; + double value[6] = {0.f}; float phi_cp2 = 0.f, eta_cp2 = 0.f; for (auto& cut1 : cuts1) { for (auto& cut2 : cuts2) { - // if (std::string(cut1.GetName()) == std::string(cut2.GetName())) { - // continue; - // } for (auto& g1 : photons1_coll) { for (auto& g2 : photons2_coll) { - if (g1.globalIndex() == g2.globalIndex()) { - continue; - } if (!IsSelectedPair(g1, g2, cut1, cut2)) { continue; } for (auto& paircut : paircuts) { - if (!paircut.IsSelected(g1, g2)) { continue; } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // tag - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe + auto pos1 = g1.template posTrack_as(); + auto ele1 = g1.template negTrack_as(); + auto pos2 = g2.template posTrack_as(); + auto ele2 = g2.template negTrack_as(); + if (pos1.trackId() == pos2.trackId() || ele1.trackId() == ele2.trackId()) { + continue; + } + + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), g1.mass()); // tag + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - phi_cp1 = atan2(g1.recalculatedVtxY(), g1.recalculatedVtxX()); - eta_cp1 = std::atanh(g1.recalculatedVtxZ() / sqrt(pow(g1.recalculatedVtxX(), 2) + pow(g1.recalculatedVtxY(), 2) + pow(g1.recalculatedVtxZ(), 2))); - phi_cp2 = atan2(g2.recalculatedVtxY(), g2.recalculatedVtxX()); - eta_cp2 = std::atanh(g2.recalculatedVtxZ() / sqrt(pow(g2.recalculatedVtxX(), 2) + pow(g2.recalculatedVtxY(), 2) + pow(g2.recalculatedVtxZ(), 2))); + phi_cp2 = atan2(g2.vy(), g2.vx()); + eta_cp2 = std::atanh(g2.vz() / sqrt(pow(g2.vx(), 2) + pow(g2.vy(), 2) + pow(g2.vz(), 2))); value[0] = v12.M(); value[1] = g1.pt(); - value[2] = g1.recalculatedVtxR(); - value[3] = phi_cp1 > 0.f ? phi_cp1 : phi_cp1 + TMath::TwoPi(); - value[4] = eta_cp1; - value[5] = g2.pt(); - value[6] = g2.recalculatedVtxR(); - value[7] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); - value[8] = eta_cp2; - + value[2] = g2.pt(); + value[3] = g2.v0radius(); + value[4] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); + value[5] = eta_cp2; reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); - } // end of pair cut loop } // end of g2 loop } // end of g1 loop @@ -324,14 +315,14 @@ struct MaterialBudget { } // end of collision loop } - Configurable ndepth{"ndepth", 5, "depth for event mixing"}; + Configurable ndepth{"ndepth", 10, "depth for event mixing"}; 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 ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 1e+10f}, "Mixing bins - multiplicity"}; using BinningType = ColumnBinningPolicy; BinningType colBinning{{ConfVtxBins, ConfMultBins}, true}; - template - void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs) + template + void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) { THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); @@ -345,46 +336,33 @@ struct MaterialBudget { // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); - double value[9] = {0.f}; - float phi_cp1 = 0.f, eta_cp1 = 0.f; + double value[6] = {0.f}; float phi_cp2 = 0.f, eta_cp2 = 0.f; for (auto& cut1 : cuts1) { for (auto& cut2 : cuts2) { - // if (std::string(cut1.GetName()) == std::string(cut2.GetName())) { - // continue; - // } for (auto& g1 : photons_coll1) { for (auto& g2 : photons_coll2) { - if (g1.globalIndex() == g2.globalIndex()) { - continue; - } if (!IsSelectedPair(g1, g2, cut1, cut2)) { continue; } // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); for (auto& paircut : paircuts) { - if (!paircut.IsSelected(g1, g2)) { continue; } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // tag - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), g1.mass()); // tag + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - phi_cp1 = atan2(g1.recalculatedVtxY(), g1.recalculatedVtxX()); - eta_cp1 = std::atanh(g1.recalculatedVtxZ() / sqrt(pow(g1.recalculatedVtxX(), 2) + pow(g1.recalculatedVtxY(), 2) + pow(g1.recalculatedVtxZ(), 2))); - phi_cp2 = atan2(g2.recalculatedVtxY(), g2.recalculatedVtxX()); - eta_cp2 = std::atanh(g2.recalculatedVtxZ() / sqrt(pow(g2.recalculatedVtxX(), 2) + pow(g2.recalculatedVtxY(), 2) + pow(g2.recalculatedVtxZ(), 2))); + phi_cp2 = atan2(g2.vy(), g2.vx()); + eta_cp2 = std::atanh(g2.vz() / sqrt(pow(g2.vx(), 2) + pow(g2.vy(), 2) + pow(g2.vz(), 2))); value[0] = v12.M(); value[1] = g1.pt(); - value[2] = g1.recalculatedVtxR(); - value[3] = phi_cp1 > 0.f ? phi_cp1 : phi_cp1 + TMath::TwoPi(); - value[4] = eta_cp1; - value[5] = g2.pt(); - value[6] = g2.recalculatedVtxR(); - value[7] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); - value[8] = eta_cp2; + value[2] = g2.pt(); + value[3] = g2.v0radius(); + value[4] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); + value[5] = eta_cp2; reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_mix"))->Fill(value); } // end of pair cut loop @@ -397,22 +375,22 @@ struct MaterialBudget { Partition grouped_collisions = CentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < CentMax; // this goes to same event. Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true && CentMin < o2::aod::cent::centFT0M&& o2::aod::cent::centFT0M < CentMax; - Filter collisionFilter_subsys = o2::aod::emreducedevent::ngpcm >= 1; + Filter collisionFilter_subsys = o2::aod::emreducedevent::ngpcm >= 1 || o2::aod::emreducedevent::neeuls >= 1; using MyFilteredCollisions = soa::Filtered; // this goes to mixed event. - void processMB(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs) + Filter DalitzEEFilter = o2::aod::dalitzee::sign == 0; // analyze only uls + using MyFilteredDalitzEEs = soa::Filtered; + + void processMB(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) { - fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbePCMCuts, legs); - SameEventPairing(grouped_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fTagPCMCuts, fProbePCMCuts, fPairCuts, legs); + fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbeCuts, legs); + SameEventPairing(grouped_collisions, dielectrons, v0photons, perCollision_ee, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, emprimaryelectrons); if (fDoMixing) { - MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fTagPCMCuts, fProbePCMCuts, fPairCuts, legs); + MixedEventPairing(filtered_collisions, dielectrons, v0photons, perCollision_ee, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, emprimaryelectrons); } } - void processDummy(MyCollisions::iterator const& collision) - { - // do nothing - } + void processDummy(MyCollisions::iterator const& collision) {} PROCESS_SWITCH(MaterialBudget, processMB, "process material budget", false); PROCESS_SWITCH(MaterialBudget, processDummy, "Dummy function", true); diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx index 50f50a861d1..46717f4b766 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx @@ -33,6 +33,7 @@ #include "PWGEM/PhotonMeson/Utils/PairUtilities.h" #include "PWGEM/PhotonMeson/Utils/MCUtilities.h" #include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/Core/DalitzEECut.h" #include "PWGEM/PhotonMeson/Core/PairCut.h" #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" @@ -50,19 +51,24 @@ using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; +using MyMCV0Legs = soa::Join; +using MyMCV0Leg = MyMCV0Legs::iterator; + using MyDalitzEEs = soa::Join; using MyDalitzEE = MyDalitzEEs::iterator; +using MyMCElectrons = soa::Join; +using MyMCElectron = MyMCElectrons::iterator; + struct MaterialBudgetMC { - using MyMCV0Legs = soa::Join; Configurable CentMin{"CentMin", -1, "min. centrality"}; Configurable CentMax{"CentMax", 999, "max. centrality"}; Configurable CentEstimator{"CentEstimator", "FT0M", "centrality estimator"}; - Configurable maxY{"maxY", 999.f, "maximum rapidity for generated particles"}; - Configurable fConfigTagPCMCuts{"cfgTagPCMCuts", "qc_ITSTPC", "Comma separated list of V0 photon cuts for tag"}; - Configurable fConfigProbePCMCuts{"cfgProbePCMCuts", "qc_ITSTPC,qc_TPConly,qc_ITSonly", "Comma separated list of V0 photon cuts for probe"}; + Configurable maxY{"maxY", 0.9, "maximum rapidity for generated particles"}; + Configurable fConfigTagCuts{"cfgTagCuts", "mee_0_120_tpconly_lowB", "Comma separated list of Dalitz EE cuts for tag"}; + Configurable fConfigProbeCuts{"cfgProbeCuts", "qc,wwire_ib", "Comma separated list of V0 photon cuts for probe"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; OutputObj fOutputEvent{"Event"}; @@ -71,19 +77,19 @@ struct MaterialBudgetMC { OutputObj fOutputGen{"Generated"}; THashList* fMainList = new THashList(); - std::vector fTagPCMCuts; - std::vector fProbePCMCuts; + std::vector fTagCuts; + std::vector fProbeCuts; std::vector fPairCuts; std::vector fPairNames; void init(InitContext& context) { if (context.mOptions.get("processMBMC")) { - fPairNames.push_back("PCMPCM"); + fPairNames.push_back("PCMDalitzEE"); } - DefineTagPCMCuts(); - DefineProbePCMCuts(); + DefineTagCuts(); + DefineProbeCuts(); DefinePairCuts(); addhistograms(); @@ -120,7 +126,7 @@ struct MaterialBudgetMC { } // end of cut1 loop } - static constexpr std::string_view pairnames[6] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PHOSEMC"}; + static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; void addhistograms() { fMainList->SetOwner(true); @@ -137,7 +143,7 @@ struct MaterialBudgetMC { THashList* list_v0 = reinterpret_cast(fMainList->FindObject("V0")); // for V0s - for (const auto& cut : fProbePCMCuts) { + for (const auto& cut : fProbeCuts) { const char* cutname = cut.GetName(); THashList* list_v0_cut = o2::aod::emphotonhistograms::AddHistClass(list_v0, cutname); o2::aod::emphotonhistograms::DefineHistograms(list_v0_cut, "material_budget_study", "V0"); @@ -152,8 +158,8 @@ struct MaterialBudgetMC { o2::aod::emphotonhistograms::AddHistClass(list_pair, pairname.data()); - if (pairname == "PCMPCM") { - add_pair_histograms(list_pair, pairname, fTagPCMCuts, fProbePCMCuts, fPairCuts); + if (pairname == "PCMDalitzEE") { + add_pair_histograms(list_pair, pairname, fTagCuts, fProbeCuts, fPairCuts); } } // end of pair name loop @@ -164,32 +170,32 @@ struct MaterialBudgetMC { o2::aod::emphotonhistograms::DefineHistograms(list_gen, "Generated", "ConversionStudy"); } - void DefineTagPCMCuts() + void DefineTagCuts() { - TString cutNamesStr = fConfigTagPCMCuts.value; + TString cutNamesStr = fConfigTagCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { const char* cutname = objArray->At(icut)->GetName(); LOGF(info, "add cut : %s", cutname); - fTagPCMCuts.push_back(*pcmcuts::GetCut(cutname)); + fTagCuts.push_back(*dalitzeecuts::GetCut(cutname)); } } - LOGF(info, "Number of Tag PCM cuts = %d", fTagPCMCuts.size()); + LOGF(info, "Number of Tag PCM cuts = %d", fTagCuts.size()); } - void DefineProbePCMCuts() + void DefineProbeCuts() { - TString cutNamesStr = fConfigProbePCMCuts.value; + TString cutNamesStr = fConfigProbeCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { const char* cutname = objArray->At(icut)->GetName(); LOGF(info, "add cut : %s", cutname); - fProbePCMCuts.push_back(*pcmcuts::GetCut(cutname)); + fProbeCuts.push_back(*pcmcuts::GetCut(cutname)); } } - LOGF(info, "Number of Probe PCM cuts = %d", fProbePCMCuts.size()); + LOGF(info, "Number of Probe PCM cuts = %d", fProbeCuts.size()); } void DefinePairCuts() @@ -207,11 +213,12 @@ struct MaterialBudgetMC { } Preslice perCollision_pcm = aod::v0photonkf::emreducedeventId; + Preslice perCollision_ee = aod::dalitzee::emreducedeventId; template bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) { - return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); + return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } template @@ -242,11 +249,7 @@ struct MaterialBudgetMC { auto ele = photon.template negTrack_as(); auto posmc = pos.template emmcparticle_as(); auto elemc = ele.template emmcparticle_as(); - int photonid = FindCommonMotherFrom2Prongs(posmc, elemc, -11, 11, 22, mcparticles); - if (photonid < 0) { // check swap, true electron is reconstructed as positron and vice versa. - photonid = FindCommonMotherFrom2Prongs(posmc, elemc, 11, -11, 22, mcparticles); - } bool is_photon_physical_primary = false; if (photonid > 0) { @@ -257,10 +260,10 @@ struct MaterialBudgetMC { continue; } - float phi_cp = atan2(photon.recalculatedVtxY(), photon.recalculatedVtxX()); - float eta_cp = std::atanh(photon.recalculatedVtxZ() / sqrt(pow(photon.recalculatedVtxX(), 2) + pow(photon.recalculatedVtxY(), 2) + pow(photon.recalculatedVtxZ(), 2))); + float phi_cp = atan2(photon.vy(), photon.vx()); + float eta_cp = std::atanh(photon.vz() / sqrt(pow(photon.vx(), 2) + pow(photon.vy(), 2) + pow(photon.vz(), 2))); value[0] = photon.pt(); - value[1] = photon.recalculatedVtxR(); + value[1] = photon.v0radius(); value[2] = phi_cp > 0 ? phi_cp : phi_cp + TMath::TwoPi(); value[3] = eta_cp; reinterpret_cast(list_v0->FindObject(cut.GetName())->FindObject("hs_conv_point"))->Fill(value); @@ -271,8 +274,8 @@ struct MaterialBudgetMC { } // end of collision loop } - template - void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TMCParticles const& mcparticles, TMCEvents const&) + template + void TruePairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TMCParticles const& mcparticles, TMCEvents const&, TEMPrimaryElectrons const& emprimaryelectrons) { THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); @@ -301,19 +304,12 @@ struct MaterialBudgetMC { auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); - double value[9] = {0.f}; - float phi_cp1 = 0.f, eta_cp1 = 0.f; + double value[6] = {0.f}; float phi_cp2 = 0.f, eta_cp2 = 0.f; for (auto& cut1 : cuts1) { for (auto& cut2 : cuts2) { - // if (std::string(cut1.GetName()) == std::string(cut2.GetName())) { - // continue; - // } for (auto& g1 : photons1_coll) { for (auto& g2 : photons2_coll) { - if (g1.globalIndex() == g2.globalIndex()) { - continue; - } if (!IsSelectedPair(g1, g2, cut1, cut2)) { continue; } @@ -323,10 +319,13 @@ struct MaterialBudgetMC { continue; } - auto pos1 = g1.template posTrack_as(); - auto ele1 = g1.template negTrack_as(); + auto pos1 = g1.template posTrack_as(); + auto ele1 = g1.template negTrack_as(); auto pos2 = g2.template posTrack_as(); auto ele2 = g2.template negTrack_as(); + if (pos1.trackId() == pos2.trackId() || ele1.trackId() == ele2.trackId()) { + continue; + } auto pos1mc = pos1.template emmcparticle_as(); auto ele1mc = ele1.template emmcparticle_as(); @@ -334,24 +333,12 @@ struct MaterialBudgetMC { auto ele2mc = ele2.template emmcparticle_as(); // LOGF(info,"pos1mc.globalIndex() = %d , ele1mc.globalIndex() = %d , pos2mc.globalIndex() = %d , ele2mc.globalIndex() = %d", pos1mc.globalIndex(), ele1mc.globalIndex(), pos2mc.globalIndex(), ele2mc.globalIndex()); - int photonid1 = FindCommonMotherFrom2Prongs(pos1mc, ele1mc, -11, 11, 22, mcparticles); int photonid2 = FindCommonMotherFrom2Prongs(pos2mc, ele2mc, -11, 11, 22, mcparticles); - - if (photonid1 < 0) { // check swap, true electron is reconstructed as positron and vice versa. - photonid1 = FindCommonMotherFrom2Prongs(pos1mc, ele1mc, 11, -11, 22, mcparticles); - } - if (photonid2 < 0) { // check swap, true electron is reconstructed as positron and vice versa. - photonid2 = FindCommonMotherFrom2Prongs(pos2mc, ele2mc, 11, -11, 22, mcparticles); - } - - // LOGF(info,"photonid1 = %d , photonid2 = %d", photonid1, photonid2); - if (photonid1 < 0 || photonid2 < 0) { + if (photonid2 < 0) { continue; } - - auto g1mc = mcparticles.iteratorAt(photonid1); auto g2mc = mcparticles.iteratorAt(photonid2); - int pi0id = FindCommonMotherFrom2Prongs(g1mc, g2mc, 22, 22, 111, mcparticles); + int pi0id = FindCommonMotherFrom3Prongs(g2mc, pos1mc, ele1mc, 22, -11, 11, 111, mcparticles); bool is_pi0_physical_primary = false; if (pi0id > 0) { @@ -362,25 +349,18 @@ struct MaterialBudgetMC { continue; } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // tag - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), g1.mass()); // tag + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - phi_cp1 = atan2(g1.recalculatedVtxY(), g1.recalculatedVtxX()); - eta_cp1 = std::atanh(g1.recalculatedVtxZ() / sqrt(pow(g1.recalculatedVtxX(), 2) + pow(g1.recalculatedVtxY(), 2) + pow(g1.recalculatedVtxZ(), 2))); - phi_cp2 = atan2(g2.recalculatedVtxY(), g2.recalculatedVtxX()); - eta_cp2 = std::atanh(g2.recalculatedVtxZ() / sqrt(pow(g2.recalculatedVtxX(), 2) + pow(g2.recalculatedVtxY(), 2) + pow(g2.recalculatedVtxZ(), 2))); + phi_cp2 = atan2(g2.vy(), g2.vx()); + eta_cp2 = std::atanh(g2.vz() / sqrt(pow(g2.vx(), 2) + pow(g2.vy(), 2) + pow(g2.vz(), 2))); value[0] = v12.M(); value[1] = g1.pt(); - value[2] = g1.recalculatedVtxR(); - value[3] = phi_cp1 > 0.f ? phi_cp1 : phi_cp1 + TMath::TwoPi(); - value[4] = eta_cp1; - value[5] = g2.pt(); - value[6] = g2.recalculatedVtxR(); - value[7] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); - value[8] = eta_cp2; - + value[2] = g2.pt(); + value[3] = g2.v0radius(); + value[4] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); + value[5] = eta_cp2; reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); - } // end of pair cut loop } // end of g2 loop } // end of g1 loop @@ -391,10 +371,10 @@ struct MaterialBudgetMC { Partition grouped_collisions = CentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < CentMax; // this goes to same event. - void processMBMC(MyCollisions const& collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions) + void processMBMC(MyCollisions const& collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions, MyDalitzEEs const& dielectrons, MyMCElectrons const& primaryelectrons) { - fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbePCMCuts, legs, mcparticles, mccollisions); - SameEventPairing(grouped_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fTagPCMCuts, fProbePCMCuts, fPairCuts, legs, mcparticles, mccollisions); + fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbeCuts, legs, mcparticles, mccollisions); + TruePairing(grouped_collisions, dielectrons, v0photons, perCollision_ee, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, mcparticles, mccollisions, primaryelectrons); } PresliceUnsorted perMcCollision = aod::emmcparticle::emreducedmceventId; @@ -451,10 +431,7 @@ struct MaterialBudgetMC { } } - void processDummy(MyCollisions::iterator const& collision) - { - // do nothing - } + void processDummy(MyCollisions::iterator const& collision) {} PROCESS_SWITCH(MaterialBudgetMC, processMBMC, "process material budget", false); PROCESS_SWITCH(MaterialBudgetMC, processGen, "process generated information", false); From 5bd917a3e1de5f29727b0224e5dbb5128f6e7ed9 Mon Sep 17 00:00:00 2001 From: rbailhac Date: Tue, 19 Dec 2023 14:04:55 +0100 Subject: [PATCH 090/156] Add processBarrelOnly functions with Cov and Cent and Mults (#4204) * Add processBarrelOnly functions with Cov and Cent and Mults * fix --- PWGDQ/TableProducer/tableMaker.cxx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 6e7aacd35eb..8467ab1d360 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -232,8 +232,8 @@ struct TableMaker { bool enableBarrelHistos = (context.mOptions.get("processFull") || context.mOptions.get("processFullWithCov") || context.mOptions.get("processFullWithCent") || context.mOptions.get("processFullWithCovAndEventFilter") || context.mOptions.get("processFullWithCovMultsAndEventFilter") || - context.mOptions.get("processBarrelOnly") || context.mOptions.get("processBarrelOnlyWithCent") || - context.mOptions.get("processBarrelOnlyWithMults") || + context.mOptions.get("processBarrelOnly") || context.mOptions.get("processBarrelOnlyWithCent") || context.mOptions.get("processBarrelOnlyWithCovWithCent") || + context.mOptions.get("processBarrelOnlyWithMults") || context.mOptions.get("processBarrelOnlyWithCentAndMults") || context.mOptions.get("processBarrelOnlyWithCovWithCentAndMults") || context.mOptions.get("processBarrelOnlyWithCov") || context.mOptions.get("processBarrelOnlyWithEventFilter") || context.mOptions.get("processBarrelOnlyWithMultsAndEventFilter") || context.mOptions.get("processBarrelOnlyWithCovAndEventFilter") || context.mOptions.get("processBarrelOnlyWithDalitzBits") || context.mOptions.get("processBarrelOnlyWithV0Bits") || @@ -1249,6 +1249,13 @@ struct TableMaker { fullSkimming(collision, bcs, tracksBarrel, nullptr, nullptr, nullptr); } + // Produce barrel only tables, with centrality ----------------------------------------------------------------------------------------------- + void processBarrelOnlyWithCovWithCent(MyEventsWithCent::iterator const& collision, aod::BCsWithTimestamps const& bcs, + soa::Filtered const& tracksBarrel) + { + fullSkimming(collision, bcs, tracksBarrel, nullptr, nullptr, nullptr); + } + // Produce barrel only tables, with centrality and multiplicity ------------------------------------------------------------------- void processBarrelOnlyWithCentAndMults(MyEventsWithCentAndMults::iterator const& collision, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksBarrel) @@ -1256,6 +1263,13 @@ struct TableMaker { fullSkimming(collision, bcs, tracksBarrel, nullptr, nullptr, nullptr); } + // Produce barrel only tables, with centrality and multiplicity ------------------------------------------------------------------- + void processBarrelOnlyWithCovWithCentAndMults(MyEventsWithCentAndMults::iterator const& collision, aod::BCsWithTimestamps const& bcs, + soa::Filtered const& tracksBarrel) + { + fullSkimming(collision, bcs, tracksBarrel, nullptr, nullptr, nullptr); + } + // Produce barrel tables only, with track cov matrix ---------------------------------------------------------------------------------------- void processBarrelOnlyWithCov(MyEventsWithMults::iterator const& collision, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksBarrel) @@ -1485,7 +1499,9 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processBarrelOnlyWithMultsAndEventFilter, "Build barrel-only DQ skimmed data model, w/ multiplicity, w/ event filter", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithCovAndEventFilter, "Build full DQ skimmed data model, w/ track and fwdtrack covariance tables, w/o centrality, w/ event filter", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithCent, "Build barrel-only DQ skimmed data model, w/ centrality", false); + PROCESS_SWITCH(TableMaker, processBarrelOnlyWithCovWithCent, "Build barrel-only DQ skimmed data model, w/ centrality and w/ track covariance", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithCentAndMults, "Build barrel-only DQ skimmed data model, w/ centrality and multiplicities", false); + PROCESS_SWITCH(TableMaker, processBarrelOnlyWithCovWithCentAndMults, "Build barrel-only DQ skimmed data model, w/ centrality and multiplicities and w/ track covariance", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithCov, "Build barrel-only DQ skimmed data model, w/ track cov matrix", false); PROCESS_SWITCH(TableMaker, processBarrelOnly, "Build barrel-only DQ skimmed data model, w/o centrality", false); PROCESS_SWITCH(TableMaker, processMuonOnlyWithCent, "Build muon-only DQ skimmed data model, w/ centrality", false); From 9466df7dda7b45acc908f788b9654cc09efabc33 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Tue, 19 Dec 2023 14:21:17 +0100 Subject: [PATCH 091/156] PWGHF: Add mass and d0xd0 in B0 reduced tree (#4199) * PWGHF: Add mass and d0xd0 in B0 reduced tree * Add missing column definition --- PWGHF/D2H/Tasks/taskB0Reduced.cxx | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index fe08c538e8a..62ad3ea4056 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -38,6 +38,7 @@ namespace hf_cand_b0_lite { DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong0 (GeV/c) DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong1 (GeV/c) +DECLARE_SOA_COLUMN(MProng0, mProng0, float); //! Invariant mass of prong0 (GeV/c) DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) @@ -51,6 +52,7 @@ DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! Normalised transverse decay length of candidate +DECLARE_SOA_COLUMN(ImpactParameterProduct, impactParameterProduct, float); //! Impact parameter product of candidate DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! Maximum normalized difference between measured and expected impact parameter of candidate prongs @@ -62,10 +64,12 @@ DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with som hf_cand_b0_lite::DecayLengthXY, hf_cand_b0_lite::DecayLengthNormalised, hf_cand_b0_lite::DecayLengthXYNormalised, + hf_cand_b0_lite::MProng0, hf_cand_b0_lite::PtProng0, hf_cand_b0_lite::PtProng1, hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, + hf_cand_b0_lite::ImpactParameterProduct, hf_cand_b0_lite::NSigTpcPi1, hf_cand_b0_lite::NSigTofPi1, hf_cand_b0_reduced::Prong0MlScoreBkg, @@ -285,6 +289,7 @@ struct HfTaskB0Reduced { auto invMassB0 = hfHelper.invMassB0ToDPi(candidate); auto candD = candidate.template prong0_as(); auto ptD = RecoDecay::pt(candD.px(), candD.py()); + auto invMassD = candD.invMass(); std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; std::array posSvD{candD.xSecondaryVertex(), candD.ySecondaryVertex(), candD.zSecondaryVertex()}; std::array momD{candD.px(), candD.py(), candD.pz()}; @@ -307,7 +312,7 @@ struct HfTaskB0Reduced { registry.fill(HIST("hCospXy"), ptCandB0, candidate.cpaXY()); registry.fill(HIST("hEta"), ptCandB0, candidate.eta()); registry.fill(HIST("hRapidity"), ptCandB0, hfHelper.yB0(candidate)); - registry.fill(HIST("hInvMassD"), ptD, candD.invMass()); + registry.fill(HIST("hInvMassD"), ptD, invMassD); registry.fill(HIST("hDecLengthD"), ptD, decLenD); registry.fill(HIST("hDecLengthXyD"), ptD, decLenXyD); registry.fill(HIST("hCospD"), ptD, cospD); @@ -321,9 +326,9 @@ struct HfTaskB0Reduced { } if (fillSparses) { if constexpr (withDmesMl) { - registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), invMassD, ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); } else { - registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); + registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), invMassD, ptD, decLenD, cospD); } } if (fillTree) { @@ -347,10 +352,12 @@ struct HfTaskB0Reduced { candidate.decayLengthXY(), candidate.decayLengthNormalised(), candidate.decayLengthXYNormalised(), + invMassD, ptD, candidate.ptProng1(), candidate.impactParameter0(), candidate.impactParameter1(), + candidate.impactParameterProduct(), prong1.tpcNSigmaPi(), prong1.tofNSigmaPi(), prong0MlScoreBkg, @@ -383,6 +390,7 @@ struct HfTaskB0Reduced { auto invMassB0 = hfHelper.invMassB0ToDPi(candidate); auto candD = candidate.template prong0_as(); auto ptD = RecoDecay::pt(candD.px(), candD.py()); + auto invMassD = candD.invMass(); std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; std::array posSvD{candD.xSecondaryVertex(), candD.ySecondaryVertex(), candD.zSecondaryVertex()}; std::array momD{candD.px(), candD.py(), candD.pz()}; @@ -408,7 +416,7 @@ struct HfTaskB0Reduced { registry.fill(HIST("hCospXyRecSig"), ptCandB0, candidate.cpaXY()); registry.fill(HIST("hEtaRecSig"), ptCandB0, candidate.eta()); registry.fill(HIST("hRapidityRecSig"), ptCandB0, hfHelper.yB0(candidate)); - registry.fill(HIST("hInvMassDRecSig"), ptD, candD.invMass()); + registry.fill(HIST("hInvMassDRecSig"), ptD, invMassD); registry.fill(HIST("hDecLengthDRecSig"), ptD, decLenD); registry.fill(HIST("hDecLengthXyDRecSig"), ptD, decLenXyD); registry.fill(HIST("hCospDRecSig"), ptD, cospD); @@ -432,7 +440,7 @@ struct HfTaskB0Reduced { registry.fill(HIST("hCospXyRecBg"), ptCandB0, candidate.cpaXY()); registry.fill(HIST("hEtaRecBg"), ptCandB0, candidate.eta()); registry.fill(HIST("hRapidityRecBg"), ptCandB0, hfHelper.yB0(candidate)); - registry.fill(HIST("hInvMassDRecBg"), ptD, candD.invMass()); + registry.fill(HIST("hInvMassDRecBg"), ptD, invMassD); registry.fill(HIST("hDecLengthDRecBg"), ptD, decLenD); registry.fill(HIST("hDecLengthXyDRecBg"), ptD, decLenXyD); registry.fill(HIST("hCospDRecBg"), ptD, cospD); @@ -447,15 +455,15 @@ struct HfTaskB0Reduced { if (fillSparses) { if (isSignal) { if constexpr (withDmesMl) { - registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), invMassD, ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); } else { - registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); + registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), invMassD, ptD, decLenD, cospD); } } else if (fillBackground) { if constexpr (withDmesMl) { - registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), invMassD, ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); } else { - registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), candD.invMass(), ptD, decLenD, cospD); + registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProduct(), candidate.cpa(), invMassD, ptD, decLenD, cospD); } } } @@ -477,10 +485,12 @@ struct HfTaskB0Reduced { candidate.decayLengthXY(), candidate.decayLengthNormalised(), candidate.decayLengthXYNormalised(), + invMassD, ptD, candidate.ptProng1(), candidate.impactParameter0(), candidate.impactParameter1(), + candidate.impactParameterProduct(), prong1.tpcNSigmaPi(), prong1.tofNSigmaPi(), prong0MlScoreBkg, From a3f97a1d765e5dc78483fe13dce5b275ab723425 Mon Sep 17 00:00:00 2001 From: feisenhu <53603353+feisenhu@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:37:59 +0100 Subject: [PATCH 092/156] PWGEM: additional pair mass cuts for trigger studies (#4208) --- PWGDQ/Core/CutsLibrary.cxx | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 80fe27d6e63..b276b2e3140 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -1587,11 +1587,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); - cut_tof_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data()))); - - cut->AddCut(cut_tof_nSigma); + cut->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data()))); return cut; } @@ -2011,6 +2007,16 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("pairMassLow11")) { + cut->AddCut(GetAnalysisCut("pairMassLow11")); + return cut; + } + + if (!nameStr.compare("pairMassLow12")) { + cut->AddCut(GetAnalysisCut("pairMassLow12")); + return cut; + } + if (!nameStr.compare("pairMass1to2")) { cut->AddCut(GetAnalysisCut("pairMass1to2")); return cut; @@ -4048,6 +4054,16 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("pairMassLow11")) { + cut->AddCut(VarManager::kMass, 3.0, 1000.0); + return cut; + } + + if (!nameStr.compare("pairMassLow12")) { + cut->AddCut(VarManager::kMass, 3.5, 1000.0); + return cut; + } + if (!nameStr.compare("pairMass1to2")) { cut->AddCut(VarManager::kMass, 1., 2.); return cut; From 01509e9f4c70614137d54c80b785cbe8b4be603f Mon Sep 17 00:00:00 2001 From: Luca Barioglio Date: Tue, 19 Dec 2023 18:15:34 +0100 Subject: [PATCH 093/156] Swap daughter flags for antimatter (#4210) --- PWGLF/TableProducer/hyperRecoTask.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/TableProducer/hyperRecoTask.cxx b/PWGLF/TableProducer/hyperRecoTask.cxx index 56cc6612cd8..c1500cc3fa2 100644 --- a/PWGLF/TableProducer/hyperRecoTask.cxx +++ b/PWGLF/TableProducer/hyperRecoTask.cxx @@ -298,8 +298,8 @@ struct hyperRecoTask { hypCand.momHe3TPC = hypCand.isMatter ? posTrack.tpcInnerParam() : negTrack.tpcInnerParam(); hypCand.momPiTPC = !hypCand.isMatter ? posTrack.tpcInnerParam() : negTrack.tpcInnerParam(); - hypCand.flags |= static_cast((posTrack.pidForTracking() & 0xF) << 4); - hypCand.flags |= static_cast(negTrack.pidForTracking() & 0xF); + hypCand.flags |= hypCand.isMatter ? static_cast((posTrack.pidForTracking() & 0xF) << 4) : static_cast((negTrack.pidForTracking() & 0xF) << 4); + hypCand.flags |= hypCand.isMatter ? static_cast(negTrack.pidForTracking() & 0xF) : static_cast(posTrack.pidForTracking() & 0xF); auto posTrackCov = getTrackParCov(posTrack); auto negTrackCov = getTrackParCov(negTrack); From e46fdbc7a416fa49831b92fef373df3c79710200 Mon Sep 17 00:00:00 2001 From: Alessandro Sturniolo <123940165+AlessandroSturniolo@users.noreply.github.com> Date: Tue, 19 Dec 2023 18:40:33 +0100 Subject: [PATCH 094/156] Implemented MC K*pm analysis, mass-pT-mult 3D dist, fixed K0s mass dist (#4211) * Implemented MC K*(892)pm analysis, mass-mom-mult 3D dist, fixed K0short mass distribution * MegaLinter fixes --------- Co-authored-by: AlessandroSturniolo Co-authored-by: ALICE Action Bot --- PWGLF/Tasks/k892pmanalysis.cxx | 61 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/PWGLF/Tasks/k892pmanalysis.cxx b/PWGLF/Tasks/k892pmanalysis.cxx index 83561df888a..8ad32fe4567 100644 --- a/PWGLF/Tasks/k892pmanalysis.cxx +++ b/PWGLF/Tasks/k892pmanalysis.cxx @@ -98,21 +98,14 @@ struct k892pmanalysis { histos.add("QAbefore/trkpT_k0s", "pT distribution of k0short track candidates", kTH1F, {ptAxisQA}); histos.add("QAafter/trkpT_pi", "pT distribution of pion track candidates", kTH1F, {ptAxisQA}); histos.add("QAafter/trkpT_k0s", "pT distribution of k0short track candidates", kTH1F, {ptAxisQA}); + // Mass vs Pt vs Multiplicity 3-dimensional histogram + histos.add("k892pmMassPtMult3d", "Charged K*(892) mass vs pT vs V0multiplicity distribution", kTH3F, {invMassAxis, ptAxis, centAxis}); - /*if (doprocessMCLight) { + if (doprocessMCLight) { // MC QA - histos.add("QAMCTrue/trkDCAxy_pi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {dcaxyAxis}); - histos.add("QAMCTrue/trkDCAxy_ka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {dcaxyAxis}); - histos.add("QAMCTrue/trkDCAz_pi", "DCAz distribution of pion track candidates", HistType::kTH1F, {dcazAxis}); - histos.add("QAMCTrue/trkDCAz_ka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {dcazAxis}); - histos.add("h3Reck892invmass", "Invariant mass of Reconstructed MC K(892)0", kTH3F, {centAxis, ptAxis, invMassAxis}); - histos.add("h3Reck892invmassAnti", "Invariant mass of Reconstructed MC Anti-K(892)0", kTH3F, {centAxis, ptAxis, invMassAxis}); - histos.add("k892pmGen", "pT distribution of True MC K(892)0", kTH1F, {ptAxis}); - histos.add("k892pmGenAnti", "pT distribution of True MC Anti-K(892)0", kTH1F, {ptAxis}); - histos.add("k892Rec", "pT distribution of Reconstructed MC K(892)0", kTH1F, {ptAxis}); - histos.add("k892RecAnti", "pT distribution of Reconstructed MC Anti-K(892)0", kTH1F, {ptAxis}); - histos.add("k892Recinvmass", "Inv mass distribution of Reconstructed MC Phi", kTH1F, {invMassAxis}); - }*/ + histos.add("k892pmPtGen", "pT distribution of True MC charged K*(892)", kTH1F, {ptAxis}); + histos.add("k892pmPtRec", "pT distribution of Reconstructed MC charged K*(892)", kTH1F, {ptAxis}); + } // Print output histograms statistics LOG(info) << "Size of the histograms in spectraTOF"; histos.print(); @@ -217,7 +210,7 @@ struct k892pmanalysis { for (auto& v0 : dV0s) { // Full index policy is needed to consider all possible combinations if (v0.indices()[0] == trkId || v0.indices()[1] == trkId) - continue; // To avoid comibining secondary and primary pions + continue; // To avoid combining secondary and primary pions //// Initialize variables // trk: Pion, v0: K0s @@ -234,17 +227,28 @@ struct k892pmanalysis { if (!IsV0QAFilled) { // pt QA (after cuts) - histos.fill(HIST("QAafter/trkpT_k0s"), v0.pt()); + histos.fill(HIST("QAafter/trkpT_k0s"), v0ptK0s); + // K0s mass QA (after cuts) + histos.fill(HIST("QAafter/k0shortmass"), v0.mK0Short()); } lDecayDaughter.SetXYZM(trk.px(), trk.py(), trk.pz(), massPi); lDecayV0.SetXYZM(v0.px(), v0.py(), v0.pz(), massK0); lResonance = lDecayDaughter + lDecayV0; // Filling invariant mass histograms - // K0s mass QA (after cuts) - histos.fill(HIST("QAafter/k0shortmass"), lDecayV0.M()); // K*(892)pm mass histos.fill(HIST("k892pminvmass"), lResonance.M()); + // K*(892)pm 3d mass, pt, multiplicity histogram + histos.fill(HIST("k892pmMassPtMult3d"), lResonance.M(), lResonance.Pt(), multiplicity); + if constexpr (IsMC) { + if (abs(trk.pdgCode()) != 211 || abs(v0.pdgCode()) != 310) // Skip to next iteration if duaghters are not charged pion + K0s/AntiK0s + continue; + if (trk.motherPDG() != v0.motherPDG()) + continue; + if (trk.motherPDG() != 323) + continue; + histos.fill(HIST("k892pmPtRec"), lResonance.Pt()); + } IsV0Processed = true; } if (IsV0Processed) { @@ -262,35 +266,32 @@ struct k892pmanalysis { } PROCESS_SWITCH(k892pmanalysis, processDataLight, "Process Event for data", false); - /*void processMCLight(aod::ResoCollision& collision, - soa::Join const& resotracks) + void processMCLight(aod::ResoCollision& collision, + soa::Join const& resotracks, + soa::Join const& resov0s) { - fillHistograms(collision, resotracks, resotracks); + fillHistograms(collision, resotracks, resov0s); } - PROCESS_SWITCH(k892pmanalysis, processMCLight, "Process Event for MC", false);*/ + PROCESS_SWITCH(k892pmanalysis, processMCLight, "Process Event for MC", false); void processMCTrue(aod::ResoMCParents& resoParents) { for (auto& part : resoParents) { // loop over all pre-filtered MC particles if (abs(part.pdgCode()) != 323) // K*892(pm) continue; - if (abs(part.y()) > 0.5) { // rapidity cut + if (abs(part.y()) > 0.5) // rapidity cut continue; - } bool pass1 = false; bool pass2 = false; - if (abs(part.daughterPDG1()) == 211 || abs(part.daughterPDG2()) == 310) { // At least one decay to K0s + if (part.daughterPDG1() == 211 && part.daughterPDG2() == 310) { // One decay to K0s and the other to pi+ (K*(892)+ mother) - Particle pass pass1 = true; } - if (abs(part.daughterPDG1()) == 310 || abs(part.daughterPDG2()) == 211) { // At least one decay to K0s + if (part.daughterPDG1() == -211 && part.daughterPDG2() == -310) { // One decay to AntiK0s and the other to pi- (K*(892)- mother) - Antiparticle pass pass2 = true; } - if (!pass1 || !pass2) // If we have both decay products + if (!pass1 || !pass2) // Go on only if we have both decay products, else skip to next iteration continue; - if (part.pdgCode() > 0) - histos.fill(HIST("k892pmGen"), part.pt()); - else - histos.fill(HIST("k892pmGenAnti"), part.pt()); + histos.fill(HIST("k892pmPtGen"), part.pt()); } } PROCESS_SWITCH(k892pmanalysis, processMCTrue, "Process Event for MC", false); From 13e8747acf269d3176fe24b20c789d6c20576606 Mon Sep 17 00:00:00 2001 From: Mario Ciacco Date: Tue, 19 Dec 2023 19:02:41 +0100 Subject: [PATCH 095/156] search missing tpc segment in adjacent collisions (#4212) * search missing tpc segment in adjacent collisions + fix binning of qa histograms * print indices in debug --- PWGLF/Tasks/QC/efficiencyQA.cxx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/PWGLF/Tasks/QC/efficiencyQA.cxx b/PWGLF/Tasks/QC/efficiencyQA.cxx index b47385d3a1c..05d8db62a27 100644 --- a/PWGLF/Tasks/QC/efficiencyQA.cxx +++ b/PWGLF/Tasks/QC/efficiencyQA.cxx @@ -65,6 +65,7 @@ float invMass2Body(std::array& momA, std::array const& momB, struct ProbeTrack { uint64_t globalIndex; uint64_t globalIndexTpc; + int32_t collIndex; float p; float pt; float pProp; @@ -113,6 +114,7 @@ struct efficiencyQA { Configurable phiWindow{"phiWindow", 0.2f, "phi window to search tpc segment"}; Configurable massWindow{"massWindow", 0.03f, "mass window to search tpc segment"}; Configurable cosPaWindow{"cosPaWindow", 0.8f, "cosPa window to search tpc segment"}; + Configurable collIdWindow{"collIdWindow", 6, "collision index window to search tpc segment"}; // CCDB options Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; @@ -135,6 +137,7 @@ struct efficiencyQA { ConfigurableAxis phiAxis{"phiAxis", {630, 0.f, 6.3f}, "binning for the phi of V0 daughter tracks"}; ConfigurableAxis phiResAxis{"phiResAxis", {800, -4.f, 4.f}, "binning for the phi resolution of V0 daughter tracks"}; ConfigurableAxis cosPaAxis{"cosPaAxis", {1000, -1.f, 1.f}, "binning for the cosine of pointing angle"}; + ConfigurableAxis collIdResAxis{"collIdResAxis", {1.e2, -50., 50.}, "binning for the collision ID resolution"}; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -194,8 +197,8 @@ struct efficiencyQA { histos.add("massTagTpc", ";#it{p} (GeV/#it{c});#it{M}(#pi^{+} + #pi^{-}) (GeV/#it{c}^{2})", HistType::kTH2F, {ptAxis, massK0sAxis}); histos.add("ptItsTpcSel", ";#it{p} (GeV/#it{c});#it{p}_{T}^{TPC} - #it{p}_{T}^{ITS} (GeV/#it{c})", HistType::kTH2F, {ptAxis, ptResAxis}); - histos.add("etaItsTpcSel", ";#it{p} (GeV/#it{c});#eta^{TPC} - #eta^{ITS}", HistType::kTH2F, {ptAxis, ptResAxis}); - histos.add("phiItsTpcSel", ";#it{p} (GeV/#it{c});#phi^{TPC} - #phi^{ITS} (rad)", HistType::kTH2F, {ptAxis, ptResAxis}); + histos.add("etaItsTpcSel", ";#it{p} (GeV/#it{c});#eta^{TPC} - #eta^{ITS}", HistType::kTH2F, {ptAxis, etaResAxis}); + histos.add("phiItsTpcSel", ";#it{p} (GeV/#it{c});#phi^{TPC} - #phi^{ITS} (rad)", HistType::kTH2F, {ptAxis, phiResAxis}); std::string binLabelsTag[]{"hasITS && hasTPC", "tracking", "PID", "v0 mass", "dcaV0dau", "cosPA", "dcaXYZ", "V0radius"}; for (int iB{0}; iB < hTagCuts->GetNbinsX(); ++iB) { @@ -213,13 +216,15 @@ struct efficiencyQA { hTpcSegment->GetXaxis()->SetBinLabel(iB + 1, binLabelsTpc[iB].data()); } histos.add("pTpcIts", ";#it{p}^{ITS} (GeV/#it{c});#it{p}^{TPC} - #it{p}^{ITS} (GeV/#it{c});Entries", HistType::kTH2F, {ptAxis, ptResAxis}); - histos.add("ptTpcIts", ";#it{p}_{T}^{ITS} (GeV/#it{c});#it{p}^{TPC}_{T} - #it{p}^{ITS}_{T} (GeV/#it{c});Entries", HistType::kTH2F, {ptAxis, ptResAxis}); + histos.add("ptTpcIts", ";#it{p}^{ITS} (GeV/#it{c});#it{p}^{TPC}_{T} - #it{p}^{ITS}_{T} (GeV/#it{c});Entries", HistType::kTH2F, {ptAxis, ptResAxis}); histos.add("etaTpcIts", ";#it{p}^{ITS} (GeV/#it{c});#eta^{TPC} - #eta^{ITS};Entries", HistType::kTH2F, {ptAxis, etaResAxis}); histos.add("phiTpcIts", ";#it{p}^{ITS} (GeV/#it{c});#phi^{TPC} - #phi^{ITS} (rad);Entries", HistType::kTH2F, {ptAxis, phiResAxis}); histos.add("massTpc", ";#it{p}^{ITS} (GeV/#it{c});#it{M}^{TPC} (GeV/#it{c}^{2});Entries", HistType::kTH2F, {ptAxis, massK0sAxis}); histos.add("massTpcIts", ";#it{p}^{ITS} (GeV/#it{c});#it{M}^{TPC} - #it{M}^{ITS} (GeV/#it{c}^{2});Entries", HistType::kTH2F, {ptAxis, massResAxis}); histos.add("cosPaTpc", ";#it{p}^{ITS} (GeV/#it{c});cos#theta_{p}", HistType::kTH2F, {ptAxis, cosPaAxis}); histos.add("ptEtaPhiTpcIts", ";#it{p}^{TPC}_{T} - #it{p}^{ITS}_{T} (GeV/#it{c});#eta^{TPC} - #eta^{ITS};#phi^{TPC} - #phi^{ITS} (rad)", HistType::kTH3F, {ptResAxis, etaResAxis, phiResAxis}); + histos.add("collTpcIts", ";ID_{coll}^{TPC} - ID_{coll}^{ITS};Entries", HistType::kTH1F, {collIdResAxis}); + histos.add("collTpcV0", ";ID_{coll}^{TPC} - ID_{coll}^{V0};Entries", HistType::kTH1F, {collIdResAxis}); } } } @@ -412,6 +417,7 @@ struct efficiencyQA { probe.vtx0 = vtx[0]; probe.vtx1 = vtx[1]; probe.vtx2 = vtx[2]; + probe.collIndex = probeTrack.collisionId(); if (probeTrack.hasITS() && !probeTrack.hasTPC() && findTpcLeg) { auto acceptIts = !(probeTrack.itsChi2NCl() > 36. || probeTrack.itsNCls() < 4); @@ -422,6 +428,9 @@ struct efficiencyQA { std::array momTpc; for (auto& tpcTrack : tpcTracks) { + if (std::abs(tpcTrack.collisionId() - probeTrack.collisionId()) > collIdWindow) { + continue; + } if (std::abs(tpcTrack.eta()) > etaMax) { continue; } @@ -569,6 +578,10 @@ struct efficiencyQA { hTpcSegment->Fill(3., probeTrack.pt); } + LOGF(debug, "globalID = %lld, probeCollId = %d, tpcCollId = %d", collision.globalIndex(), probeTrack.collIndex, tpcTrack.collisionId()); + histos.fill(HIST("collTpcIts"), tpcTrack.collisionId() - probeTrack.collIndex); + histos.fill(HIST("collTpcV0"), tpcTrack.collisionId() - collision.globalIndex()); + auto trackCov = getTrackParCov(tpcTrack); gpu::gpustd::array dcaInfo; if (propToTPCinnerWall) { From c67d1b2f09fe52f7af3818eb9419cae85124b942 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Tue, 19 Dec 2023 21:57:08 +0100 Subject: [PATCH 096/156] Common: fix type of globalBC (#4198) * Common: fix type of globalBC * Fix MegaLinter --- Common/Core/CollisionAssociation.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Common/Core/CollisionAssociation.h b/Common/Core/CollisionAssociation.h index f2206846183..a19c09c4724 100644 --- a/Common/Core/CollisionAssociation.h +++ b/Common/Core/CollisionAssociation.h @@ -125,10 +125,10 @@ class CollisionAssociation RevIndices& reverseIndices) { // cache globalBC - std::vector globalBC; + std::vector globalBC; for (const auto& track : tracks) { if (track.has_collision()) { - globalBC.push_back(track.collision().bc().globalBC()); + globalBC.push_back((int64_t)track.collision().bc().globalBC()); } else { for (const auto& ambTrack : ambiguousTracks) { if constexpr (isCentralBarrel) { // FIXME: to be removed as soon as it is possible to use getId() for joined tables @@ -137,12 +137,12 @@ class CollisionAssociation globalBC.push_back(-1); break; } - globalBC.push_back(ambTrack.bc().begin().globalBC()); + globalBC.push_back((int64_t)ambTrack.bc().begin().globalBC()); break; } } else { if (ambTrack.template getId() == track.globalIndex()) { - globalBC.push_back(ambTrack.bc().begin().globalBC()); + globalBC.push_back((int64_t)ambTrack.bc().begin().globalBC()); break; } } @@ -170,7 +170,7 @@ class CollisionAssociation if (globalBC[track.filteredIndex()] < 0) { continue; } - const int64_t bcOffsetWindow = (int64_t)globalBC[track.filteredIndex()] + trackTime / o2::constants::lhc::LHCBunchSpacingNS - (int64_t)collBC; + const int64_t bcOffsetWindow = globalBC[track.filteredIndex()] + trackTime / o2::constants::lhc::LHCBunchSpacingNS - (int64_t)collBC; if (std::abs(bcOffsetWindow) > bOffsetMax) { continue; } @@ -178,7 +178,7 @@ class CollisionAssociation float trackTimeRes = track.trackTimeRes(); if constexpr (isCentralBarrel) { if (mUsePvAssociation && track.isPVContributor()) { - trackTime = track.collision().collisionTime(); // if PV contributor, we assume the time to be the one of the collision + trackTime = track.collision().collisionTime(); // if PV contributor, we assume the time to be the one of the collision trackTimeRes = o2::constants::lhc::LHCBunchSpacingNS; // 1 BC } } From 5c74375cd145cd445ee6e635e5a9d4fe300826dc Mon Sep 17 00:00:00 2001 From: Jochen Klein Date: Tue, 19 Dec 2023 23:33:37 +0100 Subject: [PATCH 097/156] Update strangeness filter (#4186) - adjust binning for ST mass histograms - add option to use resolution-based mass cut for non-tracked cascades --- EventFiltering/PWGLF/strangenessFilter.cxx | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/EventFiltering/PWGLF/strangenessFilter.cxx b/EventFiltering/PWGLF/strangenessFilter.cxx index 8e063274770..fbf81268b51 100644 --- a/EventFiltering/PWGLF/strangenessFilter.cxx +++ b/EventFiltering/PWGLF/strangenessFilter.cxx @@ -108,6 +108,10 @@ struct strangenessFilter { Configurable kint7{"kint7", 0, "Apply kINT7 event selection"}; Configurable sel7{"sel7", 0, "Apply sel7 event selection"}; Configurable sel8{"sel8", 0, "Apply sel8 event selection"}; + Configurable useSigmaBasedMassCutXi{"useSigmaBasedMassCutXi", true, "Mass window based on n*sigma instead of fixed"}; + Configurable useSigmaBasedMassCutOmega{"useSigmaBasedMassCutOmega", true, "Mass window based on n*sigma instead of fixed"}; + Configurable massWindowOmegaNsigma{"massWindowOmegaNsigma", 6, "Inv. mass window for tracked Omega"}; + Configurable massWindowXiNsigma{"massWindowXiNsigma", 6, "Inv. mass window for tracked Xi"}; // Selections criteria for tracks Configurable hEta{"hEta", 0.9f, "Eta range for trigger particles"}; @@ -128,7 +132,7 @@ struct strangenessFilter { Configurable materialCorrectionType{"materialCorrectionType", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"}; Configurable minNoClsTrackedCascade{"minNoClsTrackedCascade", 70, "Minimum number of clusters required for daughters of tracked cascades"}; Configurable minPtTrackedCascade{"minPtTrackedCascade", 0., "Min. pt for tracked cascades"}; - Configurable useNsigmaCutTrackedXi{"useNsigmaCutTrackedXi", false, "Mass window based on n*sigma instead of fixed"}; + Configurable useNsigmaCutTrackedXi{"useNsigmaCutTrackedXi", true, "Mass window based on n*sigma instead of fixed"}; Configurable useNsigmaCutTrackedOmega{"useNsigmaCutTrackedOmega", true, "Mass window based on n*sigma instead of fixed"}; Configurable massWindowTrackedOmegaNsigma{"massWindowTrackedOmegaNsigma", 6, "Inv. mass window for tracked Omega"}; Configurable massWindowTrackedXiNsigma{"massWindowTrackedXiNsigma", 6, "Inv. mass window for tracked Xi"}; @@ -144,8 +148,8 @@ struct strangenessFilter { Configurable maxNSigmaV0PiTrackedCascade{"maxNSigmaV0PiTrackedCascade", 4., "Max Nsigma for pion from V0 fromtracked Xi"}; Configurable minDcaTrackedXi{"minDcaTrackedXi", 0., "Minimum DCA for tracked cascades"}; Configurable maxCpaTrackedXi{"maxCpaTrackedXi", 1., "Maximum CPA for tracked cascades"}; - Configurable minDcaTrackedOmega{"minDcaTrackedOmega", 0., "Minimum DCA for tracked cascades"}; - Configurable maxCpaTrackedOmega{"maxCpaTrackedOmega", 1., "Maximum CPA for tracked cascades"}; + Configurable minDcaTrackedOmega{"minDcaTrackedOmega", 0., "Minimum DCA for tracked cascades (ST)"}; + Configurable maxCpaTrackedOmega{"maxCpaTrackedOmega", 1., "Maximum CPA for tracked cascades (ST)"}; Configurable> parSigmaMass{ "parSigmaMass", {stfilter::massSigmaParameters[0], 4, 2, @@ -360,10 +364,10 @@ struct strangenessFilter { QAHistosStrangenessTracking.add("hCpaSelectedOmega", "cpa;cpa", HistType::kTH1D, {{500, .995, 1.}}); QAHistosStrangenessTracking.add("hPtCascCand", "cascades;p_{T} (GeV/#it{c})", HistType::kTH1D, {{200, 0., 10.}}); QAHistosStrangenessTracking.add("hPtCascTracked", "tracked cascades;p_{T} (GeV/#it{c})", HistType::kTH1D, {{200, 0., 10.}}); - QAHistosStrangenessTracking.add("hPtVsMassTrkXi", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1., 3.}}); - QAHistosStrangenessTracking.add("hPtVsMassTrkOmega", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1., 3.}}); - QAHistosStrangenessTracking.add("hPtVsMassTrkXiSelected", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1., 3.}}); - QAHistosStrangenessTracking.add("hPtVsMassTrkOmegaSelected", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1., 3.}}); + QAHistosStrangenessTracking.add("hPtVsMassTrkXi", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1.2, 1.7}}); + QAHistosStrangenessTracking.add("hPtVsMassTrkOmega", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1.6, 2.1}}); + QAHistosStrangenessTracking.add("hPtVsMassTrkXiSelected", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1.2, 1.7}}); + QAHistosStrangenessTracking.add("hPtVsMassTrkOmegaSelected", "cascades;p_{T} (GeV/#it{c});m (GeV/#it{c}^2)", HistType::kTH2D, {{200, 0., 10.}, {1000, 1.6, 2.1}}); } } @@ -830,23 +834,25 @@ struct strangenessFilter { } } + const auto deltaMassXi = useSigmaBasedMassCutXi ? getMassWindow(stfilter::species::Xi, casc.pt()) : ximasswindow; + const auto deltaMassOmega = useSigmaBasedMassCutOmega ? getMassWindow(stfilter::species::Omega, casc.pt()) : omegamasswindow; isXi = (TMath::Abs(bachelor.tpcNSigmaPi()) < nsigmatpcpi) && (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) > casccospaxi) && (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) > dcav0topv) && - (TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) < ximasswindow) && + (TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) < deltaMassXi) && (TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) > omegarej) && (xiproperlifetime < properlifetimefactor * ctauxi) && (TMath::Abs(casc.yXi()) < rapidity); isXiYN = (TMath::Abs(bachelor.tpcNSigmaPi()) < nsigmatpcpi) && (casc.cascradius() > lowerradiusXiYN) && - (TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) < ximasswindow) && + (TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) < deltaMassXi) && (TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) > omegarej) && (xiproperlifetime < properlifetimefactor * ctauxi) && (TMath::Abs(casc.yXi()) < rapidity); isOmega = (TMath::Abs(bachelor.tpcNSigmaKa()) < nsigmatpcka) && (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) > casccospaomega) && (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) > dcav0topv) && - (TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < omegamasswindow) && + (TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < deltaMassOmega) && (TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) > xirej) && (casc.cascradius() < upperradiusOmega) && (omegaproperlifetime < properlifetimefactor * ctauomega) && @@ -855,7 +861,7 @@ struct strangenessFilter { (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) > casccospaomega) && (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) > dcav0topv) && (casc.cascradius() > lowerradiusOmega) && - (TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < omegamasswindow) && + (TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < deltaMassOmega) && (TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) > xirej) && (omegaproperlifetime < properlifetimefactor * ctauomega) && (TMath::Abs(casc.yOmega()) < rapidity); From b0abb848a3ed3ed923594afff398dfb74c609ad9 Mon Sep 17 00:00:00 2001 From: rbailhac Date: Wed, 20 Dec 2023 12:43:25 +0100 Subject: [PATCH 098/156] Fix (#4216) --- PWGDQ/Tasks/tableReader.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index a486cd0324c..e23ccb3bcf7 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -960,7 +960,7 @@ struct AnalysisSameEventPairing { VarManager::SetupTwoProngFwdDCAFitter(fConfigMagField.value, true, 200.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); } } else { - VarManager::SetupTwoProngDCAFitter(mMagField, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations + VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fUseAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations } } fCurrentRun = event.runNumber(); From f7180ccb91df601b83e8ae1055eba14831db5341 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Wed, 20 Dec 2023 12:54:34 +0100 Subject: [PATCH 099/156] Safety changes for V0 type (#4201) * Safety changes for V0 type * Please consider the following formatting changes (#201) * Shorten table name * Add V0/V0fC counters * Please consider the following formatting changes (#202) * Match subscription to typecast * Changes from Sir Schlepper * small bugfix --------- Co-authored-by: ALICE Builder --- EventFiltering/PWGHF/HFFilter.cxx | 13 +- EventFiltering/PWGHF/HFFilterHelpers.h | 11 +- EventFiltering/PWGLF/strangenessFilter.cxx | 29 ++-- PWGEM/PhotonMeson/TableProducer/createPCM.cxx | 2 +- .../TableProducer/candidateCreatorCascade.cxx | 106 ++++++++++---- .../TableProducer/candidateCreatorToXiPi.cxx | 11 +- PWGHF/TableProducer/trackIndexSkimCreator.cxx | 12 +- PWGLF/DataModel/LFResonanceTables.h | 3 +- PWGLF/DataModel/LFStrangenessTables.h | 131 ++++++++++++++---- .../TableProducer/LFResonanceInitializer.cxx | 7 +- PWGLF/TableProducer/QC/strangenessQC.cxx | 9 +- PWGLF/TableProducer/cascadebuilder.cxx | 130 +++++++++++------ PWGLF/TableProducer/cascadefinder.cxx | 4 +- PWGLF/TableProducer/cascademcbuilder.cxx | 41 ++---- PWGLF/TableProducer/cascadepid.cxx | 5 +- PWGLF/TableProducer/cascqaanalysis.cxx | 38 ++--- .../hStrangeCorrelationFilter.cxx | 9 +- PWGLF/TableProducer/lambdakzerobuilder.cxx | 79 ++++++++--- PWGLF/TableProducer/lambdakzerofinder.cxx | 4 +- PWGLF/TableProducer/strangederivedbuilder.cxx | 24 ++-- PWGLF/Tasks/QC/straRecoStudy.cxx | 23 +-- PWGLF/Tasks/QC/v0cascadesqa.cxx | 20 +-- PWGLF/Tasks/cascadeanalysis.cxx | 36 ++--- PWGLF/Tasks/cascadeanalysisMC.cxx | 38 ++--- PWGLF/Tasks/cascadecorrelations.cxx | 39 ++---- PWGLF/Tasks/hStrangeCorrelation.cxx | 8 +- PWGLF/Tasks/hyperon-reco-test.cxx | 28 ++-- .../PWGLF/Strangeness/strangeness_step4.cxx | 12 +- 28 files changed, 467 insertions(+), 405 deletions(-) diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 5208db8e2a1..32cb1ca6c99 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -294,7 +294,6 @@ struct HfFilter { // Main struct for HF triggers void process(CollsWithEvSel const& collisions, aod::BCsWithTimestamps const&, aod::V0Datas const& theV0s, - aod::V0sLinked const& v0Links, aod::CascDatas const& cascades, aod::Hf2Prongs const& cand2Prongs, aod::Hf3Prongs const& cand3Prongs, @@ -943,15 +942,11 @@ struct HfFilter { // Main struct for HF triggers if (!keepEvent[kCharmBarToXiBach]) { auto cascThisColl = cascades.sliceBy(cascPerCollision, thisCollId); for (const auto& casc : cascThisColl) { - if (!casc.v0_as().has_v0Data()) { // check that V0 data are stored - continue; - } auto bachelorCasc = casc.bachelor_as(); - auto v0 = casc.v0_as(); - auto v0Element = v0.v0Data_as(); - auto v0DauPos = v0Element.posTrack_as(); - auto v0DauNeg = v0Element.negTrack_as(); - if (!helper.isSelectedCascade(casc, v0Element, std::array{bachelorCasc, v0DauPos, v0DauNeg}, collision)) { + auto v0DauPos = casc.posTrack_as(); + auto v0DauNeg = casc.negTrack_as(); + + if (!helper.isSelectedCascade(casc, std::array{bachelorCasc, v0DauPos, v0DauNeg}, collision)) { continue; } if (activateQA) { diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index 623c5ffe8b5..906cb440f39 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -321,8 +321,8 @@ class HfFilterHelper int8_t isSelectedXicInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptXic, const int8_t isSelected, const int& activateQA, H2 hMassVsPt); template int8_t isSelectedV0(const V0& v0, const std::array& dauTracks, const Coll& collision, const int& activateQA, H2 hV0Selected, std::array& hArmPod); - template - bool isSelectedCascade(const Casc& casc, const V0& v0, const std::array& dauTracks, const Coll& collision); + template + bool isSelectedCascade(const Casc& casc, const std::array& dauTracks, const Coll& collision); template int8_t isSelectedBachelorForCharmBaryon(const T& track, const T2& dca); template @@ -954,12 +954,11 @@ inline int8_t HfFilterHelper::isSelectedV0(const V0& v0, const std::array& /// Basic selection of cascade candidates /// \param casc is the cascade candidate -/// \param v0 is the cascade daughter /// \param dauTracks is a 3-element array with bachelor, positive and negative V0 daughter tracks /// \param collision is the collision /// \return true if cascade passes all cuts -template -inline bool HfFilterHelper::isSelectedCascade(const Casc& casc, const V0& v0, const std::array& dauTracks, const Coll& collision) +template +inline bool HfFilterHelper::isSelectedCascade(const Casc& casc, const std::array& dauTracks, const Coll& collision) { // eta of daughters if (std::fabs(dauTracks[0].eta()) > 1. || std::fabs(dauTracks[1].eta()) > 1. || std::fabs(dauTracks[2].eta()) > 1.) { // cut all V0 daughters with |eta| > 1. @@ -967,7 +966,7 @@ inline bool HfFilterHelper::isSelectedCascade(const Casc& casc, const V0& v0, co } // V0 radius - if (v0.v0radius() < 1.2) { + if (casc.v0radius() < 1.2) { return false; } diff --git a/EventFiltering/PWGLF/strangenessFilter.cxx b/EventFiltering/PWGLF/strangenessFilter.cxx index fbf81268b51..76ca6de6969 100644 --- a/EventFiltering/PWGLF/strangenessFilter.cxx +++ b/EventFiltering/PWGLF/strangenessFilter.cxx @@ -400,7 +400,7 @@ struct strangenessFilter { strgtable(keepEvent[0], keepEvent[1], keepEvent[2], keepEvent[3], keepEvent[4], keepEvent[5], keepEvent[6], keepEvent[7], keepEvent[8]); } - void processRun2(CollisionCandidates const& collision, TrackCandidates const& tracks, Cascades const& fullCasc, aod::V0sLinked const&, aod::V0Datas const& v0data, DaughterTracks& dtracks) + void processRun2(CollisionCandidates const& collision, TrackCandidates const& tracks, Cascades const& fullCasc, DaughterTracks& dtracks) { // Is event good? [0] = Omega, [1] = high-pT hadron + Xi, [2] = 2Xi, [3] = 3Xi, [4] = 4Xi, [5] single-Xi, [6] Omega with high radius // [7] tracked Xi, [8] tracked Omega, [9] tracked V0, [10] tracked 3Body @@ -448,14 +448,9 @@ struct strangenessFilter { for (auto& casc : fullCasc) { // loop over cascades triggcounterForEstimates = 0; - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - continue; // skip those cascades for which V0 doesn't exist - } - auto v0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists auto bachelor = casc.bachelor_as(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); bool isXi = false; bool isXiYN = false; @@ -661,8 +656,8 @@ struct strangenessFilter { ////////// Strangeness Filter - Run 3 MC ///////////// ////////////////////////////////////////////////////// - void processRun3(CollisionCandidatesRun3 const& collision, TrackCandidates const& tracks, Cascades const& fullCasc, aod::V0sLinked const&, aod::V0Datas const& v0data, DaughterTracks& dtracks, - aod::AssignedTrackedCascades const& trackedCascades, aod::Cascades const& cascades, aod::AssignedTrackedV0s const& trackedV0s, aod::AssignedTracked3Bodys const& tracked3Bodys, aod::BCsWithTimestamps const&) + void processRun3(CollisionCandidatesRun3 const& collision, TrackCandidates const& tracks, Cascades const& fullCasc, DaughterTracks& dtracks, + aod::AssignedTrackedCascades const& trackedCascades, aod::Cascades const& cascades, aod::AssignedTrackedV0s const& trackedV0s, aod::AssignedTracked3Bodys const& tracked3Bodys, aod::V0s const&, aod::BCsWithTimestamps const&) { // Is event good? [0] = Omega, [1] = high-pT hadron + Xi, [2] = 2Xi, [3] = 3Xi, [4] = 4Xi, [5] single-Xi, [6] Omega with high radius // [7] tracked Xi, [8] tracked Omega, [9] tracked V0, [10] tracked 3Body @@ -707,16 +702,10 @@ struct strangenessFilter { triggcounterForEstimates = 0; hCandidate->Fill(0.5); // All candidates - - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - continue; // skip those cascades for which V0 doesn't exist - } - hCandidate->Fill(1.5); // V0 exists - auto v0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists + hCandidate->Fill(1.5); // V0 exists - deprecated auto bachelor = casc.bachelor_as(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); bool isXi = false; bool isXiYN = false; @@ -1119,7 +1108,7 @@ struct strangenessFilter { // const auto itsTrack = trackedCascade.itsTrack(); const auto cascade = trackedCascade.cascade(); const auto bachelor = cascade.bachelor_as(); - const auto v0 = cascade.v0_as(); + const auto v0 = cascade.v0_as(); const auto negTrack = v0.negTrack_as(); const auto posTrack = v0.posTrack_as(); diff --git a/PWGEM/PhotonMeson/TableProducer/createPCM.cxx b/PWGEM/PhotonMeson/TableProducer/createPCM.cxx index 6462da5bebf..aad89e2ab67 100644 --- a/PWGEM/PhotonMeson/TableProducer/createPCM.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createPCM.cxx @@ -310,7 +310,7 @@ struct createPCM { pvec0[0], pvec0[1], pvec0[2], pvec1[0], pvec1[1], pvec1[2], v0dca, pos.dcaXY(), ele.dcaXY(), - v0CosinePA, dcaV0toPV); + v0CosinePA, dcaV0toPV, 3); // v0 type: photon-exclusive } else { // LOGF(info, "storing: collision.globalIndex() = %d , pos.globalIndex() = %d , ele.globalIndex() = %d, cospa = %f", collision.globalIndex(), pos.globalIndex(), ele.globalIndex(), v0CosinePA); pca_map[std::make_tuple(pos.globalIndex(), ele.globalIndex(), collision.globalIndex())] = v0dca; diff --git a/PWGHF/TableProducer/candidateCreatorCascade.cxx b/PWGHF/TableProducer/candidateCreatorCascade.cxx index b848651179b..04d99fb4d2d 100644 --- a/PWGHF/TableProducer/candidateCreatorCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorCascade.cxx @@ -87,9 +87,10 @@ struct HfCandidateCreatorCascade { void process(aod::Collisions const&, aod::HfCascades const& rowsTrackIndexCasc, - aod::TracksWCov const&, aod::V0sLinked const&, aod::V0Datas const&, + aod::V0fCDatas const&, + aod::TracksWCov const&, aod::BCsWithTimestamps const&) { // 2-prong vertex fitter @@ -105,23 +106,80 @@ struct HfCandidateCreatorCascade { // loop over pairs of track indices for (const auto& casc : rowsTrackIndexCasc) { - const auto& bach = casc.prong0_as(); LOGF(debug, "V0 %d in HF cascade %d.", casc.v0Id(), casc.globalIndex()); if (!casc.has_v0()) { LOGF(error, "V0 not there for HF cascade %d. Skipping candidate.", casc.globalIndex()); continue; } - if (!casc.v0_as().has_v0Data()) { - if (!silenceV0DataWarning) { - LOGF(warning, "V0Data not there for V0 %d in HF cascade %d. Skipping candidate.", casc.v0Id(), casc.globalIndex()); - } - continue; + + int posGlobalIndex = -1, negGlobalIndex = -1; + float v0x, v0y, v0z, v0px, v0py, v0pz; + float v0PosPx, v0PosPy, v0PosPz, v0NegPx, v0NegPy, v0NegPz; + float dcaV0dau, dcaPosToPV, dcaNegToPV, v0cosPA; + float posTrackX, negTrackX; + o2::track::TrackParCov trackParCovV0DaughPos; + o2::track::TrackParCov trackParCovV0DaughNeg; + + auto v0index = casc.v0_as(); + if (v0index.has_v0Data()) { + // this V0 passed both standard V0 and cascade V0 selections + auto v0row = v0index.v0Data(); + const auto& trackV0DaughPos = v0row.posTrack_as(); + const auto& trackV0DaughNeg = v0row.negTrack_as(); + trackParCovV0DaughPos = getTrackParCov(trackV0DaughPos); // check that aod::TracksWCov does not need TracksDCA! + trackParCovV0DaughNeg = getTrackParCov(trackV0DaughNeg); // check that aod::TracksWCov does not need TracksDCA! + posGlobalIndex = trackV0DaughPos.globalIndex(); + negGlobalIndex = trackV0DaughNeg.globalIndex(); + v0x = v0row.x(); + v0y = v0row.y(); + v0z = v0row.z(); + v0px = v0row.px(); + v0py = v0row.py(); + v0pz = v0row.pz(); + v0PosPx = v0row.pxpos(); + v0PosPy = v0row.pypos(); + v0PosPz = v0row.pzpos(); + v0NegPx = v0row.pxneg(); + v0NegPy = v0row.pyneg(); + v0NegPz = v0row.pzneg(); + dcaV0dau = v0row.dcaV0daughters(); + dcaPosToPV = v0row.dcapostopv(); + dcaNegToPV = v0row.dcanegtopv(); + v0cosPA = v0row.v0cosPA(); + posTrackX = v0row.posX(); + negTrackX = v0row.negX(); + } else if (v0index.has_v0fCData()) { + // this V0 passes only V0-for-cascade selections, use that instead + auto v0row = v0index.v0fCData(); + const auto& trackV0DaughPos = v0row.posTrack_as(); + const auto& trackV0DaughNeg = v0row.negTrack_as(); + trackParCovV0DaughPos = getTrackParCov(trackV0DaughPos); // check that aod::TracksWCov does not need TracksDCA! + trackParCovV0DaughNeg = getTrackParCov(trackV0DaughNeg); // check that aod::TracksWCov does not need TracksDCA! + posGlobalIndex = trackV0DaughPos.globalIndex(); + negGlobalIndex = trackV0DaughNeg.globalIndex(); + v0x = v0row.x(); + v0y = v0row.y(); + v0z = v0row.z(); + v0px = v0row.px(); + v0py = v0row.py(); + v0pz = v0row.pz(); + v0PosPx = v0row.pxpos(); + v0PosPy = v0row.pypos(); + v0PosPz = v0row.pzpos(); + v0NegPx = v0row.pxneg(); + v0NegPy = v0row.pyneg(); + v0NegPz = v0row.pzneg(); + dcaV0dau = v0row.dcaV0daughters(); + dcaPosToPV = v0row.dcapostopv(); + dcaNegToPV = v0row.dcanegtopv(); + v0cosPA = v0row.v0cosPA(); + posTrackX = v0row.posX(); + negTrackX = v0row.negX(); + } else { + LOGF(warning, "V0Data/V0fCData not there for V0 %d in HF cascade %d. Skipping candidate.", casc.v0Id(), casc.globalIndex()); + continue; // this was inadequately linked, should not happen } - LOGF(debug, "V0Data ID: %d", casc.v0_as().v0DataId()); - const auto& v0 = casc.v0_as().v0Data(); - const auto& trackV0DaughPos = v0.posTrack_as(); - const auto& trackV0DaughNeg = v0.negTrack_as(); auto collision = casc.collision(); @@ -137,12 +195,10 @@ struct HfCandidateCreatorCascade { df.setBz(bz); auto trackParCovBach = getTrackParCov(bach); - auto trackParCovV0DaughPos = getTrackParCov(trackV0DaughPos); // check that aod::TracksWCov does not need TracksDCA! - auto trackParCovV0DaughNeg = getTrackParCov(trackV0DaughNeg); // check that aod::TracksWCov does not need TracksDCA! - trackParCovV0DaughPos.propagateTo(v0.posX(), bz); // propagate the track to the X closest to the V0 vertex - trackParCovV0DaughNeg.propagateTo(v0.negX(), bz); // propagate the track to the X closest to the V0 vertex - const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; - const std::array momentumV0 = {v0.px(), v0.py(), v0.pz()}; + trackParCovV0DaughPos.propagateTo(posTrackX, bz); // propagate the track to the X closest to the V0 vertex + trackParCovV0DaughNeg.propagateTo(negTrackX, bz); // propagate the track to the X closest to the V0 vertex + const std::array vertexV0 = {v0x, v0y, v0z}; + const std::array momentumV0 = {v0px, v0py, v0pz}; // we build the neutral track to then build the cascade auto trackV0 = o2::dataformats::V0(vertexV0, momentumV0, {0, 0, 0, 0, 0, 0}, trackParCovV0DaughPos, trackParCovV0DaughNeg); // build the V0 track (indices for v0 daughters set to 0 for now) @@ -194,15 +250,15 @@ struct HfCandidateCreatorCascade { impactParameterBach.getY(), impactParameterV0.getY(), std::sqrt(impactParameterBach.getSigmaY2()), std::sqrt(impactParameterV0.getSigmaY2()), casc.prong0Id(), casc.v0Id(), - v0.x(), v0.y(), v0.z(), + v0x, v0y, v0z, // v0.posTrack(), v0.negTrack(), // why this was not fine? - trackV0DaughPos.globalIndex(), trackV0DaughNeg.globalIndex(), - v0.pxpos(), v0.pypos(), v0.pzpos(), - v0.pxneg(), v0.pyneg(), v0.pzneg(), - v0.dcaV0daughters(), - v0.dcapostopv(), - v0.dcanegtopv(), - v0.v0cosPA()); + posGlobalIndex, negGlobalIndex, + v0PosPx, v0PosPy, v0PosPz, + v0NegPx, v0NegPy, v0NegPz, + dcaV0dau, + dcaPosToPV, + dcaNegToPV, + v0cosPA); // fill histograms if (fillHistograms) { diff --git a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx index 0f7e503907f..89c3ef83fe3 100644 --- a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx @@ -82,7 +82,6 @@ struct HfCandidateCreatorToXiPi { using MyCascTable = soa::Join; // to use strangeness tracking, use aod::TraCascDatas instead of aod::CascDatas using CascadesLinked = soa::Join; using MyV0Table = soa::Join; - using V0sLinked = soa::Join; using MySkimIdx = soa::Filtered; Filter filterSelectIndexes = (aod::hf_track_index::hfflag > static_cast(0)); @@ -104,7 +103,6 @@ struct HfCandidateCreatorToXiPi { aod::BCsWithTimestamps const&, TracksWCovDca const&, MyCascTable const&, CascadesLinked const&, - MyV0Table const&, V0sLinked const&, MySkimIdx const& candidates) { @@ -148,12 +146,11 @@ struct HfCandidateCreatorToXiPi { auto trackPion = cand.prong0_as(); auto cascAodElement = cand.cascade_as(); + int v0index = cascAodElement.v0Id(); auto casc = cascAodElement.cascData_as(); auto trackXiDauCharged = casc.bachelor_as(); // pion <- xi track - auto v0AodElement = casc.v0_as(); - auto v0 = v0AodElement.v0Data_as(); // V0 <-- xi - auto trackV0Dau0 = v0.posTrack_as(); // V0 positive daughter track - auto trackV0Dau1 = v0.negTrack_as(); // V0 negative daughter track + auto trackV0Dau0 = casc.posTrack_as(); // V0 positive daughter track + auto trackV0Dau1 = casc.negTrack_as(); // V0 negative daughter track //-------------------------- V0 info--------------------------- // pseudorapidity @@ -315,7 +312,7 @@ struct HfCandidateCreatorToXiPi { impactParameterCasc.getY(), impactParPiFromCharmBaryonXY, impactParameterCasc.getZ(), impactParPiFromCharmBaryonZ, std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterPiFromCharmBaryon.getSigmaY2()), - casc.v0Id(), v0.posTrackId(), v0.negTrackId(), + v0index, casc.posTrackId(), casc.negTrackId(), casc.cascadeId(), trackPion.globalIndex(), casc.bachelorId(), mLambda, mCasc, mCharmBaryon, cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 20ee224bc03..19b3717a926 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -3381,7 +3381,6 @@ struct HfTrackIndexSkimCreatorLfCascades { SelectedHfTrackAssoc const& trackIndices, aod::TracksWCovDca const& tracks, aod::BCsWithTimestamps const&, - aod::V0sLinked const&, V0Full const&) { @@ -3432,16 +3431,9 @@ struct HfTrackIndexSkimCreatorLfCascades { // cascade daughter - charged particle auto trackXiDauCharged = casc.bachelor_as(); // pion <- xi track // cascade daughter - V0 - if (!casc.v0_as().has_v0Data()) { // check if V0 data are stored - continue; - } - registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists - auto v0 = casc.v0_as(); - auto v0Element = v0.v0Data_as(); // V0 element from LF table containing V0 info - // V0 positive daughter - auto trackV0PosDau = v0Element.posTrack_as(); // p <- V0 track (positive track) 0 + auto trackV0PosDau = casc.posTrack_as(); // p <- V0 track (positive track) 0 // V0 negative daughter - auto trackV0NegDau = v0Element.negTrack_as(); // pion <- V0 track (negative track) 1 + auto trackV0NegDau = casc.negTrack_as(); // pion <- V0 track (negative track) 1 // check that particles come from the same collision if (rejDiffCollTrack) { diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 5fef3be9aa6..d44b43c1a77 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -64,6 +64,7 @@ DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations +DECLARE_SOA_COLUMN(CascadeIndices, cascIndices, int[3]); //! Field for the track indices to remove auto-correlations (ordered: positive, negative, bachelor) DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows DECLARE_SOA_COLUMN(IsGlobalTrackWoDCA, isGlobalTrackWoDCA, bool); //! Is global track without DCA @@ -164,7 +165,7 @@ DECLARE_SOA_TABLE(ResoCascades, "AOD", "RESOCASCADES", resodaughter::Pz, resodaughter::Eta, resodaughter::Phi, - resodaughter::Indices, + resodaughter::CascadeIndices, resodaughter::V0CosPA, resodaughter::CascCosPA, resodaughter::DaughDCA, diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 4db1d3d6cce..641e500669f 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -103,11 +103,11 @@ DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); //! pdg code DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, bool); //! primary criterion } // namespace motherParticle -DECLARE_SOA_TABLE(MotherMCParticles, "AOD", "MOTHERMCPART", //! mother MC information +DECLARE_SOA_TABLE(MotherMCParts, "AOD", "MOTHERMCPARTS", //! mother MC information, abbreviated name due to size limit motherParticle::Px, motherParticle::Py, motherParticle::Pz, motherParticle::PDGCode, motherParticle::IsPhysicalPrimary); -using MotherMCParticle = MotherMCParticles::iterator; +using MotherMCPart = MotherMCParts::iterator; namespace v0data { @@ -121,7 +121,7 @@ DECLARE_SOA_INDEX_COLUMN(V0, v0); //! DECLARE_SOA_INDEX_COLUMN_FULL(PosTrackExtra, posTrackExtra, int, DauTrackExtras, "_PosExtra"); //! DECLARE_SOA_INDEX_COLUMN_FULL(NegTrackExtra, negTrackExtra, int, DauTrackExtras, "_NegExtra"); //! DECLARE_SOA_INDEX_COLUMN(StraCollision, straCollision); //! -DECLARE_SOA_INDEX_COLUMN(MotherMCParticle, motherMCParticle); //! +DECLARE_SOA_INDEX_COLUMN(MotherMCPart, motherMCPart); //! //______________________________________________________ // REGULAR COLUMNS FOR V0CORES @@ -145,6 +145,9 @@ DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! DCA negative pron DECLARE_SOA_COLUMN(V0CosPA, v0cosPA, float); //! V0 CosPA DECLARE_SOA_COLUMN(DCAV0ToPV, dcav0topv, float); //! DCA V0 to PV +// Type of V0 from the svertexer (photon, regular, from cascade) +DECLARE_SOA_COLUMN(V0Type, v0Type, uint8_t); //! type of V0. 0: built solely for cascades (does not pass standard V0 cuts), 1: standard 2, 3: photon-like with TPC-only use. Regular analysis should always use type 1. + // Saved from finding: covariance matrix of parent track (on request) DECLARE_SOA_COLUMN(PositionCovMat, positionCovMat, float[6]); //! covariance matrix elements DECLARE_SOA_COLUMN(MomentumCovMat, momentumCovMat, float[6]); //! covariance matrix elements @@ -325,10 +328,15 @@ DECLARE_SOA_DYNAMIC_COLUMN(PositiveEta, positiveeta, //! positive daughter eta [](float PxPos, float PyPos, float PzPos) -> float { return RecoDecay::eta(std::array{PxPos, PyPos, PzPos}); }); DECLARE_SOA_DYNAMIC_COLUMN(PositivePhi, positivephi, //! positive daughter phi [](float PxPos, float PyPos) -> float { return RecoDecay::phi(PxPos, PyPos); }); + +DECLARE_SOA_DYNAMIC_COLUMN(IsStandardV0, isStandardV0, //! is standard V0 + [](uint8_t V0Type) -> bool { return V0Type & (1 << 0); }); +DECLARE_SOA_DYNAMIC_COLUMN(IsPhotonTPConly, isPhotonTPConly, //! is photon V0 + [](uint8_t V0Type) -> bool { return V0Type & (1 << 1); }); } // namespace v0data DECLARE_SOA_TABLE(V0Indices, "AOD", "V0INDEX", //! index table when using AO2Ds - o2::soa::Index<>, v0data::PosTrackId, v0data::NegTrackId, v0data::CollisionId, v0data::V0Id); + o2::soa::Index<>, v0data::PosTrackId, v0data::NegTrackId, v0data::CollisionId, v0data::V0Id, o2::soa::Marker<1>); DECLARE_SOA_TABLE(V0CollRefs, "AOD", "V0COLLREF", //! optional table to refer back to a collision o2::soa::Index<>, v0data::StraCollisionId); @@ -337,14 +345,14 @@ DECLARE_SOA_TABLE(V0Extras, "AOD", "V0EXTRA", //! optional table to refer to cus o2::soa::Index<>, v0data::PosTrackExtraId, v0data::NegTrackExtraId); DECLARE_SOA_TABLE(V0TrackXs, "AOD", "V0TRACKX", //! track X positions at minima when using AO2Ds - v0data::PosX, v0data::NegX); + v0data::PosX, v0data::NegX, o2::soa::Marker<1>); DECLARE_SOA_TABLE_FULL(StoredV0Cores, "V0Cores", "AOD", "V0CORE", //! core information about decay, viable with AO2Ds or derived v0data::X, v0data::Y, v0data::Z, v0data::PxPos, v0data::PyPos, v0data::PzPos, v0data::PxNeg, v0data::PyNeg, v0data::PzNeg, v0data::DCAV0Daughters, v0data::DCAPosToPV, v0data::DCANegToPV, - v0data::V0CosPA, v0data::DCAV0ToPV, + v0data::V0CosPA, v0data::DCAV0ToPV, v0data::V0Type, // Dynamic columns v0data::PtHypertriton, @@ -355,7 +363,7 @@ DECLARE_SOA_TABLE_FULL(StoredV0Cores, "V0Cores", "AOD", "V0CORE", //! core infor v0data::QtArm, v0data::PsiPair, v0data::PFracPos, - v0data::PFracNeg, + v0data::PFracNeg, // 24 // Invariant masses v0data::MLambda, @@ -377,14 +385,73 @@ DECLARE_SOA_TABLE_FULL(StoredV0Cores, "V0Cores", "AOD", "V0CORE", //! core infor v0data::NegativeEta, v0data::NegativePhi, v0data::PositiveEta, - v0data::PositivePhi); + v0data::PositivePhi, + v0data::IsStandardV0, + v0data::IsPhotonTPConly, + o2::soa::Marker<1>); // extended table with expression columns that can be used as arguments of dynamic columns DECLARE_SOA_EXTENDED_TABLE_USER(V0Cores, StoredV0Cores, "V0COREEXT", //! v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study DECLARE_SOA_TABLE_FULL(V0Covs, "V0Covs", "AOD", "V0COVS", //! V0 covariance matrices - v0data::PositionCovMat, v0data::MomentumCovMat); + v0data::PositionCovMat, v0data::MomentumCovMat, o2::soa::Marker<1>); + +DECLARE_SOA_TABLE(V0fCIndices, "AOD", "V0FCINDEX", //! index table when using AO2Ds + o2::soa::Index<>, v0data::PosTrackId, v0data::NegTrackId, v0data::CollisionId, v0data::V0Id, o2::soa::Marker<2>); + +DECLARE_SOA_TABLE(V0fCTrackXs, "AOD", "V0FCTRACKX", //! track X positions at minima when using AO2Ds + v0data::PosX, v0data::NegX, o2::soa::Marker<2>); + +DECLARE_SOA_TABLE_FULL(StoredV0fCCores, "V0fCCores", "AOD", "V0FCCORE", //! core information about decay, exclusive to V0s used in cascades but not passing in V0 selections - multiple viable getters skipped since use is protected to cascades only + v0data::X, v0data::Y, v0data::Z, + v0data::PxPos, v0data::PyPos, v0data::PzPos, + v0data::PxNeg, v0data::PyNeg, v0data::PzNeg, + v0data::DCAV0Daughters, v0data::DCAPosToPV, v0data::DCANegToPV, + v0data::V0CosPA, v0data::DCAV0ToPV, v0data::V0Type, + + // Dynamic columns + v0data::PtHypertriton, + v0data::PtAntiHypertriton, + v0data::V0Radius, + v0data::DistOverTotMom, + v0data::Alpha, + v0data::QtArm, + v0data::PsiPair, + v0data::PFracPos, + v0data::PFracNeg, // 24 + + // Invariant masses + v0data::MLambda, + v0data::MAntiLambda, + v0data::MK0Short, + v0data::MGamma, + v0data::MHypertriton, + v0data::MAntiHypertriton, + v0data::M, + + // Longitudinal + v0data::YK0Short, + v0data::YLambda, + v0data::YHypertriton, + v0data::YAntiHypertriton, + v0data::Rapidity, + v0data::NegativePt, + v0data::PositivePt, + v0data::NegativeEta, + v0data::NegativePhi, + v0data::PositiveEta, + v0data::PositivePhi, + v0data::IsStandardV0, + v0data::IsPhotonTPConly, + o2::soa::Marker<2>); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(V0fCCores, StoredV0fCCores, "V0FCCOREEXT", //! + v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study + +DECLARE_SOA_TABLE_FULL(V0fCCovs, "V0fCCovs", "AOD", "V0FCCOVS", //! V0 covariance matrices + v0data::PositionCovMat, v0data::MomentumCovMat, o2::soa::Marker<2>); DECLARE_SOA_TABLE(V0MCCores, "AOD", "V0MCCORE", //! MC properties of the V0 for posterior analysis v0data::PDGCode, v0data::PDGCodeMother, @@ -394,13 +461,15 @@ DECLARE_SOA_TABLE(V0MCCores, "AOD", "V0MCCORE", //! MC properties of the V0 for v0data::PxNegMC, v0data::PyNegMC, v0data::PzNegMC); DECLARE_SOA_TABLE(V0MCMothers, "AOD", "V0MCMOTHER", //! optional table for MC mothers - o2::soa::Index<>, v0data::MotherMCParticleId); + o2::soa::Index<>, v0data::MotherMCPartId); using V0Index = V0Indices::iterator; using V0Core = V0Cores::iterator; using V0TrackX = V0TrackXs::iterator; using V0Datas = soa::Join; using V0Data = V0Datas::iterator; +using V0fCDatas = soa::Join; +using V0fCData = V0fCDatas::iterator; using V0MCDatas = soa::Join; using V0MCData = V0MCDatas::iterator; @@ -408,11 +477,12 @@ using V0MCData = V0MCDatas::iterator; namespace v0data { DECLARE_SOA_INDEX_COLUMN(V0Data, v0Data); //! Index to V0Data entry +DECLARE_SOA_INDEX_COLUMN(V0fCData, v0fCData); //! Index to V0Data entry DECLARE_SOA_INDEX_COLUMN_FULL(V0MC, v0MC, int, V0MCCores, "_MC"); //! } DECLARE_SOA_TABLE(V0DataLink, "AOD", "V0DATALINK", //! Joinable table with V0s which links to V0Data which is not produced for all entries - v0data::V0DataId); + o2::soa::Index<>, v0data::V0DataId, v0data::V0fCDataId); DECLARE_SOA_TABLE(V0MCRefs, "AOD", "V0MCREF", //! index table when using AO2Ds o2::soa::Index<>, v0data::V0MCId); @@ -472,18 +542,20 @@ namespace cascdata { //______________________________________________________ // REGULAR COLUMNS FOR CASCINDICES -DECLARE_SOA_INDEX_COLUMN(V0, v0); //! -DECLARE_SOA_INDEX_COLUMN(Cascade, cascade); //! -DECLARE_SOA_INDEX_COLUMN_FULL(Bachelor, bachelor, int, Tracks, ""); //! -DECLARE_SOA_INDEX_COLUMN_FULL(StrangeTrack, strangeTrack, int, Tracks, ""); //! -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! +DECLARE_SOA_INDEX_COLUMN(V0, v0); //! +DECLARE_SOA_INDEX_COLUMN(Cascade, cascade); //! +DECLARE_SOA_INDEX_COLUMN_FULL(PosTrack, posTrack, int, Tracks, "_Pos"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(NegTrack, negTrack, int, Tracks, "_Neg"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(Bachelor, bachelor, int, Tracks, "_Bach"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(StrangeTrack, strangeTrack, int, Tracks, "_Strange"); //! +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! // FOR DERIVED -DECLARE_SOA_INDEX_COLUMN_FULL(PosTrackExtra, posTrackExtra, int, DauTrackExtras, "_PosExtra"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(NegTrackExtra, negTrackExtra, int, DauTrackExtras, "_NegExtra"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(BachTrackExtra, bachTrackExtra, int, DauTrackExtras, "_BachExtra"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(PosTrackExtra, posTrackExtra, int, DauTrackExtras, "_PosExtra"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(NegTrackExtra, negTrackExtra, int, DauTrackExtras, "_NegExtra"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(BachTrackExtra, bachTrackExtra, int, DauTrackExtras, "_BachExtra"); //! DECLARE_SOA_INDEX_COLUMN_FULL(StrangeTrackExtra, strangeTrackExtra, int, DauTrackExtras, "_StrangeExtra"); //! -DECLARE_SOA_INDEX_COLUMN(StraCollision, straCollision); //! -DECLARE_SOA_INDEX_COLUMN(MotherMCParticle, motherMCParticle); //! +DECLARE_SOA_INDEX_COLUMN(StraCollision, straCollision); //! +DECLARE_SOA_INDEX_COLUMN(MotherMCPart, motherMCPart); //! //______________________________________________________ // REGULAR COLUMNS FOR CASCCORES @@ -519,6 +591,11 @@ DECLARE_SOA_COLUMN(DCABachToPV, dcabachtopv, float); //! DECLARE_SOA_COLUMN(DCAXYCascToPV, dcaXYCascToPV, float); //! DECLARE_SOA_COLUMN(DCAZCascToPV, dcaZCascToPV, float); //! +// Saved from finding: track position at minima +DECLARE_SOA_COLUMN(PosX, posX, float); //! positive track X at min +DECLARE_SOA_COLUMN(NegX, negX, float); //! negative track X at min +DECLARE_SOA_COLUMN(BachX, bachX, float); //! bachelor track X at min + //______________________________________________________ // REGULAR COLUMNS FOR CASCCOVS // Saved from finding: covariance matrix of parent track (on request) @@ -665,11 +742,11 @@ DECLARE_SOA_EXPRESSION_COLUMN(Eta, eta, float, //! Pseudorapidity, conditionally // as possible for ease of use and comparison DECLARE_SOA_TABLE(CascIndices, "AOD", "CascINDEX", //! index table when using AO2Ds - o2::soa::Index<>, cascdata::V0Id, cascdata::CascadeId, cascdata::BachelorId, cascdata::CollisionId, o2::soa::Marker<1>); + o2::soa::Index<>, cascdata::CascadeId, v0data::PosTrackId, v0data::NegTrackId, cascdata::BachelorId, cascdata::CollisionId, o2::soa::Marker<1>); DECLARE_SOA_TABLE(KFCascIndices, "AOD", "KFCascINDEX", //! index table when using AO2Ds - o2::soa::Index<>, cascdata::V0Id, cascdata::CascadeId, cascdata::BachelorId, cascdata::CollisionId, o2::soa::Marker<2>); + o2::soa::Index<>, cascdata::CascadeId, v0data::PosTrackId, v0data::NegTrackId, cascdata::BachelorId, cascdata::CollisionId, o2::soa::Marker<2>); DECLARE_SOA_TABLE(TraCascIndices, "AOD", "TraCascINDEX", //! index table when using AO2Ds - o2::soa::Index<>, cascdata::V0Id, cascdata::CascadeId, cascdata::BachelorId, cascdata::StrangeTrackId, cascdata::CollisionId); + o2::soa::Index<>, cascdata::CascadeId, v0data::PosTrackId, v0data::NegTrackId, cascdata::BachelorId, cascdata::StrangeTrackId, cascdata::CollisionId); DECLARE_SOA_TABLE(CascCollRefs, "AOD", "CASCCOLLREF", //! optional table to refer back to a collision o2::soa::Index<>, cascdata::StraCollisionId, o2::soa::Marker<1>); @@ -684,6 +761,10 @@ DECLARE_SOA_TABLE(CascExtras, "AOD", "CASCEXTRA", //! optional table to refer to DECLARE_SOA_TABLE(StraTrackExtras, "AOD", "STRATRACKEXTRAS", //! optional table to refer to custom track extras o2::soa::Index<>, cascdata::StrangeTrackExtraId); +// Track positions at minima (valid for regular cascade table), replayable +DECLARE_SOA_TABLE(CascTrackXs, "AOD", "CASCTRACKX", //! track X positions at minima when using AO2Ds + cascdata::PosX, cascdata::NegX, cascdata::BachX); + DECLARE_SOA_TABLE(StoredCascCores, "AOD", "CASCCORE", //! core information about decay, viable with AO2Ds or derived cascdata::Sign, cascdata::MXi, cascdata::MOmega, cascdata::X, cascdata::Y, cascdata::Z, @@ -778,7 +859,7 @@ DECLARE_SOA_TABLE(CascMCCores, "AOD", "CASCMCCORE", //! bachelor-baryon correlat cascdata::PxMC, cascdata::PyMC, cascdata::PzMC); DECLARE_SOA_TABLE(CascMCMothers, "AOD", "CASCMCMOTHER", //! optional table for MC mothers - o2::soa::Index<>, cascdata::MotherMCParticleId); + o2::soa::Index<>, cascdata::MotherMCPartId); DECLARE_SOA_TABLE(CascBBs, "AOD", "CASCBB", //! bachelor-baryon correlation variables cascdata::BachBaryonCosPA, cascdata::BachBaryonDCAxyToPV) diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 07a5d67a64a..52c9dd91022 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -490,12 +490,13 @@ struct reso2initializer { template void fillCascades(CollisionType const& collision, CascType const& cascades, TrackType const& tracks) { - int childIDs[2] = {0, 0}; // these IDs are necessary to keep track of the children + int childIDs[3] = {0, 0, 0}; // these IDs are necessary to keep track of the children for (auto& casc : cascades) { if (!IsCascSelected(collision, casc, tracks)) continue; - childIDs[0] = casc.v0Id(); - childIDs[1] = casc.bachelorId(); + childIDs[0] = casc.posTrackId(); + childIDs[1] = casc.negTrackId(); + childIDs[2] = casc.bachelorId(); reso2cascades(resoCollisions.lastIndex(), casc.pt(), casc.px(), diff --git a/PWGLF/TableProducer/QC/strangenessQC.cxx b/PWGLF/TableProducer/QC/strangenessQC.cxx index ad0875357e0..f35ad82899c 100644 --- a/PWGLF/TableProducer/QC/strangenessQC.cxx +++ b/PWGLF/TableProducer/QC/strangenessQC.cxx @@ -177,10 +177,6 @@ struct strangenessQC { // cascades loop for (const auto& casc : Cascades) { - const auto& v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) - continue; // skip those cascades for which V0 doesn't exist - // Rapidity check if (TMath::Abs(casc.yXi()) > cascadesetting_rapidity && TMath::Abs(casc.yOmega()) > cascadesetting_rapidity) { @@ -204,10 +200,9 @@ struct strangenessQC { if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascadesetting_v0masswindow) continue; - const auto& v0Casc = v0index.v0Data(); // de-reference index to correct v0data in case it exists const auto& bachDau = casc.bachelor_as(); - const auto& posDau = v0Casc.posTrack_as(); - const auto& negDau = v0Casc.negTrack_as(); + const auto& posDau = casc.posTrack_as(); + const auto& negDau = casc.negTrack_as(); float cascDecayLength = std::hypot(casc.x() - collision.posX(), casc.y() - collision.posY(), casc.z() - collision.posZ()); float cascTotalMomentum = std::hypot(casc.px(), casc.py(), casc.pz()); diff --git a/PWGLF/TableProducer/cascadebuilder.cxx b/PWGLF/TableProducer/cascadebuilder.cxx index 29c49498842..b36b445d497 100644 --- a/PWGLF/TableProducer/cascadebuilder.cxx +++ b/PWGLF/TableProducer/cascadebuilder.cxx @@ -95,6 +95,7 @@ using TracksExtraWithPIDandLabels = soa::Join; +using V0fCfull = soa::Join; using TaggedCascades = soa::Join; // For MC association in pre-selection @@ -109,7 +110,8 @@ struct cascadeBuilder { Produces cascdata; Produces kfcascdata; Produces trackedcascdata; - Produces cascbb; + Produces cascTrackXs; // if desired for replaying of position information + Produces cascbb; // if enabled Produces casccovs; // if requested by someone Produces kfcasccovs; // if requested by someone Service ccdb; @@ -118,6 +120,7 @@ struct cascadeBuilder { // Configurables related to table creation Configurable createCascCovMats{"createCascCovMats", -1, {"Produces V0 cov matrices. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; + Configurable createCascTrackXs{"createCascTrackXs", -1, {"Produces track X at minima table. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; // Topological selection criteria Configurable tpcrefit{"tpcrefit", 0, "demand TPC refit"}; @@ -215,7 +218,12 @@ struct cascadeBuilder { // Helper struct to pass cascade information struct { int v0Id; + int positiveId; + int negativeId; int bachelorId; + float positiveX; + float negativeX; + float bachelorX; int charge; std::array pos; std::array bachP; @@ -529,6 +537,11 @@ struct cascadeBuilder { LOGF(info, "Device named %s has subscribed to CascCovs table! Enabling.", device.name); createCascCovMats.value = 1; } + const std::string CascTracksXName = "CascTrackXs"; + if (input.matcher.binding == CascTracksXName) { + LOGF(info, "Device named %s has subscribed to CascTrackXs table! Enabling.", device.name); + createCascTrackXs.value = 1; + } } } @@ -760,19 +773,14 @@ struct cascadeBuilder { // to be added here as complementary information in the future } - template - bool buildCascadeCandidate(TCascObject const& cascade) + template + bool buildCascadeCandidate(TCascObject const& cascade, TV0Object const& v0) { // value 0.5: any considered cascade statisticsRegistry.cascstats[kCascAll]++; // Track casting auto bachTrack = cascade.template bachelor_as(); - auto v0index = cascade.template v0_as(); - if (!(v0index.has_v0Data())) { - return false; - } - auto v0 = v0index.template v0Data_as(); auto posTrack = v0.template posTrack_as(); auto negTrack = v0.template negTrack_as(); auto const& collision = cascade.collision(); @@ -933,8 +941,13 @@ struct cascadeBuilder { cascadecandidate.yOmega = RecoDecay::y(array{cascadecandidate.bachP[0] + v0.pxpos() + v0.pxneg(), cascadecandidate.bachP[1] + v0.pypos() + v0.pyneg(), cascadecandidate.bachP[2] + v0.pzpos() + v0.pzneg()}, o2::constants::physics::MassOmegaMinus); // Populate information - cascadecandidate.v0Id = v0index.globalIndex(); + // cascadecandidate.v0Id = v0index.globalIndex(); + cascadecandidate.positiveId = posTrack.globalIndex(); + cascadecandidate.negativeId = negTrack.globalIndex(); cascadecandidate.bachelorId = bachTrack.globalIndex(); + cascadecandidate.positiveX = v0.posX(); // from prior minimization + cascadecandidate.negativeX = v0.negX(); // from prior minimization + cascadecandidate.bachelorX = lBachelorTrack.getX(); // from this minimization cascadecandidate.v0pos[0] = v0.x(); cascadecandidate.v0pos[1] = v0.y(); cascadecandidate.v0pos[2] = v0.z(); @@ -1189,6 +1202,8 @@ struct cascadeBuilder { // basic indices cascadecandidate.v0Id = v0.globalIndex(); + cascadecandidate.positiveId = posTrack.globalIndex(); + cascadecandidate.negativeId = negTrack.globalIndex(); cascadecandidate.bachelorId = bachTrack.globalIndex(); // KF chi2 @@ -1254,11 +1269,26 @@ struct cascadeBuilder { statisticsRegistry.eventCounter++; for (auto& cascade : cascades) { - bool validCascadeCandidate = buildCascadeCandidate(cascade); + // de-reference from V0 pool, either specific for cascades or general + // use templatizing to avoid code duplication + bool validCascadeCandidate = false; + auto v0index = cascade.template v0_as(); + if (v0index.has_v0Data()) { + // this V0 passed both standard V0 and cascade V0 selections + auto v0row = v0index.template v0Data_as(); + validCascadeCandidate = buildCascadeCandidate(cascade, v0row); + } else if (v0index.has_v0fCData()) { + // this V0 passes only V0-for-cascade selections, use that instead + auto v0row = v0index.template v0fCData_as(); + validCascadeCandidate = buildCascadeCandidate(cascade, v0row); + } else { + continue; // this was inadequately linked, should not happen + } if (!validCascadeCandidate) continue; // doesn't pass cascade selections - cascidx(cascadecandidate.v0Id, cascade.globalIndex(), + cascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), + cascadecandidate.positiveId, cascadecandidate.negativeId, cascadecandidate.bachelorId, cascade.collisionId()); cascdata(cascadecandidate.charge, cascadecandidate.mXi, cascadecandidate.mOmega, cascadecandidate.pos[0], cascadecandidate.pos[1], cascadecandidate.pos[2], @@ -1272,6 +1302,9 @@ struct cascadeBuilder { cascadecandidate.v0dcadau, cascadecandidate.dcacascdau, cascadecandidate.v0dcapostopv, cascadecandidate.v0dcanegtopv, cascadecandidate.bachDCAxy, cascadecandidate.cascDCAxy, cascadecandidate.cascDCAz); // <--- no corresponding stratrack information available + if (createCascTrackXs) { + cascTrackXs(cascadecandidate.positiveX, cascadecandidate.negativeX, cascadecandidate.bachelorX); + } cascbb(cascadecandidate.bachBaryonCosPA, cascadecandidate.bachBaryonDCAxyToPV); // populate cascade covariance matrices if required by any other task @@ -1314,7 +1347,8 @@ struct cascadeBuilder { continue; // doesn't pass cascade selections registry.fill(HIST("hKFParticleStatistics"), 2.0f); - kfcascidx(cascadecandidate.v0Id, cascade.globalIndex(), + kfcascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), + cascadecandidate.positiveId, cascadecandidate.negativeId, cascadecandidate.bachelorId, cascade.collisionId()); kfcascdata(cascadecandidate.charge, cascadecandidate.mXi, cascadecandidate.mOmega, cascadecandidate.pos[0], cascadecandidate.pos[1], cascadecandidate.pos[2], @@ -1356,12 +1390,27 @@ struct cascadeBuilder { continue; // wasn't tracked } - bool validCascadeCandidate = buildCascadeCandidate(cascade); + // de-reference from V0 pool, either specific for cascades or general + // use templatizing to avoid code duplication + bool validCascadeCandidate = false; + auto v0index = cascade.template v0_as(); + if (v0index.has_v0Data()) { + // this V0 passed both standard V0 and cascade V0 selections + auto v0row = v0index.template v0Data_as(); + validCascadeCandidate = buildCascadeCandidate(cascade, v0row); + } else if (v0index.has_v0fCData()) { + // this V0 passes only V0-for-cascade selections, use that instead + auto v0row = v0index.template v0fCData_as(); + validCascadeCandidate = buildCascadeCandidate(cascade, v0row); + } else { + continue; // this was inadequately linked, should not happen + } if (!validCascadeCandidate) continue; // doesn't pass cascade selections // fill regular tables (no strangeness tracking) - cascidx(cascadecandidate.v0Id, cascade.globalIndex(), + cascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), + cascadecandidate.positiveId, cascadecandidate.negativeId, cascadecandidate.bachelorId, cascade.collisionId()); cascdata(cascadecandidate.charge, cascadecandidate.mXi, cascadecandidate.mOmega, cascadecandidate.pos[0], cascadecandidate.pos[1], cascadecandidate.pos[2], @@ -1375,6 +1424,9 @@ struct cascadeBuilder { cascadecandidate.v0dcadau, cascadecandidate.dcacascdau, cascadecandidate.v0dcapostopv, cascadecandidate.v0dcanegtopv, cascadecandidate.bachDCAxy, cascadecandidate.cascDCAxy, cascadecandidate.cascDCAz); // <--- no corresponding stratrack information available + if (createCascTrackXs) { + cascTrackXs(cascadecandidate.positiveX, cascadecandidate.negativeX, cascadecandidate.bachelorX); + } cascbb(cascadecandidate.bachBaryonCosPA, cascadecandidate.bachBaryonDCAxyToPV); // populate cascade covariance matrices if required by any other task @@ -1510,8 +1562,9 @@ struct cascadeBuilder { std::array cascadeMomentumVector; cascadeTrackPar.getPxPyPzGlo(cascadeMomentumVector); - trackedcascidx(cascadecandidate.v0Id, cascade.globalIndex(), cascadecandidate.bachelorId, - trackedCascade.trackId(), cascade.collisionId()); + trackedcascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), + cascadecandidate.positiveId, cascadecandidate.negativeId, + cascadecandidate.bachelorId, trackedCascade.trackId(), cascade.collisionId()); trackedcascdata(cascadecandidate.charge, trackedCascade.xiMass(), trackedCascade.omegaMass(), // <--- stratrack masses trackedCascade.decayX(), trackedCascade.decayY(), trackedCascade.decayZ(), // <--- stratrack position cascadecandidate.v0pos[0], cascadecandidate.v0pos[1], cascadecandidate.v0pos[2], @@ -1530,7 +1583,7 @@ struct cascadeBuilder { resetHistos(); } - void processRun2(aod::Collisions const& collisions, aod::V0sLinked const&, V0full const&, soa::Filtered const& cascades, FullTracksExt const&, aod::BCsWithTimestamps const&) + void processRun2(aod::Collisions const& collisions, aod::V0sLinked const&, V0full const&, V0fCfull const&, soa::Filtered const& cascades, FullTracksExt const&, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { // Fire up CCDB @@ -1544,7 +1597,7 @@ struct cascadeBuilder { } PROCESS_SWITCH(cascadeBuilder, processRun2, "Produce Run 2 cascade tables", false); - void processRun3(aod::Collisions const& collisions, aod::V0sLinked const&, V0full const&, soa::Filtered const& cascades, FullTracksExtIU const&, aod::BCsWithTimestamps const&) + void processRun3(aod::Collisions const& collisions, aod::V0sLinked const&, V0full const&, V0fCfull const&, soa::Filtered const& cascades, FullTracksExtIU const&, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { // Fire up CCDB @@ -1572,7 +1625,7 @@ struct cascadeBuilder { } PROCESS_SWITCH(cascadeBuilder, processRun3withKFParticle, "Produce Run 3 KF cascade tables", false); - void processRun3withStrangenessTracking(aod::Collisions const& collisions, aod::V0sLinked const&, V0full const&, soa::Filtered const& cascades, FullTracksExtIU const&, aod::BCsWithTimestamps const&, aod::TrackedCascades const& trackedCascades) + void processRun3withStrangenessTracking(aod::Collisions const& collisions, aod::V0sLinked const&, V0full const&, V0fCfull const&, soa::Filtered const& cascades, FullTracksExtIU const&, aod::BCsWithTimestamps const&, aod::TrackedCascades const& trackedCascades) { for (const auto& collision : collisions) { // Fire up CCDB @@ -1686,16 +1739,12 @@ struct cascadePreselector { template void checkTrackQuality(TCascadeObject const& lCascadeCandidate, uint16_t& maskElement, bool passdEdx = false) { - auto v0 = lCascadeCandidate.template v0_as(); - if (!(v0.has_v0Data())) { - return; - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists + auto v0 = lCascadeCandidate.template v0_as(); // Acquire all three daughter tracks, please auto lBachTrack = lCascadeCandidate.template bachelor_as(); - auto lNegTrack = v0data.template negTrack_as(); - auto lPosTrack = v0data.template posTrack_as(); + auto lNegTrack = v0.template negTrack_as(); + auto lPosTrack = v0.template posTrack_as(); if (doQA) { histos.fill(HIST("hTrackStat"), packTrackProperties(lPosTrack), packTrackProperties(lNegTrack), packTrackProperties(lBachTrack)); @@ -1724,17 +1773,13 @@ struct cascadePreselector { template void checkPDG(TCascadeObject const& lCascadeCandidate, uint16_t& maskElement) { - auto v0 = lCascadeCandidate.template v0_as(); - if (!(v0.has_v0Data())) { - return; - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists int lPDG = -1; // Acquire all three daughter tracks, please auto lBachTrack = lCascadeCandidate.template bachelor_as(); - auto lNegTrack = v0data.template negTrack_as(); - auto lPosTrack = v0data.template posTrack_as(); + auto v0 = lCascadeCandidate.template v0_as(); + auto lNegTrack = v0.template negTrack_as(); + auto lPosTrack = v0.template posTrack_as(); // Association check // There might be smarter ways of doing this in the future @@ -1789,16 +1834,11 @@ struct cascadePreselector { template void checkdEdx(TCascadeObject const& lCascadeCandidate, uint16_t& maskElement) { - auto v0 = lCascadeCandidate.template v0_as(); - if (!(v0.has_v0Data())) { - return; - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists - // Acquire all three daughter tracks, please auto lBachTrack = lCascadeCandidate.template bachelor_as(); - auto lNegTrack = v0data.template negTrack_as(); - auto lPosTrack = v0data.template posTrack_as(); + auto v0 = lCascadeCandidate.template v0_as(); + auto lNegTrack = v0.template negTrack_as(); + auto lPosTrack = v0.template posTrack_as(); // dEdx check with LF PID if (TMath::Abs(lNegTrack.tpcNSigmaPi()) < ddEdxPreSelectionWindow && @@ -1875,7 +1915,7 @@ struct cascadePreselector { } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* /// This process function ensures that all cascades are built. It will simply tag everything as true. - void processBuildAll(aod::Cascades const& cascades, aod::V0sLinked const&, aod::V0Datas const&, aod::TracksExtra const&) + void processBuildAll(aod::Cascades const& cascades, aod::V0s const&, aod::V0Datas const&, aod::TracksExtra const&) { initializeMasks(cascades.size()); for (auto& casc : cascades) { @@ -1885,7 +1925,7 @@ struct cascadePreselector { checkAndFinalize(); } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - void processBuildMCAssociated(aod::Collisions const& collisions, aod::Cascades const& cascades, aod::V0sLinked const&, aod::V0Datas const& v0table, LabeledTracksExtra const&, aod::McParticles const&) + void processBuildMCAssociated(aod::Collisions const& collisions, aod::Cascades const& cascades, aod::V0s const&, aod::V0Datas const& v0table, LabeledTracksExtra const&, aod::McParticles const&) { initializeMasks(cascades.size()); for (auto& casc : cascades) { @@ -1896,7 +1936,7 @@ struct cascadePreselector { checkAndFinalize(); } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - void processBuildValiddEdx(aod::Collisions const& collisions, aod::Cascades const& cascades, aod::V0sLinked const&, aod::V0Datas const&, TracksExtraWithPID const&) + void processBuildValiddEdx(aod::Collisions const& collisions, aod::Cascades const& cascades, aod::V0s const&, aod::V0Datas const&, TracksExtraWithPID const&) { initializeMasks(cascades.size()); for (auto& casc : cascades) { @@ -1907,7 +1947,7 @@ struct cascadePreselector { checkAndFinalize(); } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - void processBuildValiddEdxMCAssociated(aod::Collisions const& collisions, aod::Cascades const& cascades, aod::V0sLinked const&, aod::V0Datas const&, TracksExtraWithPIDandLabels const&, aod::McParticles const&) + void processBuildValiddEdxMCAssociated(aod::Collisions const& collisions, aod::Cascades const& cascades, aod::V0s const&, aod::V0Datas const&, TracksExtraWithPIDandLabels const&, aod::McParticles const&) { initializeMasks(cascades.size()); for (auto& casc : cascades) { diff --git a/PWGLF/TableProducer/cascadefinder.cxx b/PWGLF/TableProducer/cascadefinder.cxx index a9d3059f020..c058cbbf189 100644 --- a/PWGLF/TableProducer/cascadefinder.cxx +++ b/PWGLF/TableProducer/cascadefinder.cxx @@ -255,7 +255,7 @@ struct cascadefinder { lNCand++; // If we got here, it means this is a good candidate! - cascidx(v0.globalIndex(), -1, v0.posTrack().globalIndex(), v0.negTrack().collisionId()); + cascidx(/*v0.globalIndex(), */ -1, v0.posTrack().globalIndex(), v0.negTrack().globalIndex(), t0.globalIndex(), v0.negTrack().collisionId()); cascdata(-1, lXiMass, lOmegaMass, posXi[0], posXi[1], posXi[2], pos[0], pos[1], pos[2], pvecpos[0], pvecpos[1], pvecpos[2], @@ -346,7 +346,7 @@ struct cascadefinder { lNCand++; // If we got here, it means this is a good candidate! - cascidx(v0.globalIndex(), -1, v0.posTrack().globalIndex(), v0.negTrack().collisionId()); + cascidx(/*v0.globalIndex(), */ -1, v0.posTrack().globalIndex(), v0.negTrack().globalIndex(), t0.globalIndex(), v0.negTrack().collisionId()); cascdata(+1, lXiMass, lOmegaMass, posXi[0], posXi[1], posXi[2], pos[0], pos[1], pos[2], pvecpos[0], pvecpos[1], pvecpos[2], diff --git a/PWGLF/TableProducer/cascademcbuilder.cxx b/PWGLF/TableProducer/cascademcbuilder.cxx index c8be4b0f994..6282c971cfd 100644 --- a/PWGLF/TableProducer/cascademcbuilder.cxx +++ b/PWGLF/TableProducer/cascademcbuilder.cxx @@ -69,20 +69,12 @@ struct cascademcbuilder { float pxnegmc = -999.0f, pynegmc = -999.0f, pznegmc = -999.0f; float pxbachmc = -999.0f, pybachmc = -999.0f, pzbachmc = -999.0f; float px = -999.0f, py = -999.0f, pz = -999.0f; - - // Loop over those that actually have the corresponding V0 associated to them - auto v0 = casc.v0_as(); - if (!(v0.has_v0Data())) { - casclabels(-1, -1); - continue; // skip those cascades for which V0 doesn't exist (but: should never happen) - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists int lLabel = -1, lMotherLabel = -1; // Acquire all three daughter tracks, please auto lBachTrack = casc.bachelor_as(); - auto lNegTrack = v0data.negTrack_as(); - auto lPosTrack = v0data.posTrack_as(); + auto lNegTrack = casc.negTrack_as(); + auto lPosTrack = casc.posTrack_as(); // Association check // There might be smarter ways of doing this in the future @@ -164,14 +156,12 @@ struct cascademcbuilder { void processKFCascades(aod::KFCascDatas const& casctable, aod::V0sLinked const&, aod::V0Datas const& v0table, aod::McTrackLabels const&, aod::McParticles const&) { for (auto& casc : casctable) { - // Loop over those that actually have the corresponding V0 associated to them - auto v0 = casc.v0_as(); int lLabel = -1; // Acquire all three daughter tracks, please auto lBachTrack = casc.bachelor_as(); - auto lNegTrack = v0.negTrack_as(); - auto lPosTrack = v0.posTrack_as(); + auto lNegTrack = casc.negTrack_as(); + auto lPosTrack = casc.posTrack_as(); // Association check // There might be smarter ways of doing this in the future @@ -209,19 +199,12 @@ struct cascademcbuilder { void processTrackedCascades(aod::TraCascDatas const& casctable, aod::V0sLinked const&, aod::V0Datas const& v0table, aod::McTrackLabels const&, aod::McParticles const&) { for (auto& casc : casctable) { - // Loop over those that actually have the corresponding V0 associated to them - auto v0 = casc.v0_as(); - if (!(v0.has_v0Data())) { - tracasclabels(-1); - continue; // skip those cascades for which V0 doesn't exist - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists int lLabel = -1; // Acquire all three daughter tracks, please auto lBachTrack = casc.bachelor_as(); - auto lNegTrack = v0data.negTrack_as(); - auto lPosTrack = v0data.posTrack_as(); + auto lNegTrack = casc.negTrack_as(); + auto lPosTrack = casc.posTrack_as(); // Association check // There might be smarter ways of doing this in the future @@ -261,18 +244,10 @@ struct cascademcbuilder { for (auto& casc : casctable) { bool bbTag = false; // bachelor-baryon correlation tag to pass - // Loop over those that actually have the corresponding V0 associated to them - auto v0 = casc.v0_as(); - if (!(v0.has_v0Data())) { - bbtags(bbTag); - continue; // skip those cascades for which V0 doesn't exist - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists - // Acquire all three daughter tracks, please auto lBachTrack = casc.bachelor_as(); - auto lNegTrack = v0data.negTrack_as(); - auto lPosTrack = v0data.posTrack_as(); + auto lNegTrack = casc.negTrack_as(); + auto lPosTrack = casc.posTrack_as(); // Bachelor-baryon association checker // this will allow for analyses to pinpoint the effect of spurious, unwanted correlations! diff --git a/PWGLF/TableProducer/cascadepid.cxx b/PWGLF/TableProducer/cascadepid.cxx index c8b3a6f09fb..93beff60367 100644 --- a/PWGLF/TableProducer/cascadepid.cxx +++ b/PWGLF/TableProducer/cascadepid.cxx @@ -242,9 +242,8 @@ struct cascadepid { for (auto const& cascade : CascTable_thisCollision) { // Track casting auto bachTrack = cascade.bachelor_as(); - auto v0 = cascade.v0(); - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = cascade.posTrack_as(); + auto negTrack = cascade.negTrack_as(); // FIXME: TOF calculation: under construction, to follow diff --git a/PWGLF/TableProducer/cascqaanalysis.cxx b/PWGLF/TableProducer/cascqaanalysis.cxx index 650893ea362..a5ceea8856b 100644 --- a/PWGLF/TableProducer/cascqaanalysis.cxx +++ b/PWGLF/TableProducer/cascqaanalysis.cxx @@ -166,15 +166,13 @@ struct cascqaanalysis { bool AcceptCascCandidate(TCascade const& cascCand, float const& pvx, float const& pvy, float const& pvz) { // Access daughter tracks - auto v0index = cascCand.template v0_as(); - auto v0 = v0index.v0Data(); - auto posdau = v0.template posTrack_as(); - auto negdau = v0.template negTrack_as(); + auto posdau = cascCand.template posTrack_as(); + auto negdau = cascCand.template negTrack_as(); auto bachelor = cascCand.template bachelor_as(); // Basic set of selections if (cascCand.cascradius() > cascradius && - v0.v0radius() > v0radius && + cascCand.v0radius() > v0radius && cascCand.casccosPA(pvx, pvy, pvz) > casccospa && cascCand.v0cosPA(pvx, pvy, pvz) > v0cospa && TMath::Abs(posdau.eta()) < etadau && @@ -323,7 +321,6 @@ struct cascqaanalysis { aod::PVMults, aod::FT0Mults, aod::FV0Mults, aod::CentFT0Ms, aod::CentFV0As>::iterator const& collision, soa::Filtered const& Cascades, - aod::V0sLinked const&, aod::V0Datas const&, DauTracks const&) { @@ -352,21 +349,14 @@ struct cascqaanalysis { for (const auto& casc : Cascades) { // loop over Cascades registry.fill(HIST("hCandidateCounter"), 0.5); // all candidates - - // Access daughter tracks - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - return; // skip those cascades for which V0 doesn't exist - } - registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists + registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists, deprecated if (AcceptCascCandidate(casc, collision.posX(), collision.posY(), collision.posZ())) { registry.fill(HIST("hCandidateCounter"), 2.5); // passed topo cuts // Fill table if (fRand->Rndm() < lEventScale) { - auto v0 = v0index.v0Data(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); auto bachelor = casc.bachelor_as(); // ITS N hits @@ -423,8 +413,7 @@ struct cascqaanalysis { soa::Filtered const& Cascades, DauTracks const&, aod::McCollisions const&, - aod::McParticles const& mcParticles, - aod::V0sLinked const&) + aod::McParticles const& mcParticles) { if (!AcceptEvent(collision, 1)) { return; @@ -455,13 +444,7 @@ struct cascqaanalysis { for (const auto& casc : Cascades) { // loop over Cascades registry.fill(HIST("hCandidateCounter"), 0.5); // all candidates - // Access daughter tracks - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - return; // skip those cascades for which V0 doesn't exist - } - - registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists + registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists - deprecated if (AcceptCascCandidate(casc, collision.posX(), collision.posY(), collision.posZ())) { registry.fill(HIST("hCandidateCounter"), 2.5); // passed topo cuts @@ -479,9 +462,8 @@ struct cascqaanalysis { } if (fRand->Rndm() < lEventScale) { // Fill table - auto v0 = v0index.v0Data(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); auto bachelor = casc.bachelor_as(); // ITS N hits diff --git a/PWGLF/TableProducer/hStrangeCorrelationFilter.cxx b/PWGLF/TableProducer/hStrangeCorrelationFilter.cxx index d880af3f734..6fa9ff3819e 100644 --- a/PWGLF/TableProducer/hStrangeCorrelationFilter.cxx +++ b/PWGLF/TableProducer/hStrangeCorrelationFilter.cxx @@ -397,14 +397,9 @@ struct hstrangecorrelationfilter { /// _________________________________________________ /// Step 3: Populate table with associated Cascades for (auto const& casc : Cascades) { - auto v0 = casc.v0_as(); - if (!(v0.has_v0Data())) { - return; // skip those cascades for which V0 doesn't exist - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists auto bachTrackCast = casc.bachelor_as(); - auto posTrackCast = v0data.posTrack_as(); - auto negTrackCast = v0data.negTrack_as(); + auto posTrackCast = casc.posTrack_as(); + auto negTrackCast = casc.negTrack_as(); auto origCascadeEntry = casc.cascade_as(); // minimum TPC crossed rows diff --git a/PWGLF/TableProducer/lambdakzerobuilder.cxx b/PWGLF/TableProducer/lambdakzerobuilder.cxx index 3cdeb351be1..e89ec13ed76 100644 --- a/PWGLF/TableProducer/lambdakzerobuilder.cxx +++ b/PWGLF/TableProducer/lambdakzerobuilder.cxx @@ -94,11 +94,19 @@ struct lambdakzeroBuilder { Produces v0cores; Produces v0trackXs; Produces v0covs; // covariances + + Produces v0fcindices; + Produces v0fccores; + Produces v0fctrackXs; + Produces v0fccovs; + Service ccdb; // Configurables related to table creation Configurable createV0CovMats{"createV0CovMats", -1, {"Produces V0 cov matrices. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; + Configurable storePhotonCandidates{"storePhotonCandidates", false, "store photon candidates (yes/no)"}; + // use auto-detect configuration Configurable d_UseAutodetectMode{"d_UseAutodetectMode", false, "Autodetect requested topo sels"}; @@ -183,6 +191,8 @@ struct lambdakzeroBuilder { kV0DCADau, kV0CosPA, kV0Radius, + kCountStandardV0, + kCountV0forCascade, kNV0Steps }; // Helper struct to pass V0 information @@ -263,6 +273,8 @@ struct lambdakzeroBuilder { h->GetXaxis()->SetBinLabel(4, "DCA V0 Dau"); h->GetXaxis()->SetBinLabel(5, "CosPA"); h->GetXaxis()->SetBinLabel(6, "Radius"); + h->GetXaxis()->SetBinLabel(7, "Count: Standard V0"); + h->GetXaxis()->SetBinLabel(8, "Count: V0 exc. for casc"); randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); @@ -769,18 +781,46 @@ struct lambdakzeroBuilder { continue; // doesn't pass selections } - // populates the various tables for analysis - v0indices(V0.posTrackId(), V0.negTrackId(), - V0.collisionId(), V0.globalIndex()); - v0trackXs(v0candidate.posTrackX, v0candidate.negTrackX); - v0cores(v0candidate.pos[0], v0candidate.pos[1], v0candidate.pos[2], - v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2], - v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2], - v0candidate.dcaV0dau, - v0candidate.posDCAxy, - v0candidate.negDCAxy, - v0candidate.cosPA, - v0candidate.dcav0topv); + // V0 logic reminder + // 0: v0 saved for the only due to the cascade, 1: standalone v0, 3: standard v0 with photon-only test + + if (V0.v0Type() > 0) { + if (V0.v0Type() > 1 && !storePhotonCandidates) + continue; + // populates the various tables for analysis + statisticsRegistry.v0stats[kCountStandardV0]++; + v0indices(V0.posTrackId(), V0.negTrackId(), + V0.collisionId(), V0.globalIndex()); + v0trackXs(v0candidate.posTrackX, v0candidate.negTrackX); + v0cores(v0candidate.pos[0], v0candidate.pos[1], v0candidate.pos[2], + v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2], + v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2], + v0candidate.dcaV0dau, + v0candidate.posDCAxy, + v0candidate.negDCAxy, + v0candidate.cosPA, + v0candidate.dcav0topv, + V0.v0Type()); + } else { + // place V0s built exclusively for the sake of cascades + // in a fully independent table (though identical) to make + // sure there's no accidental usage of those candidates + // N.B.: these are obtained with *other selections* in + // the svertexer! + statisticsRegistry.v0stats[kCountV0forCascade]++; + v0fcindices(V0.posTrackId(), V0.negTrackId(), + V0.collisionId(), V0.globalIndex()); + v0fctrackXs(v0candidate.posTrackX, v0candidate.negTrackX); + v0fccores(v0candidate.pos[0], v0candidate.pos[1], v0candidate.pos[2], + v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2], + v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2], + v0candidate.dcaV0dau, + v0candidate.posDCAxy, + v0candidate.negDCAxy, + v0candidate.cosPA, + v0candidate.dcav0topv, + V0.v0Type()); + } // populate V0 covariance matrices if required by any other task if (createV0CovMats) { @@ -1151,17 +1191,23 @@ struct lambdakzeroV0DataLinkBuilder { //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* // build V0 -> V0Data link table - void process(aod::V0s const& v0table, aod::V0Datas const& v0datatable) + void process(aod::V0s const& v0table, aod::V0Datas const& v0datatable, aod::V0fCDatas const& v0fcdatatable) { - std::vector lIndices; + std::vector lIndices, lfCIndices; lIndices.reserve(v0table.size()); - for (int ii = 0; ii < v0table.size(); ii++) + lfCIndices.reserve(v0table.size()); + for (int ii = 0; ii < v0table.size(); ii++) { lIndices[ii] = -1; + lfCIndices[ii] = -1; + } for (auto& v0data : v0datatable) { lIndices[v0data.v0Id()] = v0data.globalIndex(); } + for (auto& v0fcdata : v0fcdatatable) { + lfCIndices[v0fcdata.v0Id()] = v0fcdata.globalIndex(); + } for (int ii = 0; ii < v0table.size(); ii++) { - v0dataLink(lIndices[ii]); + v0dataLink(lIndices[ii], lfCIndices[ii]); } } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -1170,6 +1216,7 @@ struct lambdakzeroV0DataLinkBuilder { // Extends the v0data table with expression columns struct lambdakzeroInitializer { Spawns v0cores; + Spawns v0fccores; void init(InitContext const&) {} }; diff --git a/PWGLF/TableProducer/lambdakzerofinder.cxx b/PWGLF/TableProducer/lambdakzerofinder.cxx index 08becfdc176..3743252ac63 100644 --- a/PWGLF/TableProducer/lambdakzerofinder.cxx +++ b/PWGLF/TableProducer/lambdakzerofinder.cxx @@ -289,8 +289,8 @@ struct lambdakzerofinder { pvec0[0], pvec0[1], pvec0[2], pvec1[0], pvec1[1], pvec1[2], TMath::Sqrt(fitter.getChi2AtPCACandidate()), - t1.dcaXY(), t2.dcaXY(), cosPA, smallestDCA); - v0datalink(v0cores.lastIndex()); + t1.dcaXY(), t2.dcaXY(), cosPA, smallestDCA, 1); + v0datalink(v0cores.lastIndex(), -1); return 1; } diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index 465eb8db4fd..05196d577be 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -86,7 +86,7 @@ struct strangederivedbuilder { // mother information Produces v0mothers; // V0 mother references Produces cascmothers; // casc mother references - Produces motherMCParticles; // mc particles for mothers + Produces motherMCParts; // mc particles for mothers // histogram registry for bookkeeping HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -246,9 +246,8 @@ struct strangederivedbuilder { // index tracks that belong to CascDatas for (auto const& casc : Cascades) { auto bachTrack = casc.bachelor_as(); - auto v0 = casc.v0(); - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = casc.posTrack_as(); + auto negTrack = casc.negTrack_as(); trackMap[posTrack.globalIndex()] = 0; trackMap[negTrack.globalIndex()] = 0; trackMap[bachTrack.globalIndex()] = 0; @@ -257,9 +256,8 @@ struct strangederivedbuilder { // index tracks that belong to KFCascDatas for (auto const& casc : KFCascades) { auto bachTrack = casc.bachelor_as(); - auto v0 = casc.v0(); - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = casc.posTrack_as(); + auto negTrack = casc.negTrack_as(); trackMap[posTrack.globalIndex()] = 0; trackMap[negTrack.globalIndex()] = 0; trackMap[bachTrack.globalIndex()] = 0; @@ -268,9 +266,8 @@ struct strangederivedbuilder { // index tracks that belong to TraCascDatas for (auto const& casc : TraCascades) { auto bachTrack = casc.bachelor_as(); - auto v0 = casc.v0(); - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = casc.posTrack_as(); + auto negTrack = casc.negTrack_as(); auto strangeTrack = casc.strangeTrack_as(); trackMap[posTrack.globalIndex()] = 0; trackMap[negTrack.globalIndex()] = 0; @@ -298,9 +295,8 @@ struct strangederivedbuilder { // populate track references for (auto const& casc : Cascades) { auto bachTrack = casc.bachelor_as(); - auto v0 = casc.v0(); - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = casc.posTrack_as(); + auto negTrack = casc.negTrack_as(); cascExtras(trackMap[posTrack.globalIndex()], trackMap[negTrack.globalIndex()], trackMap[bachTrack.globalIndex()]); // joinable with CascDatas @@ -356,7 +352,7 @@ struct strangederivedbuilder { // populate motherMCParticles for (auto const& tr : mcParticles) { if (motherReference[tr.globalIndex()] >= 0) { - motherMCParticles(tr.px(), tr.py(), tr.pz(), tr.pdgCode(), tr.isPhysicalPrimary()); + motherMCParts(tr.px(), tr.py(), tr.pz(), tr.pdgCode(), tr.isPhysicalPrimary()); } } } diff --git a/PWGLF/Tasks/QC/straRecoStudy.cxx b/PWGLF/Tasks/QC/straRecoStudy.cxx index 9c5dce18d9e..6c58d7993b9 100644 --- a/PWGLF/Tasks/QC/straRecoStudy.cxx +++ b/PWGLF/Tasks/QC/straRecoStudy.cxx @@ -617,14 +617,8 @@ struct straRecoStudy { return; auto bachPartTrack = casc.template bachelor_as(); - - auto v0index = casc.template v0_as(); - if (!(v0index.has_v0Data())) { - return; - } - auto v0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists - auto posPartTrack = v0.template posTrack_as(); - auto negPartTrack = v0.template negTrack_as(); + auto posPartTrack = casc.template posTrack_as(); + auto negPartTrack = casc.template negTrack_as(); if (cascmc.pdgCode() == 3312) { histos.fill(HIST("h3dTrackPtsXiMinusP"), casc.pt(), posPartTrack.itsNCls(), posPartTrack.tpcNClsCrossedRows()); @@ -698,14 +692,14 @@ struct straRecoStudy { } } - void processCascade(CollisionsWithEvSels const& collisions, aod::V0Datas const&, soa::Filtered const& Cascades, TracksCompleteIUMC const& tracks, aod::McParticles const&, aod::V0sLinked const&) + void processCascade(CollisionsWithEvSels const& collisions, aod::V0Datas const&, soa::Filtered const& Cascades, TracksCompleteIUMC const& tracks, aod::McParticles const&) { for (auto& casc : Cascades) { processCascadeCandidate(casc); } } PROCESS_SWITCH(straRecoStudy, processCascade, "Regular cascade analysis", true); - void processTrackedCascade(CollisionsWithEvSels const& collisions, aod::V0Datas const&, TraCascMC const& Cascades, TracksCompleteIUMC const& tracks, aod::McParticles const&, aod::V0sLinked const&) + void processTrackedCascade(CollisionsWithEvSels const& collisions, aod::V0Datas const&, TraCascMC const& Cascades, TracksCompleteIUMC const& tracks, aod::McParticles const&) { for (auto& casc : Cascades) { processCascadeCandidate(casc); @@ -723,13 +717,8 @@ struct straRecoStudy { } for (auto& casc : Cascades) { auto bachPartTrack = casc.bachelor_as(); - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - continue; - } - auto v0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists - auto posPartTrack = v0.posTrack_as(); - auto negPartTrack = v0.negTrack_as(); + auto posPartTrack = casc.posTrack_as(); + auto negPartTrack = casc.negTrack_as(); histos.fill(HIST("h2dITSCluMap_CascPositive"), (float)posPartTrack.itsClusterMap(), casc.v0radius()); histos.fill(HIST("h2dITSCluMap_CascNegative"), (float)negPartTrack.itsClusterMap(), casc.v0radius()); diff --git a/PWGLF/Tasks/QC/v0cascadesqa.cxx b/PWGLF/Tasks/QC/v0cascadesqa.cxx index 023b54a338f..db60f601d59 100644 --- a/PWGLF/Tasks/QC/v0cascadesqa.cxx +++ b/PWGLF/Tasks/QC/v0cascadesqa.cxx @@ -560,15 +560,9 @@ struct v0cascadesQA { } for (auto& casc : Cascades) { - - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - continue; // skip those cascades for which V0 doesn't exist - } - auto v0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists auto bachelor = casc.bachelor_as(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); // histos_Casc.fill(HIST("XiProgSelections"), ); // histos_Casc.fill(HIST("OmegaProgSelections"), ); @@ -666,14 +660,8 @@ struct v0cascadesQA { histos_Casc.fill(HIST("QA_XiMinusCandidates"), 1.5); - auto v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - continue; // skip those cascades for which V0 doesn't exist - } - auto v0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists - - auto reconegtrack = v0.negTrack_as(); - auto recopostrack = v0.posTrack_as(); + auto reconegtrack = casc.negTrack_as(); + auto recopostrack = casc.posTrack_as(); auto recobachelor = casc.bachelor_as(); if (!reconegtrack.has_mcParticle() || !recopostrack.has_mcParticle() || !recobachelor.has_mcParticle()) { continue; diff --git a/PWGLF/Tasks/cascadeanalysis.cxx b/PWGLF/Tasks/cascadeanalysis.cxx index c3c88458037..baf37b72717 100644 --- a/PWGLF/Tasks/cascadeanalysis.cxx +++ b/PWGLF/Tasks/cascadeanalysis.cxx @@ -188,14 +188,10 @@ struct cascadeAnalysis { bool lConsistentWithLambda = true; bool lConsistentWithXi = true; bool lConsistentWithOm = true; - auto v0 = lCascade.template v0_as(); - if (!(v0.has_v0Data())) { - return 0; // reject - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists + auto bachTrack = lCascade.template bachelor_as(); - auto posTrack = v0data.template posTrack_as(); - auto negTrack = v0data.template negTrack_as(); + auto posTrack = lCascade.template posTrack_as(); + auto negTrack = lCascade.template negTrack_as(); // Bachelor: depends on type if (TMath::Abs(bachTrack.tpcNSigmaPi()) > tpcNsigmaBachelor && tpcNsigmaBachelor < 9.99) @@ -224,15 +220,9 @@ struct cascadeAnalysis { // function to process cascades and generate corresponding invariant mass distributions { registry.fill(HIST("hCandidateCounter"), 0.5); // all candidates - auto v0 = casc.template v0_as(); - if (!(v0.has_v0Data())) { - return; // skip those cascades for which V0 doesn't exist - } - registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists auto bachTrackCast = casc.template bachelor_as(); - auto posTrackCast = v0data.template posTrack_as(); - auto negTrackCast = v0data.template negTrack_as(); + auto posTrackCast = casc.template posTrack_as(); + auto negTrackCast = casc.template negTrack_as(); // track-level selections Bool_t lEnoughTPCNClsBac = kTRUE; @@ -326,7 +316,7 @@ struct cascadeAnalysis { } } - void processRun3(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIU const&) + void processRun3(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIU const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -340,7 +330,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun3, "Process Run 3 data", true); - void processRun2(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExt const&) + void processRun2(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExt const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria @@ -357,7 +347,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun2, "Process Run 2 data", false); - void processRun3VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIU const&) + void processRun3VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIU const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -371,7 +361,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun3VsMultiplicity, "Process Run 3 data vs multiplicity", false); - void processRun2VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExt const&) + void processRun2VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExt const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria @@ -388,7 +378,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun2VsMultiplicity, "Process Run 2 data vs multiplicity", false); - void processRun3WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIUWithPID const&) + void processRun3WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIUWithPID const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -403,7 +393,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun3WithPID, "Process Run 3 data with PID", false); - void processRun2WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtWithPID const&) + void processRun2WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtWithPID const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria @@ -421,7 +411,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun2WithPID, "Process Run 2 data with PID", false); - void processRun3VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIUWithPID const&) + void processRun3VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIUWithPID const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -436,7 +426,7 @@ struct cascadeAnalysis { } PROCESS_SWITCH(cascadeAnalysis, processRun3VsMultiplicityWithPID, "Process Run 3 data vs multiplicity with PID", false); - void processRun2VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtWithPID const&) + void processRun2VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtWithPID const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria diff --git a/PWGLF/Tasks/cascadeanalysisMC.cxx b/PWGLF/Tasks/cascadeanalysisMC.cxx index 1e9cec8ff0a..5546989341a 100644 --- a/PWGLF/Tasks/cascadeanalysisMC.cxx +++ b/PWGLF/Tasks/cascadeanalysisMC.cxx @@ -240,14 +240,10 @@ struct cascadeAnalysisMC { bool lConsistentWithLambda = true; bool lConsistentWithXi = true; bool lConsistentWithOm = true; - auto v0 = lCascade.template v0_as(); - if (!(v0.has_v0Data())) { - return 0; // reject - } - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists + auto bachTrack = lCascade.template bachelor_as(); - auto posTrack = v0data.template posTrack_as(); - auto negTrack = v0data.template negTrack_as(); + auto posTrack = lCascade.template posTrack_as(); + auto negTrack = lCascade.template negTrack_as(); // Bachelor: depends on type if (TMath::Abs(bachTrack.tpcNSigmaPi()) > tpcNsigmaBachelor && tpcNsigmaBachelor < 9.99) @@ -286,15 +282,11 @@ struct cascadeAnalysisMC { if (TMath::Abs(cascmc.pdgCode()) == 3312 || TMath::Abs(cascmc.pdgCode()) == 3334) lPDG = cascmc.pdgCode(); } - auto v0 = casc.template v0_as(); - if (!(v0.has_v0Data())) { - return; // skip those cascades for which V0 doesn't exist - } - registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists - auto v0data = v0.v0Data(); // de-reference index to correct v0data in case it exists + + registry.fill(HIST("hCandidateCounter"), 1.5); // v0data exists - deprecated auto bachTrackCast = casc.template bachelor_as(); - auto posTrackCast = v0data.template posTrack_as(); - auto negTrackCast = v0data.template negTrack_as(); + auto posTrackCast = casc.template posTrack_as(); + auto negTrackCast = casc.template negTrack_as(); // track-level selections Bool_t lEnoughTPCNClsBac = kTRUE; @@ -388,7 +380,7 @@ struct cascadeAnalysisMC { } } - void processRun3(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIU const&, aod::McParticles const&) + void processRun3(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIU const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -402,7 +394,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun3, "Process Run 3 data", true); - void processRun2(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExt const&, aod::McParticles const&) + void processRun2(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExt const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria @@ -419,7 +411,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun2, "Process Run 2 data", false); - void processRun3VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIU const&, aod::McParticles const&) + void processRun3VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIU const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -433,7 +425,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun3VsMultiplicity, "Process Run 3 data vs multiplicity", false); - void processRun2VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExt const&, aod::McParticles const&) + void processRun2VsMultiplicity(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExt const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria @@ -450,7 +442,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun2VsMultiplicity, "Process Run 2 data vs multiplicity", false); - void processRun3WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIUWithPID const&, aod::McParticles const&) + void processRun3WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -465,7 +457,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun3WithPID, "Process Run 3 data with PID", false); - void processRun2WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtWithPID const&, aod::McParticles const&) + void processRun2WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria @@ -483,7 +475,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun2WithPID, "Process Run 2 data with PID", false); - void processRun3VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIUWithPID const&, aod::McParticles const&) + void processRun3VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIUWithPID const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -498,7 +490,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun3VsMultiplicityWithPID, "Process Run 3 data vs multiplicity with PID", false); - void processRun2VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtWithPID const&, aod::McParticles const&) + void processRun2VsMultiplicityWithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtWithPID const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria diff --git a/PWGLF/Tasks/cascadecorrelations.cxx b/PWGLF/Tasks/cascadecorrelations.cxx index dd7c0eef508..86fa65a796c 100644 --- a/PWGLF/Tasks/cascadecorrelations.cxx +++ b/PWGLF/Tasks/cascadecorrelations.cxx @@ -92,23 +92,16 @@ struct cascadeSelector { Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "cascadesetting_mindcav0topv"}; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - void process(soa::Join::iterator const& collision, aod::CascDataExt const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIUWithPID const&) + void process(soa::Join::iterator const& collision, aod::CascDataExt const& Cascades, FullTracksExtIUWithPID const&) { for (auto& casc : Cascades) { - auto v0 = casc.v0_as(); - if (!(v0.has_v0Data())) { - cascflags(0); - continue; // reject if no v0data - } - auto v0data = v0.v0Data(); - // TODO: make QA histo with info on where cascades fail selections // Let's try to do some PID & track quality cuts // these are the tracks: auto bachTrack = casc.bachelor_as(); - auto posTrack = v0data.posTrack_as(); - auto negTrack = v0data.negTrack_as(); + auto posTrack = casc.posTrack_as(); + auto negTrack = casc.negTrack_as(); // TPC N crossed rows if (posTrack.tpcNClsCrossedRows() < minTPCCrossedRows || negTrack.tpcNClsCrossedRows() < minTPCCrossedRows || bachTrack.tpcNClsCrossedRows() < minTPCCrossedRows) { @@ -244,12 +237,6 @@ struct cascadeCorrelations { // Some QA on the cascades for (auto& casc : Cascades) { - - auto v0 = casc.v0_as(); - if (!(v0.has_v0Data())) { - continue; // reject if no v0data - } - if (casc.isSelected() != 2) { // not exclusively an Omega --> consistent with Xi or both if (casc.sign() < 0) { registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt()); @@ -291,13 +278,12 @@ struct cascadeCorrelations { auto trigger = *triggerAddress; auto assoc = *assocAddress; - auto lambdaTrigg = trigger.v0_as(); - auto lambdaAssoc = assoc.v0_as(); - if (!(lambdaTrigg.has_v0Data()) || !(lambdaAssoc.has_v0Data())) { - continue; // reject if no v0data in either of the lambda's - } - auto v0dataTrigg = lambdaTrigg.v0Data(); - auto v0dataAssoc = lambdaAssoc.v0Data(); + // track indices for posterior checks + // retains logic of V0 index while being safe wrt data model + int posIdTrigg = trigger.posTrackId(); + int negIdTrigg = trigger.negTrackId(); + int posIdAssoc = assoc.posTrackId(); + int negIdAssoc = assoc.negTrackId(); // calculate angular correlations double deta = trigger.eta() - assoc.eta(); @@ -317,17 +303,14 @@ struct cascadeCorrelations { registry.fill(HIST("hOmOmOS"), dphi, deta, trigger.pt(), assoc.pt(), invMassOmTrigg, invMassOmAssoc, trigger.isSelected(), assoc.isSelected(), collision.posZ(), collision.multFT0M()); } else { // same-sign // make sure to check for autocorrelations - only possible in same-sign correlations - if (v0dataTrigg.v0Id() == v0dataAssoc.v0Id()) { + if (posIdTrigg == posIdAssoc && negIdTrigg == negIdAssoc) { // LOGF(info, "same v0 in SS correlation! %d %d", v0dataTrigg.v0Id(), v0dataAssoc.v0Id()); registry.fill(HIST("hAutoCorrelation"), 0); continue; } int bachIdTrigg = trigger.bachelorId(); int bachIdAssoc = assoc.bachelorId(); - int posIdTrigg = v0dataTrigg.posTrackId(); - int negIdTrigg = v0dataTrigg.negTrackId(); - int posIdAssoc = v0dataAssoc.posTrackId(); - int negIdAssoc = v0dataAssoc.negTrackId(); + if (bachIdTrigg == bachIdAssoc) { // LOGF(info, "same bachelor in SS correlation! %d %d", bachIdTrigg, bachIdAssoc); registry.fill(HIST("hAutoCorrelation"), 1); diff --git a/PWGLF/Tasks/hStrangeCorrelation.cxx b/PWGLF/Tasks/hStrangeCorrelation.cxx index 47812555c6c..fe224124e3e 100644 --- a/PWGLF/Tasks/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/hStrangeCorrelation.cxx @@ -223,12 +223,8 @@ struct correlateStrangeness { auto assoc = assocCandidate.cascData(); //---] removing autocorrelations [--- - auto v0index = assoc.v0_as(); - if (!(v0index.has_v0Data())) - continue; // this should not happen - included for safety - auto assocV0 = v0index.v0Data(); // de-reference index to correct v0data in case it exists - auto postrack = assocV0.posTrack_as(); - auto negtrack = assocV0.negTrack_as(); + auto postrack = assoc.posTrack_as(); + auto negtrack = assoc.negTrack_as(); auto bachtrack = assoc.bachelor_as(); if (doAutocorrelationRejection) { if (trigg.globalIndex() == postrack.globalIndex()) { diff --git a/PWGLF/Tasks/hyperon-reco-test.cxx b/PWGLF/Tasks/hyperon-reco-test.cxx index d1abec75651..c0fe1f2ac47 100644 --- a/PWGLF/Tasks/hyperon-reco-test.cxx +++ b/PWGLF/Tasks/hyperon-reco-test.cxx @@ -160,8 +160,6 @@ struct myXi { void process(aod::Collision const& collision, soa::Join const& Cascades, - aod::V0sLinked const& V0linked, - aod::V0Datas const& V0s, DauTracks const& tracks, aod::McParticles const& mcParticles) { @@ -177,20 +175,18 @@ struct myXi { } } - auto v0index = casc.v0_as(); - auto v0 = v0index.v0Data(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); auto bachelor = casc.bachelor_as(); if ( // Dau & bach track cuts TMath::Abs(posdau.eta()) < rapidity && TMath::Abs(negdau.eta()) < rapidity && TMath::Abs(bachelor.eta()) < rapidity && posdau.tpcNClsCrossedRows() > mincrossedrow && negdau.tpcNClsCrossedRows() > mincrossedrow && bachelor.tpcNClsCrossedRows() > mincrossedrow && posdau.pt() > minpt && negdau.pt() > minpt && bachelor.pt() > minpt && TMath::Abs(casc.dcapostopv()) > dcatopv && TMath::Abs(casc.dcanegtopv()) > dcatopv && TMath::Abs(casc.dcabachtopv()) > dcatopv && TMath::Abs(posdau.tpcNSigmaPr()) < tpcsigma && TMath::Abs(negdau.tpcNSigmaPi()) < tpcsigma && TMath::Abs(bachelor.tpcNSigmaPi()) < tpcsigma && bachelor.sign() < 0 && // V0 cuts - casc.v0radius() > v0radius && casc.dcaV0daughters() < dcav0dau && v0.dcav0topv() > dcav0topv && casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) > v0cospa) { - registry.fill(HIST("hmyLambda"), v0.mLambda()); + casc.v0radius() > v0radius && casc.dcaV0daughters() < dcav0dau && casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) > dcav0topv && casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) > v0cospa) { + registry.fill(HIST("hmyLambda"), casc.mLambda()); - if (TMath::Abs(v0.mLambda() - o2::constants::physics::MassLambda0) < v0masswindow && + if (TMath::Abs(casc.mLambda() - o2::constants::physics::MassLambda0) < v0masswindow && // Cascade cut casc.cascradius() > cascradius && casc.dcacascdaughters() < dcacascdau && casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) > casccospa && TMath::Abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) > removeOmega && casc.sign() < 0) { @@ -258,8 +254,6 @@ struct myOmega { void process(aod::Collision const& collision, soa::Join const& Cascades, - aod::V0sLinked const& V0linked, - aod::V0Datas const& V0s, DauTracks const& tracks, aod::McParticles const& mcParticles) { @@ -275,20 +269,18 @@ struct myOmega { } } - auto v0index = casc.v0_as(); - auto v0 = v0index.v0Data(); - auto posdau = v0.posTrack_as(); - auto negdau = v0.negTrack_as(); + auto posdau = casc.posTrack_as(); + auto negdau = casc.negTrack_as(); auto bachelor = casc.bachelor_as(); if ( // Dau & bach track cuts TMath::Abs(posdau.eta()) < rapidity && TMath::Abs(negdau.eta()) < rapidity && TMath::Abs(bachelor.eta()) < rapidity && posdau.tpcNClsCrossedRows() > mincrossedrow && negdau.tpcNClsCrossedRows() > mincrossedrow && bachelor.tpcNClsCrossedRows() > mincrossedrow && posdau.pt() > minpt && negdau.pt() > minpt && bachelor.pt() > minpt && TMath::Abs(casc.dcapostopv()) > dcatopv && TMath::Abs(casc.dcanegtopv()) > dcatopv && TMath::Abs(casc.dcabachtopv()) > dcatopv && TMath::Abs(posdau.tpcNSigmaPr()) < tpcsigma && TMath::Abs(negdau.tpcNSigmaPi()) < tpcsigma && TMath::Abs(bachelor.tpcNSigmaKa()) < tpcsigma && bachelor.sign() < 0 && // V0 cuts - casc.v0radius() > v0radius && casc.dcaV0daughters() < dcav0dau && v0.dcav0topv() > dcav0topv && casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) > v0cospa) { - registry.fill(HIST("hmyLambda"), v0.mLambda()); + casc.v0radius() > v0radius && casc.dcaV0daughters() < dcav0dau && casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) > dcav0topv && casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) > v0cospa) { + registry.fill(HIST("hmyLambda"), casc.mLambda()); - if (TMath::Abs(v0.mLambda() - o2::constants::physics::MassLambda0) < v0masswindow && + if (TMath::Abs(casc.mLambda() - o2::constants::physics::MassLambda0) < v0masswindow && // Cascade cut casc.cascradius() > cascradius && casc.dcacascdaughters() < dcacascdau && casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) > casccospa && TMath::Abs(casc.mXi() - o2::constants::physics::MassXiMinus) > removeXi && casc.sign() < 0) { diff --git a/Tutorials/PWGLF/Strangeness/strangeness_step4.cxx b/Tutorials/PWGLF/Strangeness/strangeness_step4.cxx index 59e6c9d86aa..544d4283932 100644 --- a/Tutorials/PWGLF/Strangeness/strangeness_step4.cxx +++ b/Tutorials/PWGLF/Strangeness/strangeness_step4.cxx @@ -142,8 +142,6 @@ struct strangeness_tutorial { void processRecMC(soa::Filtered>::iterator const& collision, soa::Filtered> const& Cascades, soa::Filtered> const& V0s, - aod::V0Datas const&, // it's needed to access the full table of V0s (not the filtered one) to make sure all the V0s related to cascades are present - aod::V0sLinked const&, DaughterTracks const&, aod::McParticles const&) { @@ -202,15 +200,9 @@ struct strangeness_tutorial { // Cascades for (const auto& casc : Cascades) { - const auto& v0index = casc.v0_as(); - if (!(v0index.has_v0Data())) { - continue; // skip those cascades for which V0 doesn't exist - } - - const auto& v0Casc = v0index.v0Data(); // de-reference index to correct v0data in case it exists const auto& bachDaughterTrackCasc = casc.bachelor_as(); - const auto& posDaughterTrackCasc = v0Casc.posTrack_as(); - const auto& negDaughterTrackCasc = v0Casc.negTrack_as(); + const auto& posDaughterTrackCasc = casc.posTrack_as(); + const auto& negDaughterTrackCasc = casc.negTrack_as(); rXi.fill(HIST("hMassXi"), casc.mXi()); From 58d9fd21db3d6fde751ca64e61055fdad041f94b Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Wed, 20 Dec 2023 13:17:13 +0100 Subject: [PATCH 100/156] PWGCF: FemtoUniverse -- Deleting the workaround for Phi mesons in the MC Truth producer (#4217) * Deleting the workaround for Phi mesons in the MC Truth producer * Clang fix --- .../TableProducer/femtoUniverseProducerMCTruthTask.cxx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index 2dafa1ccbbc..9f06c287ebd 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -167,12 +167,8 @@ struct femtoUniverseProducerMCTruthTask { std::vector tmpPDGCodes = ConfPDGCodes; // necessary due to some features of the Configurable for (uint32_t pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { - if (pdgCode == 333) { // ATTENTION: workaround for now, because all Phi mesons are NOT primary particles for now. + if (particle.isPhysicalPrimary()) pass = true; - } else { - if (particle.isPhysicalPrimary()) - pass = true; - } } } if (!pass) From 07425785cf3cafc575a84913a45175017da5ff3b Mon Sep 17 00:00:00 2001 From: rbailhac Date: Wed, 20 Dec 2023 15:08:06 +0100 Subject: [PATCH 101/156] pt04 (#4218) --- PWGDQ/Core/CutsLibrary.cxx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index b276b2e3140..4d0a5ce9485 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -1203,6 +1203,24 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare(Form("lmee_eNSigmaRun3%s_strongNSigEPbPb_rejBadTOF_pt04", vecPIDcase.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); + cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + + AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); + + AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); + + AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + cut_pid_OR->AddCut(cut_tpc_nSigma); + cut_pid_OR->AddCut(cut_tof_nSigma); + cut->AddCut(cut_pid_OR); + return cut; + } + // 4 cuts for QC if (!nameStr.compare(Form("lmee_posNSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { cut->AddCut(GetAnalysisCut("posTrack")); @@ -2559,7 +2577,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } if (!nameStr.compare("lmeeStandardKine_pt04")) { - cut->AddCut(VarManager::kPt, 0.4, 10.0); + cut->AddCut(VarManager::kPt, 0.4, 20.0); cut->AddCut(VarManager::kEta, -0.8, 0.8); return cut; } From d45bc89b634c05a654ebd853eb75447881a1d344 Mon Sep 17 00:00:00 2001 From: Giovanni Malfattore <89481844+giovannimalfattore@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:47:58 +0100 Subject: [PATCH 102/156] [PWFLG] LightNucleiTask - Add p shift (#4187) --- PWGLF/Tasks/LFNucleiBATask.cxx | 41 +++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/LFNucleiBATask.cxx index cc3eec7267e..db7ccec5da5 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/LFNucleiBATask.cxx @@ -122,7 +122,7 @@ struct LFNucleiBATask { Configurable usenITSLayer{"usenITSLayer", false, "Flag to enable ITS layer hit"}; Configurable useHasTRDConfig{"useHasTRDConfig", 0, "No selections on TRD (0); With TRD (1); Without TRD (2)"}; - Configurable massTOFConfig{"massTOFConfig", 0, "Estimate massTOF using beta with (0) TPC momentum (1) TOF expected momentum"}; + Configurable massTOFConfig{"massTOFConfig", 0, "Estimate massTOF using beta with (0) TPC momentum (1) TOF expected momentum (2) p momentum."}; Configurable tritonSelConfig{"tritonSelConfig", 0, "Select tritons using (0) 3Sigma TPC triton (1) additional 3sigma TPC pi,K,p veto cut"}; Configurable helium3Pt{"helium3Pt", 0, "Select use default pT (0) or use instead 2*pT (1) for helium-3"}; Configurable antiDeuteronPt{"antiDeuteronPt", 0, "Select use default pT (0) or use instead pT shift (1) for antideuteron"}; @@ -132,8 +132,11 @@ struct LFNucleiBATask { TF1* fShiftPtantiHe = 0; TF1* fShiftPHe = 0; TF1* fShiftPantiHe = 0; + TF1* fShiftTPCmomHe = 0; + TF1* fShiftTPCmomantiHe = 0; TF1* fShiftAntiD = 0; + Configurable enableTPCmomShift{"enableTPCmomShift", false, "Flag to enable TPC momentum shift (for He only)"}; Configurable enablePShift{"enablePShift", false, "Flag to enable P shift (for He only)"}; Configurable enablePtShift{"enablePtShift", false, "Flag to enable Pt shift (for He only)"}; Configurable enablePtShiftAntiD{"enablePtShiftAntiD", true, "Flag to enable Pt shift (for antiDeuteron only)"}; @@ -1410,6 +1413,9 @@ struct LFNucleiBATask { float shiftPPos = 0.f; float shiftPNeg = 0.f; + float shiftTPCmomPos = 0.f; + float shiftTPCmomNeg = 0.f; + if (enablePtShift && !fShiftPtHe) { fShiftPtHe = new TF1("fShiftPtHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); auto par = (std::vector)parShiftPtHe; @@ -1434,6 +1440,18 @@ struct LFNucleiBATask { fShiftPantiHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); } + if (enableTPCmomShift && !fShiftTPCmomHe) { + fShiftTPCmomHe = new TF1("fShiftTPCmomHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + auto par = (std::vector)parShiftPHe; + fShiftTPCmomHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); + } + + if (enableTPCmomShift && !fShiftTPCmomantiHe) { + fShiftTPCmomantiHe = new TF1("fShiftTPCmomantiHe", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + auto par = (std::vector)parShiftPantiHe; + fShiftTPCmomantiHe->SetParameters(par[0], par[1], par[2], par[3], par[4]); + } + if (enablePtShiftAntiD && !fShiftAntiD) { fShiftAntiD = new TF1("fShiftAntiD", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); auto par = (std::vector)parShiftPtAntiD; @@ -1477,15 +1495,23 @@ struct LFNucleiBATask { antiheTPCmomentum = track.tpcInnerParam(); if (enablePShift && fShiftPHe) { - shiftPPos = fShiftPHe->Eval(2 * track.tpcInnerParam()); + shiftPPos = fShiftPHe->Eval(2 * track.p()); heP = track.p() - shiftPPos / 2.f; - heTPCmomentum = track.tpcInnerParam() - shiftPPos / 2.f; } if (enablePShift && fShiftPantiHe) { - shiftPNeg = fShiftPantiHe->Eval(2 * track.tpcInnerParam()); + shiftPNeg = fShiftPantiHe->Eval(2 * track.p()); antiheP = track.p() - shiftPNeg / 2.f; - antiheTPCmomentum = track.tpcInnerParam() - shiftPNeg / 2.f; + } + + if (enableTPCmomShift && fShiftTPCmomHe) { + shiftTPCmomPos = fShiftTPCmomHe->Eval(2 * track.tpcInnerParam()); + heTPCmomentum = track.tpcInnerParam() - shiftTPCmomPos / 2.f; + } + + if (enableTPCmomShift && fShiftTPCmomantiHe) { + shiftTPCmomNeg = fShiftTPCmomantiHe->Eval(2 * track.tpcInnerParam()); + antiheTPCmomentum = track.tpcInnerParam() - shiftTPCmomNeg / 2.f; } // p cut @@ -2729,6 +2755,11 @@ struct LFNucleiBATask { case 1: massTOF = track.tofExpMom() * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); break; + case 2: + massTOF = track.p() * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); + massTOFhe = heP * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); + massTOFantihe = antiheP * TMath::Sqrt(1.f / (track.beta() * track.beta()) - 1.f); + break; } histos.fill(HIST("tracks/h2TPCsignVsBetaGamma"), (track.beta() * gamma) / (1.f * track.sign()), track.tpcSignal()); } else { From c984598084a33ae6ee32393c6f1ca4decdc7f7cc Mon Sep 17 00:00:00 2001 From: ivorobye Date: Wed, 20 Dec 2023 17:21:12 +0100 Subject: [PATCH 103/156] PWG-LF: add track filter on min. TPC momentum (#4205) --- PWGLF/TableProducer/nucleiSpectra.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PWGLF/TableProducer/nucleiSpectra.cxx b/PWGLF/TableProducer/nucleiSpectra.cxx index 90f5758daed..99c8fc11a4d 100644 --- a/PWGLF/TableProducer/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/nucleiSpectra.cxx @@ -167,6 +167,7 @@ struct nucleiSpectra { Configurable cfgCMrapidity{"cfgCMrapidity", 0.f, "Rapidity of the center of mass (only for p-Pb)"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable cfgCutTpcMom{"cfgCutTpcMom", 0.2f, "Minimum TPC momentum for tracks"}; Configurable cfgCutRapidityMin{"cfgCutRapidityMin", -0.5, "Minimum rapidity for tracks"}; Configurable cfgCutRapidityMax{"cfgCutRapidityMax", 0.5, "Maximum rapidity for tracks"}; Configurable cfgCutOnReconstructedRapidity{"cfgCutOnReconstructedRapidity", false, "Cut on reconstructed rapidity"}; @@ -209,7 +210,7 @@ struct nucleiSpectra { float mBz = 0.f; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; + Filter trackFilter = nabs(aod::track::eta) < cfgCutEta && aod::track::tpcInnerParam > cfgCutTpcMom; using TrackCandidates = soa::Filtered>; From eda1e9df81e78a98e068d7f85b9fd90d18592d70 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Wed, 20 Dec 2023 17:56:59 +0100 Subject: [PATCH 104/156] Added DCA histograms and Templates for antiprotons (#4219) --- PWGLF/Tasks/nuclei_in_jets.cxx | 72 +++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 016746bc4be..6460dcb1f4f 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -139,6 +139,10 @@ struct nuclei_in_jets { registryData.add("antiproton_ue_tpc", "antiproton_ue_tpc", HistType::kTH3F, {{20, 0.0, 1.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); registryData.add("antiproton_ue_tof", "antiproton_ue_tof", HistType::kTH3F, {{90, 0.5, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TOF}"}, {10, 0, 100, "#it{N}_{ch}"}}); + // DCA Distributions + registryData.add("antiproton_dca_jet", "antiproton_dca_jet", HistType::kTH3F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -0.5, 0.5, "DCA_{xy} (cm)"}, {10, 0, 100, "#it{N}_{ch}"}}); + registryData.add("antiproton_dca_ue", "antiproton_dca_ue", HistType::kTH3F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -0.5, 0.5, "DCA_{xy} (cm)"}, {10, 0, 100, "#it{N}_{ch}"}}); + // Antideuterons registryData.add("antideuteron_jet_tpc", "antideuteron_jet_tpc", HistType::kTH3F, {{10, 0.0, 1.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TPC}"}, {10, 0, 100, "#it{N}_{ch}"}}); registryData.add("antideuteron_jet_tof", "antideuteron_jet_tof", HistType::kTH3F, {{45, 0.5, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -10.0, 10.0, "n#sigma_{TOF}"}, {10, 0, 100, "#it{N}_{ch}"}}); @@ -175,6 +179,10 @@ struct nuclei_in_jets { registryMC.add("antideuteron_jet_rec_tof", "antideuteron_jet_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_ue_rec_tof", "antiproton_ue_rec_tof", HistType::kTH1F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antideuteron_ue_rec_tof", "antideuteron_ue_rec_tof", HistType::kTH1F, {{50, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + + // DCA Templates + registryMC.add("antiproton_dca_prim", "antiproton_dca_prim", HistType::kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -0.5, 0.5, "DCA_{xy} (cm)"}}); + registryMC.add("antiproton_dca_sec", "antiproton_dca_sec", HistType::kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -0.5, 0.5, "DCA_{xy} (cm)"}}); } // Single-Track Selection for the Particle of Interest @@ -199,10 +207,6 @@ struct nuclei_in_jets { return false; if (track.pt() < min_pt) return false; - if (TMath::Abs(track.dcaXY()) > max_dcaxy) - return false; - if (TMath::Abs(track.dcaZ()) > max_dcaz) - return false; // Rapidity Cut double mass(0); @@ -243,9 +247,9 @@ struct nuclei_in_jets { return false; if (track.pt() < 0.15) return false; - if (TMath::Abs(track.dcaXY()) > 0.2) + if (TMath::Abs(track.dcaXY()) > 0.5) return false; - if (TMath::Abs(track.dcaZ()) > 0.2) + if (TMath::Abs(track.dcaZ()) > 0.5) return false; return true; @@ -294,6 +298,21 @@ struct nuclei_in_jets { return false; } + template + bool isAntiproton(const T4& track) + { + // Variables + float nsigmaTPCPr = track.tpcNSigmaPr(); + float nsigmaTOFPr = track.tofNSigmaPr(); + float pt = track.pt(); + + if (pt < 0.5 && TMath::Abs(nsigmaTPCPr) < 2.0) + return true; + if (pt > 0.5 && TMath::Abs(nsigmaTPCPr) < 2.0 && track.hasTOF() && TMath::Abs(nsigmaTOFPr) < 2.0) + return true; + return false; + } + // Minimum float Minimum(float x1, float x2) { @@ -560,7 +579,6 @@ struct nuclei_in_jets { if (Rmax == 0) return; registryQC.fill(HIST("number_of_events_data"), 7.5); - registryQC.fill(HIST("r_max_jet"), Rmax); // Event Counter: Skip Events with jet not fully inside acceptance @@ -648,6 +666,17 @@ struct nuclei_in_jets { float nsigmaTPCHe = jet_track.tpcNSigmaHe(); float pt = jet_track.pt(); + // DCA + if (isAntiproton(jet_track) && TMath::Abs(jet_track.dcaZ()) < max_dcaz) { + registryData.fill(HIST("antiproton_dca_jet"), pt, jet_track.dcaXY(), jet_Nch); + } + + // DCA Cuts + if (TMath::Abs(jet_track.dcaXY()) > max_dcaxy) + continue; + if (TMath::Abs(jet_track.dcaZ()) > max_dcaz) + continue; + // Antiproton if (particle_of_interest == nucleus::proton) { if (pt < 1.0) @@ -689,6 +718,17 @@ struct nuclei_in_jets { float nsigmaTPCHe = ue_track.tpcNSigmaHe(); float pt = ue_track.pt(); + // DCA + if (isAntiproton(ue_track) && TMath::Abs(ue_track.dcaZ()) < max_dcaz) { + registryData.fill(HIST("antiproton_dca_ue"), pt, ue_track.dcaXY(), jet_Nch); + } + + // DCA Cuts + if (TMath::Abs(ue_track.dcaXY()) > max_dcaxy) + continue; + if (TMath::Abs(ue_track.dcaZ()) > max_dcaz) + continue; + // Antiproton if (particle_of_interest == nucleus::proton) { if (pt < 1.0) @@ -770,8 +810,6 @@ struct nuclei_in_jets { continue; const auto particle = track.mcParticle(); - if (!particle.isPhysicalPrimary()) - continue; if ((particle.pdgCode() != -2212) && (particle.pdgCode() != -1000010020) && (particle.pdgCode() != -1000020030)) continue; @@ -802,6 +840,22 @@ struct nuclei_in_jets { float nsigmaTPCHe = track.tpcNSigmaHe(); float pt = track.pt(); + // DCA Templates + if (particle.pdgCode() == -2212 && particle.isPhysicalPrimary() && TMath::Abs(track.dcaZ()) < max_dcaz) + registryMC.fill(HIST("antiproton_dca_prim"), pt, track.dcaXY()); + + if (particle.pdgCode() == -2212 && !particle.isPhysicalPrimary() && TMath::Abs(track.dcaZ()) < max_dcaz) + registryMC.fill(HIST("antiproton_dca_sec"), pt, track.dcaXY()); + + if (!particle.isPhysicalPrimary()) + continue; + + // DCA Cuts + if (TMath::Abs(track.dcaXY()) > max_dcaxy) + continue; + if (TMath::Abs(track.dcaZ()) > max_dcaz) + continue; + // Antiproton if (particle.pdgCode() != -2212) { if (pt < 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC) { From aa489879121f2ff47c3e903d857bb990e11de5c0 Mon Sep 17 00:00:00 2001 From: Shunsuke-Kurita <135583712+Shunsuke-Kurita@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:45:16 +0900 Subject: [PATCH 105/156] add kDeltaPhiPair Histogram (#4220) --- PWGDQ/Core/HistogramsLibrary.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index 8183ace5dd9..6b6d97c18aa 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -677,6 +677,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt", "", false, 750, 0.0, 30.0, VarManager::kMass, 120, 0.0, 30.0, VarManager::kPt); hm->AddHistogram(histClass, "Mass_Rapidity", "", false, 750, 0.0, 30.0, VarManager::kMass, 500, -1.0, 4.0, VarManager::kRap); hm->AddHistogram(histClass, "Mass_VtxZ", "", true, 30, -15.0, 15.0, VarManager::kVtxZ, 750, 0.0, 30.0, VarManager::kMass); + hm->AddHistogram(histClass, "DeltaPhiPair", "", false, 130, -6.5, 6.5, VarManager::kDeltaPhiPair); } if (subGroupStr.Contains("dielectrons")) { if (subGroupStr.Contains("prefilter")) { From ae0bb06720c602fcd2fa1ff19cf1867d0016a0f3 Mon Sep 17 00:00:00 2001 From: EmilGorm <50658075+EmilGorm@users.noreply.github.com> Date: Thu, 21 Dec 2023 11:25:10 +0100 Subject: [PATCH 106/156] Templated reco/gen/data processing (#4200) * Templated reco/gen/data processing * Templated reco/gen/data processing * MegaLinter * Update to MC generated processing --------- Co-authored-by: Emil Gorm Nielsen --- PWGCF/GenericFramework/Core/GFWConfig.h | 4 + .../Tasks/flowGenericFramework.cxx | 339 +++++++++++------- 2 files changed, 207 insertions(+), 136 deletions(-) diff --git a/PWGCF/GenericFramework/Core/GFWConfig.h b/PWGCF/GenericFramework/Core/GFWConfig.h index e626c37a79f..80474125bbf 100644 --- a/PWGCF/GenericFramework/Core/GFWConfig.h +++ b/PWGCF/GenericFramework/Core/GFWConfig.h @@ -12,6 +12,7 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ #define PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ +#include #include #include #include @@ -96,6 +97,9 @@ class GFWBinningCuts const auto& GetPtRefMin() const { return mPTrefmin; } const auto& GetPtRefMax() const { return mPTrefmax; } + const float& GetPtMin() const { return std::min(mPTrefmin, mPTpoimin); } + const float& GetPtMax() const { return std::max(mPTrefmax, mPTpoimax); } + void SetNchBinning(int nchbins, float nchmin, float nchmax) { mNchbins = nchbins; diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index ea910808f3c..a931760f326 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -34,6 +34,7 @@ #include "GFWWeights.h" #include #include +#include using namespace o2; using namespace o2::framework; @@ -60,8 +61,8 @@ int phibins = 72; float philow = 0.0; float phiup = constants::math::TwoPI; int nchbins = 300; -float nchlow = 0.5; -float nchup = 3000.5; +float nchlow = 0; +float nchup = 3000; std::vector centbinning(90); int nBootstrap = 10; GFWRegions regions; @@ -76,8 +77,10 @@ struct GenericFramework { O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Do correlations as function of Nch") O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") O2_DEFINE_CONFIGURABLE(cfgFillQA, bool, false, "Fill QA histograms") + O2_DEFINE_CONFIGURABLE(cfgUse22sEventCut, bool, false, "Use 22s event cut on mult correlations") O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") + O2_DEFINE_CONFIGURABLE(cfgDCAxy, float, 0.2, "Cut on DCA in the transverse direction"); Configurable cfgBinning{"cfgBinning", {40, -10.0, 10.0, 0.2, 2.0, {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, 16, -0.8, 0.8, 72, 0.2, 5.0, 300, 0.5, 3000.5, {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}}, @@ -87,8 +90,8 @@ struct GenericFramework { Configurable cfgCorrConfig{"cfgCorrConfig", {{"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, {0, 0, 0, 0, 0}}, "Configurations for each correlation to calculate"}; -#include "PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.cxx" // NOLINT - // Connect to ccdb + // #include "PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.cxx" // NOLINT + // Connect to ccdb Service ccdb; struct Config { @@ -100,7 +103,6 @@ struct GenericFramework { // Define output OutputObj fFC{FlowContainer("FlowContainer")}; OutputObj fFC_gen{FlowContainer("FlowContainer_gen")}; - OutputObj fFC_reco{FlowContainer("FlowContainer_reco")}; OutputObj fWeights{GFWWeights("weights")}; HistogramRegistry registry{"registry"}; HistogramRegistry QAregistry{"QAregistry", {}, OutputObjHandlingPolicy::QAObject}; @@ -111,6 +113,13 @@ struct GenericFramework { TRandom3* fRndm = new TRandom3(0); TAxis* fPtAxis; + // Event selection cuts - Alex + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultMultPVCut = nullptr; + void init(InitContext const&) { LOGF(info, "flowGenericFramework::init()"); @@ -129,8 +138,8 @@ struct GenericFramework { ptpoiup = cfgBinning->GetPtPOImax(); ptreflow = cfgBinning->GetPtRefMin(); ptrefup = cfgBinning->GetPtRefMax(); - ptlow = static_cast(std::min(ptpoilow, ptreflow)); - ptup = static_cast(std::max(ptpoiup, ptrefup)); + ptlow = cfgBinning->GetPtMin(); + ptup = cfgBinning->GetPtMax(); etabins = cfgBinning->GetEtaBins(); etalow = cfgBinning->GetEtaMin(); etaup = cfgBinning->GetEtaMax(); @@ -150,7 +159,12 @@ struct GenericFramework { AxisSpec vtxAxis = {vtxZbins, vtxZlow, vtxZup, "Vtx_{z} (cm)"}; AxisSpec ptAxis = {ptbinning, "#it{p}_{T} GeV/#it{c}"}; AxisSpec centAxis = {centbinning, "Centrality (%)"}; - AxisSpec nchAxis = {nchbins, nchlow, nchup}; + std::vector nchbinning; + int nchskip = (nchup - nchlow) / nchbins; + for (int i = 0; i <= nchbins; ++i) { + nchbinning.push_back(nchskip * i + nchlow + 0.5); + } + AxisSpec nchAxis = {nchbinning, "N_{ch}"}; AxisSpec multAxis = (cfgUseNch) ? nchAxis : centAxis; AxisSpec dcaZAXis = {200, -2, 2, "DCA_{z} (cm)"}; AxisSpec dcaXYAXis = {200, -1, 1, "DCA_{xy} (cm)"}; @@ -177,10 +191,11 @@ struct GenericFramework { QAregistry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); } if (doprocessReco) { - QAregistry.add("pt_reco", "", {HistType::kTH1D, {ptAxis}}); - QAregistry.add("phi_reco", "", {HistType::kTH1D, {phiAxis}}); - QAregistry.add("eta_reco", "", {HistType::kTH1D, {etaAxis}}); - QAregistry.add("vtxZ_reco", "", {HistType::kTH1D, {vtxAxis}}); + QAregistry.add("pt", "", {HistType::kTH1D, {ptAxis}}); + QAregistry.add("phi", "", {HistType::kTH1D, {phiAxis}}); + QAregistry.add("eta", "", {HistType::kTH1D, {etaAxis}}); + QAregistry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); + registry.add("phi_eta_vtxZ_corrected", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); } } else { QAregistry.add("phi", "", {HistType::kTH1D, {phiAxis}}); @@ -206,7 +221,7 @@ struct GenericFramework { fGFW->CreateRegions(); TObjArray* oba = new TObjArray(); AddConfigObjectsToObjArray(oba, corrconfigs); - if (!doprocessGen && !doprocessReco) { + if (doprocessReco || doprocessData || doprocessRun2) { fFC->SetName("FlowContainer"); fFC->SetXAxis(fPtAxis); fFC->Initialize(oba, multAxis, cfgNbootstrap); @@ -216,12 +231,22 @@ struct GenericFramework { fFC_gen->SetXAxis(fPtAxis); fFC_gen->Initialize(oba, multAxis, cfgNbootstrap); } - if (doprocessReco) { - fFC_reco->SetName("FlowContainer_reco"); - fFC_reco->SetXAxis(fPtAxis); - fFC_reco->Initialize(oba, multAxis, cfgNbootstrap); - } delete oba; + + // Event selection - Alex + if (cfgUse22sEventCut) { + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); + + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x)", 0, 100); + fMultCutLow->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x)", 0, 100); + fMultCutHigh->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); + fMultMultPVCut = new TF1("fMultMultPVCut", "[0]+[1]*x+[2]*x*x", 0, 5000); + fMultMultPVCut->SetParameters(-0.1, 0.785, -4.7e-05); + } } void AddConfigObjectsToObjArray(TObjArray* oba, const std::vector& configs) @@ -260,7 +285,24 @@ struct GenericFramework { cfg.correctionsLoaded = true; } - void FillFC(OutputObj fc, const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) + bool setCurrentParticleWeights(float& weight_nue, float& weight_nua, const float& phi, const float& eta, const float& pt, const float& vtxz) + { + float eff = 1.; + if (cfg.mEfficiency) + eff = cfg.mEfficiency->GetBinContent(cfg.mEfficiency->FindBin(pt)); + else + eff = 1.0; + if (eff == 0) + return false; + weight_nue = 1. / eff; + if (cfg.mAcceptance) + weight_nua = cfg.mAcceptance->GetNUA(phi, eta, vtxz); + else + weight_nua = 1; + return true; + } + + void FillFC(OutputObj fc, const GFW::CorrConfig& corrconf, const float& centmult, const double& rndm) { double dnx, val; dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); @@ -269,7 +311,7 @@ struct GenericFramework { if (!corrconf.pTDif) { val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; if (TMath::Abs(val) < 1) - fc->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + fc->FillProfile(corrconf.Head.c_str(), centmult, val, dnx, rndm); return; } for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { @@ -278,163 +320,188 @@ struct GenericFramework { continue; val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; if (TMath::Abs(val) < 1) - fc->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + fc->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), centmult, val, dnx, rndm); } return; } - Filter collisionFilter = aod::collision::posZ < vtxZup && aod::collision::posZ > vtxZlow; - Filter trackFilter = aod::track::eta < etaup && aod::track::eta > etalow&& aod::track::pt > ptlow&& aod::track::pt < ptup && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < 0.2f; - using myTracks = soa::Filtered>; + template + bool eventSelected(TCollision collision, const int& multTrk, const float& centrality) + { + if (collision.alias_bit(kTVXinTRD)) { + // TRD triggered + return 0; + } + float vtxz = -999; + if (collision.numContrib() > 1) { + vtxz = collision.posZ(); + float zRes = TMath::Sqrt(collision.covZZ()); + if (zRes > 0.25 && collision.numContrib() < 20) + vtxz = -999; + } + // auto multV0A = collision.multFV0A(); + // auto multT0A = collision.multFT0A(); + // auto multT0C = collision.multFT0C(); + auto multNTracksPV = collision.multNTracksPV(); + + if (vtxz > vtxZup || vtxz < vtxZlow) + return 0; + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + return 0; + if (multTrk < fMultCutLow->Eval(centrality)) + return 0; + if (multTrk > fMultCutHigh->Eval(centrality)) + return 0; + if (multTrk > fMultMultPVCut->Eval(multNTracksPV)) + return 0; + + return 1; + } enum datatype { - kRaw, - kDerived + kData, + kDerivedData, + kGen }; template - void processData(TCollision collision, TTracks tracks, float centrality) + void processCollision(TCollision collision, TTracks tracks, const float& centrality) { if (tracks.size() < 1) return; if (centrality < centbinning.front() || centrality > centbinning.back()) return; float vtxz = collision.posZ(); - - if (cfgFillQA) { - QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); - QAregistry.fill(HIST("vtxZ"), vtxz); - } + if (cfgFillQA) + (dt == kGen) ? QAregistry.fill(HIST("vtxZ_gen"), vtxz) : QAregistry.fill(HIST("vtxZ"), vtxz); fGFW->Clear(); float l_Random = fRndm->Rndm(); - float weff = 1, wacc = 1; - for (auto& track : tracks) { - if (cfgFillWeights) - fWeights->Fill(track.phi(), track.eta(), vtxz, track.pt(), centrality, 0); - if (cfg.mEfficiency) - weff = cfg.mEfficiency->GetBinContent(cfg.mEfficiency->FindBin(track.pt())); - else - weff = 1.0; - if (weff == 0) - continue; - weff = 1. / weff; - if (cfg.mAcceptance) - wacc = cfg.mAcceptance->GetNUA(track.phi(), track.eta(), vtxz); - else - wacc = 1; - registry.fill(HIST("phi_eta_vtxZ_corrected"), track.phi(), track.eta(), vtxz, wacc); - bool WithinPtPOI = (ptpoilow < track.pt()) && (track.pt() < ptpoiup); // within POI pT range - bool WithinPtRef = (ptreflow < track.pt()) && (track.pt() < ptrefup); // within RF pT range - if (WithinPtRef) - fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt() - 1), track.phi(), wacc * weff, 1); - if (WithinPtPOI) - fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), wacc * weff, 2); - if (WithinPtPOI && WithinPtRef) - fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), wacc * weff, 4); + ProcessTrack(track, centrality, vtxz); + } + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + FillFC((dt == kGen) ? fFC_gen : fFC, corrconfigs.at(l_ind), (cfgUseNch) ? tracks.size() : centrality, l_Random); + } + } + template + inline void ProcessTrack(TrackObject const& track, const float& centrality, const float& vtxz) + { + float weff = 1, wacc = 1; + float pt, eta, phi; + if constexpr (framework::has_type_v) { + if (track.mcParticleId() < 0 || !(track.has_mcParticle())) + return; + auto mcParticle = track.mcParticle(); + pt = mcParticle.pt(); + eta = mcParticle.eta(); + phi = mcParticle.phi(); + if (!mcParticle.isPhysicalPrimary() || eta < etalow || eta > etaup || pt < ptlow || pt > ptup) + return; + if (cfgFillWeights) + fWeights->Fill(phi, eta, vtxz, pt, centrality, 0); + if (!setCurrentParticleWeights(weff, wacc, phi, eta, pt, vtxz)) + return; + registry.fill(HIST("phi_eta_vtxZ_corrected"), phi, eta, vtxz, wacc); + QAregistry.fill(HIST("phi"), phi); + QAregistry.fill(HIST("eta"), eta); + QAregistry.fill(HIST("pt"), pt); + } else if constexpr (framework::has_type_v) { + pt = track.pt(); + eta = track.eta(); + phi = track.phi(); + if (!track.isPhysicalPrimary() || eta < etalow || eta > etaup || pt < ptlow || pt > ptup) + return; if (cfgFillQA) { - QAregistry.fill(HIST("phi"), track.phi()); - QAregistry.fill(HIST("eta"), track.eta()); - QAregistry.fill(HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); + QAregistry.fill(HIST("phi_gen"), phi); + QAregistry.fill(HIST("eta_gen"), eta); + QAregistry.fill(HIST("pt_gen"), pt); + } + } else { + pt = track.pt(); + eta = track.eta(); + phi = track.phi(); + if (cfgFillWeights) + fWeights->Fill(phi, eta, vtxz, pt, centrality, 0); + if (!setCurrentParticleWeights(weff, wacc, phi, eta, pt, vtxz)) + return; + registry.fill(HIST("phi_eta_vtxZ_corrected"), phi, eta, vtxz, wacc); + if (cfgFillQA) { + QAregistry.fill(HIST("phi"), phi); + QAregistry.fill(HIST("eta"), eta); + QAregistry.fill(HIST("pt_dcaXY_dcaZ"), pt, track.dcaXY(), track.dcaZ()); } } - for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - FillFC(fFC, corrconfigs.at(l_ind), centrality, l_Random); - } + bool WithinPtPOI = (ptpoilow < pt) && (pt < ptpoiup); // within POI pT range + bool WithinPtRef = (ptreflow < pt) && (pt < ptrefup); // within RF pT range + if (WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 1); + if (WithinPtPOI) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 2); + if (WithinPtPOI && WithinPtRef) + fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 4); } - void processRawData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) + Filter collisionFilter = aod::collision::posZ < cfgBinning->GetVtxZmax() && aod::collision::posZ > cfgBinning->GetVtxZmin(); + Filter trackFilter = aod::track::eta < cfgBinning->GetEtaMax() && aod::track::eta > cfgBinning->GetEtaMin() && aod::track::pt > cfgBinning->GetPtMin() && aod::track::pt < cfgBinning->GetPtMax() && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDCAxy; + using myTracks = soa::Filtered>; + + void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) { + if (!collision.sel8()) + return; const auto centrality = collision.centFT0C(); auto bc = collision.bc_as(); - if (!collision.sel8()) + if (cfgUse22sEventCut && !eventSelected(collision, tracks.size(), centrality)) return; QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); - processData(collision, tracks, centrality); + processCollision(collision, tracks, centrality); } - PROCESS_SWITCH(GenericFramework, processRawData, "Process analysis for derived data", true); + PROCESS_SWITCH(GenericFramework, processData, "Process analysis for non-derived data", true); - void processGen(soa::Filtered>::iterator const& collision, aod::McParticles const& particles) + Filter dcaFilter = nabs(aod::track::dcaXY) < cfgDCAxy; + void processReco(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks, aod::McParticles const&) { - if (collision.has_mcCollision()) { - float centrality = collision.centFT0C(); - if (particles.size() < 1) - return; - if (centrality < centbinning.front() || centrality > centbinning.back()) - return; - float vtxz = collision.posZ(); - if (cfgFillQA) { - QAregistry.fill(HIST("vtxZ_gen"), vtxz); - } - fGFW->Clear(); - float l_Random = fRndm->Rndm(); - - for (auto& particle : particles) { - if (!particle.isPhysicalPrimary() || particle.eta() < etalow || particle.eta() > etaup || particle.pt() < ptlow || particle.pt() > ptup) - continue; - bool WithinPtPOI = (ptpoilow < particle.pt()) && (particle.pt() < ptpoiup); // within POI pT range - bool WithinPtRef = (ptreflow < particle.pt()) && (particle.pt() < ptrefup); // within RF pT range - if (WithinPtRef) - fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 1); - if (WithinPtPOI) - fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 2); - if (WithinPtPOI && WithinPtRef) - fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 4); - if (cfgFillQA) { - QAregistry.fill(HIST("phi_gen"), particle.phi()); - QAregistry.fill(HIST("eta_gen"), particle.eta()); - QAregistry.fill(HIST("pt_gen"), particle.pt()); - } - } - for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - FillFC(fFC_gen, corrconfigs.at(l_ind), centrality, l_Random); - } + const auto centrality = collision.centFT0C(); + auto bc = collision.bc_as(); + if (!collision.sel8()) + return; + loadCorrections(bc.timestamp()); + processCollision(collision, tracks, centrality); + } + PROCESS_SWITCH(GenericFramework, processReco, "Process analysis for MC reconstructed events", false); + + Filter mcCollFilter = aod::mccollision::posZ < cfgBinning->GetVtxZmax() && aod::mccollision::posZ > cfgBinning->GetVtxZmin(); + void processGen(soa::Filtered::iterator const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& particles) + { + if (collisions.size() != 1) + return; + float centrality = -1; + for (auto& collision : collisions) { + centrality = collision.centFT0C(); } + processCollision(mcCollision, particles, centrality); } PROCESS_SWITCH(GenericFramework, processGen, "Process analysis for MC generated events", false); - Filter dcaFilter = nabs(aod::track::dcaXY) < 0.2f; - void processReco(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles const&) + void processRun2(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) { - float centrality = collision.centFT0C(); - if (tracks.size() < 1) + if (!collision.sel7()) return; - if (centrality < centbinning.front() || centrality > centbinning.back()) + const auto centrality = collision.centRun2V0M(); + auto bc = collision.bc_as(); + if (cfgUse22sEventCut && !eventSelected(collision, tracks.size(), centrality)) return; - float vtxz = collision.posZ(); - if (cfgFillQA) { - QAregistry.fill(HIST("vtxZ_reco"), vtxz); - } - fGFW->Clear(); - float l_Random = fRndm->Rndm(); - - for (auto& track : tracks) { - if (track.has_mcParticle()) { - auto particle = track.mcParticle(); - if (!particle.isPhysicalPrimary() || particle.eta() < etalow || particle.eta() > etaup || particle.pt() < ptlow || particle.pt() > ptup) - continue; - bool WithinPtPOI = (ptpoilow < particle.pt()) && (particle.pt() < ptpoiup); // within POI pT range - bool WithinPtRef = (ptreflow < particle.pt()) && (particle.pt() < ptrefup); // within RF pT range - if (WithinPtRef) - fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 1); - if (WithinPtPOI) - fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 2); - if (WithinPtPOI && WithinPtRef) - fGFW->Fill(particle.eta(), fPtAxis->FindBin(particle.pt()) - 1, particle.phi(), 1, 4); - if (cfgFillQA) { - QAregistry.fill(HIST("phi_reco"), particle.phi()); - QAregistry.fill(HIST("eta_reco"), particle.eta()); - QAregistry.fill(HIST("pt_reco"), particle.pt()); - } - } - } - for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - FillFC(fFC_reco, corrconfigs.at(l_ind), centrality, l_Random); - } + QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); + loadCorrections(bc.timestamp()); + processCollision(collision, tracks, centrality); } - PROCESS_SWITCH(GenericFramework, processReco, "Process analysis for MC reconstructed events", false); + PROCESS_SWITCH(GenericFramework, processRun2, "Process analysis for Run 2 converted data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 3be7757551649e7ee2e2088a951e301ff075c346 Mon Sep 17 00:00:00 2001 From: spolitan <59452587+stefanopolitano@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:13:52 +0100 Subject: [PATCH 107/156] PWGHF: Charm hadron flow task (#3861) * Adding scalar product task for D+ and Ds * Updating ScalarProduct task; Adding amplitude info in Qvector table; Adding SP function in CMakeLists * Fix typo * Updating architecture of charm hadron flow task * Renaming histos and configurables * Removing unused function and cleaning functions info * Moving task in D2H/Task folder * Adding process function for event plane resolution computation; Adjusitng THnsparse for flow analyses; adapting task to q vectors table updates * Fixing MegaLinter * Implementing corrections to taskFlowCharmHadrons * Adding SP resolution * Fixing whitespace * Fixing process func. name * Update PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx --------- Co-authored-by: Fabio Catalano --- PWGHF/D2H/Tasks/CMakeLists.txt | 5 + PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx | 409 +++++++++++++++++++++++ 2 files changed, 414 insertions(+) create mode 100644 PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index 5131936ddfb..87e4cb40fa8 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -78,3 +78,8 @@ o2physics_add_dpl_workflow(task-xicc SOURCES taskXicc.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(task-flow-charm-hadrons + SOURCES taskFlowCharmHadrons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx new file mode 100644 index 00000000000..11c3cc2a9b9 --- /dev/null +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -0,0 +1,409 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskFlowCharmHadrons.cxx +/// \brief Analysis task for charm hadron flow +/// +/// \author S. Politanò, INFN Torino, Italy + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/EventPlaneHelper.h" +#include "Common/DataModel/Qvectors.h" + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +enum DecayChannel { DplusToPiKPi = 0, + DsToKKPi, + DsToPiKK }; + +enum centralityEstimator { V0A = 0, + T0M, + T0A, + T0C }; + +enum qvecEstimator { FV0A = 0, + FT0M, + FT0A, + FT0C, + TPCPos, + TPCNeg }; + +struct HfTaskFlowCharmHadrons { + Configurable harmonic{"harmonic", 2, "harmonic number"}; + Configurable qvecDetector{"qvecDetector", 0, "Detector for Q vector estimation (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3, TPC Pos: 4, TPC Neg: 5)"}; + Configurable centDetector{"centDetector", 0, "Detector for centrality estimation (V0A: 0, T0M: 1, T0A: 2, T0C: 3"}; + Configurable selectionFlag{"selectionFlag", 1, "Selection Flag for hadron (e.g. 1 for skimming, 3 for topo. and kine., 7 for PID)"}; + Configurable storeMl{"storeMl", false, "Flag to store ML scores"}; + Configurable saveEpResoHisto{"saveEpResoHisto", false, "Flag to save event plane resolution histogram"}; + Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; + + ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; + ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; + ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; + + using CandDsData = soa::Filtered>; + using CandDplusData = soa::Filtered>; + using CollsWithQvecs = soa::Join; + + Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag; + + Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; + Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + + HfHelper hfHelper; + EventPlaneHelper epHelper; + + HistogramRegistry registry{"registry", {}}; + + void init(InitContext&) + { + const AxisSpec thnAxisInvMass{thnConfigAxisInvMass, "Inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality"}; + const AxisSpec thnAxisCosNPhi{thnConfigAxisCosNPhi, Form("cos(%d#varphi)", harmonic.value)}; + const AxisSpec thnAxisScalarProd{thnConfigAxisScalarProd, "SP"}; + const AxisSpec thnAxisMlOne{thnConfigAxisMlOne, "Bkg score"}; + const AxisSpec thnAxisMlTwo{thnConfigAxisMlTwo, "FD score"}; + + registry.add("hSparseFlowCharm", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisCosNPhi, thnAxisScalarProd, thnAxisMlOne, thnAxisMlTwo}); + registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0cFT0m", "hSpResoFT0cFT0m; centrality; Q_{FT0c} #bullet Q_{FT0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0cFV0m", "hSpResoFT0cFV0m; centrality; Q_{FT0c} #bullet Q_{FV0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0cTPCpos", "hSpResoFT0cTPCpos; centrality; Q_{FT0c} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0cTPCneg", "hSpResoFT0cTPCneg; centrality; Q_{FT0c} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0aFT0m", "hSpResoFT0aFT0m; centrality; Q_{FT0a} #bullet Q_{FT0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0aFV0m", "hSpResoFT0aFV0m; centrality; Q_{FT0a} #bullet Q_{FV0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0aTPCpos", "hSpResoFT0aTPCpos; centrality; Q_{FT0a} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0aTPCneg", "hSpResoFT0aTPCneg; centrality; Q_{FT0a} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0mFV0m", "hSpResoFT0mFV0m; centrality; Q_{FT0m} #bullet Q_{FV0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0mTPCpos", "hSpResoFT0mTPCpos; centrality; Q_{FT0m} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0mTPCneg", "hSpResoFT0mTPCneg; centrality; Q_{FT0m} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFV0mTPCpos", "hSpResoFV0mTPCpos; centrality; Q_{FV0m} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFV0mTPCneg", "hSpResoFV0mTPCneg; centrality; Q_{FV0m} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + + if (saveEpResoHisto) { + registry.add("epReso/hEpResoFT0cFT0a", "hEpResoFT0cFT0a; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0cFT0m", "hEpResoFT0cFT0m; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0cFV0m", "hEpResoFT0cFV0m; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0cTPCpos", "hEpResoFT0cTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0cTPCneg", "hEpResoFT0cTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0aFT0m", "hEpResoFT0aFT0m; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0aFV0m", "hEpResoFT0aFV0m; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0aTPCpos", "hEpResoFT0aTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0aTPCneg", "hEpResoFT0aTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0mFV0m", "hEpResoFT0mFV0m; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0mTPCpos", "hEpResoFT0mTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFT0mTPCneg", "hEpResoFT0mTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFV0mTPCpos", "hEpResoFV0mTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + registry.add("epReso/hEpResoFV0mTPCneg", "hEpResoFV0mTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTH2F, {thnAxisCent, thnAxisCosNPhi}}); + } + }; // end init + + /// Compute the Q vector for the candidate's tracks + /// \param cand is the candidate + /// \param tracksQx is the X component of the Q vector for the tracks + /// \param tracksQy is the Y component of the Q vector for the tracks + template + void getQvecDtracks(const T1& cand, + std::vector& tracksQx, + std::vector& tracksQy, + float& ampl) + { + // TODO: add possibility to consider different weights for the tracks, at the moment only pT is considered; + float pXtrack0 = cand.pxProng0(); + float pYtrack0 = cand.pyProng0(); + float pTtrack0 = cand.ptProng0(); + float phiTrack0 = TMath::ATan2(pYtrack0, pXtrack0); + float pXtrack1 = cand.pxProng1(); + float pYtrack1 = cand.pyProng1(); + float pTtrack1 = cand.ptProng1(); + float phiTrack1 = TMath::ATan2(pYtrack1, pXtrack1); + float pXtrack2 = cand.pxProng2(); + float pYtrack2 = cand.pyProng2(); + float pTtrack2 = cand.ptProng2(); + float phiTrack2 = TMath::ATan2(pYtrack2, pXtrack2); + + tracksQx.push_back(cos(harmonic * phiTrack0) * pTtrack0 / ampl); + tracksQy.push_back(sin(harmonic * phiTrack0) * pTtrack0 / ampl); + tracksQx.push_back(cos(harmonic * phiTrack1) * pTtrack1 / ampl); + tracksQy.push_back(sin(harmonic * phiTrack1) * pTtrack1 / ampl); + tracksQx.push_back(cos(harmonic * phiTrack2) * pTtrack2 / ampl); + tracksQy.push_back(sin(harmonic * phiTrack2) * pTtrack2 / ampl); + } + + /// Compute the delta psi in the range [0, pi/harmonic] + /// \param psi1 is the first angle + /// \param psi2 is the second angle + /// \note Ported from AliAnalysisTaskSECharmHadronvn::GetDeltaPsiSubInRange + float getDeltaPsiInRange(float psi1, float psi2) + { + float deltaPsi = psi1 - psi2; + if (std::abs(deltaPsi) > constants::math::PI / harmonic) { + if (deltaPsi > 0.) + deltaPsi -= constants::math::TwoPI / harmonic; + else + deltaPsi += constants::math::TwoPI / harmonic; + } + return deltaPsi; + } + + /// Fill THnSparse + /// \param mass is the invariant mass of the candidate + /// \param pt is the transverse momentum of the candidate + /// \param cent is the centrality of the collision + /// \param cosNPhi is the cosine of the n*phi angle + /// \param cosDeltaPhi is the cosine of the n*(phi - evtPl) angle + /// \param sp is the scalar product + /// \param evtPlReso is the event plane resolution + /// \param outputMl are the ML scores + void fillThn(float mass, + float pt, + float cent, + float cosNPhi, + float cosDeltaPhi, + float sp, + std::vector outputMl) + { + registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, cosNPhi, cosDeltaPhi, sp, outputMl[0], outputMl[1]); + } + + /// Get the centrality + /// \param collision is the collision with the centrality information + float getCentrality(CollsWithQvecs::iterator const& collision) + { + float cent = -999.; + switch (centDetector) { + case centralityEstimator::V0A: + cent = collision.centFV0A(); + break; + case centralityEstimator::T0M: + cent = collision.centFT0M(); + break; + case centralityEstimator::T0A: + cent = collision.centFT0A(); + break; + case centralityEstimator::T0C: + cent = collision.centFT0C(); + break; + default: + LOG(warning) << "Centrality estimator not valid. Possible values are V0A, T0M, T0A, T0C. Fallback to V0A"; + cent = collision.centFV0A(); + break; + } + return cent; + } + + /// Get the Q vector + /// \param collision is the collision with the Q vector information + std::vector getQvec(CollsWithQvecs::iterator const& collision) + { + float xQVec = -999.; + float yQVec = -999.; + float amplQVec = -999.; + switch (qvecDetector) { + case qvecEstimator::FV0A: + xQVec = collision.qvecFV0ARe(); + yQVec = collision.qvecFV0AIm(); + break; + case qvecEstimator::FT0M: + xQVec = collision.qvecFT0MRe(); + yQVec = collision.qvecFT0MIm(); + break; + case qvecEstimator::FT0A: + xQVec = collision.qvecFT0ARe(); + yQVec = collision.qvecFT0AIm(); + break; + case qvecEstimator::FT0C: + xQVec = collision.qvecFT0CRe(); + yQVec = collision.qvecFT0CIm(); + case qvecEstimator::TPCPos: + xQVec = collision.qvecBPosRe(); + yQVec = collision.qvecBPosIm(); + amplQVec = collision.nTrkBPos(); + break; + case qvecEstimator::TPCNeg: + xQVec = collision.qvecBNegRe(); + yQVec = collision.qvecBNegIm(); + amplQVec = collision.nTrkBNeg(); + break; + default: + LOG(warning) << "Q vector estimator not valid. Please choose between FV0A, FT0M, FT0A, FT0C, TPC Pos, TPC Neg. Fallback to FV0A"; + xQVec = collision.qvecFV0ARe(); + yQVec = collision.qvecFV0AIm(); + break; + } + return {xQVec, yQVec, amplQVec}; + } + + /// Compute the scalar product + /// \param collision is the collision with the Q vector information and event plane + /// \param candidates are the selected candidates + template + void runFlowAnalysis(CollsWithQvecs::iterator const& collision, + T1 const& candidates) + { + std::vector qVecs = getQvec(collision); + float xQVec = qVecs[0]; + float yQVec = qVecs[1]; + float amplQVec = qVecs[2]; + float evtPl = epHelper.GetEventPlane(xQVec, yQVec, harmonic); + float cent = getCentrality(collision); + + for (const auto& candidate : candidates) { + float massCand = 0.; + std::vector outputMl = {-999., -999.}; + + if constexpr (std::is_same::value) { + switch (DecayChannel) { + case DecayChannel::DsToKKPi: + massCand = hfHelper.invMassDsToKKPi(candidate); + if (storeMl) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) + outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; + } + break; + case DecayChannel::DsToPiKK: + massCand = hfHelper.invMassDsToPiKK(candidate); + if (storeMl) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) + outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; + } + break; + default: + break; + } + } else if constexpr (std::is_same::value) { + massCand = hfHelper.invMassDplusToPiKPi(candidate); + if (storeMl) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) + outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; + } + } + float ptCand = candidate.pt(); + float phiCand = candidate.phi(); + + // If TPC is used for the SP estimation, the tracks of the hadron candidate must be removed from the TPC Q vector to avoid double counting + if (qvecDetector == 4 || qvecDetector == 5) { + float ampl = amplQVec - 3.; + std::vector tracksQx = {}; + std::vector tracksQy = {}; + getQvecDtracks(candidate, tracksQx, tracksQy, ampl); + for (unsigned int itrack = 0; itrack < 3; itrack++) { + xQVec -= tracksQx[itrack]; + yQVec -= tracksQy[itrack]; + } + } + + float cosNPhi = TMath::Cos(harmonic * phiCand); + float sinNPhi = TMath::Sin(harmonic * phiCand); + float scalprodCand = cosNPhi * xQVec + sinNPhi * yQVec; + float cosDeltaPhi = TMath::Cos(harmonic * (phiCand - evtPl)); + + fillThn(massCand, ptCand, cent, cosNPhi, cosDeltaPhi, scalprodCand, outputMl); + } + } + + // Ds + void processDs(CollsWithQvecs::iterator const& collision, + CandDsData const& candidatesDs) + { + runFlowAnalysis>(collision, selectedDsToKKPi); + runFlowAnalysis>(collision, selectedDsToPiKK); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDs, "Process Ds candidates", false); + + // Dplus + void processDplus(CollsWithQvecs::iterator const& collision, + CandDplusData const& candidatesDplus) + { + runFlowAnalysis(collision, candidatesDplus); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplus, "Process Dplus candidates", true); + + // Resolution + void processResolution(CollsWithQvecs::iterator const& collision) + { + float centrality = getCentrality(collision); + float xQVecFT0a = collision.qvecFT0ARe(); + float yQVecFT0a = collision.qvecFT0AIm(); + float xQVecFT0c = collision.qvecFT0CRe(); + float yQVecFT0c = collision.qvecFT0CIm(); + float xQVecFT0m = collision.qvecFT0MRe(); + float yQVecFT0m = collision.qvecFT0MIm(); + float xQVecFV0a = collision.qvecFV0ARe(); + float yQVecFV0a = collision.qvecFV0AIm(); + float xQVecBPos = collision.qvecBPosRe(); + float yQVecBPos = collision.qvecBPosIm(); + float xQVecBNeg = collision.qvecBNegRe(); + float yQVecBNeg = collision.qvecBNegIm(); + + registry.fill(HIST("spReso/hSpResoFT0cFT0a"), centrality, xQVecFT0c * xQVecFT0a + yQVecFT0c * yQVecFT0a); + registry.fill(HIST("spReso/hSpResoFT0cFT0m"), centrality, xQVecFT0c * xQVecFT0m + yQVecFT0c * yQVecFT0m); + registry.fill(HIST("spReso/hSpResoFT0cFV0m"), centrality, xQVecFT0c * xQVecFV0a + yQVecFT0c * yQVecFV0a); + registry.fill(HIST("spReso/hSpResoFT0cTPCpos"), centrality, xQVecFT0c * xQVecBPos + yQVecFT0c * yQVecBPos); + registry.fill(HIST("spReso/hSpResoFT0cTPCneg"), centrality, xQVecFT0c * xQVecBNeg + yQVecFT0c * yQVecBNeg); + registry.fill(HIST("spReso/hSpResoFT0aFT0m"), centrality, xQVecFT0a * xQVecFT0m + yQVecFT0a * yQVecFT0m); + registry.fill(HIST("spReso/hSpResoFT0aFV0m"), centrality, xQVecFT0a * xQVecFV0a + yQVecFT0a * yQVecFV0a); + registry.fill(HIST("spReso/hSpResoFT0aTPCpos"), centrality, xQVecFT0a * xQVecBPos + yQVecFT0a * yQVecBPos); + registry.fill(HIST("spReso/hSpResoFT0aTPCneg"), centrality, xQVecFT0a * xQVecBNeg + yQVecFT0a * yQVecBNeg); + registry.fill(HIST("spReso/hSpResoFT0mFV0m"), centrality, xQVecFT0m * xQVecFV0a + yQVecFT0m * yQVecFV0a); + registry.fill(HIST("spReso/hSpResoFT0mTPCpos"), centrality, xQVecFT0m * xQVecBPos + yQVecFT0m * yQVecBPos); + registry.fill(HIST("spReso/hSpResoFT0mTPCneg"), centrality, xQVecFT0m * xQVecBNeg + yQVecFT0m * yQVecBNeg); + registry.fill(HIST("spReso/hSpResoFV0mTPCpos"), centrality, xQVecFV0a * xQVecBPos + yQVecFV0a * yQVecBPos); + registry.fill(HIST("spReso/hSpResoFV0mTPCneg"), centrality, xQVecFV0a * xQVecBNeg + yQVecFV0a * yQVecBNeg); + + if (saveEpResoHisto) { + float epFT0a = epHelper.GetEventPlane(xQVecFT0a, yQVecFT0a, harmonic); + float epFT0c = epHelper.GetEventPlane(xQVecFT0c, yQVecFT0c, harmonic); + float epFT0m = epHelper.GetEventPlane(xQVecFT0m, yQVecFT0m, harmonic); + float epFV0a = epHelper.GetEventPlane(xQVecFV0a, yQVecFV0a, harmonic); + float epBPoss = epHelper.GetEventPlane(xQVecBPos, yQVecBPos, harmonic); + float epBNegs = epHelper.GetEventPlane(xQVecBNeg, yQVecBNeg, harmonic); + + registry.fill(HIST("epReso/hEpResoFT0cFT0a"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epFT0a))); + registry.fill(HIST("epReso/hEpResoFT0cFT0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epFT0m))); + registry.fill(HIST("epReso/hEpResoFT0cFV0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epFV0a))); + registry.fill(HIST("epReso/hEpResoFT0cTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epBPoss))); + registry.fill(HIST("epReso/hEpResoFT0cTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epBNegs))); + registry.fill(HIST("epReso/hEpResoFT0aFT0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epFT0m))); + registry.fill(HIST("epReso/hEpResoFT0aFV0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epFV0a))); + registry.fill(HIST("epReso/hEpResoFT0aTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epBPoss))); + registry.fill(HIST("epReso/hEpResoFT0aTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epBNegs))); + registry.fill(HIST("epReso/hEpResoFT0mFV0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0m, epFV0a))); + registry.fill(HIST("epReso/hEpResoFT0mTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0m, epBPoss))); + registry.fill(HIST("epReso/hEpResoFT0mTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0m, epBNegs))); + registry.fill(HIST("epReso/hEpResoFV0mTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFV0a, epBPoss))); + registry.fill(HIST("epReso/hEpResoFV0mTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFV0a, epBNegs))); + } + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processResolution, "Process resolution", false); + +}; // End struct HfTaskFlowCharmHadrons + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 2e1b15a5a854a7af2e3b061787f27ba51c646cce Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:36:59 +0100 Subject: [PATCH 108/156] [PWGDQ] Adding histograms and reduced table for MFT pid studies (#4207) * Adding histograms and reduced table for MFT pid studies * Removing one configurable --------- Co-authored-by: Lucamicheletti93 --- PWGDQ/Core/HistogramsLibrary.cxx | 6 ++++++ PWGDQ/Core/VarManager.cxx | 6 ++++++ PWGDQ/Core/VarManager.h | 22 ++++++++++++++++++++++ PWGDQ/DataModel/ReducedInfoTables.h | 6 ++++++ PWGDQ/TableProducer/tableMaker.cxx | 24 +++++++++++++++++++++++- 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index 6b6d97c18aa..1955e110123 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -477,6 +477,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "pdca_vs_Rabs_vs_p", "pDCA vs R_{abs} vs p", false, 2000, 0.0, 20.0, VarManager::kP, 100, 0., 200., VarManager::kMuonRAtAbsorberEnd, 200, 0.0, 1000., VarManager::kMuonPDca); hm->AddHistogram(histClass, "pdca_vs_Rabs_vs_pt", "pDCA vs R_{abs} vs pt", false, 2000, 0.0, 20.0, VarManager::kPt, 100, 0., 200., VarManager::kMuonRAtAbsorberEnd, 200, 0.0, 1000., VarManager::kMuonPDca); } + if (subGroupStr.Contains("mft-pid")) { + hm->AddHistogram(histClass, "hMftTrackEtaVsPt", "", false, 100, -5.f, -2.f, VarManager::kEta, 100, 0.f, 20.f, VarManager::kPt); + hm->AddHistogram(histClass, "hMftNClusters", "", false, 16, -0.5f, 15.5f, VarManager::kMftNClusters); + hm->AddHistogram(histClass, "hMftClusterSize", "", false, 101, -0.5f, 100.5f, VarManager::kMftClusterSize); + hm->AddHistogram(histClass, "hMftMeanClusterSize", "", false, 200, 0.f, 20.f, VarManager::kMftMeanClusterSize); + } if (subGroupStr.Contains("mc")) { hm->AddHistogram(histClass, "Pt_vs_PtMC", "pT vs MC pT", false, 200, 0.0, 20.0, VarManager::kPt, 200, 0.0, 20.0, VarManager::kMCPt); hm->AddHistogram(histClass, "Eta_vs_EtaMC", "#eta vs MC #eta", false, 50, -1.0, 1.0, VarManager::kEta, 50, -1.0, 1.0, VarManager::kMCEta); diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index f7d7c0175fc..46c30797077 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -438,6 +438,12 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kIsLegFromOmega] = ""; fgVariableNames[kMuonNClusters] = "muon n-clusters"; fgVariableUnits[kMuonNClusters] = ""; + fgVariableNames[kMftNClusters] = "MFT n-clusters"; + fgVariableUnits[kMftNClusters] = ""; + fgVariableNames[kMftClusterSize] = "MFT cluster size"; + fgVariableUnits[kMftClusterSize] = ""; + fgVariableNames[kMftMeanClusterSize] = ""; + fgVariableUnits[kMftMeanClusterSize] = ""; fgVariableNames[kMuonRAtAbsorberEnd] = "R at the end of the absorber"; fgVariableUnits[kMuonRAtAbsorberEnd] = "cm"; fgVariableNames[kMuonPDca] = "p x dca"; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 9e78af9ed48..16e06c6e95c 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -345,6 +345,9 @@ class VarManager : public TObject kMuonDCAy, kMuonTime, kMuonTimeRes, + kMftNClusters, + kMftClusterSize, + kMftMeanClusterSize, // MC particle variables kMCPdgCode, @@ -1082,6 +1085,25 @@ void VarManager::FillTrack(T const& track, float* values) values = fgValues; } + if constexpr ((fillMap & TrackMFT) > 0) { + values[kPt] = track.pt(); + values[kEta] = track.eta(); + values[kPhi] = track.phi(); + values[kMftNClusters] = track.nClusters(); + + uint64_t mftClsAndFlgs = track.mftClusterSizesAndTrackFlags(); + double meanClusterSize = 0; + for (int i = 0; i < 10; ++i) { + double size = (mftClsAndFlgs >> (i * 6)) & 0x3fULL; + values[kMftClusterSize + i] = (mftClsAndFlgs >> (i * 6)) & 0x3fULL; + if (size > 0) { + meanClusterSize += size; + } + } + meanClusterSize /= track.nClusters(); + values[kMftMeanClusterSize] = meanClusterSize; + } + // Quantities based on the basic table (contains just kine information and filter bits) if constexpr ((fillMap & Track) > 0 || (fillMap & Muon) > 0 || (fillMap & ReducedTrack) > 0 || (fillMap & ReducedMuon) > 0) { values[kPt] = track.pt(); diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index 613aff6e800..86a0bd87753 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -270,6 +270,8 @@ DECLARE_SOA_COLUMN(FilteringFlags, filteringFlags, uint8_t); //! DECLARE_SOA_COLUMN(Pt, pt, float); //! DECLARE_SOA_COLUMN(Eta, eta, float); //! DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(MftClusterSizesAndTrackFlags, mftClusterSizesAndTrackFlags, uint64_t); //! } // namespace reducedmft // MFT track kinematics @@ -277,6 +279,10 @@ DECLARE_SOA_TABLE(ReducedMFTTracks, "AOD", "RMFTTR", //! o2::soa::Index<>, reducedmft::ReducedEventId, reducedmft::FilteringFlags, reducedmft::Pt, reducedmft::Eta, reducedmft::Phi); +// MFT tracks extra info (cluster size, sign) +DECLARE_SOA_TABLE(ReducedMFTTracksExtra, "AOD", "RMFTTREXTRA", //! + reducedmft::MftClusterSizesAndTrackFlags, reducedmft::Sign); + // iterator using ReducedMFTTrack = ReducedMFTTracks::iterator; diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 8467ab1d360..5022f386e1c 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -140,6 +140,7 @@ struct TableMaker { Produces muonCov; Produces muonInfo; Produces trackMFT; + Produces trackMFTExtra; OutputObj fOutputList{"output"}; //! the histogram manager output list OutputObj fStatsList{"Statistics"}; //! skimming statistics @@ -246,7 +247,7 @@ struct TableMaker { context.mOptions.get("processMuonOnlyWithCovAndCent") || context.mOptions.get("processMuonOnlyWithCov") || context.mOptions.get("processMuonOnlyWithCovAndEventFilter") || context.mOptions.get("processMuonOnlyWithEventFilter") || context.mOptions.get("processMuonOnlyWithMultsAndEventFilter") || context.mOptions.get("processAmbiguousMuonOnlyWithCov") || context.mOptions.get("processAmbiguousMuonOnly") || - context.mOptions.get("processMuonMLOnly") || context.mOptions.get("processMuonMLOnly")); + context.mOptions.get("processMuonsAndMFT") || context.mOptions.get("processMuonsAndMFTWithFilter") || context.mOptions.get("processMuonMLOnly")); if (enableBarrelHistos) { if (fDoDetailedQA) { @@ -273,6 +274,7 @@ struct TableMaker { if (enableMuonHistos) { if (fDoDetailedQA) { histClasses += "Muons_BeforeCuts;"; + histClasses += "MftTracks;"; if (fIsAmbiguous) { histClasses += "Ambiguous_Muons_BeforeCuts;"; histClasses += "Orphan_Muons_MFTMCHMID;"; @@ -570,6 +572,7 @@ struct TableMaker { if constexpr (static_cast(TMFTFillMap)) { trackMFT.reserve(mftTracks.size()); + trackMFTExtra.reserve(mftTracks.size()); // TODO add cuts on the MFT tracks int nDel = 0; for (auto& mft : mftTracks) { @@ -582,7 +585,11 @@ struct TableMaker { mftOffsets[mft.globalIndex()] = mft.offsets(); + VarManager::FillTrack(mft); + fHistMan->FillHistClass("MftTracks", VarManager::fgValues); + trackMFT(event.lastIndex(), trackFilteringTag, mft.pt(), mft.eta(), mft.phi()); + trackMFTExtra(mft.mftClusterSizesAndTrackFlags(), mft.sign()); } // end of mft : mftTracks } // end if constexpr (TMFTFillMap) @@ -1076,6 +1083,13 @@ struct TableMaker { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histMuonName); } } + + TString histMftName = fConfigAddMuonHistogram.value; + if (classStr.Contains("Mft")) { + if (fConfigDetailedQA) { + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histMftName); + } + } } // create statistics histograms (event, tracks, muons) @@ -1378,6 +1392,13 @@ struct TableMaker { } } + // Produce MFT tracks tables and muons ------------------------------------------------------------------------------------------------------------------ + void processMuonsAndMFT(MyEvents::iterator const& collision, aod::BCsWithTimestamps const& bcs, + aod::MFTTracks const& tracksMft, soa::Filtered const& tracksMuon) + { + fullSkimming(collision, bcs, nullptr, tracksMuon, nullptr, nullptr, tracksMft); + } + // Produce MFT tracks tables and muons, with event filtering ------------------------------------------------------------------------------------------------------------------ void processMuonsAndMFTWithFilter(MyEventsWithFilter::iterator const& collision, aod::BCsWithTimestamps const& bcs, aod::MFTTracks const& tracksMft, soa::Filtered const& tracksMuon) @@ -1520,6 +1541,7 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processAmbiguousBarrelOnly, "Build barrel-only DQ skimmed data model with QA plots for ambiguous tracks", false); PROCESS_SWITCH(TableMaker, processAssociatedMuonOnly, "Build muon-only DQ skimmed data model using track-collision association tables", false); PROCESS_SWITCH(TableMaker, processAssociatedMuonOnlyWithCov, "Build muon-only with cov DQ skimmed data model using track-collision association tables", false); + PROCESS_SWITCH(TableMaker, processMuonsAndMFT, "Build MFT and muons DQ skimmed data model", false); PROCESS_SWITCH(TableMaker, processMuonsAndMFTWithFilter, "Build MFT and muons DQ skimmed data model, w/ event filter", false); }; From dcdf57ccccfc43237f70d37f37e9a2c4dccfb8f5 Mon Sep 17 00:00:00 2001 From: cterrevo Date: Thu, 21 Dec 2023 18:52:03 +0100 Subject: [PATCH 109/156] [PWGHF]: fix downscale of background for Xic tree creator (#4221) * fix to downsample to bkg only * fix pdg access * Please consider the following formatting changes * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Mattia Faggin * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Mattia Faggin --------- Co-authored-by: ALICE Action Bot Co-authored-by: Mattia Faggin --- PWGHF/TableProducer/treeCreatorXicToPKPi.cxx | 22 ++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx index b3bd0e93fa5..a0af9dc888d 100644 --- a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx @@ -233,6 +233,8 @@ struct HfTreeCreatorXicToPKPi { Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; // parameters for production of training samples Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + Configurable fillOnlyBackground{"fillOnlyBackground", false, "Flag to fill derived tables with background for ML trainings"}; HfHelper hfHelper; @@ -272,15 +274,21 @@ struct HfTreeCreatorXicToPKPi { auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) auto trackPos2 = candidate.prong2_as(); // positive daughter (negative for the antiparticles) + if (fillOnlyBackground && downSampleBkgFactor < 1.) { + double pseudoRndm = trackPos1.pt() * 1000. - static_cast(trackPos1.pt() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; + } + } auto fillTable = [&](int CandFlag, int FunctionSelection, float FunctionInvMass, float FunctionCt, float FunctionY, float FunctionE) { - double pseudoRndm = trackPos1.pt() * 1000. - (int64_t)(trackPos1.pt() * 1000); - if (FunctionSelection >= 1 && pseudoRndm < downSampleBkgFactor) { + if (FunctionSelection >= 1) { if (fillCandidateLiteTable) { + rowCandidateLite( candidate.chi2PCA(), candidate.decayLength(), @@ -451,14 +459,19 @@ struct HfTreeCreatorXicToPKPi { auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) auto trackPos2 = candidate.prong2_as(); // positive daughter (negative for the antiparticles) + if (downSampleBkgFactor < 1.) { + double pseudoRndm = trackPos1.pt() * 1000. - static_cast(trackPos1.pt() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; + } + } auto fillTable = [&](int CandFlag, int FunctionSelection, float FunctionInvMass, float FunctionCt, float FunctionY, float FunctionE) { - double pseudoRndm = trackPos1.pt() * 1000. - (int64_t)(trackPos1.pt() * 1000); - if (FunctionSelection >= 1 && pseudoRndm < downSampleBkgFactor) { + if (FunctionSelection >= 1) { if (fillCandidateLiteTable) { rowCandidateLite( candidate.chi2PCA(), @@ -577,6 +590,7 @@ struct HfTreeCreatorXicToPKPi { } } }; + fillTable(0, candidate.isSelXicToPKPi(), hfHelper.invMassXicToPKPi(candidate), hfHelper.ctXic(candidate), hfHelper.yXic(candidate), hfHelper.eXic(candidate)); fillTable(1, candidate.isSelXicToPiKP(), hfHelper.invMassXicToPiKP(candidate), hfHelper.ctXic(candidate), hfHelper.yXic(candidate), hfHelper.eXic(candidate)); } From 4fcc1ae8e3573bbef6256097031c37dd6e8c1e7f Mon Sep 17 00:00:00 2001 From: smaff92 <33285879+smaff92@users.noreply.github.com> Date: Fri, 22 Dec 2023 03:54:12 +0900 Subject: [PATCH 110/156] Changes to Phi-in-jets (#4213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated and new commit of Phi in Jet tasks for PWGJE * update of phi-in-jets analysis task, fixed bug in jet finding * Please consider the following formatting changes * PWGHF: fix processMc for sigmac. (#3844) * PWGHF: fix processing on MC for SigmaC. * Use TESTBIT to check flagMcMatchRec Co-authored-by: Fabrizio --------- Co-authored-by: Mattia Faggin Co-authored-by: Fabrizio * [PWGHF] Implemented selection on DeltaMass (KK,Phi) for Ds in track index skim creator (#3862) * Implemented cut on delta mass phi for Ds * Refactored the selections and updated 2prongs code for consistency * Please consider the following formatting changes * Update PWGHF/TableProducer/trackIndexSkimCreator.cxx Co-authored-by: Fabrizio * Apply suggestions from code review Co-authored-by: Fabrizio * Implemented suggestions --------- Co-authored-by: ALICE Action Bot Co-authored-by: Fabrizio * PWGCF FemtoUniverse PairCleaner update for track-v0 (#3877) * fixed track-v0 pair check * clang-format check done --------- Co-authored-by: Shirajum Monira * PWGEM/PhotonMeson: fix for Join (#3881) * PWGLF: Update lambda1520SpherocityAnalysis.cxx (#3878) * Rework of the multiplicity and PVcontribs axis ranges settings (#3883) * Correct a typo * Reworking axis for multiplicity and PV contribs. Now, collision system dependent. Seems it is working. Resetting ranges. * Resetting the default axis to be in ideal for pp 500kHz and PbPb50kHz * even more generous ranges for PbPb * Rework of the default PbPb axis ranges. Going back to one ConfigurableAxis and placing the default values in the init. Now, this is controlled solely by defaultPbPb bool, which is by default false * Renaming of the switch * cang formatting * clang formatting wrt origin master * PWGHF: Add more centrality estimators (#3880) * PWGHF: Add more centrality estimators * Define more process functions to consume only one centrality table at a time * Remove unncecessary template and fix filling of histo * Update PWGHF/TableProducer/trackIndexSkimCreator.cxx Co-authored-by: Vít Kučera * Update PWGHF/TableProducer/trackIndexSkimCreator.cxx Co-authored-by: Vít Kučera * Add missing arguments * Fix enum names --------- Co-authored-by: Vít Kučera * PWGDQ: Fix filling of D meson histos in D-JPsi analysis (#3884) * Add histograms about tpc(and its) vs. signed pt (#3882) * Modification on hypertriton 3body decay finder method (#3887) * Fix bug and modify histos * Change processMC * Update finder method * Update finder method * Formatting * pDCAcutOptimization (#3869) * Update HistogramsLibrary.cxx Dimuon-polarization using THnSpase for cosTheta and Phi * Please consider the following formatting changes * Update HistogramsLibrary.cxx * Update HistogramsLibrary.cxx --------- Co-authored-by: ALICE Action Bot * PWGJE : Introduction of MB selection (#3888) * Introduction of MB selection * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * [PWGLF] bugfix in momentum resolution: multiply pt_rec by particle charge (#3890) * PWGHF: fix filling of some MC histos and re-order inv. mass histos for signal. (#3889) Co-authored-by: Mattia Faggin * [O2-4360] First implementation of cluster-matchedtracks-writer (#3892) - First version of the table producer that was asked for in the linked JIRA ticket * [PWGDQ] Adding process function for muons with cov and filters (#3897) * Adding process function for muons with cov and filters * Fix clang --------- Co-authored-by: Luca Micheletti * Add daughter information in table (#3898) * PWGEM/PhotonMeson: add QA histograms for e/mu (#3894) * [O2-4360] EMCALMatchedTracks: Add QPt column (#3899) - Add QPt column to the table * more PID scenarios (#3896) * Split even more multiplicities (#3891) - Split table for barrel multiplicity - Add proto MC multiplicities - Add fatal in case mult is misconfigured and Zeq is requested * PWGMM/Tasks/multiplicityPbPb.cxx modification (#3904) * PWGEM/PHOTONMESON: Add RPhi dependence plots (#3853) * PWGEM/PhotonMeson: update on event mixing for dileptons (#3905) * PWGEM/PhotonMeson: update dilepton QC MC (#3906) * [PWGLF] Change V0 Cos PA to regular column for filterability (#3834) * Change V0 Cos PA to regular for filter-ability * Please consider the following formatting changes (#183) --------- Co-authored-by: ALICE Builder * Removing unused histograms (#3901) * [Common/event plane determination] making sub tables and saving track id (#3907) * making sub tables and saving track id * fix * fix * fix * Please consider the following formatting changes --------- Co-authored-by: junleekim Co-authored-by: ALICE Action Bot * EventFiltering/PWGHF: remove obsolete task and add new task to check charm signals with trigger selections (#3895) * EventFiltering/PWGHF: remove obsolete task and add new task to check charm signals with trigger selections * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * Fix ordering in table (#3909) * PWGMM: dndeta: rework (#3910) * Add "processDecayToEESkimmedWithColl" to the init function of the AnalysisSameEventPairing task in tableReader.cxx (#3885) * Skip DF with 0 collisions (#2351) * PWGHF: Add KFParticle to D0 creator * PWGHF: Added topological chi2 to HfCand2Prong table * PWGHF: Add topological chi2 to treeCreatorD0ToKPi * PWGHF: Added histograms for D0 and D0bar after topological constraint * PWGHF: Add geometrical mass to the output table * PWGHF: Use the extra table to store KFParticle topological chi2 and geometrical mass * PWGHF: git-cland-format for candidateCreator2Prong * PWGHF:git-clang-format * PWGHF: candidateCreator2Prong.cxx with git-clang-format * PWGHF: optimize the code to add Kf to D0 * PWGHF: candidateSelectorD0.cxx conflict fix * Merge commit '76acd5f6ff94b2fa82fd234526cf84f09daf68a9', fix conflicts in PWGHF/TableProducer/candidateCreatorD0.cxx * Updates for adding KF to HF-D0 * git-clang-format for "PWGHF/DataModel/CandidateReconstructionTables.h" * PWGHF: Try to respect the grouping and sorting of the head files * Update PR * Update PR * PWGHF: update PR * PWGHF: update git-clang-format * PWGHF: update PR * PWGHF: update PR * Remove unused variables in runCreator2ProngWithKFParticle * PWGDQ: Add "processDecayToEESkimmedWithColl" to the init function of the AnalysisSameEventPairing task in tableReader.cxx --------- Co-authored-by: Maximiliano Puccio Co-authored-by: Chiara Zampolli * [PWGDQ] Add function to propagate muon tracks through absorber to PV (#3762) * Add function to propagate muon tracks through absorber to PV * Format * Fix * Fix * Fix typo * Fixing libraries * Clang format * Missing array definition * Retrieving geometry from ccdb * Clang format * Fixing retrieving of ccdb object * Calng format * Fixing covariance name * F1 ptableordering (#3914) * Fix ordering in table * Add TOF hit information of daughter * fix search of missing tpc segment + add mc truth info in tag and probe (#3917) * PWGMM: dndeta: create separate directories for registries (#3915) * Femto 3D table producer (#3893) * update the Femto3D's data model as requested --------- Co-authored-by: Nicolò Jacazio Co-authored-by: ALICE Action Bot * PWGMM/Tasks/multiplicityPbPb.cxx TPC cut removed (#3918) * Example pcm qa at builder (#3920) * Example pcm qa at builder * Require TPC only * Please consider the following formatting changes (#187) * true TPC only ONLY --------- Co-authored-by: David Dobrigkeit Chinellato Co-authored-by: ALICE Builder * Update Track Propagation (#3921) - reserve room for tracks and DCA * Incorrect preslice (#3912) * PWG-UD: Single Gap producer (#3879) * Single Gap producer, Paul's comments, mistype fixed * Please consider the following formatting changes * Update UDHelpers.h Removed CleanFitACollisions and CleanFitCCollision which are not ysed by the SGSelector --------- Co-authored-by: alexandr.bylinkin@cern.ch Co-authored-by: ALICE Action Bot * [PWGDQ] Write eventfilter to 32 highest bits of tag column in reducedEvents (#3922) * EventFiltering: fix missing magnetic field for track propagation (#3924) * EventFiltering: fix missing magnetic field for track propagation * Remove whitespace * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * EventFiltering: fix propagation for V0s and cascades in charm decays (#3923) * EventFiltering: fix propagation for V0s and cascades in charm decays * Set proper masses for propagation * Set proper masses for propagation * Adding D0 meson as a particle type (#3925) * PWGHF: fix and update cascade-bachelor index skimming (#3886) * Update cascade-bachelor skimming * Remove symbols * Remove symbols * Update authors * Continue development * Continue development * Continue development * Continue development * Continue development * Please consider the following formatting changes * Fix missing ; * Fix errors * Implement suggestions * Please consider the following formatting changes * Implement suggestions * Update PWGHF/TableProducer/trackIndexSkimCreator.cxx Co-authored-by: Fabrizio * Update PWGHF/TableProducer/trackIndexSkimCreator.cxx Co-authored-by: Fabrizio * Use different xi trackParCov for 3prong * Change default configurable and catch propagation exceptions * Please consider the following formatting changes * Remove hfFlag for 3prong --------- Co-authored-by: ALICE Action Bot Co-authored-by: Fabrizio * Improve strangeness tracking filtering (#3928) - propagate tracks for mass calculation - additional histograms for selected Xi/Omega - add cosine pointing angle - require minimum number of TPC clusters for daughters * Update singletrackselector.h (#3926) Fixing table names. * PWGLF: Update hypertriton 3body decay analysis (#3929) * Add check histo for virtual lambda * "Add mass cut for hypertriton" * Fix bug * Update 3body analysis * Update 3body builder method Add Deuteron TOF cut Change configurables Fix dcatopv bug * Delete useless comments * Fix dca bug in finder and formatting * Update 3body analysis Fix bugs in findermethod Change TOF PID cut * Small Change on QA histo * Extra builder QA (#3931) * Extra builder QA * Please consider the following formatting changes (#188) --------- Co-authored-by: ALICE Builder * PWGHF: change configurable default values for struct LfCascade (#3934) * Change configurable default values * Change configurable default values * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * Add task for measurement of nuclei in jets and ue (#3935) * Add task for measurement of nuclei in jets and ue * Use static_cast -> Fixed * fixed static cast * EventFiltering/PWGHF: fix small bugs (#3932) * EventFiltering/PWGHF: fix small bugs * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * PWGHF: improve cascade preselection in toXiPi creator (#3927) * Improve cascade preselection * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * [BUG] Incorrect Preslice (#3936) * add the cut for the PWGDQ skimmed tree production (#3930) * PWGDQ/EM: PDG in history: check only for mother (comment out: check of daughter), adapt and add new MC Signals (#3938) * Add id hypo in dedx plot (#3940) * Update HistogramsLibrary.cxx (#3814) * Update HistogramsLibrary.cxx add multiplicity for pp collision * Update HistogramsLibrary.cxx * Update HistogramsLibrary.cxx * Update HistogramsLibrary.cxx * PWGMM: dndeta: add ITS ROF border check (#3945) * PWGDQ: MuonMchTrkEfficiency adjust eta bins (#3937) * PWGDQ: MuonMchTrkEfficiency adjust eta bins * Fix clang-format * PWGDQ: fix JPsi-D derived tables filling and add BDT score in histos (#3947) * PWGHF: adding the info about the number of prongs that contributes to the PV estimation in the candidate creator. (#3948) * PWGHF: adding the info about the number of prongs that contributes to the PV calculation * indentation fix * fix clang --------- Co-authored-by: Luigi Dello Stritto * PWJGE : Adding multiplicity correlations (#3933) * add correlation of Multiplicity measures * clang formatting * Fix HistoType * Fix typo * fixing datamodel and extend with FT0A,C * clang formatting * fix type * Fix runtime problems * Fix runtime problem * remove white spaces * first try in fixing the bug (#3950) * Add abs value to dca cut (#3943) * ML, PWGHF: add possibility to pass multiple CCDB paths to fix issue with ccdbApi.retrieveBlob (#3952) * ML, PWGHF: add possibility to pass CCDB paths * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * Fix strangeness tracking filter (#3953) - fix bachelor masses used for invariant mass calculation - adjust histogram binning - add option to cut on CPA and DCA * [PWGLF] Strangeness data model improvements (#3946) * Modifications to V0 part mostly done * Changes to enable derived data directly from builders * Equiv declarations * Please consider the following formatting changes (#189) --------- Co-authored-by: ALICE Builder * [PWFLG] LightNucleiTask - Add pT-shift for charge (#3951) * PWGEM/PhotonMeson: update for relaxed v0 cut (#3957) * PWGEM/PhotonMeson: add protection for mass (#3958) * add HistogramManager's workflow to v0selector (#3949) * second try to fix the bug (#3961) * Fix Track Selection (#3963) Co-authored-by: Andrea Barra * EventFiltering/PWGHF: make axes configurable to tune memory (#3962) * PWGMM: dndeta: avoid clashing variables (#3960) * MC support in rsnanalysisTHnSparse workflow (#3964) * MC support in rsnanalysisTHnSparse workflow * Update * name change --------- Co-authored-by: Veronika Barbasova * PWGHF: Improve tree creator for Omega_c with ST (#3956) * Improve tree creator for Omega_c with ST - implement improvements from ST filter to tree creator - add missing variables to tree * [PWGLF] Fix subscriptions + add customizability (#3965) * fix subscription in cascadepid.cxx * fix subscription in lambdakzeropid.cxx * Add skipper for empty colls * Add skipper for empty colls * Please consider the following formatting changes (#190) --------- Co-authored-by: ALICE Builder * PWGMM: dndeta: separate generator-level counters (#3966) * PWGHF: Add number of primary-vertex contributors in the 2-prong candidate creator (#3954) * add histograms to mc tag and probe + add flag for vertex refit (#3968) * Next centrality (#3971) * Next centrality * Update table helper * PWGHF: implement check on prompt/non prompt toXiPi tasks (#3955) * Implement origin check * Please consider the following formatting changes * Do check at quark level * Update PWGHF/TableProducer/candidateCreatorToXiPi.cxx Co-authored-by: Fabrizio * Update PWGHF/TableProducer/candidateCreatorToXiPi.cxx Co-authored-by: Fabrizio * Implement change OriginType::None --------- Co-authored-by: ALICE Action Bot Co-authored-by: Fabrizio * PWGJE : Adding pTHat histograms (#3911) Fixing format errors Fixing format errors Fixing merge Adding minor changes from Nima Added changes from Nima Adding pTHat histograms Changed float to int Adding pTHat histograms Co-authored-by: Danny Jones * Update cascadepid.cxx (#3974) * Update V0 analysis task (#3978) * Update v0qaanalysis.cxx --------- Co-authored-by: Nicolò Jacazio * Add 3body-decay hypertriton in nuclei filter (#3980) * Fixing the index format for MFT in ReducedMuonsExtra (#3977) Co-authored-by: Luca Micheletti * Add monitoring of the delta momentum (#3981) * PWGEM/PhotonMeson: implement prefilter for dielectron (#3982) * PWGHF: fix track selection in index skimming LfCascades (#3979) * Fix track selection * Please consider the following formatting changes * reinclude filter LfCascades * Fix build error * Fix filter for cascades struct --------- Co-authored-by: ALICE Action Bot * [O2-4360] EMCALMatchedTracks: Add track alpha and TOF PID (#3983) - Add track alpha and TOF PID NSgima for electrons and pions * third try to fix the bug (#3984) * third try to fix the bug * third try * PWGEM/PhotonMeson: fix for prefilter (#3987) * PWGEM/PhotonMeson: update phiv cut for dielectron (#3988) * Centrality: Fix run2 check (#3985) * Clean LF centrality/multiplicity table sub. (#3986) * Update HMPID qa (#3991) * Update spectratof (#3990) * (tried to) fix jet finder part (#3992) * PWGJE : jetmatching: add comments and rename vars to be clearer (#3975) * Update UDHelpers.h (#3969) * PWGLF: Update lambda1520SpherocityAnalysis.cxx (#3997) * PWGLF: Update lambda1520SpherocityAnalysis.cxx * PWGLF: Update lambda1520SpherocityAnalysis.cxx * Align TOF config automatically (#3993) - extend tools for intertask comms * Track propagation with ID (#3989) * Track propagation with ID * Update trk utils * Allow running slightly more parallel analysis compile jobs (#3972) On build machines with little memory, such as the ARM VMs we have been allocated, compiling with the previous formula takes much too long (5 hours just for O2Physics). On those machines, reserving 4 GiB for the system is overkill and cuts down the number of build slots unnecessarily. Reducing this to 2 GiB allows us to squeeze in one more build slot, bringing the total to 3 instead of 2. The peak memory use per analysis build process looks accurate at around 4 GiB. In theory, this change should reduce the time taken for analysis compilation on those machines by 1/3. * [PWGLF] Strangeness data model improvement (#3998) * Extra work * Rename file * Improvements and adjustments * Cleanup * Please consider the following formatting changes (#191) --------- Co-authored-by: ALICE Builder * PWGHF: Implement the possibility to apply proton PID for baryons in skimming (#3939) * PWGHF: Implent the possibility to apply proton PID for baryons in HF finding * Please consider the following formatting changes * Restore author removed by mistake * Remove all MY_DEBUG instances * Restore line wrongly deleted * Fallback to fill PVrefit table for all tracks at once to avoid crash due to tracks with no collision * Move initialisation of whichHypo * Add check on hasTPC and hasTOF in case of single detector PID * Remove extra slash --------- Co-authored-by: ALICE Action Bot * added QC histo for leading track (#4000) * PWGHF: implementation of LcToK0Sp ML responce class and corresponding changes in the LcToK0Sp canidate selector (#3913) * implemed first version of LcToK0sP ML response class and corresponding changes in the LcToK0sP candidate selector * fixing whitespace error * Add files via upload * implemented comments about removing variables not useful for ML * Update PWGHF/Core/HfMlResponseLcToK0sP.h Co-authored-by: Fabrizio * Update PWGHF/Core/HfMlResponseLcToK0sP.h Co-authored-by: Fabrizio * Update PWGHF/Core/HfMlResponseLcToK0sP.h Co-authored-by: Fabrizio --------- Co-authored-by: Fabrizio * task for vn of helium3 and helium4 (#4001) * New cuts for jpsi2ee electron selection (#3959) * New cuts for jpsi2ee electron selection * Error fixes + new cuts * VDM AO2D task for FIT detectors (#4002) * [FIT] Add more QA plots for FIT detectors and correlation among them * VDM AO2D task for FIT detectors * Update QAHistTask.cxx (#4003) Added Ka & Pi. * PWGHF: implement worflow to run on LfCascadeBachelor derived data and fix track selection in toXiPi tasks (#3973) * PWGLF: Add task to study track propagation (#4004) * Add task to study track propagation * Formatting * [PWGLF] Bugfixes in new part (#3999) * Fix subscriptions once more * Update LFStrangenessTables.h * Add simple mc-generated histograms * Please consider the following formatting changes (#192) * Create V0-only path --------- Co-authored-by: ALICE Builder * fixed pointer to leading track (#4008) * Unify headers with mass constants (#3976) * PWGHF: change filter -> testbit in toXiPi creator (#4009) * Change filter -> testbit * Please consider the following formatting changes * Change to cast in filter * Please consider the following formatting changes * Update PWGHF/TableProducer/candidateCreatorToXiPi.cxx Co-authored-by: Vít Kučera --------- Co-authored-by: ALICE Action Bot Co-authored-by: Vít Kučera * PWGDQ: Improve filterPbPb and add muon process function (#4015) * PWGDQ: Bugfix filterPbPb * Formatting * PWGLF: Update the common column name (#4013) * Update colum name to general type * Efficient process by defining the multiplicity * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot * PWGHF: Fix tree creator for Omega_c using ST (#4005) * Fix tree creator for Omega_c using ST - add charge of Omega and bachelor - fix track association - streamlining - update histograms * Fix sign in Omega_c ST tree * PWGLF: Update cuts for 3-body decayed hypertriton (#4017) * Update and Fix bugs * Add daughter track check in processMC * Add DcaToPV cut for H3L and Fix bugs * Fixes for C++20 (#4014) * PWGCF: Update trigger (#4007) * PWGCF: Update trigger Add options to reject tracks whose assumed PID during tracking does not correspond to the selected PID selected in the analysis. This rejection can be turned on/off with a switch and can be applied up to a configurabel p_TPC threshold. It can also be configured independently for protons and deuterons. * Fix: fix linter complaint * (try to) fix the track index (#4019) * Fix ST selection for strangeness filter (#4010) - wrong variable used for DCA cut (so far unused) * [PWGLF] - Improvemnts of nsigma handling (#4012) Co-authored-by: Veronika Barbasova * PWGDQ: Vertexing for pair and triplet (2 and 3 prong decays) (#3944) Updates for the dilepton-track secondary vertexing analysis Co-authored-by: Ida Torkjellsdatter Storehaug Co-authored-by: Ida Torkjellsdatter Storehaug Co-authored-by: ALICE Action Bot * More minor adjustments to data model (#4022) * Final adjustments to data model * Please consider the following formatting changes (#193) * Update strangederivedbuilder.cxx --------- Co-authored-by: ALICE Builder * update the post-calibration of TPC (#4023) * Add TRD sel. (#4021) - add possibility to customize cuts * Add pt vs ptreco (#4020) * Reverted back to ROOT PDG features * Cleaned up white-space issues * Cleaned up white-space issues 2.0 * Cleaned up white-space issues 3.0 * Utilizing CommonConstants/PhysicsConstants * Added basic debug functionality * Added basic debug functionality * Please consider the following formatting changes * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot Co-authored-by: Mattia Faggin Co-authored-by: Mattia Faggin Co-authored-by: Fabrizio Co-authored-by: Fabrizio Chinu <91954233+fchinu@users.noreply.github.com> Co-authored-by: eloviyo <38348689+Eloviyo@users.noreply.github.com> Co-authored-by: Shirajum Monira Co-authored-by: Daiki Sekihata Co-authored-by: Yash Patley <52608802+yashpatley@users.noreply.github.com> Co-authored-by: rolavick Co-authored-by: Vít Kučera Co-authored-by: ypwangg <142303052+ypwangg@users.noreply.github.com> Co-authored-by: yuanzhe <90246048+wang-yuanzhe@users.noreply.github.com> Co-authored-by: Bhagyarathi Sahoo <125358702+bhsaho@users.noreply.github.com> Co-authored-by: fkrizek Co-authored-by: ivorobye Co-authored-by: Marvin Hemmer <53471402+mhemmer-cern@users.noreply.github.com> Co-authored-by: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Co-authored-by: Luca Micheletti Co-authored-by: skundu692 <86804743+skundu692@users.noreply.github.com> Co-authored-by: rbailhac Co-authored-by: Nicolò Jacazio Co-authored-by: hhesouno <119694396+hhesouno@users.noreply.github.com> Co-authored-by: Felix Schlepper Co-authored-by: ddobrigk Co-authored-by: ALICE Builder Co-authored-by: Andrea Sofia Triolo Co-authored-by: Junlee Kim Co-authored-by: junleekim Co-authored-by: Anton Alkin Co-authored-by: Lu, Pengzhong <55934557+lupengzhong@users.noreply.github.com> Co-authored-by: Maximiliano Puccio Co-authored-by: Chiara Zampolli Co-authored-by: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Co-authored-by: Mario Ciacco Co-authored-by: glromane <95305986+glromane@users.noreply.github.com> Co-authored-by: Sasha Bylinkin <37345380+abylinkin@users.noreply.github.com> Co-authored-by: alexandr.bylinkin@cern.ch Co-authored-by: Sigurd Nese <32108009+sigurdnese@users.noreply.github.com> Co-authored-by: kgwizdzi <116073883+kgwizdzi@users.noreply.github.com> Co-authored-by: Federica Zanone <94552525+ZFederica@users.noreply.github.com> Co-authored-by: Jochen Klein Co-authored-by: alcaliva <32872606+alcaliva@users.noreply.github.com> Co-authored-by: XiaozhiBai Co-authored-by: feisenhu <53603353+feisenhu@users.noreply.github.com> Co-authored-by: ahkhanm <37612045+ahkhanm@users.noreply.github.com> Co-authored-by: zconesa Co-authored-by: ldellost <47105254+DelloStritto@users.noreply.github.com> Co-authored-by: Luigi Dello Stritto Co-authored-by: Johanna Lömker Co-authored-by: Giovanni Malfattore <89481844+giovannimalfattore@users.noreply.github.com> Co-authored-by: Zhenjun Xiong <108917659+zjxiongOvO@users.noreply.github.com> Co-authored-by: brr-andrea <60464995+brr-andrea@users.noreply.github.com> Co-authored-by: Andrea Barra Co-authored-by: vbarbaso <146095385+vbarbaso@users.noreply.github.com> Co-authored-by: Veronika Barbasova Co-authored-by: dajones2 <140733426+dajones2@users.noreply.github.com> Co-authored-by: Danny Jones Co-authored-by: Francesca Ercolessi Co-authored-by: Nicolò Jacazio Co-authored-by: aimeric-landou <46970521+aimeric-landou@users.noreply.github.com> Co-authored-by: Timo Wilken Co-authored-by: emeninno <41640762+emeninno@users.noreply.github.com> Co-authored-by: vfeuilla <71069003+vfeuilla@users.noreply.github.com> Co-authored-by: arvindkhuntia <31609955+arvindkhuntia@users.noreply.github.com> Co-authored-by: Rafael Manhart <56776511+RafRaf11@users.noreply.github.com> Co-authored-by: creetz16 <79141119+creetz16@users.noreply.github.com> Co-authored-by: Bong-Hwi Lim Co-authored-by: Giulio Eulisse <10544+ktf@users.noreply.github.com> Co-authored-by: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Co-authored-by: Ida Storehaug <38440296+torkjellsdatter@users.noreply.github.com> Co-authored-by: Ida Torkjellsdatter Storehaug Co-authored-by: Ida Torkjellsdatter Storehaug Co-authored-by: BiaoZhang <52267892+zhangbiao-phy@users.noreply.github.com> --- PWGJE/Tasks/phiInJets.cxx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/PWGJE/Tasks/phiInJets.cxx b/PWGJE/Tasks/phiInJets.cxx index 35025786b68..16e42aa8fe4 100644 --- a/PWGJE/Tasks/phiInJets.cxx +++ b/PWGJE/Tasks/phiInJets.cxx @@ -32,7 +32,7 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Multiplicity.h" -//#include "Common/DataModel/Centrality.h" +// #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" #include "CommonConstants/PhysicsConstants.h" @@ -70,6 +70,7 @@ struct phiInJets { Configurable cfgnTOFPID{"cfgnTOFPID", 4, "nTOF PID"}; Configurable cfgjetPtMin{"cfgjetPtMin", 5.0, "minimum jet pT cut"}; Configurable cfgjetR{"cfgjetR", 0.4, "jet resolution parameter"}; + Configurable cDebugLevel{"cDebugLevel", 0, "Resolution of Debug"}; // CONFIG DONE ///////////////////////////////////////// //INIT @@ -308,8 +309,13 @@ struct phiInJets { } // MinvReconstruction int nEvents = 0; - void processJetTracks(aod::JCollision const& collision, soa::Filtered const& fulljets, soa::Join const& tracks, TrackCandidates const&) + void processJetTracks(aod::JCollision const& collision, soa::Filtered const& chargedjets, soa::Join const& tracks, TrackCandidates const&) { + if (cDebugLevel > 0) { + nEvents++; + if ((nEvents + 1) % 10000 == 0) + std::cout << nEvents << std::endl; + } JEhistos.fill(HIST("nEvents"), 0.5); if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) @@ -318,12 +324,12 @@ struct phiInJets { for (auto& [track1, track2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks, tracks))) { auto trk1 = track1.track_as>(); auto trk2 = track2.track_as>(); - minvReconstruction(1.0, trk1, trk2, fulljets); + minvReconstruction(1.0, trk1, trk2, chargedjets); } - for (auto fulljet : fulljets) { - JEhistos.fill(HIST("FJetaHistogram"), fulljet.eta()); - JEhistos.fill(HIST("FJphiHistogram"), fulljet.phi()); - JEhistos.fill(HIST("FJptHistogram"), fulljet.phi()); + for (auto chargedjet : chargedjets) { + JEhistos.fill(HIST("FJetaHistogram"), chargedjet.eta()); + JEhistos.fill(HIST("FJphiHistogram"), chargedjet.phi()); + JEhistos.fill(HIST("FJptHistogram"), chargedjet.pt()); } JEhistos.fill(HIST("nEvents"), 1.5); From 59ac6d04bba4cb526b1c0c3ba31da2abcd0c2365 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Thu, 21 Dec 2023 22:46:22 +0100 Subject: [PATCH 111/156] PWGHF:Add missing repropagation of reassociated tracks (#4196) * PWGHF:Add missing repropagation of reassociated tracks * Add missing setter * Fix MC matching and make uniform B0 and B+ * Please consider the following formatting changes * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot --- PWGHF/D2H/DataModel/ReducedDataModel.h | 2 + .../candidateCreatorB0Reduced.cxx | 6 ++ .../candidateCreatorBplusReduced.cxx | 10 ++- .../TableProducer/dataCreatorD0PiReduced.cxx | 85 +++++++++++-------- .../dataCreatorDplusPiReduced.cxx | 85 +++++++++++-------- PWGHF/D2H/Tasks/taskB0Reduced.cxx | 10 ++- .../DataModel/CandidateReconstructionTables.h | 1 + 7 files changed, 125 insertions(+), 74 deletions(-) diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 3ca7fbb410f..952c6346a24 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -309,11 +309,13 @@ DECLARE_SOA_TABLE(HfMcRecRedD0Pis, "AOD", "HFMCRECREDD0PI", //! Table with recon hf_cand_bplus_reduced::Prong0Id, hf_cand_bplus_reduced::Prong1Id, hf_cand_bplus::FlagMcMatchRec, + hf_cand_bplus::DebugMcRec, hf_bplus_mc::PtMother); // Table with same size as HFCANDBPLUS DECLARE_SOA_TABLE(HfMcRecRedBps, "AOD", "HFMCRECREDBP", //! Reconstruction-level MC information on B+ candidates for reduced workflow hf_cand_bplus::FlagMcMatchRec, + hf_cand_bplus::DebugMcRec, hf_bplus_mc::PtMother); DECLARE_SOA_TABLE(HfMcGenRedBps, "AOD", "HFMCGENREDBP", //! Generation-level MC information on B+ candidates for reduced workflow diff --git a/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx index 844945d399d..2c018590c87 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx @@ -267,11 +267,17 @@ struct HfCandidateCreatorB0ReducedExpressions { void processMc(HfMcRecRedDpPis const& rowsDPiMcRec, HfRedB0Prongs const& candsB0) { for (const auto& candB0 : candsB0) { + bool filledMcInfo{false}; for (const auto& rowDPiMcRec : rowsDPiMcRec) { if ((rowDPiMcRec.prong0Id() != candB0.prong0Id()) || (rowDPiMcRec.prong1Id() != candB0.prong1Id())) { continue; } rowB0McRec(rowDPiMcRec.flagMcMatchRec(), rowDPiMcRec.debugMcRec(), rowDPiMcRec.ptMother()); + filledMcInfo = true; + break; + } + if (!filledMcInfo) { // protection to get same size tables in case something went wrong: we created a candidate that was not preselected in the D-Pi creator + rowB0McRec(0, -1, -1.f); } } } diff --git a/PWGHF/D2H/TableProducer/candidateCreatorBplusReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorBplusReduced.cxx index 8787de8d169..359230b352f 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorBplusReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorBplusReduced.cxx @@ -35,7 +35,7 @@ using namespace o2::framework::expressions; /// Reconstruction of B+ candidates struct HfCandidateCreatorBplusReduced { - Produces rowCandidateBase; // table defined in CandidateReconstructionTables.h + Produces rowCandidateBase; // table defined in CandidateReconstructionTables.h Produces rowCandidateProngs; // table defined in ReducedDataModel.h // vertexing @@ -202,11 +202,17 @@ struct HfCandidateCreatorBplusReducedExpressions { void processMc(HfMcRecRedD0Pis const& rowsD0PiMcRec, HfRedBplusProngs const& candsBplus) { for (const auto& candBplus : candsBplus) { + bool filledMcInfo{false}; for (const auto& rowD0PiMcRec : rowsD0PiMcRec) { if ((rowD0PiMcRec.prong0Id() != candBplus.prong0Id()) || (rowD0PiMcRec.prong1Id() != candBplus.prong1Id())) { continue; } - rowBplusMcRec(rowD0PiMcRec.flagMcMatchRec(), rowD0PiMcRec.ptMother()); + rowBplusMcRec(rowD0PiMcRec.flagMcMatchRec(), rowD0PiMcRec.debugMcRec(), rowD0PiMcRec.ptMother()); + filledMcInfo = true; + break; + } + if (!filledMcInfo) { // protection to get same size tables in case something went wrong: we created a candidate that was not preselected in the D-Pi creator + rowBplusMcRec(0, -1, -1.f); } } } diff --git a/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx index 62350c0f116..b1ffbc300f6 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx @@ -23,7 +23,6 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "ReconstructionDataFormats/V0.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/CollisionAssociationTables.h" @@ -82,19 +81,14 @@ struct HfDataCreatorD0PiReduced { Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; // magnetic field setting from CCDB - Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; - Configurable ccdbPathGeo{"ccdbPathGeo", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; HfHelper hfHelper; // CCDB service Service ccdb; - o2::base::MatLayerCylSet* lut; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; int runNumber; // O2DatabasePDG service @@ -154,12 +148,12 @@ struct HfDataCreatorD0PiReduced { df2.setMinRelChi2Change(minRelChi2Change); df2.setUseAbsDCA(useAbsDCA); df2.setWeightedFinalPCA(useWeightedFinalPCA); + df2.setMatCorrType(noMatCorr); // Configure CCDB access ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; // invariant-mass window cut @@ -172,19 +166,21 @@ struct HfDataCreatorD0PiReduced { /// Pion selection (D0 Pi <-- B+) /// \param trackPion is a track with the pion hypothesis + /// \param trackParCovPion is the track parametrisation of the pion + /// \param dcaPion is the 2-D array with track DCAs of the pion /// \param track0 is prong0 of selected D0 candidate /// \param track1 is prong1 of selected D0 candidate /// \param candD0 is the D0 candidate /// \return true if trackPion passes all cuts - template - bool isPionSelected(const T1& trackPion, const T2& track0, const T2& track1, const T3& candD0) + template + bool isPionSelected(const T1& trackPion, const T2& trackParCovPion, const T3& dcaPion, const T1& track0, const T1& track1, const T4& candD0) { // check isGlobalTrackWoDCA status for pions if wanted if (usePionIsGlobalTrackWoDCA && !trackPion.isGlobalTrackWoDCA()) { return false; } // minimum pT selection - if (trackPion.pt() < ptPionMin || !isSelectedTrackDCA(trackPion)) { + if (trackParCovPion.getPt() < ptPionMin || !isSelectedTrackDCA(trackParCovPion, dcaPion)) { return false; } // reject pion not compatible with D0/D0bar hypothesis @@ -201,20 +197,21 @@ struct HfDataCreatorD0PiReduced { } /// Single-track cuts for pions on dcaXY - /// \param track is a track + /// \param trackPar is the track parametrisation + /// \param dca is the 2-D array with track DCAs /// \return true if track passes all cuts - template - bool isSelectedTrackDCA(const T& track) + template + bool isSelectedTrackDCA(const T1& trackPar, const T2& dca) { - auto pTBinTrack = findBin(binsPtPion, track.pt()); + auto pTBinTrack = findBin(binsPtPion, trackPar.getPt()); if (pTBinTrack == -1) { return false; } - if (std::abs(track.dcaXY()) < cutsTrackPionDCA->get(pTBinTrack, "min_dcaxytoprimary")) { + if (std::abs(dca[0]) < cutsTrackPionDCA->get(pTBinTrack, "min_dcaxytoprimary")) { return false; // minimum DCAxy } - if (std::abs(track.dcaXY()) > cutsTrackPionDCA->get(pTBinTrack, "max_dcaxytoprimary")) { + if (std::abs(dca[0]) > cutsTrackPionDCA->get(pTBinTrack, "max_dcaxytoprimary")) { return false; // maximum DCAxy } return true; @@ -243,7 +240,11 @@ struct HfDataCreatorD0PiReduced { auto bc = collision.bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); + o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp(ccdbPathGrpMag, bc.timestamp()); + if (grpo == nullptr) { + LOGF(fatal, "Run 3 GRP object (type o2::parameters::GRPMagField) is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + o2::base::Propagator::initFieldFromGRP(grpo); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; } @@ -303,17 +304,26 @@ struct HfDataCreatorD0PiReduced { // D0(bar) → π∓ K± std::array pVecD0 = RecoDecay::pVec(pVec0, pVec1); - auto trackParCovD0 = o2::dataformats::V0(df2.getPCACandidatePos(), pVecD0, df2.calcPCACovMatrixFlat(), trackParCov0, trackParCov1); + auto trackParCovD0 = df2.createParentTrackParCov(); + trackParCovD0.setAbsCharge(0); // to be sure for (const auto& trackId : trackIndices) { auto trackPion = trackId.template track_as(); // apply selections on pion tracks - if (!isPionSelected(trackPion, track0, track1, candD0) || !isSelectedTrackDCA(trackPion)) { + auto trackParCovPion = getTrackParCov(trackPion); + o2::gpu::gpustd::array dcaPion{trackPion.dcaXY(), trackPion.dcaZ()}; + std::array pVecPion = {trackPion.px(), trackPion.py(), trackPion.pz()}; + if (trackPion.collisionId() != thisCollId) { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovPion, 2.f, noMatCorr, &dcaPion); + getPxPyPz(trackParCovPion, pVecPion); + } + + // apply selections on pion tracks + if (!isPionSelected(trackPion, trackParCovPion, dcaPion, track0, track1, candD0)) { continue; } - registry.fill(HIST("hPtPion"), trackPion.pt()); - std::array pVecPion = {trackPion.px(), trackPion.py(), trackPion.pz()}; + registry.fill(HIST("hPtPion"), trackParCovPion.getPt()); // compute invariant mass square and apply selection auto invMass2D0Pi = RecoDecay::m2(std::array{pVecD0, pVecPion}, std::array{massD0, massPi}); if ((invMass2D0Pi < invMass2D0PiMin) || (invMass2D0Pi > invMass2D0PiMax)) { @@ -324,15 +334,15 @@ struct HfDataCreatorD0PiReduced { // if information on track already stored, go to next track if (!selectedTracksPion.count(trackPion.globalIndex())) { hfTrackPion(trackPion.globalIndex(), indexHfReducedCollision, - trackPion.x(), trackPion.alpha(), - trackPion.y(), trackPion.z(), trackPion.snp(), - trackPion.tgl(), trackPion.signed1Pt()); - hfTrackCovPion(trackPion.cYY(), trackPion.cZY(), trackPion.cZZ(), - trackPion.cSnpY(), trackPion.cSnpZ(), - trackPion.cSnpSnp(), trackPion.cTglY(), trackPion.cTglZ(), - trackPion.cTglSnp(), trackPion.cTglTgl(), - trackPion.c1PtY(), trackPion.c1PtZ(), trackPion.c1PtSnp(), - trackPion.c1PtTgl(), trackPion.c1Pt21Pt2()); + trackParCovPion.getX(), trackParCovPion.getAlpha(), + trackParCovPion.getY(), trackParCovPion.getZ(), trackParCovPion.getSnp(), + trackParCovPion.getTgl(), trackParCovPion.getQ2Pt()); + hfTrackCovPion(trackParCovPion.getSigmaY2(), trackParCovPion.getSigmaZY(), trackParCovPion.getSigmaZ2(), + trackParCovPion.getSigmaSnpY(), trackParCovPion.getSigmaSnpZ(), + trackParCovPion.getSigmaSnp2(), trackParCovPion.getSigmaTglY(), trackParCovPion.getSigmaTglZ(), + trackParCovPion.getSigmaTglSnp(), trackParCovPion.getSigmaTgl2(), + trackParCovPion.getSigma1PtY(), trackParCovPion.getSigma1PtZ(), trackParCovPion.getSigma1PtSnp(), + trackParCovPion.getSigma1PtTgl(), trackParCovPion.getSigma1Pt2()); hfTrackPidPion(trackPion.hasTPC(), trackPion.hasTOF(), trackPion.tpcNSigmaPi(), trackPion.tofNSigmaPi()); // add trackPion.globalIndex() to a list @@ -347,9 +357,11 @@ struct HfDataCreatorD0PiReduced { auto arrayDaughtersBplus = std::array{track0, track1, trackPion}; int8_t sign{0}; int8_t flag{0}; + int8_t debug{0}; // B+ → D0(bar) π+ → (K+ π-) π+ // Printf("Checking B+ → D0bar π+"); auto indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrayDaughtersBplus, Pdg::kBPlus, std::array{+kPiPlus, +kKPlus, -kPiPlus}, true, &sign, 2); + auto motherPt = -1.f; if (indexRec > -1) { // D0bar → K+ π- // Printf("Checking D0bar → K+ π-"); @@ -357,13 +369,18 @@ struct HfDataCreatorD0PiReduced { if (indexRec > -1) { flag = sign * BIT(hf_cand_bplus::DecayType::BplusToD0Pi); } else { + debug = 1; LOGF(info, "WARNING: B+ decays in the expected final state but the condition on the intermediate state is not fulfilled"); } + + auto indexMother = RecoDecay::getMother(particlesMc, trackPion.template mcParticle_as

(), Pdg::kBPlus, true); + if (indexMother >= 0) { + auto particleMother = particlesMc.rawIteratorAt(indexMother); + motherPt = particleMother.pt(); + } } - auto indexMother = RecoDecay::getMother(particlesMc, trackPion.template mcParticle_as

(), Pdg::kBPlus, true); - auto particleMother = particlesMc.rawIteratorAt(indexMother); - rowHfD0PiMcRecReduced(indexHfCand2Prong, selectedTracksPion[trackPion.globalIndex()], flag, particleMother.pt()); + rowHfD0PiMcRecReduced(indexHfCand2Prong, selectedTracksPion[trackPion.globalIndex()], flag, debug, motherPt); } fillHfCand2Prong = true; } // pion loop diff --git a/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx index 4f22e9f5450..e3ed6567983 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx @@ -23,7 +23,6 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "ReconstructionDataFormats/V0.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/CollisionAssociationTables.h" @@ -82,18 +81,14 @@ struct HfDataCreatorDplusPiReduced { Configurable selectionFlagD{"selectionFlagD", 1, "Selection Flag for D"}; // magnetic field setting from CCDB - Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; - Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; HfHelper hfHelper; // CCDB service Service ccdb; - o2::base::MatLayerCylSet* lut; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; int runNumber; // O2DatabasePDG service @@ -153,12 +148,12 @@ struct HfDataCreatorDplusPiReduced { df3.setMinRelChi2Change(minRelChi2Change); df3.setUseAbsDCA(useAbsDCA); df3.setWeightedFinalPCA(useWeightedFinalPCA); + df3.setMatCorrType(noMatCorr); // Configure CCDB access ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; // invariant-mass window cut @@ -171,19 +166,21 @@ struct HfDataCreatorDplusPiReduced { /// Pion selection (D Pi <-- B0) /// \param trackPion is a track with the pion hypothesis + /// \param trackParCovPion is the track parametrisation of the pion + /// \param dcaPion is the 2-D array with track DCAs of the pion /// \param track0 is prong0 of selected D candidate /// \param track1 is prong1 of selected D candidate /// \param track2 is prong2 of selected D candidate /// \return true if trackPion passes all cuts - template - bool isPionSelected(const T1& trackPion, const T2& track0, const T2& track1, const T2& track2) + template + bool isPionSelected(const T1& trackPion, const T2& trackParCovPion, const T3& dcaPion, const T1& track0, const T1& track1, const T1& track2) { // check isGlobalTrackWoDCA status for pions if wanted if (usePionIsGlobalTrackWoDCA && !trackPion.isGlobalTrackWoDCA()) { return false; } // minimum pT selection - if (trackPion.pt() < ptPionMin || !isSelectedTrackDCA(trackPion)) { + if (trackParCovPion.getPt() < ptPionMin || !isSelectedTrackDCA(trackParCovPion, dcaPion)) { return false; } // reject pions that are D daughters @@ -198,20 +195,21 @@ struct HfDataCreatorDplusPiReduced { } /// Single-track cuts for pions on dcaXY - /// \param track is a track + /// \param trackPar is the track parametrisation + /// \param dca is the 2-D array with track DCAs /// \return true if track passes all cuts - template - bool isSelectedTrackDCA(const T& track) + template + bool isSelectedTrackDCA(const T1& trackPar, const T2& dca) { - auto pTBinTrack = findBin(binsPtPion, track.pt()); + auto pTBinTrack = findBin(binsPtPion, trackPar.getPt()); if (pTBinTrack == -1) { return false; } - if (std::abs(track.dcaXY()) < cutsTrackPionDCA->get(pTBinTrack, "min_dcaxytoprimary")) { + if (std::abs(dca[0]) < cutsTrackPionDCA->get(pTBinTrack, "min_dcaxytoprimary")) { return false; // minimum DCAxy } - if (std::abs(track.dcaXY()) > cutsTrackPionDCA->get(pTBinTrack, "max_dcaxytoprimary")) { + if (std::abs(dca[0]) > cutsTrackPionDCA->get(pTBinTrack, "max_dcaxytoprimary")) { return false; // maximum DCAxy } return true; @@ -240,7 +238,11 @@ struct HfDataCreatorDplusPiReduced { auto bc = collision.bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); + o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp(ccdbPathGrpMag, bc.timestamp()); + if (grpo == nullptr) { + LOGF(fatal, "Run 3 GRP object (type o2::parameters::GRPMagField) is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + o2::base::Propagator::initFieldFromGRP(grpo); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; } @@ -303,20 +305,28 @@ struct HfDataCreatorDplusPiReduced { df3.getTrack(2).getPxPyPzGlo(pVec2); // D∓ → π∓ K± π∓ - std::array pVecPiK = RecoDecay::pVec(pVec0, pVec1); std::array pVecD = RecoDecay::pVec(pVec0, pVec1, pVec2); - auto trackParCovPiK = o2::dataformats::V0(df3.getPCACandidatePos(), pVecPiK, df3.calcPCACovMatrixFlat(), trackParCov0, trackParCov1); - auto trackParCovD = o2::dataformats::V0(df3.getPCACandidatePos(), pVecD, df3.calcPCACovMatrixFlat(), trackParCovPiK, trackParCov2); + auto trackParCovD = df3.createParentTrackParCov(); + int charge = (track1.signed1Pt() > 0) ? -1 : 1; + trackParCovD.setAbsCharge(charge); // to be sure for (const auto& trackId : trackIndices) { auto trackPion = trackId.template track_as(); // apply selections on pion tracks - if (!isPionSelected(trackPion, track0, track1, track2) || !isSelectedTrackDCA(trackPion)) { + auto trackParCovPion = getTrackParCov(trackPion); + o2::gpu::gpustd::array dcaPion{trackPion.dcaXY(), trackPion.dcaZ()}; + std::array pVecPion = {trackPion.px(), trackPion.py(), trackPion.pz()}; + if (trackPion.collisionId() != thisCollId) { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovPion, 2.f, noMatCorr, &dcaPion); + getPxPyPz(trackParCovPion, pVecPion); + } + + // apply selections on pion tracks + if (!isPionSelected(trackPion, trackParCovPion, dcaPion, track0, track1, track2)) { continue; } - registry.fill(HIST("hPtPion"), trackPion.pt()); - std::array pVecPion = {trackPion.px(), trackPion.py(), trackPion.pz()}; + registry.fill(HIST("hPtPion"), trackParCovPion.getPt()); // compute invariant mass square and apply selection auto invMass2DPi = RecoDecay::m2(std::array{pVecD, pVecPion}, std::array{massD, massPi}); if ((invMass2DPi < invMass2DPiMin) || (invMass2DPi > invMass2DPiMax)) { @@ -327,15 +337,15 @@ struct HfDataCreatorDplusPiReduced { // if information on track already stored, go to next track if (!selectedTracksPion.count(trackPion.globalIndex())) { hfTrackPion(trackPion.globalIndex(), indexHfReducedCollision, - trackPion.x(), trackPion.alpha(), - trackPion.y(), trackPion.z(), trackPion.snp(), - trackPion.tgl(), trackPion.signed1Pt()); - hfTrackCovPion(trackPion.cYY(), trackPion.cZY(), trackPion.cZZ(), - trackPion.cSnpY(), trackPion.cSnpZ(), - trackPion.cSnpSnp(), trackPion.cTglY(), trackPion.cTglZ(), - trackPion.cTglSnp(), trackPion.cTglTgl(), - trackPion.c1PtY(), trackPion.c1PtZ(), trackPion.c1PtSnp(), - trackPion.c1PtTgl(), trackPion.c1Pt21Pt2()); + trackParCovPion.getX(), trackParCovPion.getAlpha(), + trackParCovPion.getY(), trackParCovPion.getZ(), trackParCovPion.getSnp(), + trackParCovPion.getTgl(), trackParCovPion.getQ2Pt()); + hfTrackCovPion(trackParCovPion.getSigmaY2(), trackParCovPion.getSigmaZY(), trackParCovPion.getSigmaZ2(), + trackParCovPion.getSigmaSnpY(), trackParCovPion.getSigmaSnpZ(), + trackParCovPion.getSigmaSnp2(), trackParCovPion.getSigmaTglY(), trackParCovPion.getSigmaTglZ(), + trackParCovPion.getSigmaTglSnp(), trackParCovPion.getSigmaTgl2(), + trackParCovPion.getSigma1PtY(), trackParCovPion.getSigma1PtZ(), trackParCovPion.getSigma1PtSnp(), + trackParCovPion.getSigma1PtTgl(), trackParCovPion.getSigma1Pt2()); hfTrackPidPion(trackPion.hasTPC(), trackPion.hasTOF(), trackPion.tpcNSigmaPi(), trackPion.tofNSigmaPi()); // add trackPion.globalIndex() to a list @@ -353,6 +363,7 @@ struct HfDataCreatorDplusPiReduced { int8_t debug{0}; // B0 → D- π+ → (π- K+ π-) π+ auto indexRec = RecoDecay::getMatchedMCRec(particlesMc, arrayDaughtersB0, Pdg::kB0, std::array{-kPiPlus, +kKPlus, -kPiPlus, +kPiPlus}, true, &sign, 3); + auto motherPt = -1.f; if (indexRec > -1) { // D- → π- K+ π- // Printf("Checking D- → π- K+ π-"); @@ -363,10 +374,14 @@ struct HfDataCreatorDplusPiReduced { debug = 1; LOGF(debug, "B0 decays in the expected final state but the condition on the intermediate state is not fulfilled"); } + + auto indexMother = RecoDecay::getMother(particlesMc, trackPion.template mcParticle_as

(), Pdg::kB0, true); + if (indexMother >= 0) { + auto particleMother = particlesMc.rawIteratorAt(indexMother); + motherPt = particleMother.pt(); + } } - auto indexMother = RecoDecay::getMother(particlesMc, trackPion.template mcParticle_as

(), Pdg::kB0, true); - auto particleMother = particlesMc.rawIteratorAt(indexMother); - rowHfDPiMcRecReduced(indexHfCand3Prong, selectedTracksPion[trackPion.globalIndex()], flag, debug, particleMother.pt()); + rowHfDPiMcRecReduced(indexHfCand3Prong, selectedTracksPion[trackPion.globalIndex()], flag, debug, motherPt); } fillHfCand3Prong = true; } // pion loop diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index 62ad3ea4056..afc37574248 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -41,6 +41,7 @@ DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! DECLARE_SOA_COLUMN(MProng0, mProng0, float); //! Invariant mass of prong0 (GeV/c) DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! Transverse momentum of candidate (GeV/c) DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate @@ -85,7 +86,8 @@ DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with som hf_cand_b0_lite::Phi, hf_cand_b0_lite::Y, hf_cand_3prong::FlagMcMatchRec, - hf_cand_3prong::OriginMcRec); + hf_cand_3prong::OriginMcRec, + hf_cand_b0_lite::PtGen); } // namespace o2::aod /// B0 analysis task @@ -373,7 +375,8 @@ struct HfTaskB0Reduced { candidate.phi(), hfHelper.yB0(candidate), flag, - origin); + origin, + -1.); } } } @@ -506,7 +509,8 @@ struct HfTaskB0Reduced { candidate.phi(), hfHelper.yB0(candidate), flagMcMatchRec, - isSignal); + isSignal, + candidate.ptMother()); } } } diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 05c33e82869..84c1b68171e 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -673,6 +673,7 @@ DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction le DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); // generator level DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); // particle origin, reconstruction level DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); // particle origin, generator level +DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level enum DecayType { BplusToD0Pi = 0 }; } // namespace hf_cand_bplus From 4a4d9a2aca73c47b458d466bc0d508b399cfdc4e Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 22 Dec 2023 12:04:24 +0100 Subject: [PATCH 112/156] PWGHF: add missing update of runnumber (#4227) --- PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx | 1 + PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx | 1 + 2 files changed, 2 insertions(+) diff --git a/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx index b1ffbc300f6..279a5df243f 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorD0PiReduced.cxx @@ -247,6 +247,7 @@ struct HfDataCreatorD0PiReduced { o2::base::Propagator::initFieldFromGRP(grpo); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + runNumber = bc.runNumber(); } df2.setBz(bz); diff --git a/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx index e3ed6567983..a18be4c18b6 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorDplusPiReduced.cxx @@ -245,6 +245,7 @@ struct HfDataCreatorDplusPiReduced { o2::base::Propagator::initFieldFromGRP(grpo); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; + runNumber = bc.runNumber(); } df3.setBz(bz); From 7c6ccb5f6b1c932578437684ae96de509f018903 Mon Sep 17 00:00:00 2001 From: prchakra <47203359+prchakra@users.noreply.github.com> Date: Fri, 22 Dec 2023 13:29:24 +0100 Subject: [PATCH 113/156] PWGCF: FemtoUniverse -- Adding configurables for FT0C centrality estimation (#4226) --- .../TableProducer/femtoUniverseProducerTask.cxx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index f1866086ac1..1c5b2955c8e 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -59,7 +59,7 @@ using FemtoFullCollision = using FemtoFullCollisionCentRun2 = soa::Join::iterator; using FemtoFullCollisionCentRun3 = - soa::Join::iterator; + soa::Join::iterator; using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullTracks = @@ -121,6 +121,11 @@ struct femtoUniverseProducerTask { Configurable ConfIsActivatePhi{"ConfIsActivatePhi", true, "Activate filling of Phi into femtouniverse tables"}; Configurable ConfMCTruthAnalysisWithPID{"ConfMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; Configurable> ConfMCTruthPDGCodes{"ConfMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; + Configurable ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; + Configurable ConfCentFT0Max{"ConfCentFT0Max", 0.f, "Max CentFT0 value for centrality selection"}; + + Filter CustomCollCentFilter = (aod::cent::centFT0C > ConfCentFT0Min) && + (aod::cent::centFT0C < ConfCentFT0Max); // just sanity check to make sure in case there are problems in conversion or // MC production it does not affect results @@ -582,8 +587,8 @@ struct femtoUniverseProducerTask { int cent = 0; int multNtr = 0; if (ConfIsRun3) { - multNtr = col.centFT0M(); - cent = col.centFT0M(); + multNtr = col.centFT0C(); + cent = col.centFT0C(); } // check whether the basic event selection criteria are fulfilled @@ -1150,7 +1155,7 @@ struct femtoUniverseProducerTask { PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCentRun2Data, "Provide experimental data for Run 2 with centrality for track track", false); void - processTrackCentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, + processTrackCentRun3Data(soa::Filtered>::iterator const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks) { From 6167c3495cceaadb66f18034b9d0591d2db63326 Mon Sep 17 00:00:00 2001 From: glromane <95305986+glromane@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:03:41 +0100 Subject: [PATCH 114/156] adding binning for some variables and adding an MC table (#4225) * removing lines with table reservation and fixing linter bugs * Update femto3dPairTask.h fixing double-track cut * Update femto3dPairTask.h * Update femto3dPairTask.h * Update femto3dPairTask.cxx * Update femto3dQA.cxx * Update femto3dPairTask.cxx * Update femto3dPairTaskMC.cxx * Update femto3dPairTask.cxx --- PWGCF/Femto3D/CMakeLists.txt | 4 +- PWGCF/Femto3D/Core/CMakeLists.txt | 10 + PWGCF/Femto3D/Core/femto3dPairTask.h | 230 +++++++++++ PWGCF/Femto3D/DataModel/CMakeLists.txt | 0 PWGCF/Femto3D/DataModel/singletrackselector.h | 240 ++++++++--- PWGCF/Femto3D/TableProducer/CMakeLists.txt | 0 .../TableProducer/singleTrackSelector.cxx | 113 ++++-- PWGCF/Femto3D/Tasks/CMakeLists.txt | 25 ++ PWGCF/Femto3D/Tasks/femto3dPairTask.cxx | 382 ++++++++++++++++++ PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx | 375 +++++++++++++++++ PWGCF/Femto3D/Tasks/femto3dQA.cxx | 221 ++++++++++ 11 files changed, 1503 insertions(+), 97 deletions(-) mode change 100644 => 100755 PWGCF/Femto3D/CMakeLists.txt create mode 100755 PWGCF/Femto3D/Core/CMakeLists.txt create mode 100755 PWGCF/Femto3D/Core/femto3dPairTask.h mode change 100644 => 100755 PWGCF/Femto3D/DataModel/CMakeLists.txt mode change 100644 => 100755 PWGCF/Femto3D/TableProducer/CMakeLists.txt create mode 100755 PWGCF/Femto3D/Tasks/CMakeLists.txt create mode 100755 PWGCF/Femto3D/Tasks/femto3dPairTask.cxx create mode 100755 PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx create mode 100755 PWGCF/Femto3D/Tasks/femto3dQA.cxx diff --git a/PWGCF/Femto3D/CMakeLists.txt b/PWGCF/Femto3D/CMakeLists.txt old mode 100644 new mode 100755 index 7c83285fff0..e57cd178dd8 --- a/PWGCF/Femto3D/CMakeLists.txt +++ b/PWGCF/Femto3D/CMakeLists.txt @@ -9,7 +9,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -#add_subdirectory(Core) +add_subdirectory(Core) add_subdirectory(DataModel) add_subdirectory(TableProducer) -#add_subdirectory(Tasks) +add_subdirectory(Tasks) \ No newline at end of file diff --git a/PWGCF/Femto3D/Core/CMakeLists.txt b/PWGCF/Femto3D/Core/CMakeLists.txt new file mode 100755 index 00000000000..62f88c324cf --- /dev/null +++ b/PWGCF/Femto3D/Core/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. \ No newline at end of file diff --git a/PWGCF/Femto3D/Core/femto3dPairTask.h b/PWGCF/Femto3D/Core/femto3dPairTask.h new file mode 100755 index 00000000000..c1ff8ecd3ed --- /dev/null +++ b/PWGCF/Femto3D/Core/femto3dPairTask.h @@ -0,0 +1,230 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \brief utility functions for femto task +/// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio +/// \since 30 May 2023 + +#ifndef PWGCF_FEMTO3D_CORE_FEMTO3DPAIRTASK_H_ +#define PWGCF_FEMTO3D_CORE_FEMTO3DPAIRTASK_H_ + +// #include "Framework/ASoA.h" +// #include "Framework/DataTypes.h" +// #include "Framework/AnalysisDataModel.h" +// #include "Common/DataModel/PIDResponse.h" +// #include "Framework/Logger.h" +// #include "Common/DataModel/Multiplicity.h" + +#include +#include "TLorentzVector.h" +#include "TVector3.h" +#include "TDatabasePDG.h" + +double particle_mass(int PDGcode) +{ + // if(PDGcode == 2212) return TDatabasePDG::Instance()->GetParticle(2212)->Mass(); + if (PDGcode == 1000010020) + return 1.87561294257; + else + return TDatabasePDG::Instance()->GetParticle(PDGcode)->Mass(); +} + +namespace o2::aod::singletrackselector +{ +template +Type getBinIndex(float const& value, std::vector const& binning, int const& NsubBins = 1) +{ + Type res = -100; + for (int i = 0; i < binning.size() - 1; i++) { + if (value >= binning[i] && binning[i + 1] > value) { + if (NsubBins < 2) { + res = (Type)i; + break; + } else { + float subBinWidth = (binning[i + 1] - binning[i]) / NsubBins; + int subBin = std::floor((value - binning[i]) / subBinWidth); + int delimeter = std::pow(10, std::to_string(NsubBins).size()); + + res = (Type)i + (Type)subBin / delimeter; + break; + } + } + } + return res; +} + +//==================================================================================== + +float GetKstarFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& second4momentum, bool isIdentical) +{ + if (isIdentical) { + TLorentzVector fourmomentadiff = first4momentum - second4momentum; + return 0.5 * abs(fourmomentadiff.Mag()); + } else { + TLorentzVector fourmomentasum = first4momentum + second4momentum; + + first4momentum.Boost((-1) * fourmomentasum.BoostVector()); + second4momentum.Boost((-1) * fourmomentasum.BoostVector()); + + TVector3 qinv = first4momentum.Vect() - second4momentum.Vect(); + return 0.5 * abs(qinv.Mag()); + } +} + +//==================================================================================== + +template +class FemtoPair +{ + public: + FemtoPair() {} + FemtoPair(TrackType const& first, TrackType const& second) + { + _first = first; + _second = second; + } + FemtoPair(TrackType const& first, TrackType const& second, const bool& isidentical) + { + _first = first; + _second = second; + _isidentical = isidentical; + } + + FemtoPair(const FemtoPair& obj) + { + SetFirstParticle(obj.GetFirstParticle()); + SetSecondParticle(obj.GetSecondParticle()); + } + explicit FemtoPair(const FemtoPair* obj) + { + SetFirstParticle(obj->GetFirstParticle()); + SetSecondParticle(obj->GetSecondParticle()); + } + ~FemtoPair() {} + FemtoPair& operator=(const FemtoPair& obj) + { + if (this != &obj) { + SetFirstParticle(obj.GetFirstParticle()); + SetSecondParticle(obj.GetSecondParticle()); + } + return *this; + } + + void SetPair(TrackType const& first, TrackType const& second) + { + _first = first; + _second = second; + } + void SetFirstParticle(TrackType const& first) { _first = first; } + void SetSecondParticle(TrackType const& second) { _second = second; } + void SetIdentical(const bool& isidentical) { _isidentical = isidentical; } + void SetMagField1(const float& magfield1) { _magfield1 = magfield1; } + void SetMagField2(const float& magfield2) { _magfield2 = magfield2; } + void SetPDG1(const int& PDG1) { _PDG1 = PDG1; } + void SetPDG2(const int& PDG2) { _PDG2 = PDG2; } + void ResetPair(); + void ResetAll(); + + TrackType* GetFirstParticle() const { return _first; } + TrackType* GetSecondParticle() const { return _second; } + bool IsIdentical() { return _isidentical; } + + bool IsClosePair(const float& deta = 0.01, const float& dphi = 0.01, const float& radius = 1.2); + float GetEtaDiff() const + { + if (_first != NULL && _second != NULL) + return _first->eta() - _second->eta(); + else + return 1000; + } + float GetPhiStarDiff(const float& radius = 1.2) const + { + if (_first != NULL && _second != NULL) + return _first->phiStar(_magfield1, radius) - _second->phiStar(_magfield2, radius); + else + return 1000; + } + float GetKstar() const; + float GetKt() const; + + private: + TrackType _first = NULL; + TrackType _second = NULL; + float _magfield1 = 0.0, _magfield2 = 0.0; + int _PDG1 = 0, _PDG2 = 0; + bool _isidentical = true; +}; + +template +void FemtoPair::ResetPair() +{ + _first = NULL; + _second = NULL; +} + +template +void FemtoPair::ResetAll() +{ + _first = NULL; + _second = NULL; + _magfield1 = 0.0; + _magfield2 = 0.0; + _PDG1 = 0; + _PDG2 = 0; + _isidentical = true; +} + +template +bool FemtoPair::IsClosePair(const float& deta, const float& dphi, const float& radius) +{ + if (_first == NULL || _second == NULL) + return true; + if (!(_magfield1 * _magfield2)) + return true; + if (abs(GetEtaDiff()) < deta && abs(GetPhiStarDiff(radius)) < dphi) + return true; + + return false; +} + +template +float FemtoPair::GetKstar() const +{ + if (_first == NULL || _second == NULL) + return -1000; + if (!(_magfield1 * _magfield2)) + return -1000; + if (!(_PDG1 * _PDG2)) + return -1000; + + TLorentzVector first4momentum; + first4momentum.SetPtEtaPhiM(_first->pt(), _first->eta(), _first->phi(), particle_mass(_PDG1)); + TLorentzVector second4momentum; + second4momentum.SetPtEtaPhiM(_second->pt(), _second->eta(), _second->phi(), particle_mass(_PDG2)); + + return GetKstarFrom4vectors(first4momentum, second4momentum, _isidentical); +} + +template +float FemtoPair::GetKt() const +{ + if (_first == NULL || _second == NULL) + return -1000; + if (!(_magfield1 * _magfield2)) + return -1000; + if (!(_PDG1 * _PDG2)) + return -1000; + + return 0.5 * std::sqrt(std::pow(_first->px() + _second->px(), 2) + std::pow(_first->py() + _second->py(), 2)); +} +} // namespace o2::aod::singletrackselector + +#endif // PWGCF_FEMTO3D_CORE_FEMTO3DPAIRTASK_H_ diff --git a/PWGCF/Femto3D/DataModel/CMakeLists.txt b/PWGCF/Femto3D/DataModel/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/PWGCF/Femto3D/DataModel/singletrackselector.h b/PWGCF/Femto3D/DataModel/singletrackselector.h index 91dfb63e856..3db909f2911 100755 --- a/PWGCF/Femto3D/DataModel/singletrackselector.h +++ b/PWGCF/Femto3D/DataModel/singletrackselector.h @@ -39,29 +39,65 @@ inline typename binningType::binned_t packInTable(const float& valueToBin) } else if (valueToBin >= binningType::binned_max) { return binningType::overflowBin; } else { - return static_cast(valueToBin / binningType::bin_width); + return static_cast((valueToBin - binningType::binned_center) / binningType::bin_width); } } template inline float unPack(const typename binningType::binned_t& b) { - return static_cast(binningType::bin_width * b); + return binningType::bin_width * b + binningType::binned_center; } -namespace nsigma +template +inline o2::framework::expressions::Node unPack(const T& b) { -struct binning { + return binningType::bin_width * b + binningType::binned_center; +} + +namespace binning +{ +struct binningParent { public: typedef int8_t binned_t; static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2; static constexpr binned_t overflowBin = nbins >> 1; static constexpr binned_t underflowBin = -(nbins >> 1); - static constexpr float binned_max = 10.0; +}; + +struct nsigma : binningParent { + public: static constexpr float binned_min = -10.0; + static constexpr float binned_max = 10.0; + static constexpr float binned_center = 0.5 * (binned_min + binned_max); + static constexpr float bin_width = (binned_max - binned_min) / nbins; +}; + +struct dca : binningParent { + public: + static constexpr float binned_min = -1.0; + static constexpr float binned_max = 1.0; + static constexpr float binned_center = 0.5 * (binned_min + binned_max); static constexpr float bin_width = (binned_max - binned_min) / nbins; }; -} // namespace nsigma + +struct chi2 : binningParent { + public: + static constexpr float binned_min = 0.0; + static constexpr float binned_max = 10.0; + static constexpr float binned_center = 0.5 * (binned_min + binned_max); + static constexpr float bin_width = (binned_max - binned_min) / nbins; +}; + +struct rowsOverFindable : binningParent { + public: + static constexpr float binned_min = 0.0; + static constexpr float binned_max = 3.0; + static constexpr float binned_center = 0.5 * (binned_min + binned_max); + static constexpr float bin_width = (binned_max - binned_min) / nbins; +}; + +} // namespace binning DECLARE_SOA_COLUMN(Mult, mult, int); // Multiplicity of the collision DECLARE_SOA_COLUMN(MultPercentile, multPerc, float); // Percentiles of multiplicity of the collision @@ -79,27 +115,29 @@ DECLARE_SOA_TABLE(SingleCollSels, "AOD", "SINGLECOLLSEL", // Table of the variab namespace singletrackselector { - -DECLARE_SOA_INDEX_COLUMN(SingleCollSel, singleCollSel); // Index to the collision -DECLARE_SOA_COLUMN(P, p, float); // Momentum of the track -DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); // impact parameter of the track -DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); // impact parameter of the track -DECLARE_SOA_COLUMN(TPCInnerParam, tpcInnerParam, float); // Momentum at inner wall of the TPC -DECLARE_SOA_COLUMN(TPCSignal, tpcSignal, float); // dE/dx TPC -DECLARE_SOA_COLUMN(Beta, beta, float); // TOF beta -DECLARE_SOA_COLUMN(TPCNClsFound, tpcNClsFound, int16_t); // Number of TPC clusters -DECLARE_SOA_COLUMN(TPCChi2NCl, tpcChi2NCl, float); // TPC chi2 -DECLARE_SOA_COLUMN(TPCCrossedRowsOverFindableCls, tpcCrossedRowsOverFindableCls, float); // Ratio of found over findable clusters -DECLARE_SOA_COLUMN(TPCNClsShared, tpcNClsShared, uint8_t); // Number of shared TPC clusters -DECLARE_SOA_COLUMN(ITSNCls, itsNCls, uint8_t); // Number of ITS clusters -DECLARE_SOA_COLUMN(ITSChi2NCl, itsChi2NCl, float); // ITS chi2 -DECLARE_SOA_COLUMN(Sign, sign, int8_t); +DECLARE_SOA_INDEX_COLUMN(SingleCollSel, singleCollSel); // Index to the collision +DECLARE_SOA_COLUMN(P, p, float); // Momentum of the track DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); -DECLARE_SOA_COLUMN(StoredTOFNSigmaPr, storedTofNSigmaPr, nsigma::binning::binned_t); -DECLARE_SOA_COLUMN(StoredTPCNSigmaPr, storedTpcNSigmaPr, nsigma::binning::binned_t); -DECLARE_SOA_COLUMN(StoredTOFNSigmaDe, storedTofNSigmaDe, nsigma::binning::binned_t); -DECLARE_SOA_COLUMN(StoredTPCNSigmaDe, storedTpcNSigmaDe, nsigma::binning::binned_t); +DECLARE_SOA_COLUMN(Sign, sign, int8_t); +DECLARE_SOA_COLUMN(TPCNClsFound, tpcNClsFound, int16_t); // Number of TPC clusters +DECLARE_SOA_COLUMN(TPCNClsShared, tpcNClsShared, uint8_t); // Number of shared TPC clusters +DECLARE_SOA_COLUMN(ITSNCls, itsNCls, uint8_t); // Number of ITS clusters + +DECLARE_SOA_COLUMN(StoredDcaXY, storedDcaXY, binning::dca::binned_t); // impact parameter of the track +DECLARE_SOA_COLUMN(StoredDcaZ, storedDcaZ, binning::dca::binned_t); // impact parameter of the track +DECLARE_SOA_COLUMN(StoredTPCChi2NCl, storedTpcChi2NCl, binning::chi2::binned_t); // TPC chi2 +DECLARE_SOA_COLUMN(StoredITSChi2NCl, storedItsChi2NCl, binning::chi2::binned_t); // ITS chi2 +DECLARE_SOA_COLUMN(StoredTPCCrossedRowsOverFindableCls, storedTpcCrossedRowsOverFindableCls, binning::rowsOverFindable::binned_t); // Ratio of found over findable clusters + +DECLARE_SOA_COLUMN(StoredTOFNSigmaPi, storedTofNSigmaPi, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTPCNSigmaPi, storedTpcNSigmaPi, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTOFNSigmaKa, storedTofNSigmaKa, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTPCNSigmaKa, storedTpcNSigmaKa, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTOFNSigmaPr, storedTofNSigmaPr, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTPCNSigmaPr, storedTpcNSigmaPr, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTOFNSigmaDe, storedTofNSigmaDe, binning::nsigma::binned_t); +DECLARE_SOA_COLUMN(StoredTPCNSigmaDe, storedTpcNSigmaDe, binning::nsigma::binned_t); DECLARE_SOA_DYNAMIC_COLUMN(Energy, energy, [](float p, float mass) -> float { return sqrt(p * p + mass * mass); }); DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float p, float eta) -> float { return p / std::cosh(eta); }); @@ -115,22 +153,39 @@ DECLARE_SOA_DYNAMIC_COLUMN(PhiStar, phiStar, } }); +DECLARE_SOA_DYNAMIC_COLUMN(DcaXY, dcaXY, + [](binning::dca::binned_t dca_binned) -> float { return singletrackselector::unPack(dca_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(DcaZ, dcaZ, + [](binning::dca::binned_t dca_binned) -> float { return singletrackselector::unPack(dca_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCChi2NCl, tpcChi2NCl, + [](binning::chi2::binned_t chi2_binned) -> float { return singletrackselector::unPack(chi2_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(ITSChi2NCl, itsChi2NCl, + [](binning::chi2::binned_t chi2_binned) -> float { return singletrackselector::unPack(chi2_binned); }); + +DECLARE_SOA_DYNAMIC_COLUMN(TPCCrossedRowsOverFindableCls, tpcCrossedRowsOverFindableCls, + [](binning::rowsOverFindable::binned_t rowsOverFindable_binned) -> float { return singletrackselector::unPack(rowsOverFindable_binned); }); + +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaPi, tofNSigmaPi, + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaPi, tpcNSigmaPi, + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaKa, tofNSigmaKa, + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaKa, tpcNSigmaKa, + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); + DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaPr, tofNSigmaPr, - [](nsigma::binning::binned_t nsigma_binned) -> float { - return singletrackselector::unPack(nsigma_binned); - }); + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaPr, tpcNSigmaPr, - [](nsigma::binning::binned_t nsigma_binned) -> float { - return singletrackselector::unPack(nsigma_binned); - }); + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaDe, tofNSigmaDe, - [](nsigma::binning::binned_t nsigma_binned) -> float { - return singletrackselector::unPack(nsigma_binned); - }); + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaDe, tpcNSigmaDe, - [](nsigma::binning::binned_t nsigma_binned) -> float { - return singletrackselector::unPack(nsigma_binned); - }); + [](binning::nsigma::binned_t nsigma_binned) -> float { return singletrackselector::unPack(nsigma_binned); }); + +DECLARE_SOA_COLUMN(TPCInnerParam, tpcInnerParam, float); // Momentum at inner wall of the TPC +DECLARE_SOA_COLUMN(TPCSignal, tpcSignal, float); // dE/dx TPC +DECLARE_SOA_COLUMN(Beta, beta, float); // TOF beta } // namespace singletrackselector @@ -138,36 +193,82 @@ DECLARE_SOA_TABLE_FULL(SingleTrackSels, "SelTracks", "AOD", "SINGLETRACKSEL", // o2::soa::Index<>, singletrackselector::SingleCollSelId, singletrackselector::P, - singletrackselector::DcaXY, - singletrackselector::DcaZ, - singletrackselector::TPCInnerParam, - singletrackselector::TPCSignal, - singletrackselector::Beta, + singletrackselector::Eta, + singletrackselector::Phi, + singletrackselector::Sign, singletrackselector::TPCNClsFound, - singletrackselector::TPCChi2NCl, - singletrackselector::TPCCrossedRowsOverFindableCls, singletrackselector::TPCNClsShared, singletrackselector::ITSNCls, - singletrackselector::ITSChi2NCl, - singletrackselector::Sign, - singletrackselector::Eta, - singletrackselector::Phi, + singletrackselector::StoredDcaXY, + singletrackselector::StoredDcaZ, + singletrackselector::StoredTPCChi2NCl, + singletrackselector::StoredITSChi2NCl, + singletrackselector::StoredTPCCrossedRowsOverFindableCls, + + singletrackselector::StoredTOFNSigmaPi, + singletrackselector::StoredTPCNSigmaPi, + singletrackselector::StoredTOFNSigmaKa, + singletrackselector::StoredTPCNSigmaKa, singletrackselector::StoredTOFNSigmaPr, singletrackselector::StoredTPCNSigmaPr, singletrackselector::StoredTOFNSigmaDe, singletrackselector::StoredTPCNSigmaDe, + + singletrackselector::DcaXY, + singletrackselector::DcaZ, + singletrackselector::TPCChi2NCl, + singletrackselector::ITSChi2NCl, + singletrackselector::TPCCrossedRowsOverFindableCls, + + singletrackselector::TOFNSigmaPi, + singletrackselector::TPCNSigmaPi, + singletrackselector::TOFNSigmaKa, + singletrackselector::TPCNSigmaKa, + singletrackselector::TOFNSigmaPr, + singletrackselector::TPCNSigmaPr, + singletrackselector::TOFNSigmaDe, + singletrackselector::TPCNSigmaDe, + singletrackselector::Energy, singletrackselector::Pt, singletrackselector::Px, singletrackselector::Py, singletrackselector::Pz, - singletrackselector::PhiStar, - singletrackselector::TOFNSigmaPr, - singletrackselector::TPCNSigmaPr, - singletrackselector::TOFNSigmaDe, - singletrackselector::TPCNSigmaDe); + singletrackselector::PhiStar); + +DECLARE_SOA_TABLE(SingleTrkExtras, "AOD", "SINGLETRKEXTRA", + singletrackselector::TPCInnerParam, + singletrackselector::TPCSignal, + singletrackselector::Beta); + +namespace singletrackselector +{ +DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); +DECLARE_SOA_COLUMN(Origin, origin, int); // 0 - prymary; 1 - weak decay; 2 - material +DECLARE_SOA_COLUMN(P_MC, p_MC, float); +DECLARE_SOA_COLUMN(Eta_MC, eta_MC, float); +DECLARE_SOA_COLUMN(Phi_MC, phi_MC, float); + +DECLARE_SOA_DYNAMIC_COLUMN(Pt_MC, pt_MC, [](float p, float eta) -> float { return p / std::cosh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(Px_MC, px_MC, [](float p, float eta, float phi) -> float { return (p / std::cosh(eta)) * std::sin(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Py_MC, py_MC, [](float p, float eta, float phi) -> float { return (p / std::cosh(eta)) * std::cos(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz_MC, pz_MC, [](float p, float eta) -> float { return p * std::tanh(eta); }); + +} // namespace singletrackselector + +DECLARE_SOA_TABLE(SingleTrkMCs, "AOD", "SINGLETRKMC", // Table with generatad info from MC + singletrackselector::PdgCode, + singletrackselector::Origin, + singletrackselector::P_MC, + singletrackselector::Eta_MC, + singletrackselector::Phi_MC, + singletrackselector::Pt_MC, + singletrackselector::Px_MC, + singletrackselector::Py_MC, + singletrackselector::Pz_MC); } // namespace o2::aod + #endif // PWGCF_FEMTO3D_DATAMODEL_SINGLETRACKSELECTOR_H_ namespace o2::aod::singletrackselector @@ -176,15 +277,23 @@ namespace o2::aod::singletrackselector template inline bool TPCselection(TrackType const& track, std::pair> const& PIDcuts) { + int PDG = PIDcuts.first; float Nsigma = -1000; - - switch (PIDcuts.first) { + switch (PDG) { case 2212: Nsigma = track.tpcNSigmaPr(); break; case 1000010020: Nsigma = track.tpcNSigmaDe(); break; + case 211: + Nsigma = track.tpcNSigmaPi(); + break; + case 321: + Nsigma = track.tpcNSigmaKa(); + break; + case 0: + return false; default: LOG(fatal) << "Cannot interpret PDG for TPC selection: " << PIDcuts.first; } @@ -196,11 +305,14 @@ inline bool TPCselection(TrackType const& track, std::pair -inline bool TOFselection(TrackType const& track, std::pair> const& PIDcuts) +inline bool TOFselection(TrackType const& track, std::pair> const& PIDcuts, float const& TPCresidualCut = 5.0f) { - float Nsigma = -1000; + int PDG = PIDcuts.first; + if (!TPCselection(track, std::make_pair(PDG, std::vector{-TPCresidualCut, TPCresidualCut}))) + return false; - switch (PIDcuts.first) { + float Nsigma = -1000; + switch (PDG) { case 2212: Nsigma = track.tofNSigmaPr(); break; @@ -208,13 +320,13 @@ inline bool TOFselection(TrackType const& track, std::pair::value) { - Nsigma = track.tofNSigmaPi(); - } + Nsigma = track.tofNSigmaPi(); + break; case 321: - if constexpr (std::experimental::is_detected::value) { - Nsigma = track.tofNSigmaKa(); - } + Nsigma = track.tofNSigmaKa(); + break; + case 0: + return false; default: LOG(fatal) << "Cannot interpret PDG for TOF selection: " << PIDcuts.first; } diff --git a/PWGCF/Femto3D/TableProducer/CMakeLists.txt b/PWGCF/Femto3D/TableProducer/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx index 4ebc3723246..89b21efb5ff 100755 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -55,29 +55,34 @@ struct singleTrackSelector { Configurable> _particlesToReject{"particlesToRejectPDGs", std::vector{}, "PDG codes of perticles that will be rejected with TOF (only pion, kaon, proton and deurton are supported now)"}; Configurable> rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-5.0f, 5.0f}, "TOF rejection Nsigma range for particles specified with PDG to be rejected"}; - Configurable _tpcNClsFound{"tpcNClsFound", 70, "Minimun number of cluster found in TPC"}; - Configurable _itsNCls{"itsNCls", 0, "Minimun number of cluster found in ITS"}; - Configurable _tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0.f, "Minimun number of crossed rows over findable clusters"}; + Configurable _min_P{"min_P", 0.f, "lower mometum limit"}; + Configurable _max_P{"max_P", 100.f, "upper mometum limit"}; + Configurable _eta{"eta", 100.f, "abs eta value limit"}; Configurable _dcaXY{"dcaXY", 1000.f, "Maximum dca of track in xy"}; Configurable _dcaZ{"dcaZ", 1000.f, "Maximum dca of track in xy"}; using Trks = soa::Join; - using Coll = soa::Join; + + using Coll = soa::Join; Produces tableRow; Produces tableRowColl; + Produces tableRowExtra; + Produces tableRowMC; Filter eventFilter = (applyEvSel.node() == 0) || ((applyEvSel.node() == 1) && (aod::evsel::sel7 == true)) || ((applyEvSel.node() == 2) && (aod::evsel::sel8 == true)); Filter vertexFilter = ((o2::aod::collision::posZ < 15.f) && (o2::aod::collision::posZ > -15.f)); Filter trackFilter = ((o2::aod::track::itsChi2NCl <= 36.f) && (o2::aod::track::itsChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl <= 4.f)); - Filter tpcFilter = ((o2::aod::singletrackselector::tpcNClsFound >= _tpcNClsFound) && (o2::aod::singletrackselector::tpcCrossedRowsOverFindableCls >= _tpcCrossedRowsOverFindableCls)); - Filter itsFilter = (o2::aod::singletrackselector::itsNCls >= _itsNCls); + + Filter pFilter = o2::aod::track::p > _min_P&& o2::aod::track::p < _max_P; + Filter etaFilter = nabs(o2::aod::track::eta) < _eta; Filter dcaFilter = (o2::aod::track::dcaXY <= _dcaXY) && (o2::aod::track::dcaZ <= _dcaZ); int mRunNumber = 0; @@ -127,14 +132,10 @@ struct singleTrackSelector { d_bz = 0.1 * d_bz; } - void process(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, aod::BCsWithTimestamps const&) + template + inline void fillTheTables(Col collision, Trks const& tracks) { - bool skip_track = false; // flag used for track rejection - tableRow.reserve(tracks.size()); - - auto bc = collision.bc_as(); - initCCDB(bc); tableRowColl(collision.multTPC(), collision.centFT0M(), @@ -142,8 +143,14 @@ struct singleTrackSelector { d_bz); for (auto& track : tracks) { + if constexpr (isMC) { + if (!track.has_mcParticle()) + continue; + } skip_track = false; - + if (Configurable{"rejectNotPropagatedTrks", true, "rejects tracks that are not propagated to the primary vertex"} && track.trackType() != aod::track::Track) { + continue; + } for (auto i : particlesToReject) { // if satisfied, want to continue in the upper loop (over tracks) -- skip the current track // cannot use simple 'continue' since it will be applied to the current loop, so have to use a flag @@ -161,29 +168,73 @@ struct singleTrackSelector { tableRow(tableRowColl.lastIndex(), track.p(), - track.dcaXY(), - track.dcaZ(), - track.tpcInnerParam(), - track.tpcSignal(), - track.beta(), + track.eta(), + track.phi(), + track.sign(), track.tpcNClsFound(), - track.tpcChi2NCl(), - track.tpcCrossedRowsOverFindableCls(), track.tpcNClsShared(), track.itsNCls(), - track.itsChi2NCl(), - track.sign(), - track.eta(), - track.phi(), - singletrackselector::packInTable(track.tofNSigmaPr()), - singletrackselector::packInTable(track.tpcNSigmaPr()), - singletrackselector::packInTable(track.tofNSigmaDe()), - singletrackselector::packInTable(track.tpcNSigmaDe())); + singletrackselector::packInTable(track.dcaXY()), + singletrackselector::packInTable(track.dcaZ()), + singletrackselector::packInTable(track.tpcChi2NCl()), + singletrackselector::packInTable(track.itsChi2NCl()), + singletrackselector::packInTable(track.tpcCrossedRowsOverFindableCls()), + singletrackselector::packInTable(track.tofNSigmaPi()), + singletrackselector::packInTable(track.tpcNSigmaPi()), + singletrackselector::packInTable(track.tofNSigmaKa()), + singletrackselector::packInTable(track.tpcNSigmaKa()), + singletrackselector::packInTable(track.tofNSigmaPr()), + singletrackselector::packInTable(track.tpcNSigmaPr()), + singletrackselector::packInTable(track.tofNSigmaDe()), + singletrackselector::packInTable(track.tpcNSigmaDe())); + + tableRowExtra(track.tpcInnerParam(), + track.tpcSignal(), + track.beta()); + + if constexpr (isMC) { + int origin = -1; + if (track.mcParticle().isPhysicalPrimary()) + origin = 0; + if (!track.mcParticle().isPhysicalPrimary() && track.mcParticle().producedByGenerator()) + origin = 1; + if (!track.mcParticle().isPhysicalPrimary() && !track.mcParticle().producedByGenerator()) + origin = 2; + + if (origin == -1) + LOGF(fatal, "Could not define the origin (primary/weak decay/material) of the track!!!"); + + tableRowMC(track.mcParticle().pdgCode(), + origin, + track.mcParticle().p(), + track.mcParticle().eta(), + track.mcParticle().phi()); + } break; // break the loop with particlesToKeep after the 'if' condition is satisfied -- don't want double entries } } } + + void processData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, aod::BCsWithTimestamps const&) + { + + auto bc = collision.bc_as(); + initCCDB(bc); + + fillTheTables(collision, tracks); + } + PROCESS_SWITCH(singleTrackSelector, processData, "process data", true); + + void processMC(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles const&, aod::BCsWithTimestamps const&) + { + + auto bc = collision.bc_as(); + initCCDB(bc); + + fillTheTables(collision, tracks); + } + PROCESS_SWITCH(singleTrackSelector, processMC, "process MC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Femto3D/Tasks/CMakeLists.txt b/PWGCF/Femto3D/Tasks/CMakeLists.txt new file mode 100755 index 00000000000..a0338dce678 --- /dev/null +++ b/PWGCF/Femto3D/Tasks/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2physics_add_dpl_workflow(femto3d-qa + SOURCES femto3dQA.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto3d-pair-task + SOURCES femto3dPairTask.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto3d-pair-task-mc + SOURCES femto3dPairTaskMC.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx new file mode 100755 index 00000000000..d469eb78bf9 --- /dev/null +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -0,0 +1,382 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \brief Femto3D pair mixing task +/// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio +/// \since 31 May 2023 + +#include +#include +#include + +#include "PWGCF/Femto3D/Core/femto3dPairTask.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" +#include "TLorentzVector.h" + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoA.h" +#include "Framework/DataTypes.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/Expressions.h" +#include "Framework/StaticFor.h" +#include "MathUtils/Utils.h" +#include "Common/DataModel/Multiplicity.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct FemtoCorrelations { + // using allinfo = soa::Join; // aod::pidTPCPr + /// Construct a registry object with direct declaration + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable _min_P{"min_P", 0.0, "lower mometum limit"}; + Configurable _max_P{"max_P", 100.0, "upper mometum limit"}; + Configurable _eta{"eta", 100.0, "abs eta value limit"}; + Configurable _dcaXY{"dcaXY", 10.0, "abs dcaXY value limit"}; + Configurable _dcaZ{"dcaZ", 10.0, "abs dcaZ value limit"}; + Configurable _tpcNClsFound{"minTpcNClsFound", 0, "minimum allowed number of TPC clasters"}; + Configurable _tpcChi2NCl{"tpcChi2NCl", 100.0, "upper limit for chi2 value of a fit over TPC clasters"}; + Configurable _tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0, "lower limit of TPC CrossedRows/FindableCls value"}; + Configurable _tpcNClsShared{"maxTpcNClsShared", 100, "maximum allowed number of TPC shared clasters"}; + Configurable _itsNCls{"minItsNCls", 0, "minimum allowed number of ITS clasters"}; + Configurable _itsChi2NCl{"itsChi2NCl", 100.0, "upper limit for chi2 value of a fit over ITS clasters"}; + Configurable _vertexZ{"VertexZ", 10.0, "abs vertexZ value limit"}; + + Configurable _sign_1{"sign_1", 1, "sign of the first particle in a pair"}; + Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma_1{"tpcNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld_1{"PIDtrshld_1", 10.0, "first particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma_1{"tofNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TOF"}; + + Configurable _sign_2{"sign_2", 1, "sign of the second particle in a pair"}; + Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma_2{"tpcNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld_2{"PIDtrshld_2", 10.0, "second particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma_2{"tofNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TOF"}; + + Configurable _particlePDGtoReject{"particlePDGtoRejectFromSecond", 0, "applied only if the particles are non-identical and only to the second particle in the pair!!!"}; + Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for the particle specified with PDG to be rejected"}; + + Configurable _deta{"deta", 0.01, "minimum allowed defference in eta between two tracks in a pair"}; + Configurable _dphi{"dphi", 0.01, "minimum allowed defference in phi_star between two tracks in a pair"}; + Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; + + Configurable _vertexNbinsToMix{"vertexNbinsToMix", 10, "Number of vertexZ bins for the mixing"}; + Configurable> _centBins{"multBins", std::vector{0.0f, 100.0f}, "multiplicity percentile/centrality binning (min:0, max:100)"}; + Configurable _multNsubBins{"multSubBins", 1, "number of sub-bins to perform the mixing within"}; + Configurable> _kTbins{"kTbins", std::vector{0.0f, 100.0f}, "pair transverse momentum kT binning"}; + ConfigurableAxis CFkStarBinning{"CFkStarBinning", {500, 0.005, 5.005}, "k* binning of the CF (Nbins, lowlimit, uplimit)"}; + + bool IsIdentical; + + std::pair> TPCcuts_1; + std::pair> TOFcuts_1; + + std::pair> TPCcuts_2; + std::pair> TOFcuts_2; + + using FilteredCollisions = aod::SingleCollSels; + using FilteredTracks = aod::SingleTrackSels; + + typedef std::shared_ptr::iterator> trkType; + typedef std::shared_ptr::iterator> colType; + + std::map> selectedtracks_1; + std::map> selectedtracks_2; + std::map, std::vector> mixbins; + + std::unique_ptr> Pair = std::make_unique>(); + + Filter pFilter = o2::aod::singletrackselector::p > _min_P&& o2::aod::singletrackselector::p < _max_P; + Filter etaFilter = nabs(o2::aod::singletrackselector::eta) < _eta; + + Filter tpcTrkFilter = o2::aod::singletrackselector::tpcNClsFound >= _tpcNClsFound && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcChi2NCl) < _tpcChi2NCl && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcCrossedRowsOverFindableCls) > _tpcCrossedRowsOverFindableCls; + + Filter dcaFilter = nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaXY)) < _dcaXY && + nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaZ)) < _dcaZ; + + Filter itsTrkFilter = o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedItsChi2NCl) < _itsChi2NCl; + + Filter vertexFilter = nabs(o2::aod::singletrackselector::posZ) < _vertexZ; + + std::vector> MultHistos; + std::vector>> kThistos; + std::vector>> SEhistos; + std::vector>> MEhistos; + + void init(o2::framework::InitContext&) + { + + if (_centBins.value.size() < 2) + LOGF(fatal, "The configured number of multiplicity/centrality bins in the array is less than 2 !!!"); + if (_kTbins.value.size() < 2) + LOGF(fatal, "The configured number of kT bins in the array is less than 2 !!!"); + if (_vertexNbinsToMix.value < 1) + LOGF(fatal, "The configured number of VertexZ bins is less than 1 !!!"); + + IsIdentical = (_sign_1 * _particlePDG_1 == _sign_2 * _particlePDG_2); + + Pair->SetIdentical(IsIdentical); + Pair->SetPDG1(_particlePDG_1); + Pair->SetPDG2(_particlePDG_2); + + TPCcuts_1 = std::make_pair(_particlePDG_1, _tpcNSigma_1); + TOFcuts_1 = std::make_pair(_particlePDG_1, _tofNSigma_1); + TPCcuts_2 = std::make_pair(_particlePDG_2, _tpcNSigma_2); + TOFcuts_2 = std::make_pair(_particlePDG_2, _tofNSigma_2); + + const AxisSpec kStarAxis{CFkStarBinning, "k* (GeV/c)"}; + + for (int i = 0; i < _centBins.value.size() - 1; i++) { + std::vector> SEperMult; + std::vector> MEperMult; + std::vector> kTperMult; + + auto hMult = registry.add(Form("Cent%i/Mult_vs_cent%i", i, i), Form("Mult_vs_cent%i", i), kTH1F, {{5001, -0.5, 5000.5, "Nch"}}); + MultHistos.push_back(std::move(hMult)); + + for (int j = 0; j < _kTbins.value.size() - 1; j++) { + auto hSE = registry.add(Form("Cent%i/SE_cent%i_kT%i", i, i, j), Form("SE_cent%i_kT%i", i, j), kTH1F, {kStarAxis}); + auto hME = registry.add(Form("Cent%i/ME_cent%i_kT%i", i, i, j), Form("ME_cent%i_kT%i", i, j), kTH1F, {kStarAxis}); + auto hkT = registry.add(Form("Cent%i/kT_cent%i_kT%i", i, i, j), Form("kT_cent%i_kT%i", i, j), kTH1F, {{500, 0., 5., "kT"}}); + SEperMult.push_back(std::move(hSE)); + MEperMult.push_back(std::move(hME)); + kTperMult.push_back(std::move(hkT)); + } + + SEhistos.push_back(std::move(SEperMult)); + MEhistos.push_back(std::move(MEperMult)); + kThistos.push_back(std::move(kTperMult)); + } + + registry.add("p_first", Form("p_%i", static_cast(_particlePDG_1)), kTH1F, {{100, 0., 5., "p"}}); + registry.add("nsigmaTOF_first", Form("nsigmaTOF_%i", static_cast(_particlePDG_1)), kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + registry.add("nsigmaTPC_first", Form("nsigmaTPC_%i", static_cast(_particlePDG_1)), kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + if (!IsIdentical) { + registry.add("p_second", Form("p_%i", static_cast(_particlePDG_2)), kTH1F, {{100, 0., 5., "p"}}); + registry.add("nsigmaTOF_second", Form("nsigmaTOF_%i", static_cast(_particlePDG_2)), kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + registry.add("nsigmaTPC_second", Form("nsigmaTPC_%i", static_cast(_particlePDG_2)), kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + } + } + + template + void mixTracks(Type const& tracks, int multBin) + { // template for identical particles from the same collision + if (multBin < 0 && multBin > SEhistos.size()) + LOGF(fatal, "multBin value passed to the mixTracks function is less than 0 or exceeds the configured number of Cent. bins"); + + for (int ii = 0; ii < tracks.size(); ii++) { // nested loop for all the combinations + for (int iii = ii + 1; iii < tracks.size(); iii++) { + + Pair->SetPair(tracks[ii], tracks[iii]); + float pair_kT = Pair->GetKt(); + int kTbin = o2::aod::singletrackselector::getBinIndex(pair_kT, _kTbins); + if (kTbin < 0 && kTbin > SEhistos[multBin].size()) + LOGF(fatal, "kTbin value obtained for a pair is less than 0 or exceeds the configured number of kT bins"); + + if (!Pair->IsClosePair(_deta, _dphi, _radiusTPC)) { + kThistos[multBin][kTbin]->Fill(pair_kT); + SEhistos[multBin][kTbin]->Fill(Pair->GetKstar()); // close pair rejection and fillig the SE histo + } + Pair->ResetPair(); + } + } + } + + template + void mixTracks(Type const& tracks1, Type const& tracks2, int multBin) + { // last value: 0 -- SE; 1 -- ME + if (multBin < 0 && multBin > SEhistos.size()) + LOGF(fatal, "multBin value passed to the mixTracks function is less than 0 or exceeds the configured number of Cent. bins"); + + for (auto ii : tracks1) { + for (auto iii : tracks2) { + + Pair->SetPair(ii, iii); + float pair_kT = Pair->GetKt(); + int kTbin = o2::aod::singletrackselector::getBinIndex(pair_kT, _kTbins); + if (kTbin < 0 && kTbin > SEhistos[multBin].size()) + LOGF(fatal, "kTbin value obtained for a pair is less than 0 or exceeds the configured number of kT bins"); + + if (!Pair->IsClosePair(_deta, _dphi, _radiusTPC)) { + if (!SE_or_ME) { + SEhistos[multBin][kTbin]->Fill(Pair->GetKstar()); + kThistos[multBin][kTbin]->Fill(pair_kT); + } else { + MEhistos[multBin][kTbin]->Fill(Pair->GetKstar()); + } + } + Pair->ResetPair(); + } + } + } + + void process(soa::Filtered const& collisions, soa::Filtered const& tracks) + { + if (_particlePDG_1 == 0 || _particlePDG_2 == 0) + LOGF(fatal, "One of passed PDG is 0!!!"); + + for (auto track : tracks) { + if (abs(track.singleCollSel().posZ()) > _vertexZ) + continue; + if (track.tpcNClsShared() > _tpcNClsShared || track.itsNCls() < _itsNCls) + continue; + if (track.singleCollSel().multPerc() < *_centBins.value.begin() || track.singleCollSel().multPerc() > *(_centBins.value.end() - 1)) + continue; + + if (track.sign() == _sign_1 && (track.p() < _PIDtrshld_1 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_1) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_1))) { // filling the map: eventID <-> selected particles1 + selectedtracks_1[track.singleCollSelId()].push_back(std::make_shared(track)); + + registry.fill(HIST("p_first"), track.p()); + if (_particlePDG_1 == 211) { + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaPi()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaPi()); + } + if (_particlePDG_1 == 321) { + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaKa()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaKa()); + } + if (_particlePDG_1 == 2212) { + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaPr()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaPr()); + } + if (_particlePDG_1 == 1000010020) { + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaDe()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaDe()); + } + } + + if (IsIdentical) { + continue; + } else if (track.sign() != _sign_2 && !TOFselection(track, std::make_pair(_particlePDGtoReject, _rejectWithinNsigmaTOF)) && (track.p() < _PIDtrshld_2 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_2) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_2))) { // filling the map: eventID <-> selected particles2 if (see condition above ^) + selectedtracks_2[track.singleCollSelId()].push_back(std::make_shared(track)); + + registry.fill(HIST("p_second"), track.p()); + if (_particlePDG_2 == 211) { + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaPi()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaPi()); + } + if (_particlePDG_2 == 321) { + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaKa()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaKa()); + } + if (_particlePDG_2 == 2212) { + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaPr()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaPr()); + } + if (_particlePDG_2 == 1000010020) { + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaDe()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaDe()); + } + } + } + + for (auto collision : collisions) { + if (collision.multPerc() < *_centBins.value.begin() || collision.multPerc() > *(_centBins.value.end() - 1)) + continue; + + if (selectedtracks_1.find(collision.globalIndex()) == selectedtracks_1.end()) { + if (IsIdentical) + continue; + else if (selectedtracks_2.find(collision.globalIndex()) == selectedtracks_2.end()) + continue; + } + int vertexBinToMix = round(collision.posZ() / (2 * _vertexZ / _vertexNbinsToMix)); + float centBinToMix = o2::aod::singletrackselector::getBinIndex(collision.multPerc(), _centBins, _multNsubBins); + + mixbins[std::pair{vertexBinToMix, centBinToMix}].push_back(std::make_shared(collision)); + } + + //====================================== mixing starts here ====================================== + + if (IsIdentical) { //====================================== mixing identical ====================================== + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + + for (int indx1 = 0; indx1 < (i->second).size(); indx1++) { // loop over all the events in each vertex&mult bin + + auto col1 = (i->second)[indx1]; + + Pair->SetMagField1(col1->magField()); + Pair->SetMagField2(col1->magField()); + + int centBin = std::floor((i->first).second); + MultHistos[centBin]->Fill(col1->mult()); + + mixTracks(selectedtracks_1[col1->index()], centBin); // mixing SE identical + + for (int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + + auto col2 = (i->second)[indx2]; + + Pair->SetMagField2(col2->magField()); + mixTracks<1>(selectedtracks_1[col1->index()], selectedtracks_1[col2->index()], centBin); // mixing ME identical, in <> brackets: 0 -- SE; 1 -- ME + } + } + } + + } else { //====================================== mixing non-identical ====================================== + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + + for (int indx1 = 0; indx1 < (i->second).size(); indx1++) { // loop over all the events in each vertex&mult bin + + auto col1 = (i->second)[indx1]; + + Pair->SetMagField1(col1->magField()); + Pair->SetMagField2(col1->magField()); + + int centBin = std::floor((i->first).second); + MultHistos[centBin]->Fill(col1->mult()); + + mixTracks<0>(selectedtracks_1[col1->index()], selectedtracks_2[col1->index()], centBin); // mixing SE non-identical, in <> brackets: 0 -- SE; 1 -- ME + + for (int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + + auto col2 = (i->second)[indx2]; + + Pair->SetMagField2(col2->magField()); + mixTracks<1>(selectedtracks_1[col1->index()], selectedtracks_2[col2->index()], centBin); // mixing ME non-identical, in <> brackets: 0 -- SE; 1 -- ME + } + } + } + + } //====================================== end of mixing non-identical ====================================== + + // clearing up + for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) + (i->second).clear(); + selectedtracks_1.clear(); + + if (!IsIdentical) { + for (auto i = selectedtracks_2.begin(); i != selectedtracks_2.end(); i++) + (i->second).clear(); + selectedtracks_2.clear(); + } + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) + (i->second).clear(); + mixbins.clear(); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx new file mode 100755 index 00000000000..882a1e2221f --- /dev/null +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -0,0 +1,375 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \brief Femto3D pair mixing task +/// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio +/// \since 31 May 2023 + +#include +#include +#include + +#include "PWGCF/Femto3D/Core/femto3dPairTask.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" +#include "TLorentzVector.h" + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoA.h" +#include "Framework/DataTypes.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/Expressions.h" +#include "Framework/StaticFor.h" +#include "MathUtils/Utils.h" +#include "Common/DataModel/Multiplicity.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct FemtoCorrelationsMC { + // using allinfo = soa::Join; // aod::pidTPCPr + /// Construct a registry object with direct declaration + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable _min_P{"min_P", 0.0, "lower mometum limit"}; + Configurable _max_P{"max_P", 100.0, "upper mometum limit"}; + Configurable _eta{"eta", 100.0, "abs eta value limit"}; + Configurable _dcaXY{"dcaXY", 10.0, "abs dcaXY value limit"}; + Configurable _dcaZ{"dcaZ", 10.0, "abs dcaZ value limit"}; + Configurable _tpcNClsFound{"minTpcNClsFound", 0, "minimum allowed number of TPC clasters"}; + Configurable _tpcChi2NCl{"tpcChi2NCl", 100.0, "upper limit for chi2 value of a fit over TPC clasters"}; + Configurable _tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0, "lower limit of TPC CrossedRows/FindableCls value"}; + Configurable _tpcNClsShared{"maxTpcNClsShared", 100, "maximum allowed number of TPC shared clasters"}; + Configurable _itsNCls{"minItsNCls", 0, "minimum allowed number of ITS clasters"}; + Configurable _itsChi2NCl{"itsChi2NCl", 100.0, "upper limit for chi2 value of a fit over ITS clasters"}; + Configurable _vertexZ{"VertexZ", 10.0, "abs vertexZ value limit"}; + + Configurable _sign_1{"sign_1", 1, "sign of the first particle in a pair"}; + Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma_1{"tpcNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld_1{"PIDtrshld_1", 10.0, "first particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma_1{"tofNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TOF"}; + + Configurable _sign_2{"sign_2", 1, "sign of the second particle in a pair"}; + Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma_2{"tpcNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld_2{"PIDtrshld_2", 10.0, "second particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma_2{"tofNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TOF"}; + + Configurable _particlePDGtoReject{"particlePDGtoRejectFromSecond", 0, "applied only if the particles are non-identical and only to the second particle in the pair!!!"}; + Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for the particle specified with PDG to be rejected"}; + + Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; + + ConfigurableAxis CFkStarBinning{"CFkStarBinning", {500, 0.005, 5.005}, "k* binning of the res. matrix (Nbins, lowlimit, uplimit)"}; + + bool IsIdentical; + + std::pair> TPCcuts_1; + std::pair> TOFcuts_1; + + std::pair> TPCcuts_2; + std::pair> TOFcuts_2; + + using FilteredCollisions = aod::SingleCollSels; + using FilteredTracks = soa::Join; + + typedef std::shared_ptr::iterator> trkType; + typedef std::shared_ptr::iterator> colType; + + std::map> selectedtracks_1; + std::map> selectedtracks_2; + + std::unique_ptr> Pair = std::make_unique>(); + + Filter pFilter = o2::aod::singletrackselector::p > _min_P&& o2::aod::singletrackselector::p < _max_P; + Filter etaFilter = nabs(o2::aod::singletrackselector::eta) < _eta; + + Filter tpcTrkFilter = o2::aod::singletrackselector::tpcNClsFound >= _tpcNClsFound && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcChi2NCl) < _tpcChi2NCl && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcCrossedRowsOverFindableCls) > _tpcCrossedRowsOverFindableCls; + + Filter itsTrkFilter = o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedItsChi2NCl) < _itsChi2NCl; + + Filter vertexFilter = nabs(o2::aod::singletrackselector::posZ) < _vertexZ; + + void init(o2::framework::InitContext&) + { + + IsIdentical = (_sign_1 * _particlePDG_1 == _sign_2 * _particlePDG_2); + + Pair->SetIdentical(IsIdentical); + Pair->SetPDG1(_particlePDG_1); + Pair->SetPDG2(_particlePDG_2); + + TPCcuts_1 = std::make_pair(_particlePDG_1, _tpcNSigma_1); + TOFcuts_1 = std::make_pair(_particlePDG_1, _tofNSigma_1); + TPCcuts_2 = std::make_pair(_particlePDG_2, _tpcNSigma_2); + TOFcuts_2 = std::make_pair(_particlePDG_2, _tofNSigma_2); + + registry.add("FirstParticle/dcaxyz_vs_pt_primary", "dcaxyz_vs_pt_primary", kTH3F, {{100, 0., 5., "pt"}, {250, -1., 1., "DCA_XY(pt) primary"}, {250, -1., 1., "DCA_Z(pt) primary"}}); + registry.add("FirstParticle/dcaxyz_vs_pt_weakdecay", "dcaxyz_vs_pt_weakdecay", kTH3F, {{100, 0., 5., "pt"}, {250, -1., 1., "DCA_XY(pt) weakdecay"}, {250, -1., 1., "DCA_Z(pt) weakdecay"}}); + registry.add("FirstParticle/dcaxyz_vs_pt_material", "dcaxyz_vs_pt_material", kTH3F, {{100, 0., 5., "pt"}, {250, -1., 1., "DCA_XY(pt) material"}, {250, -1., 1., "DCA_Z(pt) material"}}); + + registry.add("FirstParticle/3dmomentumEl", "3dmomentumEl", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/3dmomentumMu", "3dmomentumMu", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/3dmomentumPi", "3dmomentumPi", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/3dmomentumKa", "3dmomentumKa", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/3dmomentumPr", "3dmomentumPr", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/3dmomentumDe", "3dmomentumDe", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/3dmomentumAll", "3dmomentumAll", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("FirstParticle/PtSpectraEl", "PtSpectraEl", kTH1F, {{100, 0., 5.}}); + registry.add("FirstParticle/PtSpectraMu", "PtSpectraMu", kTH1F, {{100, 0., 5.}}); + registry.add("FirstParticle/PtSpectraPi", "PtSpectraPi", kTH1F, {{100, 0., 5.}}); + registry.add("FirstParticle/PtSpectraKa", "PtSpectraKa", kTH1F, {{100, 0., 5.}}); + registry.add("FirstParticle/PtSpectraPr", "PtSpectraPr", kTH1F, {{100, 0., 5.}}); + registry.add("FirstParticle/PtSpectraDe", "PtSpectraDe", kTH1F, {{100, 0., 5.}}); + registry.add("FirstParticle/PtSpectraAll", "PtSpectrAll", kTH1F, {{100, 0., 5.}}); + + if (!IsIdentical) { + registry.add("SecondParticle/dcaxyz_vs_pt_primary", "dcaxyz_vs_pt_primary", kTH3F, {{100, 0., 5., "pt"}, {200, -1., 1., "DCA_XY(pt) primary"}, {200, -1., 1., "DCA_Z(pt) primary"}}); + registry.add("SecondParticle/dcaxyz_vs_pt_weakdecay", "dcaxyz_vs_pt_weakdecay", kTH3F, {{100, 0., 5., "pt"}, {200, -1., 1., "DCA_XY(pt) weakdecay"}, {200, -1., 1., "DCA_Z(pt) weakdecay"}}); + registry.add("SecondParticle/dcaxyz_vs_pt_material", "dcaxyz_vs_pt_material", kTH3F, {{100, 0., 5., "pt"}, {200, -1., 1., "DCA_XY(pt) material"}, {200, -1., 1., "DCA_Z(pt) material"}}); + + registry.add("SecondParticle/3dmomentumEl", "3dmomentumEl", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/3dmomentumMu", "3dmomentumMu", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/3dmomentumPi", "3dmomentumPi", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/3dmomentumKa", "3dmomentumKa", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/3dmomentumPr", "3dmomentumPr", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/3dmomentumDe", "3dmomentumDe", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/3dmomentumAll", "3dmomentumAll", kTH3F, {{100, 0., 5., "px"}, {100, 0., 5., "py"}, {100, 0., 5., "pz"}}); + registry.add("SecondParticle/PtSpectraEl", "PtSpectraEl", kTH1F, {{100, 0., 5.}}); + registry.add("SecondParticle/PtSpectraMu", "PtSpectraMu", kTH1F, {{100, 0., 5.}}); + registry.add("SecondParticle/PtSpectraPi", "PtSpectraPi", kTH1F, {{100, 0., 5.}}); + registry.add("SecondParticle/PtSpectraKa", "PtSpectraKa", kTH1F, {{100, 0., 5.}}); + registry.add("SecondParticle/PtSpectraPr", "PtSpectraPr", kTH1F, {{100, 0., 5.}}); + registry.add("SecondParticle/PtSpectraDe", "PtSpectraDe", kTH1F, {{100, 0., 5.}}); + registry.add("SecondParticle/PtSpectraAll", "PtSpectrAll", kTH1F, {{100, 0., 5.}}); + } + + registry.add("ResolutionMatrix", "ResolutionMatrix_rec(gen)", kTH2F, {{CFkStarBinning, "k*_gen (GeV/c)"}, {CFkStarBinning, "k*_rec (GeV/c)"}}); + registry.add("DoubleTrackEffects", "DoubleTrackEffects_deta(dphi*)", kTH2F, {{200, -M_PI, M_PI, "dphi*"}, {200, -0.5, 0.5, "deta"}}); + } + + template + void fillEtaPhi(Type const& tracks) + { // template for particles from the same collision identical + for (int ii = 0; ii < tracks.size(); ii++) { // nested loop for all the combinations + for (int iii = ii + 1; iii < tracks.size(); iii++) { + + Pair->SetPair(tracks[ii], tracks[iii]); + Pair->SetMagField1((tracks[ii]->singleCollSel()).magField()); + Pair->SetMagField2((tracks[iii]->singleCollSel()).magField()); + + registry.fill(HIST("DoubleTrackEffects"), Pair->GetPhiStarDiff(_radiusTPC), Pair->GetEtaDiff()); + Pair->ResetPair(); + } + } + } + + template + void fillEtaPhi(Type const& tracks1, Type const& tracks2) + { // template for particles from the same collision non-identical + for (auto ii : tracks1) { + for (auto iii : tracks2) { + + Pair->SetPair(ii, iii); + Pair->SetMagField1((ii->singleCollSel()).magField()); + Pair->SetMagField2((iii->singleCollSel()).magField()); + + registry.fill(HIST("DoubleTrackEffects"), Pair->GetPhiStarDiff(_radiusTPC), Pair->GetEtaDiff()); + Pair->ResetPair(); + } + } + } + + template + void fillResMatrix(Type const& tracks1, Type const& tracks2) + { // template for ME + for (auto ii : tracks1) { + for (auto iii : tracks2) { + Pair->SetPair(ii, iii); + + TLorentzVector first4momentumGen; + first4momentumGen.SetPtEtaPhiM(ii->pt_MC(), ii->eta_MC(), ii->phi_MC(), particle_mass(_particlePDG_1)); + TLorentzVector second4momentumGen; + second4momentumGen.SetPtEtaPhiM(iii->pt_MC(), iii->eta_MC(), iii->phi_MC(), particle_mass(_particlePDG_2)); + + registry.fill(HIST("ResolutionMatrix"), o2::aod::singletrackselector::GetKstarFrom4vectors(first4momentumGen, second4momentumGen, IsIdentical), Pair->GetKstar()); + Pair->ResetPair(); + } + } + } + + void process(soa::Filtered const& collisions, soa::Filtered const& tracks) + { + if (_particlePDG_1 == 0 || _particlePDG_2 == 0) + LOGF(fatal, "One of passed PDG is 0!!!"); + + int trackPDG, trackOrigin; + + for (auto track : tracks) { + if (abs(track.singleCollSel().posZ()) > _vertexZ) + continue; + if (track.tpcNClsShared() > _tpcNClsShared || track.itsNCls() < _itsNCls) + continue; + + if (track.sign() == _sign_1 && (track.p() < _PIDtrshld_1 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_1) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_1))) { + trackOrigin = track.origin(); + switch (trackOrigin) { + case 0: + registry.fill(HIST("FirstParticle/dcaxyz_vs_pt_primary"), track.pt(), track.dcaXY(), track.dcaZ()); + break; + case 1: + registry.fill(HIST("FirstParticle/dcaxyz_vs_pt_weakdecay"), track.pt(), track.dcaXY(), track.dcaZ()); + break; + case 2: + registry.fill(HIST("FirstParticle/dcaxyz_vs_pt_material"), track.pt(), track.dcaXY(), track.dcaZ()); + break; + } + if (abs(track.dcaXY()) > _dcaXY || abs(track.dcaZ()) > _dcaZ) + continue; + + selectedtracks_1[track.singleCollSelId()].push_back(std::make_shared(track)); // filling the map: eventID <-> selected particles1 + + trackPDG = abs(track.pdgCode()); + + registry.fill(HIST("FirstParticle/3dmomentumAll"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraAll"), track.pt_MC()); + + switch (trackPDG) { + case 11: + registry.fill(HIST("FirstParticle/3dmomentumEl"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraEl"), track.pt_MC()); + break; + case 13: + registry.fill(HIST("FirstParticle/3dmomentumMu"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraMu"), track.pt_MC()); + break; + case 211: + registry.fill(HIST("FirstParticle/3dmomentumPi"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraPi"), track.pt_MC()); + break; + case 321: + registry.fill(HIST("FirstParticle/3dmomentumKa"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraKa"), track.pt_MC()); + break; + case 2212: + registry.fill(HIST("FirstParticle/3dmomentumPr"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraPr"), track.pt_MC()); + break; + case 1000010020: + registry.fill(HIST("FirstParticle/3dmomentumDe"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("FirstParticle/PtSpectraDe"), track.pt_MC()); + break; + } + } + + if (IsIdentical) { + continue; + } else if (track.sign() != _sign_2 && !TOFselection(track, std::make_pair(_particlePDGtoReject, _rejectWithinNsigmaTOF)) && (track.p() < _PIDtrshld_2 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_2) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_2))) { // filling the map: eventID <-> selected particles2 if (see condition above ^) + trackOrigin = track.origin(); + switch (trackOrigin) { + case 0: + registry.fill(HIST("SecondParticle/dcaxyz_vs_pt_primary"), track.pt(), track.dcaXY(), track.dcaZ()); + break; + case 1: + registry.fill(HIST("SecondParticle/dcaxyz_vs_pt_weakdecay"), track.pt(), track.dcaXY(), track.dcaZ()); + break; + case 2: + registry.fill(HIST("SecondParticle/dcaxyz_vs_pt_material"), track.pt(), track.dcaXY(), track.dcaZ()); + break; + } + if (abs(track.dcaXY()) > _dcaXY || abs(track.dcaZ()) > _dcaZ) + continue; + + selectedtracks_2[track.singleCollSelId()].push_back(std::make_shared(track)); // filling the map: eventID <-> selected particles2 + + trackPDG = abs(track.pdgCode()); + + registry.fill(HIST("SecondParticle/3dmomentumAll"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraAll"), track.pt_MC()); + + switch (trackPDG) { + case 11: + registry.fill(HIST("SecondParticle/3dmomentumEl"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraEl"), track.pt_MC()); + break; + case 13: + registry.fill(HIST("SecondParticle/3dmomentumMu"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraMu"), track.pt_MC()); + break; + case 211: + registry.fill(HIST("SecondParticle/3dmomentumPi"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraPi"), track.pt_MC()); + break; + case 321: + registry.fill(HIST("SecondParticle/3dmomentumKa"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraKa"), track.pt_MC()); + break; + case 2212: + registry.fill(HIST("SecondParticle/3dmomentumPr"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraPr"), track.pt_MC()); + break; + case 1000010020: + registry.fill(HIST("SecondParticle/3dmomentumDe"), track.px_MC(), track.py_MC(), track.pz_MC()); + registry.fill(HIST("SecondParticle/PtSpectraDe"), track.pt_MC()); + break; + } + } + } + + //====================================== filling deta(dphi*) & res. matrix starts here ====================================== + + if (IsIdentical) { //====================================== identical ====================================== + + for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) { // iterating over all selected collisions with selected tracks + fillEtaPhi(i->second); // filling deta(dphi*) -- SE identical + auto j = i; + + for (++j; j != selectedtracks_1.end(); j++) { // nested loop to do all the ME identical combinations + fillResMatrix(i->second, j->second); // filling res. matrix -- ME identical + } + } + } else { //====================================== non-identical ====================================== + + for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) { // iterating over all selected collisions with selected tracks1 + auto ii = selectedtracks_2.find(i->first); + if (ii != selectedtracks_2.end()) + fillEtaPhi(i->second, ii->second); // checking if there are tracks2 for the choosen collision and filling deta(dphi*) -- SE non-identical + + for (auto j = selectedtracks_2.begin(); j != selectedtracks_2.end(); j++) { // nested loop to do all the ME non-identical combinations + fillResMatrix(i->second, j->second); // filling res. matrix -- ME non-identical + } + } + } //====================================== end of mixing non-identical ====================================== + + // clearing up + for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) + (i->second).clear(); + selectedtracks_1.clear(); + + if (!IsIdentical) { + for (auto i = selectedtracks_2.begin(); i != selectedtracks_2.end(); i++) + (i->second).clear(); + selectedtracks_2.clear(); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGCF/Femto3D/Tasks/femto3dQA.cxx b/PWGCF/Femto3D/Tasks/femto3dQA.cxx new file mode 100755 index 00000000000..d652d4d0d3f --- /dev/null +++ b/PWGCF/Femto3D/Tasks/femto3dQA.cxx @@ -0,0 +1,221 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \brief Femto3D QA task +/// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio +/// \since 31 May 2023 + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include +#include + +#include "Framework/ASoA.h" +#include "MathUtils/Utils.h" +#include "Framework/DataTypes.h" +#include "Common/DataModel/Multiplicity.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/Expressions.h" + +#include "Framework/StaticFor.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct QAHistograms { + // using allinfo = soa::Join; // aod::pidTPCPr + /// Construct a registry object with direct declaration + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable _sign{"sign", 1, "sign of a track"}; + Configurable _vertexZ{"VertexZ", 10.0, "abs vertexZ value limit"}; + Configurable _min_P{"min_P", 0.0, "lower mometum limit"}; + Configurable _max_P{"max_P", 100.0, "upper mometum limit"}; + Configurable _eta{"eta", 100.0, "abs eta value limit"}; + Configurable _dcaXY{"dcaXY", 10.0, "abs dcaXY value limit"}; + Configurable _dcaZ{"dcaZ", 10.0, "abs dcaZ value limit"}; + Configurable _tpcNClsFound{"minTpcNClsFound", 0, "minimum allowed number of TPC clasters"}; + Configurable _tpcChi2NCl{"tpcChi2NCl", 100.0, "upper limit for chi2 value of a fit over TPC clasters"}; + Configurable _tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0, "lower limit of TPC CrossedRows/FindableCls value"}; + Configurable _tpcNClsShared{"maxTpcNClsShared", 0, "maximum allowed number of TPC shared clasters"}; + Configurable _itsNCls{"minItsNCls", 0, "minimum allowed number of ITS clasters for a track"}; + Configurable _itsChi2NCl{"itsChi2NCl", 100.0, "upper limit for chi2 value of a fit over ITS clasters for a track"}; + Configurable _particlePDG{"particlePDG", 2212, "PDG code of a particle to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma{"tpcNSigma", std::vector{-4.0f, 4.0f}, "Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld{"PIDtrshld", 10.0, "value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma{"tofNSigma", std::vector{-4.0f, 4.0f}, "Nsigma range in TOF"}; + + Configurable _particlePDGtoReject{"particlePDGtoReject", 211, "PDG codes of perticles that will be rejected with TOF (only proton and deurton are supported now)"}; + Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for particles specified with PDG to be rejected"}; + + std::pair> TPCcuts; + std::pair> TOFcuts; + + Filter signFilter = o2::aod::singletrackselector::sign == _sign; + Filter pFilter = o2::aod::singletrackselector::p > _min_P&& o2::aod::singletrackselector::p < _max_P; + Filter etaFilter = nabs(o2::aod::singletrackselector::eta) < _eta; + + Filter tpcTrkFilter = o2::aod::singletrackselector::tpcNClsFound >= _tpcNClsFound && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcChi2NCl) < _tpcChi2NCl && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcCrossedRowsOverFindableCls) > _tpcCrossedRowsOverFindableCls; + + Filter dcaFilter = nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaXY)) < _dcaXY && + nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaZ)) < _dcaZ; + + Filter itsTrkFilter = o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedItsChi2NCl) < _itsChi2NCl; + + Filter vertexFilter = nabs(o2::aod::singletrackselector::posZ) < _vertexZ; + + void init(o2::framework::InitContext&) + { + TPCcuts = std::make_pair(_particlePDG, _tpcNSigma); + TOFcuts = std::make_pair(_particlePDG, _tofNSigma); + + registry.add("TPCSignal_nocuts", "TPC signal without cuts", kTH2F, {{{200, 0., 5.0, "#it{p}_{inner} (GeV/#it{c})"}, {1000, 0., 1000.0, "dE/dx in TPC (arbitrary units)"}}}); + registry.add("TOFSignal_nocuts", "TOF signal without cuts", kTH2F, {{{200, 0., 5.0, "#it{p} (GeV/#it{c})"}, {100, 0., 1.5, "#beta"}}}); + + registry.add("eta", "eta", kTH1F, {{200, -2.5, 2.5, "eta"}}); + registry.add("phi", "phi", kTH1F, {{200, 0., 2. * M_PI, "phi"}}); + registry.add("px", "px", kTH1F, {{100, 0., 5., "px"}}); + registry.add("py", "py", kTH1F, {{100, 0., 5., "py"}}); + registry.add("pz", "pz", kTH1F, {{100, 0., 5., "pz"}}); + registry.add("p", "p", kTH1F, {{100, 0., 5., "p"}}); + registry.add("pt", "pt", kTH1F, {{100, 0., 5., "pt"}}); + registry.add("sign", "sign", kTH1F, {{3, -1.5, 1.5, "sign"}}); + registry.add("dcaxy_to_p", "dcaxy_to_p", kTH2F, {{100, 0., 5.0, "p"}, {200, -1., 1., "dcaxy"}}); + registry.add("dcaxy_to_pt", "dcaxy_to_pt", kTH2F, {{100, 0., 5., "pt"}, {200, -1., 1., "dcaxy"}}); + registry.add("dcaz_to_p", "dcaz_to_p", kTH2F, {{100, 0., 5., "p"}, {200, -1., 1., "dcaz"}}); + registry.add("dcaz_to_pt", "dcaz_to_pt", kTH2F, {{100, 0., 5., "pt"}, {200, -1., 1., "dcaz"}}); + registry.add("TPCClusters", "TPCClusters", kTH1F, {{163, -0.5, 162.5, "NTPCClust"}}); + registry.add("TPCCrossedRowsOverFindableCls", "TPCCrossedRowsOverFindableCls", kTH1F, {{100, 0.0, 10.0, "NcrossedRowsOverFindable"}}); + registry.add("TPCNClsShared", "TPCNClsShared", kTH1F, {{160, -0.5, 159.5, "TPCNshared"}}); + registry.add("ITSClusters", "ITSClusters", kTH1F, {{10, -0.5, 9.5, "NITSClust"}}); + registry.add("ITSchi2", "ITSchi2", kTH1F, {{100, 0.0, 40., "ITSchi2"}}); + registry.add("TPCchi2", "TPCchi2", kTH1F, {{100, 0.0, 6., "TPCchi2"}}); + + registry.add("TPCSignal", "TPC Signal", kTH2F, {{{200, 0., 5.0, "#it{p}_{inner} (GeV/#it{c})"}, {1000, 0., 1000.0, "dE/dx in TPC (arbitrary units)"}}}); + registry.add("TOFSignal", "TOF Signal", kTH2F, {{200, 0., 5.0, "#it{p} (GeV/#it{c})"}, {100, 0., 1.5, "#beta"}}); + + switch (_particlePDG) { + case 211: + registry.add("nsigmaTOFPi", "nsigmaTOFPi", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + registry.add("nsigmaTPCPi", "nsigmaTPCPi", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + break; + case 321: + registry.add("nsigmaTOFKa", "nsigmaTOFKa", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + registry.add("nsigmaTPCKa", "nsigmaTPCKa", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + break; + case 2212: + registry.add("nsigmaTOFPr", "nsigmaTOFPr", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + registry.add("nsigmaTPCPr", "nsigmaTPCPr", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + break; + case 1000010020: + registry.add("nsigmaTOFDe", "nsigmaTOFDe", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + registry.add("nsigmaTPCDe", "nsigmaTPCDe", kTH2F, {{100, 0., 5.}, {100, -10., 10.}}); + break; + default: + break; + } + + registry.add("posZ", "posZ", kTH1F, {{300, -16., 16., "posZ"}}); + registry.add("mult", "mult", kTH1F, {{500, 0., 500., "mult"}}); + } + + template + void fillHistograms(ColsType const& collisions, TracksType const& tracks) + { + for (auto& collision : collisions) { + registry.fill(HIST("posZ"), collision.posZ()); + registry.fill(HIST("mult"), collision.mult()); + } + + for (auto& track : tracks) { + if (abs(track.singleCollSel().posZ()) > _vertexZ) + continue; + if ((track.tpcNClsShared()) > _tpcNClsShared || (track.itsNCls()) < _itsNCls) + continue; + + if constexpr (FillExtra) { + registry.fill(HIST("TPCSignal_nocuts"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("TOFSignal_nocuts"), track.p(), track.beta()); + } + + if (!TOFselection(track, std::make_pair(_particlePDGtoReject, _rejectWithinNsigmaTOF)) && (track.p() < _PIDtrshld ? o2::aod::singletrackselector::TPCselection(track, TPCcuts) : o2::aod::singletrackselector::TOFselection(track, TOFcuts))) { + registry.fill(HIST("eta"), track.eta()); + registry.fill(HIST("phi"), track.phi()); + registry.fill(HIST("px"), track.px()); + registry.fill(HIST("py"), track.py()); + registry.fill(HIST("pz"), track.pz()); + registry.fill(HIST("p"), track.p()); + registry.fill(HIST("pt"), track.pt()); + registry.fill(HIST("sign"), track.sign()); + registry.fill(HIST("dcaxy_to_p"), track.p(), track.dcaXY()); + registry.fill(HIST("dcaxy_to_pt"), track.pt(), track.dcaXY()); + registry.fill(HIST("dcaz_to_p"), track.p(), track.dcaZ()); + registry.fill(HIST("dcaz_to_pt"), track.pt(), track.dcaZ()); + registry.fill(HIST("TPCClusters"), track.tpcNClsFound()); + registry.fill(HIST("TPCCrossedRowsOverFindableCls"), track.tpcCrossedRowsOverFindableCls()); + registry.fill(HIST("TPCNClsShared"), track.tpcNClsShared()); + registry.fill(HIST("ITSClusters"), track.itsNCls()); + registry.fill(HIST("ITSchi2"), track.itsChi2NCl()); + registry.fill(HIST("TPCchi2"), track.tpcChi2NCl()); + + switch (_particlePDG) { + case 211: + registry.fill(HIST("nsigmaTOFPi"), track.p(), track.tofNSigmaPi()); + registry.fill(HIST("nsigmaTPCPi"), track.p(), track.tpcNSigmaPi()); + break; + case 321: + registry.fill(HIST("nsigmaTOFKa"), track.p(), track.tofNSigmaKa()); + registry.fill(HIST("nsigmaTPCKa"), track.p(), track.tpcNSigmaKa()); + break; + case 2212: + registry.fill(HIST("nsigmaTOFPr"), track.p(), track.tofNSigmaPr()); + registry.fill(HIST("nsigmaTPCPr"), track.p(), track.tpcNSigmaPr()); + break; + case 1000010020: + registry.fill(HIST("nsigmaTOFDe"), track.p(), track.tofNSigmaDe()); + registry.fill(HIST("nsigmaTPCDe"), track.p(), track.tpcNSigmaDe()); + break; + default: + break; + } + + if constexpr (FillExtra) { + registry.fill(HIST("TPCSignal"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("TOFSignal"), track.p(), track.beta()); + } + } + } + } + + void processDefault(soa::Filtered const& collisions, soa::Filtered const& tracks) + { + fillHistograms(collisions, tracks); + } + PROCESS_SWITCH(QAHistograms, processDefault, "process default", true); + + void processExtra(soa::Filtered const& collisions, soa::Filtered> const& tracks) + { + fillHistograms(collisions, tracks); + } + PROCESS_SWITCH(QAHistograms, processExtra, "process extra", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From b7ea22ed2f8108da1069fc73bfd024de8a040221 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Fri, 22 Dec 2023 19:07:16 +0100 Subject: [PATCH 115/156] V0fCCov cursor fill fix (#4228) * V0fCCov cursor fill fix * Small bugfix * Please consider the following formatting changes (#204) * MegaLinter fixes (#205) Co-authored-by: ddobrigk --------- Co-authored-by: ALICE Builder --- PWGLF/TableProducer/lambdakzerobuilder.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/PWGLF/TableProducer/lambdakzerobuilder.cxx b/PWGLF/TableProducer/lambdakzerobuilder.cxx index e89ec13ed76..07d239f0c0b 100644 --- a/PWGLF/TableProducer/lambdakzerobuilder.cxx +++ b/PWGLF/TableProducer/lambdakzerobuilder.cxx @@ -845,7 +845,13 @@ struct lambdakzeroBuilder { for (int i = 0; i < 6; i++) { momentumCovariance[i] = covTpositive[MomInd[i]] + covTnegative[MomInd[i]]; } - v0covs(positionCovariance, momentumCovariance); + if (V0.v0Type() > 0) { + if (V0.v0Type() > 1 && !storePhotonCandidates) + continue; + v0covs(positionCovariance, momentumCovariance); + } else { + v0fccovs(positionCovariance, momentumCovariance); + } } } // En masse histo filling at end of process call From 1b8043c6e8018f83a077e71dbb7d01eff4452576 Mon Sep 17 00:00:00 2001 From: jaimenorman Date: Sun, 24 Dec 2023 11:40:43 +0000 Subject: [PATCH 116/156] PWGJE: add weighted track and number of collisions option (#4179) * add weighted track and number of collisions options to QA tasks * fix exponent in weighting --- PWGJE/Tasks/jetfinderQA.cxx | 52 +++++++++++++++++++------- PWGJE/Tasks/jetfinderfullQA.cxx | 66 ++++++++++++++++++++++----------- PWGJE/Tasks/jetfinderhfQA.cxx | 51 ++++++++++++++++++------- 3 files changed, 120 insertions(+), 49 deletions(-) diff --git a/PWGJE/Tasks/jetfinderQA.cxx b/PWGJE/Tasks/jetfinderQA.cxx index 5d8aa9d7be7..b9792d1287a 100644 --- a/PWGJE/Tasks/jetfinderQA.cxx +++ b/PWGJE/Tasks/jetfinderQA.cxx @@ -54,7 +54,7 @@ struct JetFinderQATask { Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; - Configurable pTHatExponent{"pTHatExponent", 0.1666, "exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; std::vector filledJetR; std::vector jetRadiiValues; @@ -158,11 +158,15 @@ struct JetFinderQATask { registry.add("h3_jet_r_jet_pt_track_eta_Triggered_Both", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi_Triggered_Both", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); } - if (doprocessTracks) { + + if (doprocessTracks || doprocessTracksWeighted) { registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h_track_pt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_track_eta", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_track_phi", "track #varphi;#varphi_{track};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + if (doprocessTracksWeighted) { + registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + } } if (doprocessMCCollisionsWeighted) { @@ -180,7 +184,7 @@ struct JetFinderQATask { void fillHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jet.pt() > pTHatMaxMCD * pTHat) { return; } @@ -210,7 +214,7 @@ struct JetFinderQATask { void fillMCPHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jet.pt() > pTHatMaxMCP * pTHat) { return; } @@ -238,7 +242,7 @@ struct JetFinderQATask { template void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (mcdjet.pt() > pTHatMaxMCD * pTHat) { return; } @@ -265,6 +269,18 @@ struct JetFinderQATask { } } + void fillTrackHistograms(soa::Filtered const& tracks, float weight = 1.0) + { + for (auto const& track : tracks) { + if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { + continue; + } + registry.fill(HIST("h_track_pt"), track.pt(), weight); + registry.fill(HIST("h_track_eta"), track.eta(), weight); + registry.fill(HIST("h_track_phi"), track.phi(), weight); + } + } + void processJetsData(soa::Join::iterator const& jet, JetTracks const& tracks) { fillHistograms(jet); @@ -452,22 +468,30 @@ struct JetFinderQATask { void processTracks(aod::JCollision const& collision, soa::Filtered const& tracks) { - registry.fill(HIST("h_collisions"), 0.5); if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); - for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { - continue; - } - registry.fill(HIST("h_track_pt"), track.pt()); - registry.fill(HIST("h_track_eta"), track.eta()); - registry.fill(HIST("h_track_phi"), track.phi()); - } + fillTrackHistograms(tracks); } PROCESS_SWITCH(JetFinderQATask, processTracks, "QA for charged tracks", false); + + void processTracksWeighted(soa::Join::iterator const& collision, + aod::JMcCollisions const& mcCollisions, + soa::Filtered const& tracks) + { + float eventWeight = collision.mcCollision().weight(); + registry.fill(HIST("h_collisions"), 0.5); + registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); + if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + return; + } + registry.fill(HIST("h_collisions"), 1.5); + registry.fill(HIST("h_collisions_weighted"), 1.5, eventWeight); + fillTrackHistograms(tracks, eventWeight); + } + PROCESS_SWITCH(JetFinderQATask, processTracksWeighted, "QA for charged tracks weighted", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"jet-finder-charged-qa"})}; } diff --git a/PWGJE/Tasks/jetfinderfullQA.cxx b/PWGJE/Tasks/jetfinderfullQA.cxx index be3eb984981..78f854107ca 100644 --- a/PWGJE/Tasks/jetfinderfullQA.cxx +++ b/PWGJE/Tasks/jetfinderfullQA.cxx @@ -63,7 +63,7 @@ struct JetFinderFullQATask { Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; - Configurable pTHatExponent{"pTHatExponent", 0.1666, "exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; std::vector filledJetR; std::vector jetRadiiValues; @@ -138,7 +138,7 @@ struct JetFinderFullQATask { registry.add("h3_jet_pt_part_jet_ntracks_part_jet_ntracks", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); N_{jet tracks}^{part}; N_{jet tracks}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); } - if (doprocessTracks) { + if (doprocessTracks || doprocessTracksWeighted) { registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h_track_pt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_track_eta", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); @@ -147,6 +147,9 @@ struct JetFinderFullQATask { registry.add("h_cluster_eta", "cluster #eta;#eta_{cluster};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_cluster_phi", "cluster #varphi;#varphi_{cluster};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); registry.add("h_cluster_energy", "cluster E;E_{cluster} (GeV);entries", {HistType::kTH1F, {{200, 0., 200.}}}); + if (doprocessTracksWeighted) { + registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + } } if (doprocessMCCollisionsWeighted) { @@ -176,7 +179,7 @@ struct JetFinderFullQATask { void fillHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jet.pt() > pTHatMaxMCD * pTHat) { return; } @@ -216,7 +219,7 @@ struct JetFinderFullQATask { void fillMCPHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jet.pt() > pTHatMaxMCP * pTHat) { return; } @@ -245,7 +248,7 @@ struct JetFinderFullQATask { void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (mcdjet.pt() > pTHatMaxMCD * pTHat) { return; } @@ -272,6 +275,25 @@ struct JetFinderFullQATask { } } + void fillTrackHistograms(soa::Filtered const& tracks, soa::Filtered const& clusters, float weight = 1.0) + { + for (auto const& track : tracks) { + if (!JetDerivedDataUtilities::selectTrack(track, trackSelection) || !JetDerivedDataUtilities::applyTrackKinematics(track, trackPtMin, trackPtMax, trackEtaMin, trackEtaMax)) { + continue; + } + registry.fill(HIST("h_track_pt"), track.pt(), weight); + registry.fill(HIST("h_track_eta"), track.eta(), weight); + registry.fill(HIST("h_track_phi"), track.phi(), weight); + } + for (auto const& cluster : clusters) { + double clusterpt = cluster.energy() / std::cosh(cluster.eta()); + registry.fill(HIST("h_cluster_pt"), clusterpt, weight); + registry.fill(HIST("h_cluster_eta"), cluster.eta(), weight); + registry.fill(HIST("h_cluster_phi"), cluster.phi(), weight); + registry.fill(HIST("h_cluster_energy"), cluster.energy(), weight); + } + } + void processDummy(aod::JCollisions const& collision) { } @@ -348,29 +370,31 @@ struct JetFinderFullQATask { soa::Filtered const& tracks, soa::Filtered const& clusters) { - registry.fill(HIST("h_collisions"), 0.5); if (!JetDerivedDataUtilities::eventEMCAL(collision)) { return; } registry.fill(HIST("h_collisions"), 1.5); - for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection) || !JetDerivedDataUtilities::applyTrackKinematics(track, trackPtMin, trackPtMax, trackEtaMin, trackEtaMax)) { - continue; - } - registry.fill(HIST("h_track_pt"), track.pt()); - registry.fill(HIST("h_track_eta"), track.eta()); - registry.fill(HIST("h_track_phi"), track.phi()); - } - for (auto const& cluster : clusters) { - double clusterpt = cluster.energy() / std::cosh(cluster.eta()); - registry.fill(HIST("h_cluster_pt"), clusterpt); - registry.fill(HIST("h_cluster_eta"), cluster.eta()); - registry.fill(HIST("h_cluster_phi"), cluster.phi()); - registry.fill(HIST("h_cluster_energy"), cluster.energy()); - } + fillTrackHistograms(tracks, clusters); } PROCESS_SWITCH(JetFinderFullQATask, processTracks, "QA for charged tracks", false); + + void processTracksWeighted(soa::Join::iterator const& collision, + aod::JMcCollisions const& mcCollisions, + soa::Filtered const& tracks, + soa::Filtered const& clusters) + { + float eventWeight = collision.mcCollision().weight(); + registry.fill(HIST("h_collisions"), 0.5); + registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); + if (!JetDerivedDataUtilities::eventEMCAL(collision)) { + return; + } + registry.fill(HIST("h_collisions"), 1.5); + registry.fill(HIST("h_collisions_weighted"), 1.5, eventWeight); + fillTrackHistograms(tracks, clusters, eventWeight); + } + PROCESS_SWITCH(JetFinderFullQATask, processTracksWeighted, "QA for charged tracks weighted", false); }; using JetFinderFullJetsQATask = JetFinderFullQATask; diff --git a/PWGJE/Tasks/jetfinderhfQA.cxx b/PWGJE/Tasks/jetfinderhfQA.cxx index 9ec10903cd4..1072e967b6d 100644 --- a/PWGJE/Tasks/jetfinderhfQA.cxx +++ b/PWGJE/Tasks/jetfinderhfQA.cxx @@ -60,7 +60,7 @@ struct JetFinderHFQATask { Configurable selectionFlagBplus{"selectionFlagBplus", 1, "Selection Flag for B+"}; Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; - Configurable pTHatExponent{"pTHatExponent", 0.1666, "exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; HfHelper hfHelper; std::vector filledJetR; @@ -204,11 +204,14 @@ struct JetFinderHFQATask { registry.add("h3_jet_r_jet_pt_candidate_y_Triggered_Both", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});y_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); } - if (doprocessTracks) { + if (doprocessTracks || doprocessTracksWeighted) { registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h_track_pt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_track_eta", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_track_phi", "track #varphi;#varphi_{track};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + if (doprocessTracksWeighted) { + registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + } } if (doprocessMCCollisionsWeighted) { @@ -234,7 +237,7 @@ struct JetFinderHFQATask { void fillHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jet.pt() > pTHatMaxMCD * pTHat) { return; } @@ -303,7 +306,7 @@ struct JetFinderHFQATask { void fillMCPHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jet.pt() > pTHatMaxMCP * pTHat) { return; } @@ -344,7 +347,7 @@ struct JetFinderHFQATask { void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, pTHatExponent)); + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (mcdjet.pt() > pTHatMaxMCD * pTHat) { return; } @@ -399,6 +402,18 @@ struct JetFinderHFQATask { } } + void fillTrackHistograms(soa::Filtered const& tracks, float weight = 1.0) + { + for (auto const& track : tracks) { + if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { + continue; + } + registry.fill(HIST("h_track_pt"), track.pt(), weight); + registry.fill(HIST("h_track_eta"), track.eta(), weight); + registry.fill(HIST("h_track_phi"), track.phi(), weight); + } + } + void processDummy(aod::Collisions const& collision) { } @@ -611,22 +626,30 @@ struct JetFinderHFQATask { void processTracks(aod::JCollision const& collision, soa::Filtered const& tracks) { - registry.fill(HIST("h_collisions"), 0.5); if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); - for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { - continue; - } - registry.fill(HIST("h_track_pt"), track.pt()); - registry.fill(HIST("h_track_eta"), track.eta()); - registry.fill(HIST("h_track_phi"), track.phi()); - } + fillTrackHistograms(tracks); } PROCESS_SWITCH(JetFinderHFQATask, processTracks, "QA for charged tracks", false); + + void processTracksWeighted(soa::Join::iterator const& collision, + aod::JMcCollisions const& mcCollisions, + soa::Filtered const& tracks) + { + float eventWeight = collision.mcCollision().weight(); + registry.fill(HIST("h_collisions"), 0.5); + registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); + if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + return; + } + registry.fill(HIST("h_collisions"), 1.5); + registry.fill(HIST("h_collisions_weighted"), 1.5, eventWeight); + fillTrackHistograms(tracks, eventWeight); + } + PROCESS_SWITCH(JetFinderHFQATask, processTracksWeighted, "QA for charged tracks weighted", false); }; using JetFinderD0QATask = JetFinderHFQATask, aod::D0ChargedMCDetectorLevelJets, aod::D0ChargedMCDetectorLevelJetConstituents, aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCParticleLevelJets, aod::D0ChargedMCDetectorLevelJetEventWeights, soa::Join, aod::D0ChargedMCParticleLevelJets, aod::D0ChargedMCParticleLevelJetConstituents, aod::D0ChargedMCParticleLevelJetsMatchedToD0ChargedMCDetectorLevelJets, aod::D0ChargedMCParticleLevelJetEventWeights, soa::Join>; From 78911d04f281202091653a65174c40a40afe5c71 Mon Sep 17 00:00:00 2001 From: EmilGorm <50658075+EmilGorm@users.noreply.github.com> Date: Wed, 27 Dec 2023 12:01:20 +0100 Subject: [PATCH 117/156] Fixed crash when merging (#4230) * Templated reco/gen/data processing * Templated reco/gen/data processing * MegaLinter * Update to MC generated processing * Fixed crash when merging uninitialised FlowContainer --------- Co-authored-by: Emil Gorm Nielsen --- PWGCF/GenericFramework/Core/FlowContainer.cxx | 112 +++++++++--------- .../Tasks/flowGenericFramework.cxx | 106 ++++++++--------- 2 files changed, 111 insertions(+), 107 deletions(-) diff --git a/PWGCF/GenericFramework/Core/FlowContainer.cxx b/PWGCF/GenericFramework/Core/FlowContainer.cxx index 3d27a13169d..91b42d423eb 100644 --- a/PWGCF/GenericFramework/Core/FlowContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowContainer.cxx @@ -71,8 +71,8 @@ void FlowContainer::Initialize(TObjArray* inputList, const o2::framework::AxisSp fProfRand = new TObjArray(); fProfRand->SetOwner(kTRUE); for (int i = 0; i < nRandom; i++) { - fProfRand->Add(reinterpret_cast(fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i)))); - reinterpret_cast(fProfRand->At(i))->Sumw2(); + fProfRand->Add(dynamic_cast(fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i)))); + dynamic_cast(fProfRand->At(i))->Sumw2(); } } }; @@ -96,8 +96,8 @@ void FlowContainer::Initialize(TObjArray* inputList, int nMultiBins, double Mult fProfRand = new TObjArray(); fProfRand->SetOwner(kTRUE); for (int i = 0; i < nRandom; i++) { - fProfRand->Add(reinterpret_cast(fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i)))); - reinterpret_cast(fProfRand->At(i))->Sumw2(); + fProfRand->Add(dynamic_cast(fProf->Clone(Form("%s_Rand_%i", fProf->GetName(), i)))); + dynamic_cast(fProfRand->At(i))->Sumw2(); } } }; @@ -113,7 +113,7 @@ bool FlowContainer::CreateBinsFromAxis(TAxis* inax) } void FlowContainer::SetXAxis(TAxis* inax) { - fXAxis = reinterpret_cast(inax->Clone("pTAxis")); + fXAxis = dynamic_cast(inax->Clone("pTAxis")); bool success = CreateBinsFromAxis(fXAxis); if (!success) printf("Something went wrong setting the x axis!\n"); @@ -145,7 +145,7 @@ int FlowContainer::FillProfile(const char* hname, double multi, double corr, dou fProf->Fill(multi, yin, corr, w); if (fNRandom) { double rnind = rn * fNRandom; - reinterpret_cast(fProfRand->At(static_cast(rnind)))->Fill(multi, yin, corr, w); + dynamic_cast(fProfRand->At(static_cast(rnind)))->Fill(multi, yin, corr, w); } return 0; }; @@ -183,16 +183,19 @@ void FlowContainer::OverrideProfileErrors(TProfile2D* inpf) } } } + Long64_t FlowContainer::Merge(TCollection* collist) { Long64_t nmerged = 0; FlowContainer* l_FC = 0; TIter all_FC(collist); - while ((l_FC = reinterpret_cast(all_FC()))) { + while (l_FC = dynamic_cast(all_FC())) { + if (!fProf) + continue; TProfile2D* tpro = GetProfile(); TProfile2D* spro = l_FC->GetProfile(); if (!tpro) { - fProf = reinterpret_cast(spro->Clone(spro->GetName())); + fProf = dynamic_cast(spro->Clone(spro->GetName())); fProf->SetDirectory(0); } else { tpro->Add(spro); @@ -207,15 +210,16 @@ Long64_t FlowContainer::Merge(TCollection* collist) } for (int i = 0; i < tarr->GetEntries(); i++) { if (!(fProfRand->FindObject(tarr->At(i)->GetName()))) { - fProfRand->Add(reinterpret_cast(tarr->At(i)->Clone(tarr->At(i)->GetName()))); - reinterpret_cast(fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); + fProfRand->Add(dynamic_cast(tarr->At(i)->Clone(tarr->At(i)->GetName()))); + dynamic_cast(fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); } else { - reinterpret_cast(fProfRand->FindObject(tarr->At(i)->GetName()))->Add(reinterpret_cast(tarr->At(i))); + dynamic_cast(fProfRand->FindObject(tarr->At(i)->GetName()))->Add(dynamic_cast(tarr->At(i))); } } } return nmerged; -}; +} + void FlowContainer::ReadAndMerge(const char* filelist) { FILE* flist = fopen(filelist, "r"); @@ -240,10 +244,10 @@ void FlowContainer::ReadAndMerge(const char* filelist) PickAndMerge(tf); tf->Close(); } -}; +} void FlowContainer::PickAndMerge(TFile* tfi) { - FlowContainer* lfc = reinterpret_cast(tfi->Get(this->GetName())); + FlowContainer* lfc = dynamic_cast(tfi->Get(this->GetName())); if (!lfc) { printf("Could not pick up the %s from %s\n", this->GetName(), tfi->GetName()); return; @@ -251,7 +255,7 @@ void FlowContainer::PickAndMerge(TFile* tfi) TProfile2D* spro = lfc->GetProfile(); TProfile2D* tpro = GetProfile(); if (!tpro) { - fProf = reinterpret_cast(spro->Clone(spro->GetName())); + fProf = dynamic_cast(spro->Clone(spro->GetName())); fProf->SetDirectory(0); } else { tpro->Add(spro); @@ -266,13 +270,13 @@ void FlowContainer::PickAndMerge(TFile* tfi) } for (int i = 0; i < tarr->GetEntries(); i++) { if (!(fProfRand->FindObject(tarr->At(i)->GetName()))) { - fProfRand->Add(reinterpret_cast(tarr->At(i)->Clone(tarr->At(i)->GetName()))); - reinterpret_cast(fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); + fProfRand->Add(dynamic_cast(tarr->At(i)->Clone(tarr->At(i)->GetName()))); + dynamic_cast(fProfRand->At(fProfRand->GetEntries() - 1))->SetDirectory(0); } else { - reinterpret_cast(fProfRand->FindObject(tarr->At(i)->GetName()))->Add(reinterpret_cast(tarr->At(i))); + dynamic_cast(fProfRand->FindObject(tarr->At(i)->GetName()))->Add(dynamic_cast(tarr->At(i))); } } -}; +} bool FlowContainer::OverrideBinsWithZero(int xb1, int yb1, int xb2, int yb2) { ProfileSubset* t_apf = new ProfileSubset(*fProf); @@ -281,7 +285,7 @@ bool FlowContainer::OverrideBinsWithZero(int xb1, int yb1, int xb2, int yb2) return kFALSE; } delete fProf; - fProf = reinterpret_cast(t_apf); + fProf = dynamic_cast(t_apf); return kTRUE; } bool FlowContainer::OverrideMainWithSub(int ind, bool ExcludeChosen) @@ -291,14 +295,14 @@ bool FlowContainer::OverrideMainWithSub(int ind, bool ExcludeChosen) return kFALSE; } if (!ExcludeChosen) { - TProfile2D* tarprof = reinterpret_cast(fProfRand->At(ind)); + TProfile2D* tarprof = dynamic_cast(fProfRand->At(ind)); if (!tarprof) { printf("Target random histogram does not exist.\n"); return kFALSE; } TString ts(fProf->GetName()); delete fProf; - fProf = reinterpret_cast(tarprof->Clone(ts.Data())); + fProf = dynamic_cast(tarprof->Clone(ts.Data())); return kTRUE; } else { TString ts(fProf->GetName()); @@ -307,9 +311,9 @@ bool FlowContainer::OverrideMainWithSub(int ind, bool ExcludeChosen) for (int i = 0; i < fProfRand->GetEntries(); i++) { if (i == ind) continue; - TProfile2D* tarprof = reinterpret_cast(fProfRand->At(i)); + TProfile2D* tarprof = dynamic_cast(fProfRand->At(i)); if (!fProf) - fProf = reinterpret_cast(tarprof->Clone(ts.Data())); + fProf = dynamic_cast(tarprof->Clone(ts.Data())); else fProf->Add(tarprof); } @@ -329,9 +333,9 @@ bool FlowContainer::RandomizeProfile(int nSubsets) if (!i) { TString ts(fProf->GetName()); delete fProf; - fProf = reinterpret_cast(fProfRand->At(rInd)->Clone(ts.Data())); + fProf = dynamic_cast(fProfRand->At(rInd)->Clone(ts.Data())); } else { - fProf->Add(reinterpret_cast(fProfRand->At(rInd))); + fProf->Add(dynamic_cast(fProfRand->At(rInd))); } } return kTRUE; @@ -356,7 +360,7 @@ bool FlowContainer::CreateStatisticsProfile(StatisticsType StatType, int arg) void FlowContainer::SetIDName(TString newname) { fIDName = newname; -}; +} TProfile* FlowContainer::GetCorrXXVsMulti(const char* order, int l_pti) { TProfile* retSubset = 0; @@ -370,10 +374,10 @@ TProfile* FlowContainer::GetCorrXXVsMulti(const char* order, int l_pti) printf("Could not find %s!\n", ybinlab); return 0; } - TProfile* rethist = reinterpret_cast(fProf->ProfileX("temp_prof", ybinno, ybinno)); + TProfile* rethist = dynamic_cast(fProf->ProfileX("temp_prof", ybinno, ybinno)); rethist->SetTitle(Form(";multi.;#LT#LT%s#GT#GT", order)); if (!retSubset) { - retSubset = reinterpret_cast(rethist->Clone(Form("corr_%s", order))); + retSubset = dynamic_cast(rethist->Clone(Form("corr_%s", order))); } else { retSubset->Add(rethist); } @@ -381,9 +385,9 @@ TProfile* FlowContainer::GetCorrXXVsMulti(const char* order, int l_pti) } if (fMultiRebin > 0) { TString temp_name(retSubset->GetName()); - TProfile* tempprof = reinterpret_cast(retSubset->Clone("tempProfile")); + TProfile* tempprof = dynamic_cast(retSubset->Clone("tempProfile")); delete retSubset; - retSubset = reinterpret_cast(tempprof->Rebin(fMultiRebin, temp_name.Data(), fMultiRebinEdges)); + retSubset = dynamic_cast(tempprof->Rebin(fMultiRebin, temp_name.Data(), fMultiRebinEdges)); delete tempprof; } return retSubset; @@ -413,7 +417,7 @@ TProfile* FlowContainer::GetCorrXXVsPt(const char* order, double lminmulti, doub TProfile* tempprof = rhProfSub->GetSubset(kFALSE, "tempprof", minm, maxm, fNbinsPt, fbinsPt); if (!retSubset) { TString profname = Form("%s_MultiB_%i_%i", order, minm, maxm); - retSubset = reinterpret_cast(tempprof->Clone(profname.Data())); + retSubset = dynamic_cast(tempprof->Clone(profname.Data())); } else { retSubset->Add(tempprof); } @@ -423,7 +427,7 @@ TProfile* FlowContainer::GetCorrXXVsPt(const char* order, double lminmulti, doub if (fPtRebinEdges) { TString pnbu(retSubset->GetName()); retSubset->SetName("TempName"); - TProfile* tempprof = reinterpret_cast(retSubset->Rebin(fPtRebin, pnbu.Data(), fPtRebinEdges)); + TProfile* tempprof = dynamic_cast(retSubset->Rebin(fPtRebin, pnbu.Data(), fPtRebinEdges)); delete retSubset; retSubset = tempprof; } else { @@ -445,14 +449,14 @@ TH1D* FlowContainer::ProfToHist(TProfile* inpf) } } return rethist; -}; +} TH1D* FlowContainer::GetHistCorrXXVsMulti(const char* order, int l_pti) { TProfile* tpf = GetCorrXXVsMulti(order, l_pti); TH1D* rethist = ProfToHist(tpf); delete tpf; return rethist; -}; +} TH1D* FlowContainer::GetHistCorrXXVsPt(const char* order, double lminmulti, double lmaxmulti) { TProfile* tpf = GetCorrXXVsPt(order, lminmulti, lmaxmulti); @@ -464,10 +468,10 @@ TH1D* FlowContainer::GetHistCorrXXVsPt(const char* order, double lminmulti, doub delete refflow; delete tpf; return rethist; -}; +} TH1D* FlowContainer::GetVN2(TH1D* cn2) { - TH1D* rethist = reinterpret_cast(cn2->Clone(Form("vn2_%s", cn2->GetName()))); + TH1D* rethist = dynamic_cast(cn2->Clone(Form("vn2_%s", cn2->GetName()))); rethist->Reset(); double rf2 = cn2->GetBinContent(0); double rf2e = cn2->GetBinError(0); @@ -524,14 +528,14 @@ TH1D* FlowContainer::GetVN2VsX(int n, bool onPt, double arg1, double arg2) } delete nam; return rethist; -}; +} TH1D* FlowContainer::GetCN2(TH1D* corrN2) { double rf2 = corrN2->GetBinContent(0); double rf2e = corrN2->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = reinterpret_cast(corrN2->Clone(Form("cN2_%s", corrN2->GetName()))); + TH1D* rethist = dynamic_cast(corrN2->Clone(Form("cN2_%s", corrN2->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor2v = corrN2->GetBinContent(i); @@ -547,7 +551,7 @@ TH1D* FlowContainer::GetCN2(TH1D* corrN2) rethist->SetBinError(0, 0); } return rethist; -}; +} TH1D* FlowContainer::GetCN4(TH1D* corrN4, TH1D* corrN2) { @@ -556,7 +560,7 @@ TH1D* FlowContainer::GetCN4(TH1D* corrN4, TH1D* corrN2) double rf4 = corrN4->GetBinContent(0); double rf4e = corrN4->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = reinterpret_cast(corrN4->Clone(Form("cN4_%s", corrN4->GetName()))); + TH1D* rethist = dynamic_cast(corrN4->Clone(Form("cN4_%s", corrN4->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor4v = corrN4->GetBinContent(i); @@ -578,9 +582,9 @@ TH1D* FlowContainer::GetCN4(TH1D* corrN4, TH1D* corrN2) TH1D* FlowContainer::GetCN6(TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) { - TH1D* tn2 = reinterpret_cast(corrN2->Clone(Form("tn2_%s", corrN2->GetName()))); - TH1D* tn4 = reinterpret_cast(corrN4->Clone(Form("tn4_%s", corrN4->GetName()))); - TH1D* tn6 = reinterpret_cast(corrN6->Clone(Form("tn6_%s", corrN6->GetName()))); + TH1D* tn2 = dynamic_cast(corrN2->Clone(Form("tn2_%s", corrN2->GetName()))); + TH1D* tn4 = dynamic_cast(corrN4->Clone(Form("tn4_%s", corrN4->GetName()))); + TH1D* tn6 = dynamic_cast(corrN6->Clone(Form("tn6_%s", corrN6->GetName()))); double rf2 = corrN2->GetBinContent(0); double rf2e = corrN2->GetBinError(0); @@ -589,7 +593,7 @@ TH1D* FlowContainer::GetCN6(TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) double rf6 = corrN6->GetBinContent(0); double rf6e = corrN6->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = reinterpret_cast(corrN6->Clone(Form("cN6_%s", corrN6->GetName()))); + TH1D* rethist = dynamic_cast(corrN6->Clone(Form("cN6_%s", corrN6->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor6v = corrN6->GetBinContent(i); @@ -615,10 +619,10 @@ TH1D* FlowContainer::GetCN6(TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) } TH1D* FlowContainer::GetCN8(TH1D* corrN8, TH1D* corrN6, TH1D* corrN4, TH1D* corrN2) { - TH1D* tn2 = reinterpret_cast(corrN2->Clone(Form("tn2_%s", corrN2->GetName()))); - TH1D* tn4 = reinterpret_cast(corrN4->Clone(Form("tn4_%s", corrN4->GetName()))); - TH1D* tn6 = reinterpret_cast(corrN6->Clone(Form("tn6_%s", corrN6->GetName()))); - TH1D* tn8 = reinterpret_cast(corrN8->Clone(Form("tn8_%s", corrN6->GetName()))); + TH1D* tn2 = dynamic_cast(corrN2->Clone(Form("tn2_%s", corrN2->GetName()))); + TH1D* tn4 = dynamic_cast(corrN4->Clone(Form("tn4_%s", corrN4->GetName()))); + TH1D* tn6 = dynamic_cast(corrN6->Clone(Form("tn6_%s", corrN6->GetName()))); + TH1D* tn8 = dynamic_cast(corrN8->Clone(Form("tn8_%s", corrN6->GetName()))); double rf2 = corrN2->GetBinContent(0); double rf2e = corrN2->GetBinError(0); @@ -629,7 +633,7 @@ TH1D* FlowContainer::GetCN8(TH1D* corrN8, TH1D* corrN6, TH1D* corrN4, TH1D* corr double rf8 = corrN8->GetBinContent(0); double rf8e = corrN8->GetBinError(0); bool OnPt = (rf2 != 0); - TH1D* rethist = reinterpret_cast(corrN8->Clone(Form("cN8_%s", corrN8->GetName()))); + TH1D* rethist = dynamic_cast(corrN8->Clone(Form("cN8_%s", corrN8->GetName()))); rethist->Reset(); for (int i = 1; i <= rethist->GetNbinsX(); i++) { double cor8v = corrN8->GetBinContent(i); @@ -689,7 +693,7 @@ TH1D* FlowContainer::GetCN4VsX(int n, bool onPt, double arg1, double arg2) } TH1D* FlowContainer::GetVN4(TH1D* inh) { - TH1D* rethist = reinterpret_cast(inh->Clone(Form("v24_%s", inh->GetName()))); + TH1D* rethist = dynamic_cast(inh->Clone(Form("v24_%s", inh->GetName()))); double c4 = inh->GetBinContent(0); double c4e = inh->GetBinError(0); bool OnPt = ((!c4) == 0); @@ -707,7 +711,7 @@ TH1D* FlowContainer::GetVN4(TH1D* inh) } TH1D* FlowContainer::GetVN6(TH1D* inh) { - TH1D* rethist = reinterpret_cast(inh->Clone(Form("v26_%s", inh->GetName()))); + TH1D* rethist = dynamic_cast(inh->Clone(Form("v26_%s", inh->GetName()))); double c6 = inh->GetBinContent(0); double c6e = inh->GetBinError(0); bool OnPt = ((!c6) == 0); @@ -725,7 +729,7 @@ TH1D* FlowContainer::GetVN6(TH1D* inh) } TH1D* FlowContainer::GetVN8(TH1D* inh) { - TH1D* rethist = reinterpret_cast(inh->Clone(Form("v28_%s", inh->GetName()))); + TH1D* rethist = dynamic_cast(inh->Clone(Form("v28_%s", inh->GetName()))); double c8 = inh->GetBinContent(0); double c8e = inh->GetBinError(0); bool OnPt = ((!c8) == 0); @@ -906,7 +910,7 @@ TProfile* FlowContainer::GetRefFlowProfile(const char* order, double m1, double int ybin = fProf->GetYaxis()->FindBin(l_name.Data()); TProfile* tempprof = rhSubset->GetSubset(kTRUE, "tempprof", ybin, ybin, nBins, l_bins); if (!retpf) - retpf = reinterpret_cast(tempprof->Clone("RefFlowProf")); + retpf = dynamic_cast(tempprof->Clone("RefFlowProf")); else retpf->Add(tempprof); delete tempprof; diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index a931760f326..79622a51e50 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -183,25 +183,16 @@ struct GenericFramework { fWeights->Init(true, false); } - if (doprocessGen || doprocessReco) { - if (doprocessGen) { - QAregistry.add("pt_gen", "", {HistType::kTH1D, {ptAxis}}); - QAregistry.add("phi_gen", "", {HistType::kTH1D, {phiAxis}}); - QAregistry.add("eta_gen", "", {HistType::kTH1D, {etaAxis}}); - QAregistry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); - } - if (doprocessReco) { - QAregistry.add("pt", "", {HistType::kTH1D, {ptAxis}}); - QAregistry.add("phi", "", {HistType::kTH1D, {phiAxis}}); - QAregistry.add("eta", "", {HistType::kTH1D, {etaAxis}}); - QAregistry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); - registry.add("phi_eta_vtxZ_corrected", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - } - } else { + if (doprocessGen) { + QAregistry.add("pt_gen", "", {HistType::kTH1D, {ptAxis}}); + QAregistry.add("phi_gen", "", {HistType::kTH1D, {phiAxis}}); + QAregistry.add("eta_gen", "", {HistType::kTH1D, {etaAxis}}); + QAregistry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); + } + if (doprocessReco || doprocessData || doprocessRun2) { QAregistry.add("phi", "", {HistType::kTH1D, {phiAxis}}); QAregistry.add("eta", "", {HistType::kTH1D, {etaAxis}}); QAregistry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); - QAregistry.add("pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); registry.add("phi_eta_vtxZ_corrected", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); QAregistry.add("cent_nch", "", {HistType::kTH2D, {nchAxis, centAxis}}); @@ -390,58 +381,64 @@ struct GenericFramework { inline void ProcessTrack(TrackObject const& track, const float& centrality, const float& vtxz) { float weff = 1, wacc = 1; - float pt, eta, phi; if constexpr (framework::has_type_v) { if (track.mcParticleId() < 0 || !(track.has_mcParticle())) return; auto mcParticle = track.mcParticle(); - pt = mcParticle.pt(); - eta = mcParticle.eta(); - phi = mcParticle.phi(); - if (!mcParticle.isPhysicalPrimary() || eta < etalow || eta > etaup || pt < ptlow || pt > ptup) + if (!mcParticle.isPhysicalPrimary() || mcParticle.eta() < etalow || mcParticle.eta() > etaup || mcParticle.pt() < ptlow || mcParticle.pt() > ptup) return; if (cfgFillWeights) - fWeights->Fill(phi, eta, vtxz, pt, centrality, 0); - if (!setCurrentParticleWeights(weff, wacc, phi, eta, pt, vtxz)) + fWeights->Fill(mcParticle.phi(), mcParticle.eta(), vtxz, mcParticle.pt(), centrality, 0); + if (!setCurrentParticleWeights(weff, wacc, mcParticle.phi(), mcParticle.eta(), mcParticle.pt(), vtxz)) return; - registry.fill(HIST("phi_eta_vtxZ_corrected"), phi, eta, vtxz, wacc); - QAregistry.fill(HIST("phi"), phi); - QAregistry.fill(HIST("eta"), eta); - QAregistry.fill(HIST("pt"), pt); + registry.fill(HIST("phi_eta_vtxZ_corrected"), mcParticle.phi(), mcParticle.eta(), vtxz, wacc); + if (cfgFillQA) + FillQA(mcParticle.phi(), mcParticle.eta(), mcParticle.pt(), track.dcaXY(), track.dcaZ()); + FillGFW(mcParticle.phi(), mcParticle.eta(), mcParticle.pt(), weff * wacc); } else if constexpr (framework::has_type_v) { - pt = track.pt(); - eta = track.eta(); - phi = track.phi(); - if (!track.isPhysicalPrimary() || eta < etalow || eta > etaup || pt < ptlow || pt > ptup) + if (!track.isPhysicalPrimary() || track.eta() < etalow || track.eta() > etaup || track.pt() < ptlow || track.pt() > ptup) return; - if (cfgFillQA) { - QAregistry.fill(HIST("phi_gen"), phi); - QAregistry.fill(HIST("eta_gen"), eta); - QAregistry.fill(HIST("pt_gen"), pt); - } + if (cfgFillQA) + FillQA(track.phi(), track.eta(), track.pt()); + FillGFW(track.phi(), track.eta(), track.pt(), 1.); } else { - pt = track.pt(); - eta = track.eta(); - phi = track.phi(); if (cfgFillWeights) - fWeights->Fill(phi, eta, vtxz, pt, centrality, 0); - if (!setCurrentParticleWeights(weff, wacc, phi, eta, pt, vtxz)) + fWeights->Fill(track.phi(), track.eta(), vtxz, track.pt(), centrality, 0); + if (!setCurrentParticleWeights(weff, wacc, track.phi(), track.eta(), track.pt(), vtxz)) return; - registry.fill(HIST("phi_eta_vtxZ_corrected"), phi, eta, vtxz, wacc); - if (cfgFillQA) { - QAregistry.fill(HIST("phi"), phi); - QAregistry.fill(HIST("eta"), eta); - QAregistry.fill(HIST("pt_dcaXY_dcaZ"), pt, track.dcaXY(), track.dcaZ()); - } + registry.fill(HIST("phi_eta_vtxZ_corrected"), track.phi(), track.eta(), vtxz, wacc); + if (cfgFillQA) + FillQA(track.phi(), track.eta(), track.pt(), track.dcaXY(), track.dcaZ()); + FillGFW(track.phi(), track.eta(), track.pt(), weff * wacc); } + } + + template + inline void FillGFW(T phi, T eta, T pt, float w) + { bool WithinPtPOI = (ptpoilow < pt) && (pt < ptpoiup); // within POI pT range bool WithinPtRef = (ptreflow < pt) && (pt < ptrefup); // within RF pT range if (WithinPtRef) - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 1); + fGFW->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, w, 1); if (WithinPtPOI) - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 2); + fGFW->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, w, 2); if (WithinPtPOI && WithinPtRef) - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, phi, wacc * weff, 4); + fGFW->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, w, 4); + return; + } + + template + inline void FillQA(T phi, T eta, T pt, T dcaxy = 0, T dcaz = 0) + { + if (dt == kGen) { + QAregistry.fill(HIST("phi_gen"), phi); + QAregistry.fill(HIST("eta_gen"), eta); + QAregistry.fill(HIST("pt_gen"), pt); + } else { + QAregistry.fill(HIST("phi"), phi); + QAregistry.fill(HIST("eta"), eta); + QAregistry.fill(HIST("pt_dcaXY_dcaZ"), pt, dcaxy, dcaz); + } } Filter collisionFilter = aod::collision::posZ < cfgBinning->GetVtxZmax() && aod::collision::posZ > cfgBinning->GetVtxZmin(); @@ -463,13 +460,16 @@ struct GenericFramework { } PROCESS_SWITCH(GenericFramework, processData, "Process analysis for non-derived data", true); - Filter dcaFilter = nabs(aod::track::dcaXY) < cfgDCAxy; - void processReco(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks, aod::McParticles const&) + void processReco(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks, aod::McParticles const&) { + if (!collision.sel8()) + return; const auto centrality = collision.centFT0C(); auto bc = collision.bc_as(); - if (!collision.sel8()) + if (cfgUse22sEventCut && !eventSelected(collision, tracks.size(), centrality)) return; + QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); processCollision(collision, tracks, centrality); } From f91accd258b1e6ab06077e99d653611665ed6442 Mon Sep 17 00:00:00 2001 From: basiach <74355517+basiach@users.noreply.github.com> Date: Sun, 31 Dec 2023 14:11:46 +0100 Subject: [PATCH 118/156] PWGCF: FemtoUniverse - Adding TPC TOF combined nSigma cuts to Producer (#4232) * Adding TOFbeta histograms * Revoking changes to TOFbeta histograms * Revoking changes to TOFnSigmaPr ranges * Adding TOFbeta histograms * Commenting TOF Beta histogram * Revoking changes to TOFnSigmaPr ranges * Revoking comment for adding TOF beta histograms * Adding TPC TOF nSigma cut * MegaLinter fixes --------- Co-authored-by: Barbara Chytla Co-authored-by: ALICE Action Bot --- .../TableProducer/femtoUniverseProducerTask.cxx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 1c5b2955c8e..d722a977a8f 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -122,7 +122,7 @@ struct femtoUniverseProducerTask { Configurable ConfMCTruthAnalysisWithPID{"ConfMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; Configurable> ConfMCTruthPDGCodes{"ConfMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; Configurable ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; - Configurable ConfCentFT0Max{"ConfCentFT0Max", 0.f, "Max CentFT0 value for centrality selection"}; + Configurable ConfCentFT0Max{"ConfCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; Filter CustomCollCentFilter = (aod::cent::centFT0C > ConfCentFT0Min) && (aod::cent::centFT0C < ConfCentFT0Max); @@ -162,6 +162,9 @@ struct femtoUniverseProducerTask { Configurable ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; Configurable> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; // Numbers from ~/alice/O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h //static constexpr ID Pion = 2; static constexpr ID Kaon = 3; static constexpr ID Proton = 4; static constexpr ID Deuteron = 5; + Configurable ConfTPCTOFnSigmaCutPion{"ConfTPCTOFnSigmaCutPion", 10., "TPC TOF combined NSigma cut for pions"}; + Configurable ConfTPCTOFnSigmaCutProton{"ConfTPCTOFnSigmaCutProton", 10., "TPC TOF combined NSigma cut for protons"}; + Configurable ConfTPCTOFnSigmaCutKaon{"ConfTPCTOFnSigmaCutKaon", 10., "TPC TOF combined NSigma cut for kaons"}; // TrackSelection *o2PhysicsTrackSelection; /// \todo Labeled array (see Track-Track task) @@ -620,6 +623,14 @@ struct femtoUniverseProducerTask { continue; } + if (!(ConfIsActivateV0 || ConfIsActivatePhi)) { + if (track.pt() > 0.5) { + if (!(TMath::Hypot(trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion)) < ConfTPCTOFnSigmaCutPion || TMath::Hypot(trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton)) < ConfTPCTOFnSigmaCutProton || TMath::Hypot(trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon)) < ConfTPCTOFnSigmaCutKaon)) { + continue; + } + } + } + trackCuts.fillQA(track); // the bit-wise container of the systematic variations is obtained From 4a6ced5ca8446c526547d77258c929c9c05dfa06 Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Tue, 2 Jan 2024 19:53:43 +0100 Subject: [PATCH 119/156] PWGCF: FemtoUniverse -- Fixing Delta Eta Delta Phi* cut for h-Phi correlations (#4233) * Fixing Delta Eta Delta Phi* cut for h-Phi correlations * Fixing error * Fixing errors (2) --- .../Core/FemtoUniverseDetaDphiStar.h | 48 +++++++++++++++++-- .../Tasks/femtoUniversePairTaskTrackD0.cxx | 4 +- .../Tasks/femtoUniversePairTaskTrackPhi.cxx | 4 +- .../Tasks/femtoUniversePairTaskTrackTrack.cxx | 4 +- ...emtoUniversePairTaskTrackTrackExtended.cxx | 4 +- .../femtoUniversePairTaskTrackTrackMC.cxx | 4 +- ...iversePairTaskTrackTrackMultKtExtended.cxx | 4 +- .../femtoUniversePairTaskTrackV0Extended.cxx | 4 +- 8 files changed, 65 insertions(+), 11 deletions(-) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h index cb4532079c3..4c5e728c297 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h @@ -20,6 +20,7 @@ #include #include #include +#include "TMath.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "Framework/HistogramRegistry.h" @@ -42,10 +43,12 @@ class FemtoUniverseDetaDphiStar /// Destructor virtual ~FemtoUniverseDetaDphiStar() = default; /// Initialization of the histograms and setting required values - void init(HistogramRegistry* registry, HistogramRegistry* registryQA, float ldeltaPhiMax, float ldeltaEtaMax, bool lplotForEveryRadii) + void init(HistogramRegistry* registry, HistogramRegistry* registryQA, float ldeltaPhiMax, float ldeltaEtaMax, float ldeltaphistarcut, float ldeltaetacut, bool lplotForEveryRadii) { deltaPhiMax = ldeltaPhiMax; deltaEtaMax = ldeltaEtaMax; + CutDeltaPhStar = ldeltaphistarcut; + CutDeltaEta = ldeltaetacut; plotForEveryRadii = lplotForEveryRadii; mHistogramRegistry = registry; mHistogramRegistryQA = registryQA; @@ -177,10 +180,11 @@ class FemtoUniverseDetaDphiStar auto indexOfDaughter = part2.index() - 2 + i; auto daughter = particles.begin() + indexOfDaughter; auto deta = part1.eta() - daughter.eta(); - auto dphiAvg = AveragePhiStar(part1, *daughter, i); + auto dphiAvg = CalculateDphiStar(part1, *daughter); + dphiAvg = TVector2::Phi_mpi_pi(dphiAvg); histdetadpi[i][0]->Fill(deta, dphiAvg); - if (pow(dphiAvg, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { - pass = true; + if ((fabs(dphiAvg) < CutDeltaPhStar) && (fabs(deta) < CutDeltaEta)) { + pass = true; // pair is close } else { histdetadpi[i][1]->Fill(deta, dphiAvg); } @@ -217,6 +221,8 @@ class FemtoUniverseDetaDphiStar float deltaPhiMax; float deltaEtaMax; + float CutDeltaPhStar; + float CutDeltaEta; float magfield; bool plotForEveryRadii = false; @@ -268,6 +274,40 @@ class FemtoUniverseDetaDphiStar } return dPhiAvg / num; } + + // Get particle charge from mask + template + float GetCharge(const T1& part) + { + float charge = 0; + if ((part.cut() & kSignMinusMask) == kValue0 && (part.cut() & kSignPlusMask) == kValue0) { + charge = 0; + } else if ((part.cut() & kSignPlusMask) == kSignPlusMask) { + charge = 1; + } else if ((part.cut() & kSignMinusMask) == kSignMinusMask) { + charge = -1; + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: Charge bits are set wrong!"; + } + return charge; + } + + // Calculate phi* as in https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoPairCutRadialDistance.cxx + template + double CalculateDphiStar(const T1& part1, const T2& part2) + { + float charge1 = GetCharge(part1); + float charge2 = GetCharge(part2); + float rad = 0.8; + + double deltaphiconstFD = 0.3 * 0.1 * 0.01 / 2; + // double deltaphiconstAF = 0.15; + double afsi0b = deltaphiconstFD * magfield * charge1 * rad / part1.pt(); + double afsi1b = deltaphiconstFD * magfield * charge2 * rad / part2.pt(); + + double dphis = part2.phi() - part1.phi() + TMath::ASin(afsi1b) - TMath::ASin(afsi0b); + return dphis; + } }; } /* namespace femtoUniverse */ diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index a338c9ddca2..5d49ed1abc2 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -138,6 +138,8 @@ struct femtoUniversePairTaskTrackD0 { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; FemtoUniverseFemtoContainer sameEventFemtoCont; FemtoUniverseFemtoContainer mixedEventFemtoCont; @@ -310,7 +312,7 @@ struct femtoUniversePairTaskTrackD0 { pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } vPIDTrack = ConfTrack.ConfPIDTrack.value; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index e9d8b0af0ae..b2aedbfa996 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -138,6 +138,8 @@ struct femtoUniversePairTaskTrackPhi { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.01, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.004, "Delta Eta cut for Close Pair Rejection"}; FemtoUniverseFemtoContainer sameEventFemtoCont; FemtoUniverseFemtoContainer mixedEventFemtoCont; @@ -288,7 +290,7 @@ struct femtoUniversePairTaskTrackPhi { pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } vPIDPhiCandidate = ConfPhi.ConfPIDPhi.value; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx index b2c899261f0..ba3ea87efd5 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx @@ -122,6 +122,8 @@ struct femtoUniversePairTaskTrackTrack { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; @@ -161,7 +163,7 @@ struct femtoUniversePairTaskTrackTrack { pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } vPIDPartOne = ConfPIDPartOne.value; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx index 6854b1097f0..799eb890e07 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx @@ -149,6 +149,8 @@ struct femtoUniversePairTaskTrackTrackExtended { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; @@ -312,7 +314,7 @@ struct femtoUniversePairTaskTrackTrackExtended { mixedEventCont.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } vPIDPartOne = trackonefilter.ConfPIDPartOne.value; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx index c9a8b5c2092..71a4a85c333 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx @@ -155,6 +155,8 @@ struct femtoUniversePairTaskTrackTrackMC { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; @@ -384,7 +386,7 @@ struct femtoUniversePairTaskTrackTrackMC { pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } vPIDPartOne = trackonefilter.ConfPIDPartOne.value; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index 8fe38d3e784..a264835b731 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -162,6 +162,8 @@ struct femtoUniversePairTaskTrackTrackMultKtExtended { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; Configurable cfgProcessPM{"cfgProcessPM", false, "Process particles of the opposite charge"}; Configurable cfgProcessPP{"cfgProcessPP", true, "Process particles of the same, positice charge"}; @@ -389,7 +391,7 @@ struct femtoUniversePairTaskTrackTrackMultKtExtended { pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } vPIDPartOne = trackonefilter.ConfPIDPartOne.value; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index 64a824f1cbb..0ebf2cce07c 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -97,6 +97,8 @@ struct femtoUniversePairTaskTrackV0Extended { Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; ConfigurableAxis ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; @@ -146,7 +148,7 @@ struct femtoUniversePairTaskTrackV0Extended { pairCleaner.init(&qaRegistry); if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); } } /// This function processes the same event and takes care of all the histogramming From c6a0b1f97218ca6c7ab90592eeedef10adc01a81 Mon Sep 17 00:00:00 2001 From: basiach <74355517+basiach@users.noreply.github.com> Date: Wed, 3 Jan 2024 20:16:51 +0100 Subject: [PATCH 120/156] PWGCF: FemtoUniverse - Changing TPC TOF combined cut to TOF nSigma cut (#4235) * Adding TOFbeta histograms * Revoking changes to TOFbeta histograms * Revoking changes to TOFnSigmaPr ranges * Adding TOFbeta histograms * Commenting TOF Beta histogram * Revoking changes to TOFnSigmaPr ranges * Revoking comment for adding TOF beta histograms * Changing TPC TOF combined cut to TOF nSigma cut * Changing TPC TOF combined cut to TOF nSigma cut * MegaLinter fixes --------- Co-authored-by: Barbara Chytla Co-authored-by: ALICE Action Bot --- .../TableProducer/femtoUniverseProducerTask.cxx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index d722a977a8f..2812bd46246 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -162,9 +162,8 @@ struct femtoUniverseProducerTask { Configurable ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; Configurable> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; // Numbers from ~/alice/O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h //static constexpr ID Pion = 2; static constexpr ID Kaon = 3; static constexpr ID Proton = 4; static constexpr ID Deuteron = 5; - Configurable ConfTPCTOFnSigmaCutPion{"ConfTPCTOFnSigmaCutPion", 10., "TPC TOF combined NSigma cut for pions"}; - Configurable ConfTPCTOFnSigmaCutProton{"ConfTPCTOFnSigmaCutProton", 10., "TPC TOF combined NSigma cut for protons"}; - Configurable ConfTPCTOFnSigmaCutKaon{"ConfTPCTOFnSigmaCutKaon", 10., "TPC TOF combined NSigma cut for kaons"}; + Configurable ConfTOFnSigmaCut{"ConfTOFnSigmaCut", 5., "TOF NSigma cut"}; + Configurable ConfTOFpTmin{"ConfTOFpTmin", 0.5, "TOF pT min"}; // TrackSelection *o2PhysicsTrackSelection; /// \todo Labeled array (see Track-Track task) @@ -624,10 +623,16 @@ struct femtoUniverseProducerTask { } if (!(ConfIsActivateV0 || ConfIsActivatePhi)) { - if (track.pt() > 0.5) { - if (!(TMath::Hypot(trackCuts.getNsigmaTPC(track, o2::track::PID::Pion), trackCuts.getNsigmaTOF(track, o2::track::PID::Pion)) < ConfTPCTOFnSigmaCutPion || TMath::Hypot(trackCuts.getNsigmaTPC(track, o2::track::PID::Proton), trackCuts.getNsigmaTOF(track, o2::track::PID::Proton)) < ConfTPCTOFnSigmaCutProton || TMath::Hypot(trackCuts.getNsigmaTPC(track, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(track, o2::track::PID::Kaon)) < ConfTPCTOFnSigmaCutKaon)) { + if (track.pt() > ConfTOFpTmin) { + if (!track.hasTOF()) { continue; } + std::vector tmpPids = ConfChildPIDspecies; + for (o2::track::PID pid : tmpPids) { + if (!trackCuts.getNsigmaTOF(track, pid) < ConfTOFnSigmaCut) { + continue; + } + } } } From f892519f8bd663e890e28d7f22fcdf3bb0bd4eb5 Mon Sep 17 00:00:00 2001 From: fkrizek Date: Fri, 5 Jan 2024 17:00:08 +0100 Subject: [PATCH 121/156] Histogram switches implemented (#4240) * Histogram switches implemented * Please consider the following formatting changes * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot --- PWGJE/Tasks/ChJetTriggerQATask.cxx | 203 ++++++++++++++--------------- 1 file changed, 95 insertions(+), 108 deletions(-) diff --git a/PWGJE/Tasks/ChJetTriggerQATask.cxx b/PWGJE/Tasks/ChJetTriggerQATask.cxx index 274e6cb7c69..0c918c128b5 100644 --- a/PWGJE/Tasks/ChJetTriggerQATask.cxx +++ b/PWGJE/Tasks/ChJetTriggerQATask.cxx @@ -91,79 +91,12 @@ struct ChJetTriggerQATask { Configurable bLowPtTrigger{"bLowPtTrigger", false, "charged jet low pT trigger selection"}; Configurable bHighPtTrigger{"bHighPtTrigger", false, "charged jet high pT trigger selection"}; + Configurable bAddSupplementHistosToOutput{"bAddAdditionalHistosToOutput", false, "add supplementary histos to the output"}; + Configurable bAddBigHistosToOutput{"bAddBigHistosToOutput", false, "add 3D histos to the output"}; + float fiducialVolume; // 0.9 - jetR - HistogramRegistry spectra{ - "spectra", - { - {"vertexZ", "z vertex", {HistType::kTH1F, {{400, -20., +20.}}}}, // - {"ptphiTrackInclGood", - "pT vs phi inclusive good tracks", - {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}}, // - {"ptetaTrackInclGood", - "pT vs eta inclusive good tracks", - {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}}, // - {"phietaTrackAllInclGood", - "phi vs eta all inclusive good tracks", - {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}}, // - {"phietaTrackHighPtInclGood", - "phi vs eta inclusive good tracks with pT > 10 GeV", - {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}}, // - {"ptJetChInclFidVol", - "inclusive charged jet pT in fiducial volume", - {HistType::kTH1F, {{200, 0., +200.}}}}, // - {"ptJetChInclFullVol", - "inclusive charged jet pT in full volume", - {HistType::kTH1F, {{200, 0., +200.}}}}, // - {"ptphiJetChInclFidVol", - "inclusive charged jet pT vs phi in fiducial volume", - {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}}, // - {"ptphiJetChInclFullVol", - "inclusive charged jet pT vs phi in full TPC volume", - {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}}, // - {"ptetaJetChInclFidVol", - "inclusive charged jet pT vs eta in fiducial volume", - {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}}, // - {"phietaJetChInclFidVol", - "inclusive charged jet phi vs eta in fiducial volume", - {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}}, // - {"phietaJetChInclFullVol", - "inclusive charged jet phi vs eta in full TPC volume", - {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}}, // - {"phietaJetChInclHighPtFidVol", - "inclusive charged jet phi vs eta in fiducial volume", - {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}}, // - {"phietaJetChInclHighPtFullVol", - "inclusive charged jet phi vs eta in full TPC volume", - {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}}, // - {"ptetaJetChInclFullVol", - "inclusive charged jet pT vs eta in full TPC volume", - {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}}, // - {"fLeadJetChPtVsLeadingTrack", - "inclusive charged jet pT in TPC volume", - {HistType::kTH2F, {{200, 0., +200.}, {200, 0., +200.}}}}, // - {"ptetaLeadingTrack", - "pT vs eta leading tracks", - {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}}, // - {"ptphiLeadingTrack", - "pT vs phi leading tracks", - {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}}, // - {"ptetaLeadingJet", - "pT vs eta leading jet", - {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}}, // - {"ptphiLeadingJet", - "pT vs phi leading jet", - {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}}, // - {"jetAreaFullVol", - "area of all jets in full TPC volume", - {HistType::kTH2F, {{100, 0., +100.}, {50, 0., 2.}}}}, // - {"jetAreaFidVol", - "area of all jets in fiducial volume", - {HistType::kTH2F, {{100, 0., +100.}, {50, 0., 2.}}}}, // - {"tracksThatWereNotJetConstituentsPtEtaPhi", - "PtEtaPhi of tracksThatWereNotjetConsituents in full volume", - {HistType::kTH3F, {{100, 0., +100.}, {40, -1., 1.}, {60, 0., TMath::TwoPi()}}}} // - }}; + HistogramRegistry spectra; int eventSelection = -1; int trackSelection = -1; @@ -172,6 +105,40 @@ struct ChJetTriggerQATask { fiducialVolume = static_cast(cfgTPCVolume) - static_cast(cfgJetR); eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(evSel)); trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + + // Basic histos + spectra.add("vertexZ", "z vertex", {HistType::kTH1F, {{400, -20., +20.}}}); + spectra.add("ptphiTrackInclGood", "pT vs phi inclusive good tracks", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("ptetaTrackInclGood", "pT vs eta inclusive good tracks", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); + spectra.add("ptJetChInclFidVol", "inclusive charged jet pT in fiducial volume", {HistType::kTH1F, {{200, 0., +200.}}}); + spectra.add("ptphiJetChInclFidVol", "inclusive charged jet pT vs phi in fiducial volume", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("ptphiJetChInclFullVol", "inclusive charged jet pT vs phi in full TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("ptetaJetChInclFidVol", "inclusive charged jet pT vs eta in fiducial volume", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); + spectra.add("ptetaJetChInclFullVol", "inclusive charged jet pT vs eta in full TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); + spectra.add("ptetaLeadingJetFullVol", "pT vs eta leading jet", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); + spectra.add("ptphiLeadingJetFullVol", "pT vs phi leading jet", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); + + // Supplementary plots + if (bAddSupplementHistosToOutput) { + spectra.add("ptJetChInclFullVol", "inclusive charged jet pT in full volume", {HistType::kTH1F, {{200, 0., +200.}}}); + spectra.add("phietaTrackAllInclGood", "phi vs eta all inclusive good tracks", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("phietaTrackHighPtInclGood", "phi vs eta inclusive good tracks with pT > 10 GeV", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("phietaJetChInclFidVol", "inclusive charged jet phi vs eta in fiducial volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("phietaJetChInclFullVol", "inclusive charged jet phi vs eta in full TPC volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("phietaJetChInclHighPtFidVol", "inclusive charged jet phi vs eta in fiducial volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("phietaJetChInclHighPtFullVol", "inclusive charged jet phi vs eta in full TPC volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("ptetaLeadingTrack", "pT vs eta leading tracks", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); + spectra.add("ptphiLeadingTrack", "pT vs phi leading tracks", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); + spectra.add("jetAreaFullVol", "area of all jets in full TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {50, 0., 2.}}}); + spectra.add("jetAreaFidVol", "area of all jets in fiducial volume", {HistType::kTH2F, {{100, 0., +100.}, {50, 0., 2.}}}); + } + + // 3D histogram + if (bAddBigHistosToOutput) { + spectra.add("fLeadJetChPtVsLeadingTrack", "inclusive charged jet pT in TPC volume", {HistType::kTH2F, {{200, 0., +200.}, {200, 0., +200.}}}); + spectra.add("tracksThatWereNotJetConstituentsPtEtaPhi", "PtEtaPhi of tracksThatWereNotjetConsituents in full volume", + {HistType::kTH3F, {{100, 0., +100.}, {40, -1., 1.}, {60, 0., TMath::TwoPi()}}}); + } } // declare filters on collisions @@ -217,13 +184,16 @@ struct ChJetTriggerQATask { TLorentzVector v; - for (auto& trk : tracks) { //loop over filtered tracks in full TPC volume having pT > 100 MeV + for (auto& trk : tracks) { // loop over filtered tracks in full TPC volume having pT > 100 MeV if (!JetDerivedDataUtilities::selectTrack(trk, trackSelection)) { continue; } - v.SetPtEtaPhiM(trk.pt(), trk.eta(), trk.phi(), 0.139); - acceptedTracks.push_back(GoodTrack(v, false, trk.globalIndex())); + + if (bAddBigHistosToOutput) { + v.SetPtEtaPhiM(trk.pt(), trk.eta(), trk.phi(), 0.139); + acceptedTracks.push_back(GoodTrack(v, false, trk.globalIndex())); + } spectra.fill( HIST("ptphiTrackInclGood"), trk.pt(), @@ -232,14 +202,16 @@ struct ChJetTriggerQATask { HIST("ptetaTrackInclGood"), trk.pt(), trk.eta()); // Inclusive Track pT vs eta spectrum in TPC volume - spectra.fill( - HIST("phietaTrackAllInclGood"), trk.eta(), - trk.phi()); // Inclusive Track pT vs eta spectrum in TPC volume - - if (trk.pt() > 5.0) { + if (bAddSupplementHistosToOutput) { spectra.fill( - HIST("phietaTrackHighPtInclGood"), trk.eta(), + HIST("phietaTrackAllInclGood"), trk.eta(), trk.phi()); // Inclusive Track pT vs eta spectrum in TPC volume + + if (trk.pt() > 5.0) { + spectra.fill( + HIST("phietaTrackHighPtInclGood"), trk.eta(), + trk.phi()); // Inclusive Track pT vs eta spectrum in TPC volume + } } if (trk.pt() > @@ -250,11 +222,13 @@ struct ChJetTriggerQATask { } } - if (leadingTrackPt > -1.) { - spectra.fill(HIST("ptphiLeadingTrack"), leadingTrackPt, - leadingTrackPhi); - spectra.fill(HIST("ptetaLeadingTrack"), leadingTrackPt, - leadingTrackEta); + if (bAddSupplementHistosToOutput) { + if (leadingTrackPt > -1.) { + spectra.fill(HIST("ptphiLeadingTrack"), leadingTrackPt, + leadingTrackPhi); + spectra.fill(HIST("ptetaLeadingTrack"), leadingTrackPt, + leadingTrackEta); + } } // Find leading jet pT in full TPC volume @@ -268,32 +242,38 @@ struct ChJetTriggerQATask { } // access jet constituents as tracks - for (auto& jct : jet.tracks_as()) { - for (UInt_t itr = 0; itr < acceptedTracks.size(); itr++) { - if (acceptedTracks[itr].globalIndex == jct.globalIndex()) { - - acceptedTracks[itr].isJetConstituent = true; // initialization - break; + if (bAddBigHistosToOutput) { + for (auto& jct : jet.tracks_as()) { + for (UInt_t itr = 0; itr < acceptedTracks.size(); itr++) { + if (acceptedTracks[itr].globalIndex == jct.globalIndex()) { + + acceptedTracks[itr].isJetConstituent = true; // initialization + break; + } } } } } } - for (UInt_t itr = 0; itr < acceptedTracks.size(); itr++) { - if (!acceptedTracks[itr].isJetConstituent) { - spectra.fill(HIST("tracksThatWereNotJetConstituentsPtEtaPhi"), acceptedTracks[itr].lv.Pt(), acceptedTracks[itr].lv.Eta(), TVector2::Phi_0_2pi(acceptedTracks[itr].lv.Phi())); + if (bAddBigHistosToOutput) { + for (UInt_t itr = 0; itr < acceptedTracks.size(); itr++) { + if (!acceptedTracks[itr].isJetConstituent) { + spectra.fill(HIST("tracksThatWereNotJetConstituentsPtEtaPhi"), acceptedTracks[itr].lv.Pt(), acceptedTracks[itr].lv.Eta(), TVector2::Phi_0_2pi(acceptedTracks[itr].lv.Phi())); + } } } if (leadingJetPt > -1.) { - spectra.fill(HIST("ptphiLeadingJet"), leadingJetPt, leadingJetPhi); - spectra.fill(HIST("ptetaLeadingJet"), leadingJetPt, leadingJetEta); + spectra.fill(HIST("ptphiLeadingJetFullVol"), leadingJetPt, leadingJetPhi); + spectra.fill(HIST("ptetaLeadingJetFullVol"), leadingJetPt, leadingJetEta); } - if (leadingJetPt > -1. && leadingTrackPt > -1.) { - spectra.fill(HIST("fLeadJetChPtVsLeadingTrack"), leadingTrackPt, - leadingJetPt); // leading jet pT versus leading track pT + if (bAddBigHistosToOutput) { + if (leadingJetPt > -1. && leadingTrackPt > -1.) { + spectra.fill(HIST("fLeadJetChPtVsLeadingTrack"), leadingTrackPt, + leadingJetPt); // leading jet pT versus leading track pT + } } // Inclusive Jet pT spectrum in Fiducial volume @@ -302,22 +282,29 @@ struct ChJetTriggerQATask { spectra.fill(HIST("ptJetChInclFidVol"), jet.pt()); spectra.fill(HIST("ptphiJetChInclFidVol"), jet.pt(), jet.phi()); spectra.fill(HIST("ptetaJetChInclFidVol"), jet.pt(), jet.eta()); - spectra.fill(HIST("phietaJetChInclFidVol"), jet.eta(), jet.phi()); - if (jet.pt() > 10.0) { - spectra.fill(HIST("phietaJetChInclHighPtFidVol"), jet.eta(), jet.phi()); + + if (bAddSupplementHistosToOutput) { + spectra.fill(HIST("phietaJetChInclFidVol"), jet.eta(), jet.phi()); + if (jet.pt() > 10.0) { + spectra.fill(HIST("phietaJetChInclHighPtFidVol"), jet.eta(), jet.phi()); + } + spectra.fill(HIST("jetAreaFidVol"), jet.pt(), jet.area()); } - spectra.fill(HIST("jetAreaFidVol"), jet.pt(), jet.area()); } if (fabs(jet.eta()) < static_cast(cfgTPCVolume)) { - spectra.fill(HIST("ptJetChInclFullVol"), jet.pt()); spectra.fill(HIST("ptphiJetChInclFullVol"), jet.pt(), jet.phi()); spectra.fill(HIST("ptetaJetChInclFullVol"), jet.pt(), jet.eta()); - spectra.fill(HIST("phietaJetChInclFullVol"), jet.eta(), jet.phi()); - if (jet.pt() > 10.0) { - spectra.fill(HIST("phietaJetChInclHighPtFullVol"), jet.eta(), jet.phi()); + + if (bAddSupplementHistosToOutput) { + spectra.fill(HIST("ptJetChInclFullVol"), jet.pt()); + + spectra.fill(HIST("phietaJetChInclFullVol"), jet.eta(), jet.phi()); + if (jet.pt() > 10.0) { + spectra.fill(HIST("phietaJetChInclHighPtFullVol"), jet.eta(), jet.phi()); + } + spectra.fill(HIST("jetAreaFullVol"), jet.pt(), jet.area()); } - spectra.fill(HIST("jetAreaFullVol"), jet.pt(), jet.area()); } } } From e506a5287797249e3cd6b9fe3971b58adcaeb250 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Fri, 5 Jan 2024 18:44:08 +0100 Subject: [PATCH 122/156] [PWGLF] Strangeness TOF PID updates (#4241) * Strangeness TOF PID updates * Add stamps, fixes * Please consider the following formatting changes (#209) * Bugfixes * Please consider the following formatting changes (#210) --------- Co-authored-by: David Dobrigkeit Chinellato Co-authored-by: ALICE Builder --- PWGLF/DataModel/LFStrangenessPIDTables.h | 71 +++---- PWGLF/DataModel/LFStrangenessTables.h | 2 + PWGLF/TableProducer/cascadepid.cxx | 16 +- PWGLF/TableProducer/lambdakzeropid.cxx | 186 ++++++++++++------ PWGLF/TableProducer/strangederivedbuilder.cxx | 68 +++++-- 5 files changed, 216 insertions(+), 127 deletions(-) diff --git a/PWGLF/DataModel/LFStrangenessPIDTables.h b/PWGLF/DataModel/LFStrangenessPIDTables.h index af9dd2e44db..ab8e0ccd37b 100644 --- a/PWGLF/DataModel/LFStrangenessPIDTables.h +++ b/PWGLF/DataModel/LFStrangenessPIDTables.h @@ -43,12 +43,16 @@ namespace v0data { // ==== TOF INFORMATION === // lengths as stored in the AO2D for TOF calculations -DECLARE_SOA_COLUMN(PosTOFLength, posTOFLength, float); //! positive track length -DECLARE_SOA_COLUMN(NegTOFLength, negTOFLength, float); //! negative track length -DECLARE_SOA_COLUMN(PosTOFSignal, posTOFSignal, float); //! positive track signal -DECLARE_SOA_COLUMN(NegTOFSignal, negTOFSignal, float); //! negative track signal -DECLARE_SOA_COLUMN(PosTOFEventTime, posTOFEventTime, float); //! positive track event time -DECLARE_SOA_COLUMN(NegTOFEventTime, negTOFEventTime, float); //! negative track event time +DECLARE_SOA_COLUMN(PosTOFLengthToPV, posTOFLengthToPV, float); //! positive track length to PV +DECLARE_SOA_COLUMN(NegTOFLengthToPV, negTOFLengthToPV, float); //! negative track length to PV +DECLARE_SOA_COLUMN(PosTOFSignal, posTOFSignal, float); //! positive track signal +DECLARE_SOA_COLUMN(NegTOFSignal, negTOFSignal, float); //! negative track signal +DECLARE_SOA_COLUMN(PosTOFEventTime, posTOFEventTime, float); //! positive track event time +DECLARE_SOA_COLUMN(NegTOFEventTime, negTOFEventTime, float); //! negative track event time + +// recalculated lengths +DECLARE_SOA_COLUMN(PosTOFLength, posTOFLength, float); //! positive track length, recalculated +DECLARE_SOA_COLUMN(NegTOFLength, negTOFLength, float); //! negative track length, recalculated // delta-times DECLARE_SOA_COLUMN(PosTOFDeltaTLaPi, posTOFDeltaTLaPi, float); //! positive track TOFDeltaT from pion <- lambda expectation @@ -68,13 +72,14 @@ DECLARE_SOA_COLUMN(NegNSigmaK0Pi, negNSigmaK0Pi, float); //! positive track NSig } // namespace v0data DECLARE_SOA_TABLE(V0TOFs, "AOD", "V0TOF", // raw information table (for debug, etc) - v0data::PosTOFLength, v0data::NegTOFLength, + v0data::PosTOFLengthToPV, v0data::NegTOFLengthToPV, v0data::PosTOFSignal, v0data::NegTOFSignal, - v0data::PosTOFEventTime, v0data::NegTOFEventTime, + v0data::PosTOFEventTime, v0data::NegTOFEventTime); +DECLARE_SOA_TABLE(V0TOFPIDs, "AOD", "V0TOFPID", // processed info table (for analysis) + v0data::PosTOFLength, v0data::NegTOFLength, v0data::PosTOFDeltaTLaPi, v0data::PosTOFDeltaTLaPr, v0data::NegTOFDeltaTLaPi, v0data::NegTOFDeltaTLaPr, - v0data::PosTOFDeltaTK0Pi, v0data::NegTOFDeltaTK0Pi); -DECLARE_SOA_TABLE(V0TOFPIDs, "AOD", "V0TOFPID", // nsigma table (for analysis) + v0data::PosTOFDeltaTK0Pi, v0data::NegTOFDeltaTK0Pi, v0data::PosNSigmaLaPi, v0data::PosNSigmaLaPr, v0data::NegNSigmaLaPi, v0data::NegNSigmaLaPr, v0data::PosNSigmaK0Pi, v0data::NegNSigmaK0Pi); @@ -83,15 +88,15 @@ namespace cascdata { // ==== TOF INFORMATION === // lengths as stored in the AO2D for TOF calculations -DECLARE_SOA_COLUMN(PosTOFLength, posTOFLength, float); //! positive track length -DECLARE_SOA_COLUMN(NegTOFLength, negTOFLength, float); //! negative track length -DECLARE_SOA_COLUMN(BachTOFLength, bachTOFLength, float); //! bachelor track length -DECLARE_SOA_COLUMN(PosTOFSignal, posTOFSignal, float); //! positive track signal -DECLARE_SOA_COLUMN(NegTOFSignal, negTOFSignal, float); //! negative track signal -DECLARE_SOA_COLUMN(BachTOFSignal, bachTOFSignal, float); //! bachelor track signal -DECLARE_SOA_COLUMN(PosTOFEventTime, posTOFEventTime, float); //! positive track event time -DECLARE_SOA_COLUMN(NegTOFEventTime, negTOFEventTime, float); //! negative track event time -DECLARE_SOA_COLUMN(BachTOFEventTime, bachTOFEventTime, float); //! bachelor track event time +DECLARE_SOA_COLUMN(PosTOFLengthToPV, posTOFLengthToPV, float); //! positive track length +DECLARE_SOA_COLUMN(NegTOFLengthToPV, negTOFLengthToPV, float); //! negative track length +DECLARE_SOA_COLUMN(BachTOFLengthToPV, bachTOFLengthToPV, float); //! bachelor track length +DECLARE_SOA_COLUMN(PosTOFSignal, posTOFSignal, float); //! positive track signal +DECLARE_SOA_COLUMN(NegTOFSignal, negTOFSignal, float); //! negative track signal +DECLARE_SOA_COLUMN(BachTOFSignal, bachTOFSignal, float); //! bachelor track signal +DECLARE_SOA_COLUMN(PosTOFEventTime, posTOFEventTime, float); //! positive track event time +DECLARE_SOA_COLUMN(NegTOFEventTime, negTOFEventTime, float); //! negative track event time +DECLARE_SOA_COLUMN(BachTOFEventTime, bachTOFEventTime, float); //! bachelor track event time // delta-times DECLARE_SOA_COLUMN(PosTOFDeltaTXiPi, posTOFDeltaTXiPi, float); //! positive track TOFDeltaT from pion <- lambda <- xi expectation @@ -106,29 +111,29 @@ DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float); //! negative tr DECLARE_SOA_COLUMN(BachTOFDeltaTOmPi, bachTOFDeltaTOmPi, float); //! bachelor track TOFDeltaT from pion <- omega expectation // n-sigmas -DECLARE_SOA_COLUMN(PosNSigmaXiPi, posNSigmaXiPi, float); //! positive track NSigma from pion <- lambda <- xi expectation -DECLARE_SOA_COLUMN(PosNSigmaXiPr, posNSigmaXiPr, float); //! positive track NSigma from proton <- lambda <- xi expectation -DECLARE_SOA_COLUMN(NegNSigmaXiPi, negNSigmaXiPi, float); //! negative track NSigma from pion <- lambda <- xi expectation -DECLARE_SOA_COLUMN(NegNSigmaXiPr, negNSigmaXiPr, float); //! negative track NSigma from proton <- lambda <- xi expectation -DECLARE_SOA_COLUMN(BachNSigmaXiPi, bachNSigmaXiPi, float); //! bachelor track NSigma from pion <- xi expectation -DECLARE_SOA_COLUMN(PosNSigmaOmPi, posNSigmaOmPi, float); //! positive track NSigma from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(PosNSigmaOmPr, posNSigmaOmPr, float); //! positive track NSigma from proton <- lambda <- omega expectation -DECLARE_SOA_COLUMN(NegNSigmaOmPi, negNSigmaOmPi, float); //! negative track NSigma from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(NegNSigmaOmPr, negNSigmaOmPr, float); //! negative track NSigma from proton <- lambda <- omega expectation -DECLARE_SOA_COLUMN(BachNSigmaOmKa, bachNSigmaOmKa, float); //! bachelor track NSigma from kaon <- omega expectation +DECLARE_SOA_COLUMN(PosNSigmaXiPi, posNSigmaXiPi, float); //! positive track NSigma from pion <- lambda <- xi expectation +DECLARE_SOA_COLUMN(PosNSigmaXiPr, posNSigmaXiPr, float); //! positive track NSigma from proton <- lambda <- xi expectation +DECLARE_SOA_COLUMN(NegNSigmaXiPi, negNSigmaXiPi, float); //! negative track NSigma from pion <- lambda <- xi expectation +DECLARE_SOA_COLUMN(NegNSigmaXiPr, negNSigmaXiPr, float); //! negative track NSigma from proton <- lambda <- xi expectation +DECLARE_SOA_COLUMN(BachNSigmaXiPi, bachNSigmaXiPi, float); //! bachelor track NSigma from pion <- xi expectation +DECLARE_SOA_COLUMN(PosNSigmaOmPi, posNSigmaOmPi, float); //! positive track NSigma from pion <- lambda <- omega expectation +DECLARE_SOA_COLUMN(PosNSigmaOmPr, posNSigmaOmPr, float); //! positive track NSigma from proton <- lambda <- omega expectation +DECLARE_SOA_COLUMN(NegNSigmaOmPi, negNSigmaOmPi, float); //! negative track NSigma from pion <- lambda <- omega expectation +DECLARE_SOA_COLUMN(NegNSigmaOmPr, negNSigmaOmPr, float); //! negative track NSigma from proton <- lambda <- omega expectation +DECLARE_SOA_COLUMN(BachNSigmaOmKa, bachNSigmaOmKa, float); //! bachelor track NSigma from kaon <- omega expectation } // namespace cascdata DECLARE_SOA_TABLE(CascTOFs, "AOD", "CascTOF", // raw information table (for debug, etc) - cascdata::PosTOFLength, cascdata::NegTOFLength, cascdata::BachTOFLength, + cascdata::PosTOFLengthToPV, cascdata::NegTOFLengthToPV, cascdata::BachTOFLengthToPV, cascdata::PosTOFSignal, cascdata::NegTOFSignal, cascdata::BachTOFSignal, - cascdata::PosTOFEventTime, cascdata::NegTOFEventTime, cascdata::BachTOFEventTime, + cascdata::PosTOFEventTime, cascdata::NegTOFEventTime, cascdata::BachTOFEventTime); +DECLARE_SOA_TABLE(CascTOFPIDs, "AOD", "CASCTOFPID", // processed information for analysis cascdata::PosTOFDeltaTXiPi, cascdata::PosTOFDeltaTXiPr, cascdata::NegTOFDeltaTXiPi, cascdata::NegTOFDeltaTXiPr, cascdata::BachTOFDeltaTXiPi, cascdata::PosTOFDeltaTOmPi, cascdata::PosTOFDeltaTOmPr, cascdata::NegTOFDeltaTOmPi, cascdata::NegTOFDeltaTOmPr, - cascdata::BachTOFDeltaTOmPi); -DECLARE_SOA_TABLE(CascTOFPIDs, "AOD", "CASCTOFPID", // nsigma table (for analysis) + cascdata::BachTOFDeltaTOmPi, cascdata::PosNSigmaXiPi, cascdata::PosNSigmaXiPr, cascdata::NegNSigmaXiPi, cascdata::NegNSigmaXiPr, cascdata::BachNSigmaXiPi, diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 641e500669f..d3d1ef73813 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -34,6 +34,8 @@ DECLARE_SOA_TABLE(StraEPs, "AOD", "STRAEPS", //! centrality percentiles qvec::QvecFT0CRe, qvec::QvecFT0CIm, qvec::SumAmplFT0C, qvec::QvecFT0MRe, qvec::QvecFT0MIm, qvec::SumAmplFT0M, qvec::QvecFV0ARe, qvec::QvecFV0AIm, qvec::SumAmplFV0A); +DECLARE_SOA_TABLE(StraStamps, "AOD", "STRASTAMPS", //! information for ID-ing mag field if needed + bc::RunNumber, timestamp::Timestamp); using StraCollision = StraCollisions::iterator; using StraCent = StraCents::iterator; diff --git a/PWGLF/TableProducer/cascadepid.cxx b/PWGLF/TableProducer/cascadepid.cxx index 93beff60367..eb73ff9f635 100644 --- a/PWGLF/TableProducer/cascadepid.cxx +++ b/PWGLF/TableProducer/cascadepid.cxx @@ -77,8 +77,7 @@ using LabeledTracksExtra = soa::Join; struct cascadepid { // TOF pid for strangeness (recalculated with topology) - Produces casctof; // raw table for checks - Produces casctofpid; // table with Nsigmas + Produces casctofpids; // table with Nsigmas Service ccdb; @@ -246,14 +245,11 @@ struct cascadepid { auto negTrack = cascade.negTrack_as(); // FIXME: TOF calculation: under construction, to follow - - if (fillRawPID) { - casctof(posTrack.length(), negTrack.length(), bachTrack.length(), - posTrack.tofSignal(), negTrack.tofSignal(), bachTrack.tofSignal(), - posTrack.tofEvTime(), negTrack.tofEvTime(), bachTrack.tofEvTime(), - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); - } + casctofpids(0.0f, 0.0f, + posTrack.length(), negTrack.length(), bachTrack.length(), + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); } } } diff --git a/PWGLF/TableProducer/lambdakzeropid.cxx b/PWGLF/TableProducer/lambdakzeropid.cxx index 0d353634411..626b1adc5c8 100644 --- a/PWGLF/TableProducer/lambdakzeropid.cxx +++ b/PWGLF/TableProducer/lambdakzeropid.cxx @@ -77,7 +77,6 @@ using LabeledTracksExtra = soa::Join; struct lambdakzeropid { // TOF pid for strangeness (recalculated with topology) - Produces v0tof; // raw table for checks Produces v0tofpid; // table with Nsigmas Service ccdb; @@ -89,9 +88,8 @@ struct lambdakzeropid { // Operation and minimisation criteria Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - Configurable tofPosition{"tofPosition", 370, "TOF position for tests"}; + Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; Configurable checkTPCCompatibility{"checkTPCCompatibility", true, "check compatibility with dE/dx in QA plots"}; - Configurable fillRawPID{"fillRawPID", true, "fill raw PID tables for debug/x-check"}; // CCDB options Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -110,71 +108,132 @@ struct lambdakzeropid { float maxSnp; // max sine phi for propagation float maxStep; // max step size (cm) for propagation - /// function to calculate track length of this track up to a certain radius + /// function to calculate track length of this track up to a certain segment of a detector + /// to be used internally in another funcrtion that calculates length until it finds the proper one + /// warning: this could be optimised further for speed /// \param track the input track - /// \param radius the radius of the layer you're calculating the length to + /// \param x1 x of the first point of the detector segment + /// \param y1 y of the first point of the detector segment + /// \param x2 x of the first point of the detector segment + /// \param y2 y of the first point of the detector segment /// \param magneticField the magnetic field to use when propagating - float trackLength(o2::track::TrackParCov track, float radius, float magneticField) + float trackLengthToSegment(o2::track::TrackParCov track, float x1, float y1, float x2, float y2, float magneticField) { // don't make use of the track parametrization - float length = -100; + float length = -104; + // causality protection + std::array mom; + track.getPxPyPzGlo(mom); + // get start point + std::array startPoint; + track.getXYZGlo(startPoint); + + if (((x1 + x2) * mom[0] + (y1 + y2) * mom[1]) < 0.0f) + return -101; + + // get circle X, Y please o2::math_utils::CircleXYf_t trcCircle; float sna, csa; track.getCircleParams(magneticField, trcCircle, sna, csa); - // distance between circle centers (one circle is at origin -> easy) - float centerDistance = std::hypot(trcCircle.xC, trcCircle.yC); - - // condition of circles touching - if not satisfied returned length will be -100 - if (centerDistance < trcCircle.rC + radius && centerDistance > fabs(trcCircle.rC - radius)) { - length = 0.0f; - - // base radical direction - float ux = trcCircle.xC / centerDistance; - float uy = trcCircle.yC / centerDistance; - // calculate perpendicular vector (normalized) for +/- displacement - float vx = -uy; - float vy = +ux; - // calculate coordinate for radical line - float radical = (centerDistance * centerDistance - trcCircle.rC * trcCircle.rC + radius * radius) / (2.0f * centerDistance); - // calculate absolute displacement from center-to-center axis - float displace = (0.5f / centerDistance) * TMath::Sqrt( - (-centerDistance + trcCircle.rC - radius) * - (-centerDistance - trcCircle.rC + radius) * - (-centerDistance + trcCircle.rC + radius) * - (centerDistance + trcCircle.rC + radius)); - - // possible intercept points of track and TOF layer in 2D plane - float point1[2] = {radical * ux + displace * vx, radical * uy + displace * vy}; - float point2[2] = {radical * ux - displace * vx, radical * uy - displace * vy}; - - // decide on correct intercept point - std::array mom; - track.getPxPyPzGlo(mom); - float scalarProduct1 = point1[0] * mom[0] + point1[1] * mom[1]; - float scalarProduct2 = point2[0] * mom[0] + point2[1] * mom[1]; - - // get start point - std::array startPoint; - track.getXYZGlo(startPoint); - - float cosAngle = -1000, modulus = -1000; - - if (scalarProduct1 > scalarProduct2) { - modulus = std::hypot(point1[0] - trcCircle.xC, point1[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[0] - trcCircle.yC); - } else { - modulus = std::hypot(point2[0] - trcCircle.xC, point2[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[0] - trcCircle.yC); - } - cosAngle /= modulus; - length = trcCircle.rC * TMath::ACos(cosAngle); - length *= sqrt(1.0f + track.getTgl() * track.getTgl()); + // Calculate necessary inner product + float segmentModulus = std::hypot(x2 - x1, y2 - y1); + float alongSegment = ((trcCircle.xC - x1) * (x2 - x1) + (trcCircle.yC - y1) * (y2 - y1)) / segmentModulus; + + // find point of closest approach between segment and circle center + float pcaX = (x2 - x1) * alongSegment / segmentModulus + x1; + float pcaY = (y2 - y1) * alongSegment / segmentModulus + y1; + + float centerDistToPC = std::hypot(pcaX - trcCircle.xC, pcaY - trcCircle.yC); + + // distance pca-to-intercept in multiples of segment modulus (for convenience) + if (centerDistToPC > trcCircle.rC) + return -103; + + float pcaToIntercept = TMath::Sqrt(TMath::Abs(trcCircle.rC * trcCircle.rC - centerDistToPC * centerDistToPC)); + + float interceptX1 = pcaX + (x2 - x1) / segmentModulus * pcaToIntercept; + float interceptY1 = pcaY + (y2 - y1) / segmentModulus * pcaToIntercept; + float interceptX2 = pcaX - (x2 - x1) / segmentModulus * pcaToIntercept; + float interceptY2 = pcaY - (y2 - y1) / segmentModulus * pcaToIntercept; + + float scalarCheck1 = ((x2 - x1) * (interceptX1 - x1) + (y2 - y1) * (interceptY1 - y1)) / segmentModulus; + float scalarCheck2 = ((x2 - x1) * (interceptX2 - x1) + (y2 - y1) * (interceptY2 - y1)) / segmentModulus; + + float cosAngle1 = -1000, sinAngle1 = -1000, modulus1 = -1000; + float cosAngle2 = -1000, sinAngle2 = -1000, modulus2 = -1000; + float length1 = -1000, length2 = -1000; + + modulus1 = std::hypot(interceptX1 - trcCircle.xC, interceptY1 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); + cosAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY1 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); + sinAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY1 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); + cosAngle1 /= modulus1; + sinAngle1 /= modulus1; + length1 = trcCircle.rC * TMath::ACos(cosAngle1); + length1 *= sqrt(1.0f + track.getTgl() * track.getTgl()); + + modulus2 = std::hypot(interceptX2 - trcCircle.xC, interceptY2 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); + cosAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY2 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); + sinAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY2 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); + cosAngle2 /= modulus2; + sinAngle2 /= modulus2; + length2 = trcCircle.rC * TMath::ACos(cosAngle2); + length2 *= sqrt(1.0f + track.getTgl() * track.getTgl()); + + // rotate transverse momentum vector such that it is at intercepts + float angle1 = TMath::ACos(cosAngle1); + if (sinAngle1 < 0) + angle1 *= -1.0f; + float px1 = +TMath::Cos(angle1) * mom[0] + TMath::Sin(angle1) * mom[1]; + float py1 = -TMath::Sin(angle1) * mom[0] + TMath::Cos(angle1) * mom[1]; + + float angle2 = TMath::ACos(cosAngle2); + if (sinAngle2 < 0) + angle2 *= -1.0f; + float px2 = +TMath::Cos(angle2) * mom[0] + TMath::Sin(angle2) * mom[1]; + float py2 = -TMath::Sin(angle2) * mom[0] + TMath::Cos(angle2) * mom[1]; + + float midSegX = 0.5f * (x2 + x1); + float midSegY = 0.5f * (y2 + y1); + + float scalarMomentumCheck1 = px1 * midSegX + py1 * midSegY; + float scalarMomentumCheck2 = px2 * midSegX + py2 * midSegY; + + float halfPerimeter = TMath::Pi() * trcCircle.rC; // perimeter check. Length should not pass this ever + + if (scalarCheck1 > 0.0f && scalarCheck1 < segmentModulus && length1 < halfPerimeter && scalarMomentumCheck1 > 0.0f) { + length = length1; + // X = interceptX1; Y = interceptY1; + } + if (scalarCheck2 > 0.0f && scalarCheck2 < segmentModulus && length2 < halfPerimeter && scalarMomentumCheck2 > 0.0f) { + length = length2; + // X = interceptX2; Y = interceptY2; } return length; } + /// function to calculate track length of this track up to a certain segmented detector + /// \param track the input track + /// \param magneticField the magnetic field to use when propagating + float findInterceptLength(o2::track::TrackParCov track, float magneticField) + { + for (int iSeg = 0; iSeg < 18; iSeg++) { + // Detector segmentation loop + float segmentAngle = 20.0f / 180.0f * TMath::Pi(); + float theta = static_cast(iSeg) * 20.0f / 180.0f * TMath::Pi(); + float halfWidth = tofPosition * TMath::Tan(0.5f * segmentAngle); + float x1 = TMath::Cos(theta) * (-halfWidth) + TMath::Sin(theta) * tofPosition; + float y1 = -TMath::Sin(theta) * (-halfWidth) + TMath::Cos(theta) * tofPosition; + float x2 = TMath::Cos(theta) * (+halfWidth) + TMath::Sin(theta) * tofPosition; + float y2 = -TMath::Sin(theta) * (+halfWidth) + TMath::Cos(theta) * tofPosition; + float length = trackLengthToSegment(track, x1, y1, x2, y2, magneticField); + if (length > 0) + return length; + } + return -100; // not reached / not found + } + void init(InitContext& context) { mRunNumber = 0; @@ -282,8 +341,8 @@ struct lambdakzeropid { posTrack.propagateTo(v0.posX(), d_bz); negTrack.propagateTo(v0.negX(), d_bz); - float lengthPositive = trackLength(posTrack, tofPosition, d_bz); // FIXME: tofPosition ok? adjust? - float lengthNegative = trackLength(negTrack, tofPosition, d_bz); // FIXME: tofPosition ok? adjust? + float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? + float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? float timePositivePr = lengthPositive / velocityPositivePr; float timePositivePi = lengthPositive / velocityPositivePi; float timeNegativePr = lengthNegative / velocityNegativePr; @@ -296,14 +355,11 @@ struct lambdakzeropid { deltaTimePositiveK0ShortPi = (posTrackRow.tofSignal() - posTrackRow.tofEvTime()) - (timeK0Short + timeNegativePi); deltaTimeNegativeK0ShortPi = (negTrackRow.tofSignal() - negTrackRow.tofEvTime()) - (timeK0Short + timeNegativePi); - if (fillRawPID) { - v0tof(posTrackRow.length(), negTrackRow.length(), - posTrackRow.tofSignal(), negTrackRow.tofSignal(), - posTrackRow.tofEvTime(), negTrackRow.tofEvTime(), - deltaTimePositiveLambdaPi, deltaTimePositiveLambdaPr, - deltaTimeNegativeLambdaPi, deltaTimeNegativeLambdaPr, - deltaTimePositiveK0ShortPi, deltaTimeNegativeK0ShortPi); - } + v0tofpid(lengthPositive, lengthNegative, + deltaTimePositiveLambdaPi, deltaTimePositiveLambdaPr, + deltaTimeNegativeLambdaPi, deltaTimeNegativeLambdaPr, + deltaTimePositiveK0ShortPi, deltaTimeNegativeK0ShortPi, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); // FIXME auto originalV0 = v0.v0_as(); // this could look confusing, so: // the first v0 is the v0data row; the getter de-references the v0 (stored indices) row diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index 05196d577be..ef9dc048c5d 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -52,6 +52,7 @@ using namespace o2::framework::expressions; using std::array; using TracksWithExtra = soa::Join; +using FullTracksExtIUTOF = soa::Join; // simple checkers #define bitset(var, nbit) ((var) |= (1 << (nbit))) @@ -62,6 +63,7 @@ struct strangederivedbuilder { // fundamental building blocks of derived data Produces strangeColl; // characterises collisions Produces strangeCents; // characterises collisions / centrality + Produces strangeStamps; // provides timestamps, run numbers Produces v0collref; // references collisions from V0s Produces casccollref; // references collisions from cascades Produces kfcasccollref; // references collisions from KF cascades @@ -84,9 +86,14 @@ struct strangederivedbuilder { //__________________________________________________ // mother information - Produces v0mothers; // V0 mother references - Produces cascmothers; // casc mother references - Produces motherMCParts; // mc particles for mothers + Produces v0mothers; // V0 mother references + Produces cascmothers; // casc mother references + Produces motherMCParts; // mc particles for mothers + + //__________________________________________________ + // raw TOF PID for posterior use if requested + Produces v0tofs; // V0 part + Produces casctofs; // cascade part // histogram registry for bookkeeping HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -119,8 +126,11 @@ struct strangederivedbuilder { Preslice KFCascperCollision = o2::aod::cascdata::collisionId; Preslice TraCascperCollision = o2::aod::cascdata::collisionId; + int64_t currentCollIdx; + void init(InitContext& context) { + currentCollIdx = -1; // setup map for fast checking if enabled static_for<0, nSpecies - 1>([&](auto i) { constexpr int index = i.value; @@ -135,30 +145,27 @@ struct strangederivedbuilder { histos.add(Form("hGen%s", particleNames[i].data()), Form("hGen%s", particleNames[i].data()), kTH1D, {axisPt}); } - void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s) + void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { - int currentCollIdx = -1; for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisColl = V0s.sliceBy(V0perCollision, collIdx); bool strange = V0Table_thisColl.size() > 0; // casc table sliced if (strange || fillEmptyCollisions) { - if (currentCollIdx != collIdx) { - strangeColl(collision.posX(), collision.posY(), collision.posZ()); - strangeCents(collision.centFT0M(), collision.centFT0A(), - collision.centFT0C(), collision.centFV0A()); - currentCollIdx = collIdx; - } + strangeColl(collision.posX(), collision.posY(), collision.posZ()); + strangeCents(collision.centFT0M(), collision.centFT0A(), + collision.centFT0C(), collision.centFV0A()); + auto bc = collision.bc_as(); + strangeStamps(bc.timestamp(), bc.runNumber()); } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); } } - void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades) + void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&) { - int currentCollIdx = -1; for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisColl = V0s.sliceBy(V0perCollision, collIdx); @@ -171,12 +178,11 @@ struct strangederivedbuilder { TraCascTable_thisColl.size() > 0; // casc table sliced if (strange || fillEmptyCollisions) { - if (currentCollIdx != collIdx) { - strangeColl(collision.posX(), collision.posY(), collision.posZ()); - strangeCents(collision.centFT0M(), collision.centFT0A(), - collision.centFT0C(), collision.centFV0A()); - currentCollIdx = collIdx; - } + strangeColl(collision.posX(), collision.posY(), collision.posZ()); + strangeCents(collision.centFT0M(), collision.centFT0A(), + collision.centFT0C(), collision.centFV0A()); + auto bc = collision.bc_as(); + strangeStamps(bc.timestamp(), bc.runNumber()); } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); @@ -418,6 +424,28 @@ struct strangederivedbuilder { } } + void processProduceV0TOFs(aod::Collision const& collision, aod::V0Datas const& V0s, FullTracksExtIUTOF const&) + { + for (auto const& v0 : V0s) { + auto const& posTrackRow = v0.posTrack_as(); + auto const& negTrackRow = v0.negTrack_as(); + v0tofs(posTrackRow.length(), negTrackRow.length(), + posTrackRow.tofSignal(), negTrackRow.tofSignal(), + posTrackRow.tofEvTime(), negTrackRow.tofEvTime()); + } + } + void processProduceCascTOFs(aod::Collision const& collision, aod::CascDatas const& Cascades, FullTracksExtIUTOF const&) + { + for (auto const& cascade : Cascades) { + auto const& posTrackRow = cascade.posTrack_as(); + auto const& negTrackRow = cascade.negTrack_as(); + auto const& bachTrackRow = cascade.bachelor_as(); + casctofs(posTrackRow.length(), negTrackRow.length(), bachTrackRow.length(), + posTrackRow.tofSignal(), negTrackRow.tofSignal(), bachTrackRow.tofSignal(), + posTrackRow.tofEvTime(), negTrackRow.tofEvTime(), bachTrackRow.tofEvTime()); + } + } + PROCESS_SWITCH(strangederivedbuilder, processCollisionsV0sOnly, "Produce collisions (V0s only)", true); PROCESS_SWITCH(strangederivedbuilder, processCollisions, "Produce collisions (V0s + casc)", true); PROCESS_SWITCH(strangederivedbuilder, processTrackExtrasV0sOnly, "Produce track extra information (V0s only)", true); @@ -426,6 +454,8 @@ struct strangederivedbuilder { PROCESS_SWITCH(strangederivedbuilder, processCascadeInterlinkTracked, "Produce tables interconnecting cascades", false); PROCESS_SWITCH(strangederivedbuilder, processCascadeInterlinkKF, "Produce tables interconnecting cascades", false); PROCESS_SWITCH(strangederivedbuilder, processSimulation, "Produce simulated information", true); + PROCESS_SWITCH(strangederivedbuilder, processProduceV0TOFs, "Produce V0TOFs table", true); + PROCESS_SWITCH(strangederivedbuilder, processProduceCascTOFs, "Produce CascTOFs table", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From a338787ba087ffd79cb678b5acd101a342cd6aee Mon Sep 17 00:00:00 2001 From: EmilGorm <50658075+EmilGorm@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:42:27 +0100 Subject: [PATCH 123/156] Moved QA plots from QA file to analysis file (#4243) Co-authored-by: Emil Gorm Nielsen --- .../Tasks/flowGenericFramework.cxx | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index 79622a51e50..fd67307c5c2 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -105,7 +105,6 @@ struct GenericFramework { OutputObj fFC_gen{FlowContainer("FlowContainer_gen")}; OutputObj fWeights{GFWWeights("weights")}; HistogramRegistry registry{"registry"}; - HistogramRegistry QAregistry{"QAregistry", {}, OutputObjHandlingPolicy::QAObject}; // define global variables GFW* fGFW = new GFW(); @@ -184,19 +183,19 @@ struct GenericFramework { } if (doprocessGen) { - QAregistry.add("pt_gen", "", {HistType::kTH1D, {ptAxis}}); - QAregistry.add("phi_gen", "", {HistType::kTH1D, {phiAxis}}); - QAregistry.add("eta_gen", "", {HistType::kTH1D, {etaAxis}}); - QAregistry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); + registry.add("pt_gen", "", {HistType::kTH1D, {ptAxis}}); + registry.add("phi_gen", "", {HistType::kTH1D, {phiAxis}}); + registry.add("eta_gen", "", {HistType::kTH1D, {etaAxis}}); + registry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); } if (doprocessReco || doprocessData || doprocessRun2) { - QAregistry.add("phi", "", {HistType::kTH1D, {phiAxis}}); - QAregistry.add("eta", "", {HistType::kTH1D, {etaAxis}}); - QAregistry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); - QAregistry.add("pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); + registry.add("phi", "", {HistType::kTH1D, {phiAxis}}); + registry.add("eta", "", {HistType::kTH1D, {etaAxis}}); + registry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); + registry.add("pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); registry.add("phi_eta_vtxZ_corrected", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - QAregistry.add("cent_nch", "", {HistType::kTH2D, {nchAxis, centAxis}}); - QAregistry.add("globalTracks_PVTracks", "", {HistType::kTH2D, {nchAxis, nchAxis}}); + registry.add("cent_nch", "", {HistType::kTH2D, {nchAxis, centAxis}}); + registry.add("globalTracks_PVTracks", "", {HistType::kTH2D, {nchAxis, nchAxis}}); } if (regions.GetSize() < 0) @@ -366,7 +365,7 @@ struct GenericFramework { return; float vtxz = collision.posZ(); if (cfgFillQA) - (dt == kGen) ? QAregistry.fill(HIST("vtxZ_gen"), vtxz) : QAregistry.fill(HIST("vtxZ"), vtxz); + (dt == kGen) ? registry.fill(HIST("vtxZ_gen"), vtxz) : registry.fill(HIST("vtxZ"), vtxz); fGFW->Clear(); float l_Random = fRndm->Rndm(); for (auto& track : tracks) { @@ -431,13 +430,13 @@ struct GenericFramework { inline void FillQA(T phi, T eta, T pt, T dcaxy = 0, T dcaz = 0) { if (dt == kGen) { - QAregistry.fill(HIST("phi_gen"), phi); - QAregistry.fill(HIST("eta_gen"), eta); - QAregistry.fill(HIST("pt_gen"), pt); + registry.fill(HIST("phi_gen"), phi); + registry.fill(HIST("eta_gen"), eta); + registry.fill(HIST("pt_gen"), pt); } else { - QAregistry.fill(HIST("phi"), phi); - QAregistry.fill(HIST("eta"), eta); - QAregistry.fill(HIST("pt_dcaXY_dcaZ"), pt, dcaxy, dcaz); + registry.fill(HIST("phi"), phi); + registry.fill(HIST("eta"), eta); + registry.fill(HIST("pt_dcaXY_dcaZ"), pt, dcaxy, dcaz); } } @@ -453,8 +452,8 @@ struct GenericFramework { auto bc = collision.bc_as(); if (cfgUse22sEventCut && !eventSelected(collision, tracks.size(), centrality)) return; - QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); - QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); + registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + registry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); processCollision(collision, tracks, centrality); } @@ -468,8 +467,8 @@ struct GenericFramework { auto bc = collision.bc_as(); if (cfgUse22sEventCut && !eventSelected(collision, tracks.size(), centrality)) return; - QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); - QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); + registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + registry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); processCollision(collision, tracks, centrality); } @@ -496,8 +495,8 @@ struct GenericFramework { auto bc = collision.bc_as(); if (cfgUse22sEventCut && !eventSelected(collision, tracks.size(), centrality)) return; - QAregistry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); - QAregistry.fill(HIST("cent_nch"), tracks.size(), centrality); + registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + registry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); processCollision(collision, tracks, centrality); } From 88a7673303f4eb2c152f44225be9cfb5ed2d539e Mon Sep 17 00:00:00 2001 From: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:54:56 +0100 Subject: [PATCH 124/156] PWGCF: update FemtoDream (#4222) * Feat: Clean up Clean up code for masked mixing and also add option for collision masks for MC processing. Fix bug in pair cleaner. * Fix: small fixes * Feat: add support for multiplicity percentiles Delete V0-only producer. The reduced producer will also soon follow. The main producer task will be updated to be modular. * Fix: fix header * Fix: fix formatting * Fix: fix typo --- PWGCF/FemtoDream/CMakeLists.txt | 5 - .../FemtoDream/FemtoDreamCollisionSelection.h | 21 +- PWGCF/FemtoDream/FemtoDreamPairCleaner.h | 2 +- .../femtoDreamPairTaskTrackTrack.cxx | 76 ++- .../FemtoDream/femtoDreamPairTaskTrackV0.cxx | 80 ++- .../femtoDreamProducerReducedTask.cxx | 19 +- PWGCF/FemtoDream/femtoDreamProducerTask.cxx | 22 +- .../femtoDreamProducerTaskV0Only.cxx | 493 ------------------ 8 files changed, 132 insertions(+), 586 deletions(-) delete mode 100644 PWGCF/FemtoDream/femtoDreamProducerTaskV0Only.cxx diff --git a/PWGCF/FemtoDream/CMakeLists.txt b/PWGCF/FemtoDream/CMakeLists.txt index 8a4e2aa9e15..6e4282fe53b 100644 --- a/PWGCF/FemtoDream/CMakeLists.txt +++ b/PWGCF/FemtoDream/CMakeLists.txt @@ -58,8 +58,3 @@ o2physics_add_executable(femtodream-cutculator SOURCES femtoDreamCutCulator.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-producer-v0 - SOURCES femtoDreamProducerTaskV0Only.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) diff --git a/PWGCF/FemtoDream/FemtoDreamCollisionSelection.h b/PWGCF/FemtoDream/FemtoDreamCollisionSelection.h index 5c35e861453..4e27e96b4ce 100644 --- a/PWGCF/FemtoDream/FemtoDreamCollisionSelection.h +++ b/PWGCF/FemtoDream/FemtoDreamCollisionSelection.h @@ -58,12 +58,12 @@ class FemtoDreamCollisionSelection LOGF(error, "Event selection not set - quitting!"); } mHistogramRegistry = registry; - mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", kTH1F, {{16384, 0, 32768}}); - mHistogramRegistry->add("Event/MultT0M", "; vMultT0M; Entries", kTH1F, {{4096, 0, 8192}}); - mHistogramRegistry->add("Event/MultNTracksPV", "; vMultNTracksPV; Entries", kTH1F, {{120, 0, 120}}); - mHistogramRegistry->add("Event/MultNTracklets", "; vMultNTrackslets; Entries", kTH1F, {{300, 0, 300}}); - mHistogramRegistry->add("Event/MultTPC", "; vMultTPC; Entries", kTH1I, {{600, 0, 600}}); + mHistogramRegistry->add("Event/Zvtx", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultPercentile", "; Multiplicity Percentile; Entries", kTH1F, {{100, 0, 100}}); + mHistogramRegistry->add("Event/MultPercentileVSMultNTracksPV", "; Multiplicity Percentile; MultNTracks", kTH2F, {{100, 0, 100}, {200, 0, 200}}); + mHistogramRegistry->add("Event/MultNTracksPV", "; MultNTracksPV; Entries", kTH1F, {{200, 0, 200}}); + mHistogramRegistry->add("Event/MultNTracklets", "; MultNTrackslets; Entries", kTH1F, {{300, 0, 300}}); + mHistogramRegistry->add("Event/MultTPC", "; MultTPC; Entries", kTH1F, {{600, 0, 600}}); } /// Print some debug information @@ -134,15 +134,14 @@ class FemtoDreamCollisionSelection void fillQA(T const& col) { if (mHistogramRegistry) { - mHistogramRegistry->fill(HIST("Event/zvtxhist"), col.posZ()); - mHistogramRegistry->fill(HIST("Event/MultT0M"), col.multFT0M()); + mHistogramRegistry->fill(HIST("Event/Zvtx"), col.posZ()); mHistogramRegistry->fill(HIST("Event/MultNTracksPV"), col.multNTracksPV()); - mHistogramRegistry->fill(HIST("Event/MultNTracklets"), col.multTracklets()); mHistogramRegistry->fill(HIST("Event/MultTPC"), col.multTPC()); if (mCheckIsRun3) { - mHistogramRegistry->fill(HIST("Event/MultV0M"), col.multFV0M()); + mHistogramRegistry->fill(HIST("Event/MultPercentile"), col.centFT0M()); + mHistogramRegistry->fill(HIST("Event/MultPercentileVSMultNTracksPV"), col.centFT0M(), col.multNTracksPV()); } else { - mHistogramRegistry->fill(HIST("Event/MultV0M"), 0.5 * (col.multFV0M())); // in AliPhysics, the VOM was defined by (V0A + V0C)/2. + mHistogramRegistry->fill(HIST("Event/MultNTracklets"), col.multTracklets()); } } } diff --git a/PWGCF/FemtoDream/FemtoDreamPairCleaner.h b/PWGCF/FemtoDream/FemtoDreamPairCleaner.h index fe63d95b536..f140d1e626f 100644 --- a/PWGCF/FemtoDream/FemtoDreamPairCleaner.h +++ b/PWGCF/FemtoDream/FemtoDreamPairCleaner.h @@ -70,7 +70,7 @@ class FemtoDreamPairCleaner } const auto& posChild = particles.iteratorAt(part2.index() - 2); const auto& negChild = particles.iteratorAt(part2.index() - 1); - if (part1.globalIndex() != posChild.globalIndex() || part2.globalIndex() != negChild.globalIndex()) { + if (part1.globalIndex() != posChild.globalIndex() || part1.globalIndex() != negChild.globalIndex()) { return true; } return false; diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx b/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx index 48dc654b816..93f20708efc 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx @@ -209,7 +209,9 @@ struct femtoDreamPairTaskTrackTrack { } } if ((doprocessSameEvent && doprocessSameEventMasked) || - (doprocessMixedEvent && doprocessMixedEventMasked)) { + (doprocessMixedEvent && doprocessMixedEventMasked) || + (doprocessSameEventMC && doprocessSameEventMCMasked) || + (doprocessMixedEventMC && doprocessMixedEventMCMasked)) { LOG(fatal) << "Normal and masked processing cannot be activated simultaneously!"; } }; @@ -283,6 +285,9 @@ struct femtoDreamPairTaskTrackTrack { fillCollision(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceTrk1.size() == 0 && SliceTrk2.size() == 0) { + return; + } doSameEvent(SliceTrk1, SliceTrk2, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEvent, "Enable processing same event", true); @@ -301,9 +306,6 @@ struct femtoDreamPairTaskTrackTrack { fillCollision(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - if (SliceTrk1.size() == 0 || SliceTrk2.size() == 0) { - return; - } doSameEvent(SliceTrk1, SliceTrk2, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMasked, "Enable processing same event with masks", false); @@ -318,12 +320,33 @@ struct femtoDreamPairTaskTrackTrack { fillCollision(col); auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceMCTrk1.size() == 0 && SliceMCTrk2.size() == 0) { + return; + } doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMC, "Enable processing same event for Monte Carlo", false); + void processSameEventMCMasked(MaskedCollision& col, soa::Join& parts, + o2::aod::FDMCParticles&) + { + if (ConfIsSame.value) { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit) { + return; + } + } else { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + return; + } + } + fillCollision(col); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMCMasked, "Enable processing same event for Monte Carlo with masked collisions", false); + /// This function processes the mixed event - /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... /// \tparam PartitionType /// \tparam PartType /// \tparam isMC: enables Monte Carlo truth specific histograms @@ -351,22 +374,14 @@ struct femtoDreamPairTaskTrackTrack { void processMixedEvent(o2::aod::FDCollisions& cols, o2::aod::FDParticles& parts) { for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - - if (magFieldTesla1 != magFieldTesla2) { + if (SliceTrk1.size() == 0 || SliceTrk2.size() == 0) { continue; } - /// \todo before mixing we should check whether both collisions contain a pair of particles! - // if (partsOne.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTwo.size() == 0 ) continue; - + const auto magFieldTesla1 = collision1.magField(); doMixedEvent(SliceTrk1, SliceTrk2, parts, magFieldTesla1, multiplicityCol); } } @@ -398,26 +413,37 @@ struct femtoDreamPairTaskTrackTrack { void processMixedEventMC(o2::aod::FDCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - - if (magFieldTesla1 != magFieldTesla2) { + if (SliceMCTrk1.size() == 0 || SliceMCTrk2.size() == 0) { continue; } - /// \todo before mixing we should check whether both collisions contain a pair of particles! - // if (partsOne.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTwo.size() == 0 ) continue; - + const auto magFieldTesla1 = collision1.magField(); doMixedEvent(SliceMCTrk1, SliceMCTrk2, parts, magFieldTesla1, multiplicityCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMC, "Enable processing mixed events MC", false); + + void processMixedEventMCMasked(MaskedCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) + { + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; + Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; + + PartitionMaskedCol1.bindTable(cols); + PartitionMaskedCol2.bindTable(cols); + + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { + const auto multiplicityCol = collision1.multNtr(); + const auto& magFieldTesla1 = collision1.magField(); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(SliceMCTrk1, SliceMCTrk2, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMCMasked, "Enable processing mixed events MC with masked collisions", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx b/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx index bc0cb0a1903..025f2df1271 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx +++ b/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx @@ -216,7 +216,9 @@ struct femtoDreamPairTaskTrackV0 { } } if ((doprocessSameEvent && doprocessSameEventMasked) || - (doprocessMixedEvent && doprocessMixedEventMasked)) { + (doprocessMixedEvent && doprocessMixedEventMasked) || + (doprocessSameEventMC && doprocessSameEventMCMasked) || + (doprocessMixedEventMC && doprocessMixedEventMCMasked)) { LOG(fatal) << "Normal and masked processing cannot be activated simultaneously!"; } } @@ -234,7 +236,7 @@ struct femtoDreamPairTaskTrackV0 { const auto& posChild = parts.iteratorAt(v0.index() - 2); const auto& negChild = parts.iteratorAt(v0.index() - 1); // This is how it is supposed to work but there seems to be an issue - // with partitions and accessing elements in tables that have been + // with partitions and accessing elements in tables that have been declared // with an SELF_INDEX column. Under investigation. Maybe need to change // femtdream dataformat to take special care of v0 candidates // auto posChild = v0.template children_as().front(); @@ -278,6 +280,9 @@ struct femtoDreamPairTaskTrackV0 { eventHisto.fillQA(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceTrk1.size() == 0 && SliceV02.size() == 0) { + return; + } doSameEvent(SliceTrk1, SliceV02, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEvent, "Enable processing same event", true); @@ -295,21 +300,34 @@ struct femtoDreamPairTaskTrackV0 { PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMasked, "Enable processing same event with masks", false); void processSameEventMC(o2::aod::FDCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) - // void processSameEventMC(o2::aod::FDCollision& col, soa::Join& parts, o2::aod::FDMCParticles&) { eventHisto.fillQA(col); auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceMCTrk1.size() == 0 && SliceMCV02.size() == 0) { + return; + } doSameEvent(SliceMCTrk1, SliceMCV02, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMC, "Enable processing same event MC", false); + void processSameEventMCMasked(MaskedCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) + { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + return; + } + eventHisto.fillQA(col); + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceMCTrk1, SliceMCV02, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMCMasked, "Enable processing same event MC with masks", false); + /// This function processes the mixed event /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... template void doMixedEvent(PartitionType SliceTrk1, PartitionType SliceV02, PartType parts, float magFieldTesla, int multCol) { - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { const auto& posChild = parts.iteratorAt(p2.index() - 2); const auto& negChild = parts.iteratorAt(p2.index() - 1); @@ -325,7 +343,7 @@ struct femtoDreamPairTaskTrackV0 { continue; } } - // track cleaning + // pair cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } @@ -336,16 +354,13 @@ struct femtoDreamPairTaskTrackV0 { void processMixedEvent(o2::aod::FDCollisions& cols, FilteredFDParticles& parts) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multCol = collision1.multNtr(); - auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - - if (magFieldTesla1 != magFieldTesla2) { - continue; + const int multCol = collision1.multNtr(); + const auto magFieldTesla1 = collision1.magField(); + if (SliceTrk1.size() == 0 || SliceV02.size() == 0) { + return; } doMixedEvent(SliceTrk1, SliceV02, parts, magFieldTesla1, multCol); } @@ -354,7 +369,6 @@ struct femtoDreamPairTaskTrackV0 { void processMixedEventMasked(MaskedCollisions const& cols, FilteredFDParticles const& parts) { - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; @@ -362,39 +376,49 @@ struct femtoDreamPairTaskTrackV0 { PartitionMaskedCol2.bindTable(cols); for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { - const int multCol = collision1.multNtr(); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - if (magFieldTesla1 != magFieldTesla2) { - continue; - } + + const int multCol = collision1.multNtr(); + const auto magFieldTesla1 = collision1.magField(); doMixedEvent(SliceTrk1, SliceV02, parts, magFieldTesla1, multCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMasked, "Enable processing mixed events with masks", false); void processMixedEventMC(o2::aod::FDCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) - // void processMixedEventMC(o2::aod::FDCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) { for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multCol = collision1.multNtr(); - auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - - if (magFieldTesla1 != magFieldTesla2) { - continue; + const int multCol = collision1.multNtr(); + const auto magFieldTesla1 = collision1.magField(); + if (SliceMCTrk1.size() == 0 || SliceMCV02.size() == 0) { + return; } - doMixedEvent(SliceMCTrk1, SliceMCV02, parts, magFieldTesla1, multCol); } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMC, "Enable processing mixed events MC", false); + + void processMixedEventMCMasked(MaskedCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) + { + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; + Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; + + PartitionMaskedCol1.bindTable(cols); + PartitionMaskedCol2.bindTable(cols); + + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { + auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + const int multCol = collision1.multNtr(); + const auto magFieldTesla1 = collision1.magField(); + doMixedEvent(SliceMCTrk1, SliceMCV02, parts, magFieldTesla1, multCol); + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMCMasked, "Enable processing mixed events MC with masks", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx index cb809110cf9..3a56b7bf907 100644 --- a/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx @@ -45,13 +45,8 @@ using namespace o2::framework::expressions; namespace o2::aod { -using FemtoFullCollision = soa::Join::iterator; -using FemtoFullCollisionMC = soa::Join::iterator; +using FemtoFullCollision = soa::Join::iterator; +using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullTracks = soa::Join ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; Configurable> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry Registry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; int mRunNumber; @@ -226,20 +221,21 @@ struct femtoDreamProducerReducedTask { const auto vtxZ = col.posZ(); const auto spher = colCuts.computeSphericity(col, tracks); - int mult = 0; int multNtr = 0; if (ConfIsRun3) { - mult = col.multFV0M(); + mult = col.centFT0M(); multNtr = col.multNTracksPV(); } else { - mult = 0.5 * (col.multFV0M()); /// For benchmarking on Run 2, V0M in FemtoDreamRun2 is defined V0M/2 + mult = 1; // multiplicity percentile is known in Run 2 multNtr = col.multTracklets(); } if (ConfEvtUseTPCmult) { multNtr = col.multTPC(); } + colCuts.fillQA(col); + /// First thing to do is to check whether the basic event selection criteria are fulfilled /// That includes checking if there are any usable tracks in a collision if (!colCuts.isSelectedCollision(col)) { @@ -249,7 +245,6 @@ struct femtoDreamProducerReducedTask { return; } - colCuts.fillQA(col); // now the table is filled outputCollision(vtxZ, mult, multNtr, spher, mMagField); diff --git a/PWGCF/FemtoDream/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/femtoDreamProducerTask.cxx index 3bf67e81b12..58f7ca12545 100644 --- a/PWGCF/FemtoDream/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/femtoDreamProducerTask.cxx @@ -17,6 +17,7 @@ #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "DataFormatsParameters/GRPMagField.h" @@ -37,16 +38,16 @@ #include "TMath.h" using namespace o2; -using namespace o2::analysis::femtoDream; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::analysis::femtoDream; namespace o2::aod { using FemtoFullCollision = - soa::Join::iterator; -using FemtoFullCollisionMC = soa::Join::iterator; + soa::Join::iterator; +using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullTracks = soa::Join V0TranRadV0Min.value); to be added, not working // for now do not know why - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry TrackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry V0Registry{"V0", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -344,23 +345,23 @@ struct femtoDreamProducerTask { template void fillCollisionsAndTracksAndV0(CollisionType const& col, TrackType const& tracks, V0Type const& fullV0s) { - const auto vtxZ = col.posZ(); const auto spher = colCuts.computeSphericity(col, tracks); - int mult = 0; + float mult = 0; int multNtr = 0; if (ConfIsRun3) { - mult = col.multFV0M(); + mult = col.centFT0M(); multNtr = col.multNTracksPV(); } else { - mult = 0.5 * (col.multFV0M()); /// For benchmarking on Run 2, V0M in - /// FemtoDreamRun2 is defined V0M/2 + mult = 1; // multiplicity percentile is know in Run 2 multNtr = col.multTracklets(); } if (ConfEvtUseTPCmult) { multNtr = col.multTPC(); } + colCuts.fillQA(col); + // check whether the basic event selection criteria are fulfilled // that included checking if there is at least on usable track or V0 if (!colCuts.isSelectedCollision(col)) { @@ -376,7 +377,6 @@ struct femtoDreamProducerTask { } } - colCuts.fillQA(col); outputCollision(vtxZ, mult, multNtr, spher, mMagField); std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children @@ -503,7 +503,7 @@ struct femtoDreamProducerTask { processData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s) /// \todo with FilteredFullV0s + o2::aod::V0Datas const& fullV0s) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); diff --git a/PWGCF/FemtoDream/femtoDreamProducerTaskV0Only.cxx b/PWGCF/FemtoDream/femtoDreamProducerTaskV0Only.cxx deleted file mode 100644 index 081c7855846..00000000000 --- a/PWGCF/FemtoDream/femtoDreamProducerTaskV0Only.cxx +++ /dev/null @@ -1,493 +0,0 @@ -// Copyright 2019-2022 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// \file femtoDreamProducerTaskV0Only.cxx -/// \brief Tasks that produces the track tables used for the pairing -/// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de - -#include -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "FemtoDreamCollisionSelection.h" -#include "FemtoDreamTrackSelection.h" -#include "FemtoDreamV0Selection.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Math/Vector4D.h" -#include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "ReconstructionDataFormats/Track.h" -#include "TMath.h" - -using namespace o2; -using namespace o2::analysis::femtoDream; -using namespace o2::framework; -using namespace o2::framework::expressions; - -namespace o2::aod -{ - -using FemtoFullCollision = - soa::Join::iterator; -using FemtoFullTracks = - soa::Join; -// using FilteredFullV0s = soa::Filtered; /// predefined Join -// table for o2::aod::V0s = soa::Join -// to be used when we add v0Filter -} // namespace o2::aod - -/// \todo fix how to pass array to setSelection, getRow() passing a different -/// type! -// static constexpr float arrayV0Sel[3][3] = {{100.f, 100.f, 100.f}, {0.2f, -// 0.2f, 0.2f}, {100.f, 100.f, 100.f}}; unsigned int rows = sizeof(arrayV0Sel) / -// sizeof(arrayV0Sel[0]); unsigned int columns = sizeof(arrayV0Sel[0]) / -// sizeof(arrayV0Sel[0][0]); - -template -int getRowDaughters(int daughID, T const& vecID) -{ - int rowInPrimaryTrackTableDaugh = -1; - for (size_t i = 0; i < vecID.size(); i++) { - if (vecID.at(i) == daughID) { - rowInPrimaryTrackTableDaugh = i; - break; - } - } - return rowInPrimaryTrackTableDaugh; -} - -struct femtoDreamProducerTaskV0Only { - - Produces outputCollision; - Produces outputParts; - Produces outputDebugParts; - - Configurable ConfDebugOutput{"ConfDebugOutput", true, "Debug output"}; - Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Run3 or pilot"}; - Configurable ConfIsMC{"ConfIsMC", false, "Running on MC; implemented only for Run3"}; - - /// Event cuts - FemtoDreamCollisionSelection colCuts; - Configurable ConfUseTPCmult{"ConfUseTPCmult", false, "Use multiplicity based on the number of tracks with TPC information"}; - Configurable ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; - Configurable ConfEvtTriggerCheck{"ConfEvtTriggerCheck", true, "Evt sel: check for trigger"}; - Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; - Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; - - Configurable ConfStoreV0{"ConfStoreV0", true, "True: store V0 table"}; - // just sanity check to make sure in case there are problems in conversion or - // MC production it does not affect results - Configurable ConfRejectNotPropagatedTracks{"ConfRejectNotPropagatedTracks", false, "True: reject not propagated tracks"}; - FemtoDreamV0Selection v0Cuts; - /// \todo Labeled array (see Track-Track task) - - Configurable> ConfV0Sign{ - FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0Sign, - "ConfV0"), - std::vector{-1, 1}, - FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0Sign, - "V0 selection: ")}; - Configurable> ConfV0PtMin{ - FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0pTMin, - "ConfV0"), - std::vector{0.3f}, - FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0pTMin, - "V0 selection: ")}; - Configurable> ConfV0PtMax{ - FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0pTMax, - "ConfV0"), - std::vector{6.f}, - FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0pTMax, - "V0 selection: ")}; - Configurable> ConfV0EtaMax{ - FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0etaMax, - "ConfV0"), - std::vector{6.f}, - FemtoDreamV0Selection::getSelectionHelper(femtoDreamV0Selection::kV0etaMax, - "V0 selection: ")}; - Configurable> ConfDCAV0DaughMax{ - FemtoDreamV0Selection::getSelectionName( - femtoDreamV0Selection::kV0DCADaughMax, "ConfV0"), - std::vector{1.5f}, - FemtoDreamV0Selection::getSelectionHelper( - femtoDreamV0Selection::kV0DCADaughMax, "V0 selection: ")}; - Configurable> ConfCPAV0Min{ - FemtoDreamV0Selection::getSelectionName(femtoDreamV0Selection::kV0CPAMin, - "ConfV0"), - std::vector{0.99f}, - FemtoDreamV0Selection::getSelectionHelper( - femtoDreamV0Selection::kV0CPAMin, "V0 selection: ")}; - - Configurable> V0TranRadV0Min{ - FemtoDreamV0Selection::getSelectionName( - femtoDreamV0Selection::kV0TranRadMin, "ConfV0"), - std::vector{0.2f}, - FemtoDreamV0Selection::getSelectionHelper( - femtoDreamV0Selection::kV0TranRadMin, "V0 selection: ")}; - Configurable> V0TranRadV0Max{ - FemtoDreamV0Selection::getSelectionName( - femtoDreamV0Selection::kV0TranRadMax, "ConfV0"), - std::vector{100.f}, - FemtoDreamV0Selection::getSelectionHelper( - femtoDreamV0Selection::kV0TranRadMax, "V0 selection: ")}; - Configurable> V0DecVtxMax{ - FemtoDreamV0Selection::getSelectionName( - femtoDreamV0Selection::kV0DecVtxMax, "ConfV0"), - std::vector{100.f}, - FemtoDreamV0Selection::getSelectionHelper( - femtoDreamV0Selection::kV0DecVtxMax, "V0 selection: ")}; - - Configurable> ConfV0DaughCharge{ - "ConfV0DaughCharge", std::vector{-1, 1}, "V0 Daugh sel: Charge"}; - Configurable> ConfDaughEta{ - "ConfDaughEta", std::vector{0.8f}, "V0 Daugh sel: max eta"}; - Configurable> ConfV0DaughTPCnclsMin{ - "ConfV0DaughTPCnclsMin", std::vector{70.f}, - "V0 Daugh sel: Min. nCls TPC"}; - Configurable> ConfV0DaughDCAMin{ - "ConfV0DaughDCAMin", std::vector{0.05f}, - "V0 Daugh sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfV0DaughPIDnSigmaMax{ - "ConfV0DaughPIDnSigmaMax", std::vector{5.f}, - "V0 Daugh sel: Max. PID nSigma TPC"}; - - Configurable> ConfV0DaughTPIDspecies{ - "ConfV0DaughTPIDspecies", - std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, - o2::track::PID::Proton}, - "V0 Daugh sel: Particles species for PID"}; - - Configurable ConfInvMassLowLimit{ - "ConfInvMassLowLimit", 1.05, "Lower limit of the V0 invariant mass"}; - Configurable ConfInvMassUpLimit{ - "ConfInvMassUpLimit", 1.30, "Upper limit of the V0 invariant mass"}; - - Configurable ConfRejectKaons{"ConfRejectKaons", false, - "Switch to reject kaons"}; - Configurable ConfInvKaonMassLowLimit{ - "ConfInvKaonMassLowLimit", 0.48, - "Lower limit of the V0 invariant mass for Kaon rejection"}; - Configurable ConfInvKaonMassUpLimit{ - "ConfInvKaonMassUpLimit", 0.515, - "Upper limit of the V0 invariant mass for Kaon rejection"}; - - /// \todo should we add filter on min value pT/eta of V0 and daughters? - /*Filter v0Filter = (nabs(aod::v0data::x) < V0DecVtxMax.value) && - (nabs(aod::v0data::y) < V0DecVtxMax.value) && - (nabs(aod::v0data::z) < V0DecVtxMax.value);*/ - // (aod::v0data::v0radius > V0TranRadV0Min.value); to be added, not working - // for now do not know why - - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; - HistogramRegistry Registry{"Producer", {}, OutputObjHandlingPolicy::AnalysisObject}; - - int mRunNumber; - float mMagField; - Service ccdb; /// Accessing the CCDB - - void init(InitContext&) - { - colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, - ConfEvtOfflineCheck, ConfIsRun3); - colCuts.init(&qaRegistry); - - /// \todo fix how to pass array to setSelection, getRow() passing a - /// different type! - // v0Cuts.setSelection(ConfV0Selection->getRow(0), - // femtoDreamV0Selection::kDecVtxMax, femtoDreamSelection::kAbsUpperLimit); - if (ConfStoreV0) { - v0Cuts.setSelection(ConfV0Sign, femtoDreamV0Selection::kV0Sign, - femtoDreamSelection::kEqual); - v0Cuts.setSelection(ConfV0PtMin, femtoDreamV0Selection::kV0pTMin, - femtoDreamSelection::kLowerLimit); - v0Cuts.setSelection(ConfV0PtMax, femtoDreamV0Selection::kV0pTMax, - femtoDreamSelection::kUpperLimit); - v0Cuts.setSelection(ConfV0EtaMax, femtoDreamV0Selection::kV0etaMax, - femtoDreamSelection::kUpperLimit); - v0Cuts.setSelection(ConfDCAV0DaughMax, - femtoDreamV0Selection::kV0DCADaughMax, - femtoDreamSelection::kUpperLimit); - v0Cuts.setSelection(ConfCPAV0Min, femtoDreamV0Selection::kV0CPAMin, - femtoDreamSelection::kLowerLimit); - - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfV0DaughCharge, - femtoDreamTrackSelection::kSign, - femtoDreamSelection::kEqual); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfDaughEta, - femtoDreamTrackSelection::kEtaMax, - femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, - ConfV0DaughTPCnclsMin, - femtoDreamTrackSelection::kTPCnClsMin, - femtoDreamSelection::kLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfV0DaughDCAMin, - femtoDreamTrackSelection::kDCAMin, - femtoDreamSelection::kAbsLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, - ConfV0DaughPIDnSigmaMax, - femtoDreamTrackSelection::kPIDnSigmaMax, - femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfV0DaughCharge, - femtoDreamTrackSelection::kSign, - femtoDreamSelection::kEqual); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfDaughEta, - femtoDreamTrackSelection::kEtaMax, - femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, - ConfV0DaughTPCnclsMin, - femtoDreamTrackSelection::kTPCnClsMin, - femtoDreamSelection::kLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfV0DaughDCAMin, - femtoDreamTrackSelection::kDCAMin, - femtoDreamSelection::kAbsLowerLimit); - v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, - ConfV0DaughPIDnSigmaMax, - femtoDreamTrackSelection::kPIDnSigmaMax, - femtoDreamSelection::kAbsUpperLimit); - v0Cuts.setChildPIDSpecies(femtoDreamV0Selection::kPosTrack, - ConfV0DaughTPIDspecies); - v0Cuts.setChildPIDSpecies(femtoDreamV0Selection::kNegTrack, - ConfV0DaughTPIDspecies); - v0Cuts.init(&qaRegistry, &Registry); - v0Cuts.setInvMassLimits(ConfInvMassLowLimit, ConfInvMassUpLimit); - v0Cuts.setChildRejectNotPropagatedTracks(femtoDreamV0Selection::kPosTrack, - ConfRejectNotPropagatedTracks); - v0Cuts.setChildRejectNotPropagatedTracks(femtoDreamV0Selection::kNegTrack, - ConfRejectNotPropagatedTracks); - if (ConfRejectKaons) { - v0Cuts.setKaonInvMassLimits(ConfInvKaonMassLowLimit, - ConfInvKaonMassUpLimit); - } - } - mRunNumber = 0; - mMagField = 0.0; - /// Initializing CCDB - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - - int64_t now = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); - ccdb->setCreatedNotAfter(now); - } - - /// Function to retrieve the nominal mgnetic field in kG (0.1T) and convert it - /// directly to T - float getMagneticFieldTesla(uint64_t timestamp) - { - // TODO done only once (and not per run). Will be replaced by - // CCDBConfigurable - float output = -999; - - if (ConfIsRun3 && !ConfIsMC) { - static o2::parameters::GRPMagField* grpo = nullptr; - if (grpo == nullptr) { - grpo = ccdb->getForTimeStamp( - "GLO/Config/GRPMagField", timestamp); - if (grpo == nullptr) { - LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); - return 0; - } - LOGF(info, "Retrieved GRP for timestamp %llu with L3 ", timestamp, - grpo->getL3Current()); - } - // taken from GRP onject definition of getNominalL3Field; update later to - // something smarter (mNominalL3Field = std::lround(5.f * mL3Current / - // 30000.f);) - auto NominalL3Field = std::lround(5.f * grpo->getL3Current() / 30000.f); - output = 0.1 * (NominalL3Field); - } - - if (!ConfIsRun3 || (ConfIsRun3 && ConfIsMC)) { - static o2::parameters::GRPObject* grpo = nullptr; - if (grpo == nullptr) { - grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", - timestamp); - if (grpo == nullptr) { - LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); - return 0; - } - LOGF(info, - "Retrieved GRP for timestamp %llu with magnetic field of %d kG", - timestamp, grpo->getNominalL3Field()); - } - output = 0.1 * (grpo->getNominalL3Field()); - } - return output; - } - - void process(aod::FemtoFullCollision const& col, - aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s) /// \todo with FilteredFullV0s - { - // get magnetic field for run - auto bc = col.bc_as(); - if (mRunNumber != bc.runNumber()) { - mMagField = getMagneticFieldTesla(bc.timestamp()); - mRunNumber = bc.runNumber(); - } - - const auto vtxZ = col.posZ(); - const auto spher = colCuts.computeSphericity(col, tracks); - - int mult = 0; - int multNtr = 0; - if (ConfIsRun3) { - mult = col.multFV0M(); - multNtr = col.multNTracksPV(); - } else { - mult = 0.5 * (col.multFV0M()); /// For benchmarking on Run 2, V0M in - /// FemtoDreamRun2 is defined V0M/2 - multNtr = col.multTracklets(); - } - if (ConfUseTPCmult) { - multNtr = col.multTPC(); - } - - /// First thing to do is to check whether the basic event selection criteria are fullfilled - /// that includes checking if there is at least one usable V0 in the collision - if (!colCuts.isSelectedCollision(col)) { - return; - } - if (colCuts.isEmptyCollision(col, fullV0s, v0Cuts, tracks)) { - return; - } - - colCuts.fillQA(col); - // now the table is filled - outputCollision(vtxZ, mult, multNtr, spher, mMagField); - - std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children - std::vector - tmpIDtrack; // this vector keeps track of the matching of the primary - // track table row <-> aod::track table global index - - if (ConfStoreV0) { - for (auto const& v0 : fullV0s) { - const auto postrack = v0.posTrack_as(); - const auto negtrack = v0.negTrack_as(); - // const auto dcaXYpos = postrack.dcaXY(); - // const auto dcaZpos = postrack.dcaZ(); - // const auto dcapos = std::sqrt(pow(dcaXYpos, 2.) + pow(dcaZpos, 2.)); - v0Cuts.fillLambdaQA(col, v0, postrack, negtrack); - - if (!v0Cuts.isSelectedMinimal(col, v0, postrack, negtrack)) { - continue; - } - v0Cuts.fillQA( - col, v0, postrack, negtrack); ///\todo fill QA also for daughters - auto cutContainerV0 = - v0Cuts.getCutContainer( - col, v0, postrack, negtrack); - - if ((cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kV0) > 0) && - (cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kPosCuts) > 0) && - (cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kNegCuts) > 0)) { - int postrackID = v0.posTrackId(); - int rowInPrimaryTrackTablePos = -1; - rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); - childIDs[0] = rowInPrimaryTrackTablePos; - childIDs[1] = 0; - outputParts(outputCollision.lastIndex(), v0.positivept(), - v0.positiveeta(), v0.positivephi(), - aod::femtodreamparticle::ParticleType::kV0Child, - cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kPosCuts), - cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kPosPID), - 0., childIDs, 0, 0); - const int rowOfPosTrack = outputParts.lastIndex(); - int negtrackID = v0.negTrackId(); - int rowInPrimaryTrackTableNeg = -1; - rowInPrimaryTrackTableNeg = getRowDaughters(negtrackID, tmpIDtrack); - childIDs[0] = 0; - childIDs[1] = rowInPrimaryTrackTableNeg; - outputParts(outputCollision.lastIndex(), v0.negativept(), - v0.negativeeta(), v0.negativephi(), - aod::femtodreamparticle::ParticleType::kV0Child, - cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kNegCuts), - cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kNegPID), - 0., childIDs, 0, 0); - const int rowOfNegTrack = outputParts.lastIndex(); - std::vector indexChildID = {rowOfPosTrack, rowOfNegTrack}; - outputParts(outputCollision.lastIndex(), v0.pt(), v0.eta(), v0.phi(), - aod::femtodreamparticle::ParticleType::kV0, - cutContainerV0.at( - femtoDreamV0Selection::V0ContainerPosition::kV0), - 0, v0.v0cosPA(), - indexChildID, v0.mLambda(), v0.mAntiLambda()); - if (ConfDebugOutput) { - outputDebugParts( - postrack.sign(), (uint8_t)postrack.tpcNClsFound(), - postrack.tpcNClsFindable(), - (uint8_t)postrack.tpcNClsCrossedRows(), - postrack.tpcNClsShared(), postrack.tpcInnerParam(), - postrack.itsNCls(), postrack.itsNClsInnerBarrel(), - postrack.dcaXY(), postrack.dcaZ(), postrack.tpcSignal(), - postrack.tpcNSigmaStoreEl(), postrack.tpcNSigmaStorePi(), - postrack.tpcNSigmaStoreKa(), postrack.tpcNSigmaStorePr(), - postrack.tpcNSigmaStoreDe(), postrack.tofNSigmaStoreEl(), - postrack.tofNSigmaStorePi(), postrack.tofNSigmaStoreKa(), - postrack.tofNSigmaStorePr(), postrack.tofNSigmaStoreDe(), -999., - -999., -999., -999., -999., - -999.); // QA for positive daughter - outputDebugParts( - negtrack.sign(), (uint8_t)negtrack.tpcNClsFound(), - negtrack.tpcNClsFindable(), - (uint8_t)negtrack.tpcNClsCrossedRows(), - negtrack.tpcNClsShared(), negtrack.tpcInnerParam(), - negtrack.itsNCls(), negtrack.itsNClsInnerBarrel(), - negtrack.dcaXY(), negtrack.dcaZ(), negtrack.tpcSignal(), - negtrack.tpcNSigmaStoreEl(), negtrack.tpcNSigmaStorePi(), - negtrack.tpcNSigmaStoreKa(), negtrack.tpcNSigmaStorePr(), - negtrack.tpcNSigmaStoreDe(), negtrack.tofNSigmaStoreEl(), - negtrack.tofNSigmaStorePi(), negtrack.tofNSigmaStoreKa(), - negtrack.tofNSigmaStorePr(), negtrack.tofNSigmaStoreDe(), -999., - -999., -999., -999., -999., - -999.); // QA for negative daughter - outputDebugParts(-999., -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., -999., -999., - -999., -999., -999., -999., -999., -999., -999., - v0.dcaV0daughters(), v0.v0radius(), v0.x(), v0.y(), - v0.z(), - v0.mK0Short()); // QA for V0 - } - } - } - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} From 25dae17336de7e478950a59d18b59cb453050d7c Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sun, 7 Jan 2024 16:34:10 +0100 Subject: [PATCH 125/156] Add strange TOF PID QA task (#4245) * Make pid task independent of orig ao2d * Add TOF PID QA task for strangeness * Please consider the following formatting changes (#212) --------- Co-authored-by: ALICE Builder --- PWGLF/DataModel/LFStrangenessTables.h | 2 +- PWGLF/TableProducer/lambdakzeropid.cxx | 76 ++++------- PWGLF/TableProducer/strangederivedbuilder.cxx | 4 +- PWGLF/Tasks/QC/CMakeLists.txt | 5 + PWGLF/Tasks/QC/strangepidqa.cxx | 120 ++++++++++++++++++ 5 files changed, 154 insertions(+), 53 deletions(-) create mode 100644 PWGLF/Tasks/QC/strangepidqa.cxx diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index d3d1ef73813..2be338700ad 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -25,7 +25,7 @@ namespace o2::aod // this is optional but will ensure full flexibility // if required (for 2pc, etc) DECLARE_SOA_TABLE(StraCollisions, "AOD", "STRACOLLISION", //! basic collision properties: position - collision::PosX, collision::PosY, collision::PosZ); + o2::soa::Index<>, collision::PosX, collision::PosY, collision::PosZ); DECLARE_SOA_TABLE(StraCents, "AOD", "STRACENTS", //! centrality percentiles cent::CentFT0M, cent::CentFT0A, cent::CentFT0C, cent::CentFV0A); diff --git a/PWGLF/TableProducer/lambdakzeropid.cxx b/PWGLF/TableProducer/lambdakzeropid.cxx index 626b1adc5c8..2dd4ecb79c7 100644 --- a/PWGLF/TableProducer/lambdakzeropid.cxx +++ b/PWGLF/TableProducer/lambdakzeropid.cxx @@ -75,6 +75,9 @@ using TaggedV0s = soa::Join; // For MC association in pre-selection using LabeledTracksExtra = soa::Join; +// Cores with references and TOF pid +using V0FullCores = soa::Join; + struct lambdakzeropid { // TOF pid for strangeness (recalculated with topology) Produces v0tofpid; // table with Nsigmas @@ -82,7 +85,7 @@ struct lambdakzeropid { Service ccdb; // For manual sliceBy - Preslice perCollision = o2::aod::v0data::collisionId; + Preslice perCollision = o2::aod::v0data::straCollisionId; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -117,7 +120,7 @@ struct lambdakzeropid { /// \param x2 x of the first point of the detector segment /// \param y2 y of the first point of the detector segment /// \param magneticField the magnetic field to use when propagating - float trackLengthToSegment(o2::track::TrackParCov track, float x1, float y1, float x2, float y2, float magneticField) + float trackLengthToSegment(o2::track::TrackPar track, float x1, float y1, float x2, float y2, float magneticField) { // don't make use of the track parametrization float length = -104; @@ -216,7 +219,7 @@ struct lambdakzeropid { /// function to calculate track length of this track up to a certain segmented detector /// \param track the input track /// \param magneticField the magnetic field to use when propagating - float findInterceptLength(o2::track::TrackParCov track, float magneticField) + float findInterceptLength(o2::track::TrackPar track, float magneticField) { for (int iSeg = 0; iSeg < 18; iSeg++) { // Detector segmentation loop @@ -246,17 +249,13 @@ struct lambdakzeropid { ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - histos.add("h3dMassK0ShortPositive", "h3dMassK0ShortPositive", kTH3F, {axisPtQA, axisDeltaTime, axisK0ShortMass}); - histos.add("h3dMassLambdaPositive", "h3dMassLambdaPositive", kTH3F, {axisPtQA, axisDeltaTime, axisLambdaMass}); - histos.add("h3dMassAntiLambdaPositive", "h3dMassAntiLambdaPositive", kTH3F, {axisPtQA, axisDeltaTime, axisLambdaMass}); - histos.add("h3dMassK0ShortNegative", "h3dMassK0ShortNegative", kTH3F, {axisPtQA, axisDeltaTime, axisK0ShortMass}); - histos.add("h3dMassLambdaNegative", "h3dMassLambdaNegative", kTH3F, {axisPtQA, axisDeltaTime, axisLambdaMass}); - histos.add("h3dMassAntiLambdaNegative", "h3dMassAntiLambdaNegative", kTH3F, {axisPtQA, axisDeltaTime, axisLambdaMass}); + // per event + histos.add("hCandidateCounter", "hCandidateCounter", kTH1F, {{500, -0.5f, 499.5f}}); } - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + void initCCDB(soa::Join::iterator const& collision) { - if (mRunNumber == bc.runNumber()) { + if (mRunNumber == collision.runNumber()) { return; } @@ -268,11 +267,11 @@ struct lambdakzeropid { grpmag.setL3Current(30000.f / (d_bz / 5.0f)); } o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = bc.runNumber(); + mRunNumber = collision.runNumber(); return; } - auto run3grp_timestamp = bc.timestamp(); + auto run3grp_timestamp = collision.timestamp(); o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); o2::parameters::GRPMagField* grpmag = 0x0; if (grpo) { @@ -290,7 +289,7 @@ struct lambdakzeropid { d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; } - mRunNumber = bc.runNumber(); + mRunNumber = collision.runNumber(); } float velocity(float lMomentum, float lMass) @@ -301,15 +300,15 @@ struct lambdakzeropid { return 0.0299792458 * TMath::Sqrt(lA / (1 + lA)); } - void process(aod::Collisions const& collisions, aod::V0Datas const& V0s, FullTracksExtIU const&, aod::BCsWithTimestamps const&, TaggedV0s const& allV0s) + void process(soa::Join const& collisions, V0FullCores const& V0s) { for (const auto& collision : collisions) { - // Fire up CCDB - auto bc = collision.bc_as(); - initCCDB(bc); + // Fire up CCDB - based on StraCollisions for derived analysis + initCCDB(collision); // Do analysis with collision-grouped V0s, retain full collision information const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisCollision = V0s.sliceBy(perCollision, collIdx); + histos.fill(HIST("hCandidateCounter"), V0Table_thisCollision.size()); // V0 table sliced for (auto const& v0 : V0Table_thisCollision) { // time of V0 segment @@ -319,11 +318,9 @@ struct lambdakzeropid { float timeK0Short = lengthV0 / velocityK0Short; // in picoseconds float timeLambda = lengthV0 / velocityLambda; // in picoseconds - auto const& posTrackRow = v0.posTrack_as(); - auto const& negTrackRow = v0.negTrack_as(); - - auto posTrack = getTrackParCov(posTrackRow); - auto negTrack = getTrackParCov(negTrackRow); + // initialize from V0 position and momenta + o2::track::TrackPar posTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxpos(), v0.pypos(), v0.pzpos()}, +1); + o2::track::TrackPar negTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxneg(), v0.pyneg(), v0.pzneg()}, -1); float deltaTimePositiveLambdaPi = -1e+6; float deltaTimeNegativeLambdaPi = -1e+6; @@ -337,10 +334,6 @@ struct lambdakzeropid { float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); - // propagate to V0 decay vertex - posTrack.propagateTo(v0.posX(), d_bz); - negTrack.propagateTo(v0.negX(), d_bz); - float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? float timePositivePr = lengthPositive / velocityPositivePr; @@ -348,35 +341,18 @@ struct lambdakzeropid { float timeNegativePr = lengthNegative / velocityNegativePr; float timeNegativePi = lengthNegative / velocityNegativePi; - deltaTimePositiveLambdaPr = (posTrackRow.tofSignal() - posTrackRow.tofEvTime()) - (timeLambda + timePositivePr); - deltaTimePositiveLambdaPi = (posTrackRow.tofSignal() - posTrackRow.tofEvTime()) - (timeLambda + timePositivePi); - deltaTimeNegativeLambdaPr = (negTrackRow.tofSignal() - negTrackRow.tofEvTime()) - (timeLambda + timeNegativePr); - deltaTimeNegativeLambdaPi = (negTrackRow.tofSignal() - negTrackRow.tofEvTime()) - (timeLambda + timeNegativePi); - deltaTimePositiveK0ShortPi = (posTrackRow.tofSignal() - posTrackRow.tofEvTime()) - (timeK0Short + timeNegativePi); - deltaTimeNegativeK0ShortPi = (negTrackRow.tofSignal() - negTrackRow.tofEvTime()) - (timeK0Short + timeNegativePi); + deltaTimePositiveLambdaPr = (v0.posTOFSignal() - v0.posTOFEventTime()) - (timeLambda + timePositivePr); + deltaTimePositiveLambdaPi = (v0.posTOFSignal() - v0.posTOFEventTime()) - (timeLambda + timePositivePi); + deltaTimeNegativeLambdaPr = (v0.negTOFSignal() - v0.negTOFEventTime()) - (timeLambda + timeNegativePr); + deltaTimeNegativeLambdaPi = (v0.negTOFSignal() - v0.negTOFEventTime()) - (timeLambda + timeNegativePi); + deltaTimePositiveK0ShortPi = (v0.posTOFSignal() - v0.posTOFEventTime()) - (timeK0Short + timeNegativePi); + deltaTimeNegativeK0ShortPi = (v0.negTOFSignal() - v0.negTOFEventTime()) - (timeK0Short + timeNegativePi); v0tofpid(lengthPositive, lengthNegative, deltaTimePositiveLambdaPi, deltaTimePositiveLambdaPr, deltaTimeNegativeLambdaPi, deltaTimeNegativeLambdaPr, deltaTimePositiveK0ShortPi, deltaTimeNegativeK0ShortPi, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); // FIXME - - auto originalV0 = v0.v0_as(); // this could look confusing, so: - // the first v0 is the v0data row; the getter de-references the v0 (stored indices) row - // the v0 (stored indices) contain the tags of the lambdakzero preselector - - if (originalV0.isdEdxK0Short() || !checkTPCCompatibility) { - histos.fill(HIST("h3dMassK0ShortPositive"), v0.pt(), deltaTimePositiveK0ShortPi, v0.mK0Short()); - histos.fill(HIST("h3dMassK0ShortNegative"), v0.pt(), deltaTimePositiveK0ShortPi, v0.mK0Short()); - } - if (originalV0.isdEdxLambda() || !checkTPCCompatibility) { - histos.fill(HIST("h3dMassLambdaPositive"), v0.pt(), deltaTimePositiveLambdaPr, v0.mLambda()); - histos.fill(HIST("h3dMassLambdaNegative"), v0.pt(), deltaTimeNegativeLambdaPi, v0.mLambda()); - } - if (originalV0.isdEdxAntiLambda() || !checkTPCCompatibility) { - histos.fill(HIST("h3dMassAntiLambdaPositive"), v0.pt(), deltaTimePositiveK0ShortPi, v0.mAntiLambda()); - histos.fill(HIST("h3dMassAntiLambdaNegative"), v0.pt(), deltaTimeNegativeK0ShortPi, v0.mAntiLambda()); - } } } } diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index ef9dc048c5d..833676bce8a 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -157,7 +157,7 @@ struct strangederivedbuilder { strangeCents(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centFV0A()); auto bc = collision.bc_as(); - strangeStamps(bc.timestamp(), bc.runNumber()); + strangeStamps(bc.runNumber(), bc.timestamp()); } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); @@ -182,7 +182,7 @@ struct strangederivedbuilder { strangeCents(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centFV0A()); auto bc = collision.bc_as(); - strangeStamps(bc.timestamp(), bc.runNumber()); + strangeStamps(bc.runNumber(), bc.timestamp()); } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); diff --git a/PWGLF/Tasks/QC/CMakeLists.txt b/PWGLF/Tasks/QC/CMakeLists.txt index dd6df615f88..41e8287a954 100644 --- a/PWGLF/Tasks/QC/CMakeLists.txt +++ b/PWGLF/Tasks/QC/CMakeLists.txt @@ -68,3 +68,8 @@ o2physics_add_dpl_workflow(strangenessqcpp SOURCES strangenessQCPP.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(strangepidqa + SOURCES strangepidqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/QC/strangepidqa.cxx b/PWGLF/Tasks/QC/strangepidqa.cxx new file mode 100644 index 00000000000..a27aa7df1d3 --- /dev/null +++ b/PWGLF/Tasks/QC/strangepidqa.cxx @@ -0,0 +1,120 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// This task is designed to do QA to the TOF PID applied to strangeness +// in the regular framework + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/PIDResponse.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Framework/ASoAHelpers.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; +using std::cout; +using std::endl; + +struct strangepidqa { + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + ConfigurableAxis vertexZ{"vertexZ", {30, -15.0f, 15.0f}, ""}; + + // base properties + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisRadius{"axisRadius", {200, 0.0f, 100.0f}, "V0 radius (cm)"}; + + // Invariant Mass + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.08f, 1.16f}, "M_{#Lambda} (GeV/c^{2})"}; + + // Delta time + ConfigurableAxis axisDeltaTime{"axisDeltaTime", {200, -1000.0f, +1000.0f}, "#Delta time (ps)"}; + + // Length axis + ConfigurableAxis axisLength{"axisLength", {600, 0.0f, +600.0f}, "track Length (cm)"}; + + void init(InitContext const&) + { + // Event counter + histos.add("hEventVertexZ", "hEventVertexZ", kTH1F, {vertexZ}); + + // V0 Radius + histos.add("h2dLambdaRadiusVsPt", "hLambdaRadiusVsPt", {HistType::kTH2F, {axisPt, axisRadius}}); + + // Invariant Mass + histos.add("h2dLambdaMassVsPt", "hLambdaMassVsPt", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + + // radius vs prong length + histos.add("h2dProtonLengthVsRadius", "h2dProtonLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); + histos.add("h2dPionLengthVsRadius", "h2dPionLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); + + // recalculated vs topv lengths + histos.add("h2dProtonLengthVsLengthToPV", "h2dProtonLengthVsRadiusToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); + histos.add("h2dPionLengthVsLengthToPV", "h2dPionLengthVsLengthToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); + + // TOF PID testing for prongs + histos.add("h2dProtonDeltaTimeVsPt", "h2dProtonDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dProtonDeltaTimeVsRadius", "h2dProtonDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + histos.add("h2dPionDeltaTimeVsPt", "h2dPionDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dPionDeltaTimeVsRadius", "h2dPionDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + } + + void process(aod::StraCollision const& coll, soa::Join const& v0s) + { + histos.fill(HIST("hEventVertexZ"), coll.posZ()); + + for (auto& lambda : v0s) { // selecting photons from Sigma0 + if (lambda.pdgCode() != 3122) + continue; + + histos.fill(HIST("h2dLambdaRadiusVsPt"), lambda.pt(), lambda.v0radius()); + histos.fill(HIST("h2dLambdaMassVsPt"), lambda.pt(), lambda.mLambda()); + + histos.fill(HIST("h2dProtonDeltaTimeVsPt"), lambda.pt(), lambda.posTOFDeltaTLaPr()); + histos.fill(HIST("h2dProtonDeltaTimeVsRadius"), lambda.v0radius(), lambda.posTOFDeltaTLaPr()); + histos.fill(HIST("h2dPionDeltaTimeVsPt"), lambda.pt(), lambda.negTOFDeltaTLaPi()); + histos.fill(HIST("h2dPionDeltaTimeVsRadius"), lambda.v0radius(), lambda.negTOFDeltaTLaPi()); + + histos.fill(HIST("h2dProtonLengthVsRadius"), lambda.v0radius(), lambda.posTOFLength()); + histos.fill(HIST("h2dPionLengthVsRadius"), lambda.v0radius(), lambda.negTOFLength()); + + histos.fill(HIST("h2dProtonLengthVsLengthToPV"), lambda.posTOFLengthToPV(), lambda.posTOFLength()); + histos.fill(HIST("h2dPionLengthVsLengthToPV"), lambda.negTOFLengthToPV(), lambda.negTOFLength()); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 4676841c9184b810307a4004215f2bbb84106b6a Mon Sep 17 00:00:00 2001 From: mcoquet642 <74600025+mcoquet642@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:03:38 +0100 Subject: [PATCH 126/156] [PWGDQ] Various fixes for muons (#4236) * [PWGDQ] Various fixes for muons in tableMaker * Clang format --- PWGDQ/Core/VarManager.h | 13 ++++++-- PWGDQ/TableProducer/tableMaker.cxx | 16 +++++---- PWGDQ/TableProducer/tableMakerMC.cxx | 50 +++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 16e06c6e95c..076d950bc2d 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -552,6 +552,11 @@ class VarManager : public TObject KFParticle::SetField(magField); fgUsedKF = true; } + // Setup magnetic field for muon propagation + static void SetupMuonMagField() + { + o2::mch::TrackExtrap::setField(); + } // Setup the 2 prong DCAFitterN static void SetupTwoProngDCAFitter(float magField, bool propagateToPCA, float maxR, float maxDZIni, float minParamChange, float minRelChi2Change, bool useAbsDCA) @@ -816,7 +821,6 @@ void VarManager::FillPropagateMuon(const T& muon, const C& collision, float* val o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; o2::dataformats::GlobalFwdTrack propmuon; if (static_cast(muon.trackType()) > 2) { - o2::mch::TrackExtrap::setField(); o2::dataformats::GlobalFwdTrack track; track.setParameters(tpars); track.setZ(fwdtrack.getZ()); @@ -2060,8 +2064,11 @@ void VarManager::FillPairVertexing(C const& collision, T const& t1, T const& t2, auto geoMan2 = o2::base::GeometryManager::meanMaterialBudget(t2.x(), t2.y(), t2.z(), KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY(), KFGeoTwoProng.GetZ()); auto x2x01 = static_cast(geoMan1.meanX2X0); auto x2x02 = static_cast(geoMan2.meanX2X0); - pars1.propagateToVtxhelixWithMCS(KFGeoTwoProng.GetZ(), {KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY()}, {KFGeoTwoProng.GetCovariance(0, 0), KFGeoTwoProng.GetCovariance(1, 1)}, fgFitterTwoProngFwd.getBz(), x2x01); - pars2.propagateToVtxhelixWithMCS(KFGeoTwoProng.GetZ(), {KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY()}, {KFGeoTwoProng.GetCovariance(0, 0), KFGeoTwoProng.GetCovariance(1, 1)}, fgFitterTwoProngFwd.getBz(), x2x02); + float B[3]; + float xyz[3] = {0, 0, 0}; + KFGeoTwoProng.GetFieldValue(xyz, B); + pars1.propagateToVtxhelixWithMCS(KFGeoTwoProng.GetZ(), {KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY()}, {KFGeoTwoProng.GetCovariance(0, 0), KFGeoTwoProng.GetCovariance(1, 1)}, B[2], x2x01); + pars2.propagateToVtxhelixWithMCS(KFGeoTwoProng.GetZ(), {KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY()}, {KFGeoTwoProng.GetCovariance(0, 0), KFGeoTwoProng.GetCovariance(1, 1)}, B[2], x2x02); v1 = {pars1.getPt(), pars1.getEta(), pars1.getPhi(), m1}; v2 = {pars2.getPt(), pars2.getEta(), pars2.getPhi(), m2}; v12 = v1 + v2; diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 5022f386e1c..6baa6fdc067 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -190,7 +190,6 @@ struct TableMaker { Preslice trackIndicesPerCollision = aod::track_association::collisionId; Preslice fwdtrackIndicesPerCollision = aod::track_association::collisionId; - Service ccdb; bool fDoDetailedQA = false; // Bool to set detailed QA true, if QA is set true int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. @@ -202,12 +201,12 @@ struct TableMaker { void init(o2::framework::InitContext& context) { DefineCuts(); - ccdb->setURL(fConfigCcdbUrl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); + fCCDB->setURL(fConfigCcdbUrl); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); if (fPropMuon) { if (!o2::base::GeometryManager::isGeometryLoaded()) { - ccdb->get(geoPath); + fCCDB->get(geoPath); } } @@ -360,12 +359,15 @@ struct TableMaker { } } if (fIsRun2 == true) { - grpmagrun2 = ccdb->getForTimeStamp(grpmagPathRun2, bc.timestamp()); + grpmagrun2 = fCCDB->getForTimeStamp(grpmagPathRun2, bc.timestamp()); if (grpmagrun2 != nullptr) { o2::base::Propagator::initFieldFromGRP(grpmagrun2); } } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, bc.timestamp()); + if (fPropMuon) { + VarManager::SetupMuonMagField(); + } + grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); if (grpmag != nullptr) { o2::base::Propagator::initFieldFromGRP(grpmag); } diff --git a/PWGDQ/TableProducer/tableMakerMC.cxx b/PWGDQ/TableProducer/tableMakerMC.cxx index f02a07d5dee..08dfe3d60c7 100644 --- a/PWGDQ/TableProducer/tableMakerMC.cxx +++ b/PWGDQ/TableProducer/tableMakerMC.cxx @@ -39,6 +39,13 @@ #include "PWGDQ/Core/MCSignalLibrary.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Field/MagneticField.h" +#include "TGeoGlobalMagField.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "CCDB/BasicCCDBManager.h" using std::cout; using std::endl; @@ -138,12 +145,23 @@ struct TableMakerMC { Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigDetailedQA{"cfgDetailedQA", false, "If true, include more QA histograms (BeforeCuts classes)"}; Configurable fIsAmbiguous{"cfgIsAmbiguous", false, "Whether we enable QA plots for ambiguous tracks"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fPropMuon{"cfgPropMuon", false, "Propgate muon tracks through absorber"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable grpmagPathRun2{"grpmagPathRun2", "GLO/GRP/GRP", "CCDB path of the GRPObject (Usage for Run 2)"}; + + Service fCCDB; + + o2::parameters::GRPObject* grpmagrun2 = nullptr; // for run 2, we access the GRPObject from GLO/GRP/GRP + o2::parameters::GRPMagField* grpmag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField AnalysisCompositeCut* fEventCut; //! Event selection cut std::vector fTrackCuts; //! Barrel track cuts std::vector fMuonCuts; //! Muon track cuts bool fDoDetailedQA = false; // Bool to set detailed QA true, if QA is set true + int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. // TODO: filter on TPC dedx used temporarily until electron PID will be improved Filter barrelSelectedTracks = ifnode(fIsRun2.node() == true, aod::track::trackType == uint8_t(aod::track::Run2Track), aod::track::trackType == uint8_t(aod::track::Track)) && o2::aod::track::pt >= fConfigBarrelTrackPtLow && nabs(o2::aod::track::eta) <= 0.9f; @@ -152,6 +170,15 @@ struct TableMakerMC { void init(o2::framework::InitContext& context) { + fCCDB->setURL(fConfigCcdbUrl); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + if (fPropMuon) { + if (!o2::base::GeometryManager::isGeometryLoaded()) { + fCCDB->get(geoPath); + } + } + // Define cuts -------------------------------------------------------------------------------------------- fEventCut = new AnalysisCompositeCut(true); TString eventCutStr = fConfigEventCuts.value; @@ -336,6 +363,25 @@ struct TableMakerMC { if (!collision.has_mcCollision()) { continue; } + auto bc = collision.template bc_as(); + if (fCurrentRun != bc.runNumber()) { + if (fIsRun2 == true) { + grpmagrun2 = fCCDB->getForTimeStamp(grpmagPathRun2, bc.timestamp()); + if (grpmagrun2 != nullptr) { + o2::base::Propagator::initFieldFromGRP(grpmagrun2); + } + } else { + if (fPropMuon) { + VarManager::SetupMuonMagField(); + } + grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); + if (grpmag != nullptr) { + o2::base::Propagator::initFieldFromGRP(grpmag); + } + } + fCurrentRun = bc.runNumber(); + } + // get the trigger aliases uint32_t triggerAliases = collision.alias_raw(); // store the selection decisions @@ -345,7 +391,6 @@ struct TableMakerMC { } auto mcCollision = collision.mcCollision(); - auto bc = collision.template bc_as(); VarManager::ResetValues(0, VarManager::kNEventWiseVariables); VarManager::fgValues[VarManager::kRunNo] = bc.runNumber(); VarManager::fgValues[VarManager::kBC] = bc.globalBC(); @@ -613,6 +658,9 @@ struct TableMakerMC { } VarManager::FillTrack(muon); + if (fPropMuon) { + VarManager::FillPropagateMuon(muon, collision); + } if (muon.index() > idxPrev + 1) { // checks if some muons are filtered even before the skimming function nDel += muon.index() - (idxPrev + 1); From 4b65f8657139e5138dcccb35a9da904a3d50f4f2 Mon Sep 17 00:00:00 2001 From: Shyam Kumar Date: Mon, 8 Jan 2024 10:26:08 +0100 Subject: [PATCH 127/156] PWGHF: Derived data table for the event mixing (#4214) * Event Mixing added * Event Mixing added * Event Mixing Implemented * Mixed event implemented * Please consider the following formatting changes * Fixed for using and Filter guidelines * Please consider the following formatting changes * Comments implemented * Comments implemented * Fixed for comments * Please consider the following formatting changes * Fixing comment for D-meson as suggested. * Fixed comments * Please consider the following formatting changes * Fixed for error in built * Sort includes and fixed float at line 72-73 I fixed the recent comment to sort all the includes w.r.t. directories and also double changed to float as suggested at line 72-73. * Update correlatorDplusHadrons.cxx PtBins increased by 1 to avoid vector range error. Default selection flag = 7 to make it similar to taskDplus * Please consider the following formatting changes * Fixed vector for size * Fixed vector for the error also in the task * Update correlatorDplusHadrons.cxx * Update taskCorrelationDplusHadrons.cxx * Update PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx Co-authored-by: Fabrizio * Update taskCorrelationDplusHadrons.cxx * Please consider the following formatting changes * Update CorrelationTables.h * Update CorrelationTables.h * Update correlatorDplusHadrons.cxx * Please consider the following formatting changes * Update CorrelationTables.h * Update CorrelationTables.h * Please consider the following formatting changes * Update correlatorDplusHadrons.cxx * Please consider the following formatting changes * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot Co-authored-by: Fabrizio --- PWGHF/HFC/DataModel/CorrelationTables.h | 40 +++++++++++++++++++ .../TableProducer/correlatorDplusHadrons.cxx | 15 +++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index a383c78e7c4..b92e6beb80f 100644 --- a/PWGHF/HFC/DataModel/CorrelationTables.h +++ b/PWGHF/HFC/DataModel/CorrelationTables.h @@ -137,6 +137,46 @@ DECLARE_SOA_TABLE(DsHadronRecoInfo, "AOD", "DSHRECOINFO", //! Ds-Hadrons pairs R DECLARE_SOA_TABLE(DsHadronGenInfo, "AOD", "DSHGENINFO", //! Ds-Hadrons pairs Generated Informations aod::hf_correlation_ds_hadron::IsPrompt); +// definition of columns and tables for Dplus properties +namespace hf_dplus_meson +{ +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi of D+ +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta of D+ +DECLARE_SOA_COLUMN(PtD, ptD, float); //! Transverse momentum of D+ +DECLARE_SOA_COLUMN(MD, mD, float); //! Invariant mass of D+ +DECLARE_SOA_COLUMN(PoolBin, poolBin, int); //! Pool Bin of event defined using zvtx and multiplicity +DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collision +DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision +} // namespace hf_dplus_meson + +DECLARE_SOA_TABLE(Dplus, "AOD", "DPLUS", //! D+-meson properties + aod::hf_dplus_meson::Phi, + aod::hf_dplus_meson::Eta, + aod::hf_dplus_meson::PtD, + aod::hf_dplus_meson::MD, + aod::hf_dplus_meson::PoolBin, + aod::hf_dplus_meson::GIndexCol, + aod::hf_dplus_meson::TimeStamp); + +// definition of columns and tables for associated hadron properties +namespace hf_assoc_tracks +{ +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi of hadron +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta of hadron +DECLARE_SOA_COLUMN(PtH, ptH, float); //! Transverse momentum of hadron +DECLARE_SOA_COLUMN(PoolBin, poolBin, int); //! Pool Bin of event defined using zvtx and multiplicity +DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collision +DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision +} // namespace hf_assoc_tracks + +DECLARE_SOA_TABLE(Hadron, "AOD", "HADRON", //! Associated hadron properties + aod::hf_assoc_tracks::Phi, + aod::hf_assoc_tracks::Eta, + aod::hf_assoc_tracks::PtH, + aod::hf_assoc_tracks::PoolBin, + aod::hf_assoc_tracks::GIndexCol, + aod::hf_assoc_tracks::TimeStamp); + // definition of columns and tables for Dplus-Hadron correlation pairs namespace hf_correlation_dplus_hadron { diff --git a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx index 9e9ea123395..9e223991d31 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx @@ -154,6 +154,8 @@ struct HfDplusSelection { struct HfCorrelatorDplusHadrons { Produces entryDplusHadronPair; Produces entryDplusHadronRecoInfo; + Produces entryDplus; + Produces entryHadron; Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for Dplus"}; // 7 corresponds to topo+PID cuts Configurable applyEfficiency{"applyEfficiency", 1, "Flag for applying D-meson efficiency weights"}; @@ -238,8 +240,11 @@ struct HfCorrelatorDplusHadrons { /// Dplus-hadron correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) void processData(soa::Join::iterator const& collision, aod::TracksWDca const& tracks, - soa::Join const& candidates) + soa::Join const& candidates, aod::BCsWithTimestamps const&) { + auto bc = collision.bc_as(); + int gCollisionId = collision.globalIndex(); + int64_t timeStamp = bc.timestamp(); if (selectedDplusCandidates.size() > 0) { int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFV0M())); int nTracks = 0; @@ -263,7 +268,7 @@ struct HfCorrelatorDplusHadrons { registry.fill(HIST("hMultiplicity"), nTracks); auto selectedDplusCandidatesGrouped = selectedDplusCandidates->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - + int cntDplus = 0; for (const auto& candidate1 : selectedDplusCandidatesGrouped) { if (yCandMax >= 0. && std::abs(hfHelper.yDplus(candidate1)) > yCandMax) { continue; @@ -294,6 +299,7 @@ struct HfCorrelatorDplusHadrons { registry.fill(HIST("hY"), hfHelper.yDplus(candidate1)); registry.fill(HIST("hSelectionStatus"), candidate1.isSelDplusToPiKPi()); registry.fill(HIST("hDplusBin"), poolBin); + entryDplus(candidate1.phi(), candidate1.eta(), candidate1.pt(), hfHelper.invMassDplusToPiKPi(candidate1), poolBin, gCollisionId, timeStamp); // Dplus-Hadron correlation dedicated section // if the candidate is a Dplus, search for Hadrons and evaluate correlations for (const auto& track : tracks) { @@ -315,8 +321,11 @@ struct HfCorrelatorDplusHadrons { candidate1.pt(), track.pt(), poolBin); entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate1), 0); + if (cntDplus == 0) + entryHadron(track.phi(), track.eta(), track.pt(), poolBin, gCollisionId, timeStamp); } // Hadron Tracks loop - } // end outer Dplus loop + cntDplus++; + } // end outer Dplus loop registry.fill(HIST("hZvtx"), collision.posZ()); registry.fill(HIST("hMultV0M"), collision.multFV0M()); } From 7aa9907107789dcd207e7984ab49802ea2381547 Mon Sep 17 00:00:00 2001 From: alcaliva <32872606+alcaliva@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:35:30 +0100 Subject: [PATCH 128/156] Reduced Range QC Plots (#4248) --- PWGLF/Tasks/nuclei_in_jets.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/nuclei_in_jets.cxx index 6460dcb1f4f..173b351b539 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/nuclei_in_jets.cxx @@ -125,8 +125,8 @@ struct nuclei_in_jets { registryQC.add("jet_multiplicity", "jet multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("ue_multiplicity", "underlying-event multiplicity", HistType::kTH1F, {{100, 0, 100, "#it{N}_{ch}"}}); registryQC.add("pt_leading", "pt leading", HistType::kTH1F, {{500, 0, 50, "#it{p}_{T} (GeV/#it{c})"}}); - registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, -TMath::Pi(), TMath::Pi(), "#Delta#phi"}}); - registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{100, -0.5, 0.5, "#Delta#eta"}, {100, -TMath::Pi(), TMath::Pi(), "#Delta#phi"}}); + registryQC.add("eta_phi_jet", "DeltaEta DeltaPhi jet", HistType::kTH2F, {{200, -0.5, 0.5, "#Delta#eta"}, {200, 0, 0.5 * TMath::Pi(), "#Delta#phi"}}); + registryQC.add("eta_phi_ue", "DeltaEta DeltaPhi UE", HistType::kTH2F, {{200, -0.5, 0.5, "#Delta#eta"}, {200, 0, 0.5 * TMath::Pi(), "#Delta#phi"}}); registryQC.add("r_max_jet", "R Max jet", HistType::kTH1F, {{200, 0.0, 6.0, "#it{R}_{max}"}}); registryQC.add("r_jet", "R jet", HistType::kTH1F, {{200, 0.0, 1.0, "#it{R}"}}); registryQC.add("r_ue", "R ue", HistType::kTH1F, {{200, 0.0, 1.0, "#it{R}"}}); From 749f9807e5f4411d48a749c3eab8e9374631793b Mon Sep 17 00:00:00 2001 From: Andrea Sofia Triolo Date: Mon, 8 Jan 2024 15:13:52 +0100 Subject: [PATCH 129/156] [PWGLF] nonPromptCascade task - adding tables production (#4224) * Starting tables production nonPromptCascade * Fix nonPromptCascade task * Modifying tables * nonPromptCascade - Finalizing tables for data and MC --- PWGLF/DataModel/LFNonPromptCascadeTables.h | 177 ++++++++ PWGLF/Tasks/nonPromptCascade.cxx | 477 +++++++++++++++++---- 2 files changed, 562 insertions(+), 92 deletions(-) create mode 100644 PWGLF/DataModel/LFNonPromptCascadeTables.h diff --git a/PWGLF/DataModel/LFNonPromptCascadeTables.h b/PWGLF/DataModel/LFNonPromptCascadeTables.h new file mode 100644 index 00000000000..7b8d32c76f6 --- /dev/null +++ b/PWGLF/DataModel/LFNonPromptCascadeTables.h @@ -0,0 +1,177 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file LFNonPromptCascadeTable.h +/// \brief Non prompt cascade tables +/// + +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" + +#ifndef PWGLF_DATAMODEL_LFNONPROMPTCASCADETABLES_H_ +#define PWGLF_DATAMODEL_LFNONPROMPTCASCADETABLES_H_ + +namespace o2::aod +{ +namespace NPCascadeTable +{ +DECLARE_SOA_COLUMN(CascPt, cascPt, float); +DECLARE_SOA_COLUMN(CascEta, cascEta, float); +DECLARE_SOA_COLUMN(CascPhi, cascPhi, float); + +DECLARE_SOA_COLUMN(CascDCAxy, cascDCAxy, float); +DECLARE_SOA_COLUMN(CascDCAz, cascDCAz, float); +DECLARE_SOA_COLUMN(ProtonDCAxy, protonDCAxy, float); +DECLARE_SOA_COLUMN(ProtonDCAz, protonDCAz, float); +DECLARE_SOA_COLUMN(PionDCAxy, pionDCAxy, float); +DECLARE_SOA_COLUMN(PionDCAz, pionDCAz, float); +DECLARE_SOA_COLUMN(BachDCAxy, bachDCAxy, float); +DECLARE_SOA_COLUMN(BachDCAz, bachDCAz, float); + +DECLARE_SOA_COLUMN(CascCosPA, casccosPA, float); +DECLARE_SOA_COLUMN(V0CosPA, v0cosPA, float); + +DECLARE_SOA_COLUMN(MassXi, massXi, double); +DECLARE_SOA_COLUMN(MassOmega, massOmega, double); +DECLARE_SOA_COLUMN(MassV0, massV0, double); + +DECLARE_SOA_COLUMN(CascRadius, cascRadius, float); +DECLARE_SOA_COLUMN(V0Radius, v0Radius, float); + +DECLARE_SOA_COLUMN(CascLenght, cascLenght, float); +DECLARE_SOA_COLUMN(V0Lenght, v0Lenght, float); + +DECLARE_SOA_COLUMN(CascNClusITS, cascNClusITS, int); +DECLARE_SOA_COLUMN(ProtonNClusITS, protonNClusITS, int); +DECLARE_SOA_COLUMN(PionNClusITS, pionNClusITS, int); +DECLARE_SOA_COLUMN(BachKaonNClusITS, bachKaonNClusITS, int); +DECLARE_SOA_COLUMN(BachPionNClusITS, bachPionNClusITS, int); + +DECLARE_SOA_COLUMN(ProtonNClusTPC, protonNClusTPC, int); +DECLARE_SOA_COLUMN(PionNClusTPC, pionNClusTPC, int); +DECLARE_SOA_COLUMN(BachKaonNClusTPC, bachKaonNClusTPC, int); +DECLARE_SOA_COLUMN(BachPionNClusTPC, bachPionNClusTPC, int); + +DECLARE_SOA_COLUMN(ProtonTPCNSigma, protonTPCNSigma, float); +DECLARE_SOA_COLUMN(PionTPCNSigma, pionTPCNSigma, float); +DECLARE_SOA_COLUMN(BachKaonTPCNSigma, bachKaonTPCNSigma, float); +DECLARE_SOA_COLUMN(BachPionTPCNSigma, bachPionTPCNSigma, float); + +DECLARE_SOA_COLUMN(ProtonHasTOF, protonHasTOF, bool); +DECLARE_SOA_COLUMN(PionHasTOF, pionHasTOF, bool); +DECLARE_SOA_COLUMN(BachKaonHasTOF, bachKaonHasTOF, bool); +DECLARE_SOA_COLUMN(BachPionHasTOF, bachPionHasTOF, bool); + +DECLARE_SOA_COLUMN(ProtonTOFNSigma, protonTOFNSigma, float); +DECLARE_SOA_COLUMN(PionTOFNSigma, pionTOFNSigma, float); +DECLARE_SOA_COLUMN(BachKaonTOFNSigma, bachKaonTOFNSigma, float); +DECLARE_SOA_COLUMN(BachPionTOFNSigma, bachPionTOFNSigma, float); + +DECLARE_SOA_COLUMN(gPt, genPt, float); +DECLARE_SOA_COLUMN(gEta, genEta, float); +DECLARE_SOA_COLUMN(gPhi, genPhi, float); +DECLARE_SOA_COLUMN(PDGcode, pdgCode, int); + +} // namespace NPCascadeTable +DECLARE_SOA_TABLE(NPCascTable, "AOD", "NPCASCTABLE", + NPCascadeTable::CascPt, + NPCascadeTable::CascEta, + NPCascadeTable::CascPhi, + NPCascadeTable::CascDCAxy, + NPCascadeTable::CascDCAz, + NPCascadeTable::ProtonDCAxy, + NPCascadeTable::ProtonDCAz, + NPCascadeTable::PionDCAxy, + NPCascadeTable::PionDCAz, + NPCascadeTable::BachDCAxy, + NPCascadeTable::BachDCAz, + NPCascadeTable::CascCosPA, + NPCascadeTable::V0CosPA, + NPCascadeTable::MassXi, + NPCascadeTable::MassOmega, + NPCascadeTable::MassV0, + NPCascadeTable::CascRadius, + NPCascadeTable::V0Radius, + NPCascadeTable::CascLenght, + NPCascadeTable::V0Lenght, + NPCascadeTable::CascNClusITS, + NPCascadeTable::ProtonNClusITS, + NPCascadeTable::PionNClusITS, + NPCascadeTable::BachKaonNClusITS, + NPCascadeTable::BachPionNClusITS, + NPCascadeTable::ProtonNClusTPC, + NPCascadeTable::PionNClusTPC, + NPCascadeTable::BachKaonNClusTPC, + NPCascadeTable::BachPionNClusTPC, + NPCascadeTable::ProtonTPCNSigma, + NPCascadeTable::PionTPCNSigma, + NPCascadeTable::BachKaonTPCNSigma, + NPCascadeTable::BachPionTPCNSigma, + NPCascadeTable::ProtonHasTOF, + NPCascadeTable::PionHasTOF, + NPCascadeTable::BachKaonHasTOF, + NPCascadeTable::BachPionHasTOF, + NPCascadeTable::ProtonTOFNSigma, + NPCascadeTable::PionTOFNSigma, + NPCascadeTable::BachKaonTOFNSigma, + NPCascadeTable::BachPionTOFNSigma) + +DECLARE_SOA_TABLE(NPCascTableMC, "AOD", "NPCASCTABLEMC", + NPCascadeTable::CascPt, + NPCascadeTable::CascEta, + NPCascadeTable::CascPhi, + NPCascadeTable::CascDCAxy, + NPCascadeTable::CascDCAz, + NPCascadeTable::ProtonDCAxy, + NPCascadeTable::ProtonDCAz, + NPCascadeTable::PionDCAxy, + NPCascadeTable::PionDCAz, + NPCascadeTable::BachDCAxy, + NPCascadeTable::BachDCAz, + NPCascadeTable::CascCosPA, + NPCascadeTable::V0CosPA, + NPCascadeTable::MassXi, + NPCascadeTable::MassOmega, + NPCascadeTable::MassV0, + NPCascadeTable::CascRadius, + NPCascadeTable::V0Radius, + NPCascadeTable::CascLenght, + NPCascadeTable::V0Lenght, + NPCascadeTable::CascNClusITS, + NPCascadeTable::ProtonNClusITS, + NPCascadeTable::PionNClusITS, + NPCascadeTable::BachKaonNClusITS, + NPCascadeTable::BachPionNClusITS, + NPCascadeTable::ProtonNClusTPC, + NPCascadeTable::PionNClusTPC, + NPCascadeTable::BachKaonNClusTPC, + NPCascadeTable::BachPionNClusTPC, + NPCascadeTable::ProtonTPCNSigma, + NPCascadeTable::PionTPCNSigma, + NPCascadeTable::BachKaonTPCNSigma, + NPCascadeTable::BachPionTPCNSigma, + NPCascadeTable::ProtonHasTOF, + NPCascadeTable::PionHasTOF, + NPCascadeTable::BachKaonHasTOF, + NPCascadeTable::BachPionHasTOF, + NPCascadeTable::ProtonTOFNSigma, + NPCascadeTable::PionTOFNSigma, + NPCascadeTable::BachKaonTOFNSigma, + NPCascadeTable::BachPionTOFNSigma, + NPCascadeTable::gPt, + NPCascadeTable::gEta, + NPCascadeTable::gPhi, + NPCascadeTable::PDGcode) + +} // namespace o2::aod + +#endif // PWGLF_DATAMODEL_LFNONPROMPTCASCADETABLES_H_ diff --git a/PWGLF/Tasks/nonPromptCascade.cxx b/PWGLF/Tasks/nonPromptCascade.cxx index 62e6251ec8b..cd7f79e8073 100644 --- a/PWGLF/Tasks/nonPromptCascade.cxx +++ b/PWGLF/Tasks/nonPromptCascade.cxx @@ -9,31 +9,93 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" +#include "CCDB/BasicCCDBManager.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/DCA.h" -#include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DetectorsBase/Propagator.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsTPC/BetheBlochAleph.h" +#include "DCAFitter/DCAFitterN.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +// #include "PWGHF/Core/PDG.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "ReconstructionDataFormats/DCA.h" +#include "ReconstructionDataFormats/Track.h" +#include "PWGLF/DataModel/LFNonPromptCascadeTables.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +struct NPCascCandidate { + int globalIndex; + float cascPt; + float cascEta; + float cascPhi; + float cascDCAxy; + float cascDCAz; + float protonDCAxy; + float protonDCAz; + float pionDCAxy; + float pionDCAz; + float bachDCAxy; + float bachDCAz; + float casccosPA; + float v0cosPA; + double massXi; + double massOmega; + double massV0; + float cascRadius; + float v0radius; + float cascLength; + float v0length; + int cascNClusITS; + int protonNClusITS; + int pionNClusITS; + int bachKaonNClusITS; + int bachPionNClusITS; + int protonNClusTPC; + int pionNClusTPC; + int bachKaonNClusTPC; + int bachPionNClusTPC; + float protonTPCNSigma; + float pionTPCNSigma; + float bachKaonTPCNSigma; + float bachPionTPCNSigma; + bool protonHasTOF; + bool pionHasTOF; + bool bachKaonHasTOF; + bool bachPionHasTOF; + float protonTOFNSigma; + float pionTOFNSigma; + float bachKaonTOFNSigma; + float bachPionTOFNSigma; +}; + +struct motherDCA { + float DCAxy; + float DCAz; +}; + +struct daughtersDCA { + float bachDCAxy; + float bachDCAz; + float protonDCAxy; + float protonDCAz; + float pionDCAxy; + float pionDCAz; +}; + namespace { static constexpr int nParticles{4}; @@ -54,17 +116,29 @@ std::shared_ptr invMassBCOmega; std::shared_ptr invMassACOmega; std::shared_ptr invMassBCXi; std::shared_ptr invMassACXi; +std::shared_ptr invMassBCV0; +std::shared_ptr invMassACV0; + +std::vector candidates; } // namespace struct NonPromptCascadeTask { - using TracksExtData = soa::Join; - using TracksExtMC = soa::Join; + Produces NPCTable; + Produces NPCTableMC; + + using TracksExtData = soa::Join; + using TracksExtMC = soa::Join; using CollisionCandidatesRun3 = soa::Join::iterator; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable bz{"bz", -50., "magnetic field"}; + Configurable propToDCA{"propToDCA", true, "create tracks version propagated to PCA"}; + Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; + Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"}; Configurable cfgGRPmagPath{"cfgGRPmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable cfgGRPpath{"cfgGRPpath", "GLO/GRP/GRP", "Path of the grp file"}; @@ -74,7 +148,7 @@ struct NonPromptCascadeTask { Service ccdb; int mRunNumber = 0; - float mBz = 0.f; + float bz = 0.f; HistogramRegistry registry{ "registry", @@ -114,27 +188,27 @@ struct NonPromptCascadeTask { {"h_buildermassvspt_Xi", "Mass (from builder) vs p_{T};Mass (GeV/#it{c}^2);p_{T} (GeV/#it{c})", {HistType::kTH2D, {{125, 1.296, 1.346}, {50, 0., 10.}}}}, {"h_massvsmass_Xi", "Mass vs mass;Mass (GeV/#it{c}^{2});Mass (GeV/#it{c}^{2})", {HistType::kTH2D, {{125, 1.296, 1.346}, {125, 1.296, 1.346}}}}, {"h_bachelorsign_Xi", "Bachelor sign;Sign;Counts", {HistType::kTH1D, {{6, -3., 3.}}}}, + + {"h_massvspt_V0", "Mass vs p_{T};Mass (GeV/#it{c}^2);p_{T} (GeV/#it{c})", {HistType::kTH2D, {{125, 1.090, 1.140}, {50, 0., 10.}}}}, + }}; void initCCDB(aod::BCsWithTimestamps::iterator const& bc) { - - if (mRunNumber == bc.runNumber()) { - return; - } - LOG(debug) << "Run number: " << mRunNumber << " bc runNumber: " << bc.runNumber(); - - auto run3grp_timestamp = bc.timestamp(); - mRunNumber = bc.runNumber(); - - if (o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(cfgGRPpath, run3grp_timestamp)) { - o2::base::Propagator::initFieldFromGRP(grpo); - LOG(debug) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG"; - } else if (o2::parameters::GRPMagField* grpmag = ccdb->getForTimeStamp(cfgGRPmagPath, run3grp_timestamp)) { - o2::base::Propagator::initFieldFromGRP(grpmag); - LOG(debug) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG"; - } else { - LOG(fatal) << "Got nullptr from CCDB for path " << cfgGRPpath << " of object GRPMagField and " << cfgGRPmagPath << " of object GRPObject for timestamp " << run3grp_timestamp; + if (mRunNumber != bc.runNumber()) { + mRunNumber = bc.runNumber(); + auto timestamp = bc.timestamp(); + + if (o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(cfgGRPpath, timestamp)) { + o2::base::Propagator::initFieldFromGRP(grpo); + bz = grpo->getNominalL3Field(); + } else if (o2::parameters::GRPMagField* grpmag = ccdb->getForTimeStamp(cfgGRPmagPath, timestamp)) { + o2::base::Propagator::initFieldFromGRP(grpmag); + bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + LOG(debug) << "bz = " << bz; + } else { + LOG(fatal) << "Got nullptr from CCDB for path " << cfgGRPmagPath << " of object GRPMagField and " << cfgGRPpath << " of object GRPObject for timestamp " << timestamp; + } } return; } @@ -174,23 +248,18 @@ struct NonPromptCascadeTask { invMassACOmega = registry.add("h_invariantmass_afterCuts_Omega", "Invariant Mass (GeV/#it{c}^{2})", HistType::kTH1D, {{125, 1.650, 1.700, "Invariant Mass (GeV/#it{c}^{2})"}}); invMassBCXi = registry.add("h_invariantmass_beforeCuts_Xi", "Invariant Mass (GeV/#it{c}^{2})", HistType::kTH1D, {{125, 1.296, 1.346, "Invariant Mass (GeV/#it{c}^{2})"}}); invMassACXi = registry.add("h_invariantmass_afterCuts_Xi", "Invariant Mass (GeV/#it{c}^{2})", HistType::kTH1D, {{125, 1.296, 1.346, "Invariant Mass (GeV/#it{c}^{2})"}}); + invMassBCV0 = registry.add("h_invariantmass_beforeCuts_V0", "Invariant Mass (GeV/#it{c}^{2})", HistType::kTH1D, {{125, 1.090, 1.140, "Invariant Mass (GeV/#it{c}^{2})"}}); + invMassACV0 = registry.add("h_invariantmass_afterCuts_V0", "Invariant Mass (GeV/#it{c}^{2})", HistType::kTH1D, {{125, 1.090, 1.140, "Invariant Mass (GeV/#it{c}^{2})"}}); } - template - void fillCascadeDCA(TC const& trackedCascade, T const track, B const bachelor, PR const& protonTrack, PI const& pionTrack, o2::dataformats::VertexBase primaryVertex, bool isOmega) + template + void fillCascadeDCA(T const track, PR const& protonTrack, PI const& pionTrack, o2::dataformats::VertexBase primaryVertex, bool isOmega, motherDCA& mDCA) { const auto matCorr = static_cast(cfgMaterialCorrection.value); - std::array, 2> momenta; - std::array masses; auto trackCovTrk = getTrackParCov(track); o2::dataformats::DCA impactParameterTrk; - if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovTrk, mBz, 2.f, matCorr, &impactParameterTrk)) { - momenta[0] = {protonTrack.px() + pionTrack.px(), protonTrack.py() + pionTrack.py(), protonTrack.pz() + pionTrack.pz()}; - momenta[1] = {bachelor.px(), bachelor.py(), bachelor.pz()}; - masses = {constants::physics::MassLambda, constants::physics::MassKaonCharged}; - const auto massOmega = RecoDecay::m(momenta, masses); - + if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovTrk, bz, 2.f, matCorr, &impactParameterTrk)) { if (protonTrack.hasTPC() && pionTrack.hasTPC()) { if (isOmega) { registry.fill(HIST("h_dca_Omega"), TMath::Sqrt(impactParameterTrk.getR2())); @@ -198,33 +267,29 @@ struct NonPromptCascadeTask { registry.fill(HIST("h_dcaz_Omega"), impactParameterTrk.getZ()); registry.fill(HIST("h_dcavspt_Omega"), impactParameterTrk.getY(), track.pt()); registry.fill(HIST("h_dcavsr_Omega"), impactParameterTrk.getY(), std::hypot(track.x(), track.y())); - registry.fill(HIST("h_massvspt_Omega"), massOmega, track.pt()); } } - masses = {constants::physics::MassLambda, constants::physics::MassPionCharged}; - const auto massXi = RecoDecay::m(momenta, masses); - if (protonTrack.hasTPC() && pionTrack.hasTPC()) { registry.fill(HIST("h_dca_Xi"), TMath::Sqrt(impactParameterTrk.getR2())); registry.fill(HIST("h_dcaxy_Xi"), impactParameterTrk.getY()); registry.fill(HIST("h_dcaz_Xi"), impactParameterTrk.getZ()); registry.fill(HIST("h_dcavspt_Xi"), impactParameterTrk.getY(), track.pt()); registry.fill(HIST("h_dcavsr_Xi"), impactParameterTrk.getY(), std::hypot(track.x(), track.y())); - registry.fill(HIST("h_massvspt_Xi"), massXi, track.pt()); } } + mDCA.DCAxy = impactParameterTrk.getY(); + mDCA.DCAz = impactParameterTrk.getZ(); } template - void fillDauDCA(TC const& trackedCascade, B const& bachelor, PR const& protonTrack, PI const& pionTrack, o2::dataformats::VertexBase primaryVertex, bool isOmega) + void fillDauDCA(TC const& trackedCascade, B const& bachelor, PR const& protonTrack, PI const& pionTrack, o2::dataformats::VertexBase primaryVertex, bool isOmega, daughtersDCA& dDCA) { - const auto matCorr = static_cast(cfgMaterialCorrection.value); auto trackCovBach = getTrackParCov(bachelor); o2::dataformats::DCA impactParameterBach; - if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovBach, mBz, 2.f, matCorr, &impactParameterBach)) { + if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovBach, bz, 2.f, matCorr, &impactParameterBach)) { if (isOmega) { if (bachelor.sign() < 0) { registry.fill(HIST("h_bachdcaxyM_Omega"), impactParameterBach.getY()); @@ -250,30 +315,39 @@ struct NonPromptCascadeTask { } auto trackCovNtrack = getTrackParCov(pionTrack); - o2::dataformats::DCA impactParameterNtrack; - if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovNtrack, mBz, 2.f, matCorr, &impactParameterNtrack)) { + o2::dataformats::DCA impactParameterPiontrack; + if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovNtrack, bz, 2.f, matCorr, &impactParameterPiontrack)) { if (isOmega) { - registry.fill(HIST("h_ntrackdcavspt_Omega"), impactParameterNtrack.getY(), pionTrack.pt()); + registry.fill(HIST("h_ntrackdcavspt_Omega"), impactParameterPiontrack.getY(), pionTrack.pt()); } - registry.fill(HIST("h_ntrackdcavspt_Xi"), impactParameterNtrack.getY(), pionTrack.pt()); + registry.fill(HIST("h_ntrackdcavspt_Xi"), impactParameterPiontrack.getY(), pionTrack.pt()); } auto trackCovPtrack = getTrackParCov(protonTrack); - o2::dataformats::DCA impactParameterPtrack; - if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovPtrack, mBz, 2.f, matCorr, &impactParameterPtrack)) { + o2::dataformats::DCA impactParameterProtontrack; + if (o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackCovPtrack, bz, 2.f, matCorr, &impactParameterProtontrack)) { if (isOmega) { - registry.fill(HIST("h_ptrackdcavspt_Omega"), impactParameterPtrack.getY(), protonTrack.pt()); + registry.fill(HIST("h_ptrackdcavspt_Omega"), impactParameterProtontrack.getY(), protonTrack.pt()); } - registry.fill(HIST("h_ptrackdcavspt_Xi"), impactParameterPtrack.getY(), protonTrack.pt()); + registry.fill(HIST("h_ptrackdcavspt_Xi"), impactParameterProtontrack.getY(), protonTrack.pt()); } + + dDCA.bachDCAxy = impactParameterBach.getY(); + dDCA.bachDCAz = impactParameterBach.getZ(); + dDCA.protonDCAxy = impactParameterProtontrack.getY(); + dDCA.protonDCAz = impactParameterProtontrack.getZ(); + dDCA.pionDCAxy = impactParameterPiontrack.getY(); + dDCA.pionDCAz = impactParameterPiontrack.getZ(); } void processTrackedCascadesMC(CollisionCandidatesRun3 const& collision, aod::AssignedTrackedCascades const& trackedCascades, aod::Cascades const& cascades, aod::V0s const& v0s, TracksExtMC const& tracks, soa::Join const& trackedcascdata, - aod::McParticles const& mcParticles, aod::BCsWithTimestamps const&) + aod::McParticles const& mcParticles, aod::BCsWithTimestamps const&, + aod::McTrackLabels const& trackLabelsMC) { + candidates.clear(); bool isOmega{false}; auto bc = collision.bc_as(); @@ -281,6 +355,15 @@ struct NonPromptCascadeTask { const auto primaryVertex = getPrimaryVertex(collision); + o2::vertexing::DCAFitterN<2> df2; + df2.setBz(bz); + df2.setPropagateToPCA(propToDCA); + df2.setMaxR(maxR); + df2.setMaxDZIni(maxDZIni); + df2.setMinParamChange(minParamChange); + df2.setMinRelChi2Change(minRelChi2Change); + df2.setUseAbsDCA(useAbsDCA); + for (const auto& trackedCascadeData : trackedcascdata) { registry.fill(HIST("h_buildermassvspt_Omega"), trackedCascadeData.mOmega(), trackedCascadeData.pt()); registry.fill(HIST("h_buildermassvspt_Xi"), trackedCascadeData.mXi(), trackedCascadeData.pt()); @@ -290,7 +373,7 @@ struct NonPromptCascadeTask { isOmega = false; - const auto track = trackedCascade.track_as(); + const auto& track = trackedCascade.track_as(); const auto& casc = trackedCascade.cascade(); const auto& bachelor = casc.bachelor_as(); const auto& v0 = casc.v0(); @@ -299,32 +382,98 @@ struct NonPromptCascadeTask { const auto& protonTrack = bachelor.sign() > 0 ? ntrack : ptrack; const auto& pionTrack = bachelor.sign() > 0 ? ptrack : ntrack; + std::array, 2> momenta; + std::array masses; + + // track propagation + o2::track::TrackParCov trackParCovV0; + o2::track::TrackPar trackParV0; + o2::track::TrackPar trackParBachelor; + + float cascCpa = -1; + float v0Cpa = -1; + + std::array v0Pos = {-999., -999., -999.}; + + if (df2.process(getTrackParCov(pionTrack), getTrackParCov(protonTrack))) { + trackParCovV0 = df2.createParentTrackParCov(0); // V0 track retrieved from p and pi daughters + v0Pos = {trackParCovV0.getX(), trackParCovV0.getY(), trackParCovV0.getZ()}; + if (df2.process(trackParCovV0, getTrackParCov(bachelor))) { + trackParV0 = df2.getTrackParamAtPCA(0); + trackParBachelor = df2.getTrackParamAtPCA(1); + trackParV0.getPxPyPzGlo(momenta[0]); // getting the V0 momentum + trackParBachelor.getPxPyPzGlo(momenta[1]); // getting the bachelor momentum + std::array pVec; + df2.createParentTrackParCov().getPxPyPzGlo(pVec); + std::array pvPos = {primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}; + cascCpa = RecoDecay::cpa(pvPos, df2.getPCACandidate(), pVec); + v0Cpa = RecoDecay::cpa(pvPos, df2.getPCACandidate(), momenta[0]); + } else { + continue; + } + } else { + continue; + } + + // Omega + masses = {o2::constants::physics::MassLambda0, o2::constants::physics::MassKPlus}; + const auto massOmega = RecoDecay::m(momenta, masses); + + // Xi + masses = {o2::constants::physics::MassLambda0, o2::constants::physics::MassPiPlus}; + const auto massXi = RecoDecay::m(momenta, masses); + + // Lambda + masses = {o2::constants::physics::MassProton, o2::constants::physics::MassPiMinus}; + momenta[0] = {protonTrack.px(), protonTrack.py(), protonTrack.pz()}; + momenta[1] = {pionTrack.px(), pionTrack.py(), pionTrack.pz()}; + const auto v0mass = RecoDecay::m(momenta, masses); + ////Omega hypohesis -> rejecting Xi - if (TMath::Abs(trackedCascade.xiMass() - constants::physics::MassXiMinus) > 0.005) { + if (TMath::Abs(massXi - constants::physics::MassXiMinus) > 0.005) { isOmega = true; - invMassBCOmega->Fill(trackedCascade.omegaMass()); + invMassBCOmega->Fill(massOmega); } - invMassBCXi->Fill(trackedCascade.xiMass()); + invMassBCXi->Fill(massXi); + invMassBCV0->Fill(v0mass); + + registry.fill(HIST("h_PIDcutsOmega"), 0, massOmega); + registry.fill(HIST("h_PIDcutsXi"), 0, massXi); - registry.fill(HIST("h_PIDcutsOmega"), 0, trackedCascade.omegaMass()); - registry.fill(HIST("h_PIDcutsXi"), 0, trackedCascade.xiMass()); + int bachKaonNClusTPC = -1; + int bachPionNClusTPC = -1; + int bachKaonNClusITS = -1; + int bachPionNClusITS = -1; + if (isOmega) { + bachKaonNClusTPC = bachelor.tpcNClsFound(); + bachKaonNClusITS = bachelor.itsNCls(); + } + bachPionNClusTPC = bachelor.tpcNClsFound(); /// by default cascade = Xi + bachPionNClusITS = bachelor.itsNCls(); /// by default cascade = Xi + + bool bachKaonHasTOF = 0; + bool bachPionHasTOF = 0; + if (isOmega) { + bachKaonHasTOF = bachelor.hasTOF(); + } + bachPionHasTOF = bachelor.hasTOF(); // if (!bachelor.hasTOF() && !ptrack.hasTOF() && !ntrack.hasTOF()) { // LOG(debug) << "no TOF: " << bachelor.hasTOF() << "/" << ptrack.hasTOF() << "/" << ntrack.hasTOF(); // continue; // } - registry.fill(HIST("h_PIDcutsOmega"), 1, trackedCascade.omegaMass()); - registry.fill(HIST("h_PIDcutsXi"), 1, trackedCascade.xiMass()); + registry.fill(HIST("h_PIDcutsOmega"), 1, massOmega); + registry.fill(HIST("h_PIDcutsXi"), 1, massXi); if (protonTrack.tpcNClsFound() < cfgCutNclusTPC || pionTrack.tpcNClsFound() < cfgCutNclusTPC) { LOG(debug) << "no tpcNClsFound: " << bachelor.tpcNClsFound() << "/" << protonTrack.tpcNClsFound() << "/" << pionTrack.tpcNClsFound(); continue; } - registry.fill(HIST("h_PIDcutsOmega"), 2, trackedCascade.omegaMass()); - registry.fill(HIST("h_PIDcutsXi"), 2, trackedCascade.xiMass()); + registry.fill(HIST("h_PIDcutsOmega"), 2, massOmega); + registry.fill(HIST("h_PIDcutsXi"), 2, massXi); // QA PID float nSigmaTPC[nParticles]{bachelor.tpcNSigmaKa(), bachelor.tpcNSigmaPi(), protonTrack.tpcNSigmaPr(), pionTrack.tpcNSigmaPi()}; @@ -336,7 +485,7 @@ struct NonPromptCascadeTask { continue; } } - registry.fill(HIST("h_PIDcutsOmega"), 3, trackedCascade.omegaMass()); + registry.fill(HIST("h_PIDcutsOmega"), 3, massOmega); } if (bachelor.hasTPC()) { @@ -345,28 +494,39 @@ struct NonPromptCascadeTask { continue; } } - registry.fill(HIST("h_PIDcutsXi"), 3, trackedCascade.xiMass()); + registry.fill(HIST("h_PIDcutsXi"), 3, massXi); LOG(debug) << "TPCSignal protonTrack " << protonTrack.sign() << "/" << protonTrack.tpcInnerParam() << "/" << protonTrack.tpcSignal(); if (nSigmaTPC[2] < cfgCutsPID->get(2u, 0u) || nSigmaTPC[2] > cfgCutsPID->get(2u, 1u)) { continue; } - registry.fill(HIST("h_PIDcutsOmega"), 4, trackedCascade.omegaMass()); - registry.fill(HIST("h_PIDcutsXi"), 4, trackedCascade.xiMass()); + registry.fill(HIST("h_PIDcutsOmega"), 4, massOmega); + registry.fill(HIST("h_PIDcutsXi"), 4, massXi); LOG(debug) << "TPCSignal ntrack " << pionTrack.sign() << "/" << pionTrack.tpcInnerParam() << "/" << pionTrack.tpcSignal(); if (nSigmaTPC[3] < cfgCutsPID->get(3u, 0u) || nSigmaTPC[3] > cfgCutsPID->get(3u, 1u)) { continue; } - registry.fill(HIST("h_PIDcutsXi"), 5, trackedCascade.xiMass()); - registry.fill(HIST("h_PIDcutsOmega"), 5, trackedCascade.omegaMass()); + registry.fill(HIST("h_PIDcutsXi"), 5, massXi); - invMassACXi->Fill(trackedCascade.xiMass()); - invMassACOmega->Fill(trackedCascade.omegaMass()); + if (isOmega) { + registry.fill(HIST("h_PIDcutsOmega"), 5, massOmega); + invMassACOmega->Fill(massOmega); + registry.fill(HIST("h_massvspt_Omega"), massOmega, track.pt()); + } - fillCascadeDCA(trackedCascade, track, bachelor, protonTrack, pionTrack, primaryVertex, isOmega); + registry.fill(HIST("h_PIDcutsXi"), 5, massXi); + + invMassACXi->Fill(massXi); + registry.fill(HIST("h_massvspt_Xi"), massXi, track.pt()); + + invMassACV0->Fill(v0mass); + registry.fill(HIST("h_massvspt_V0"), v0mass, track.pt()); + + motherDCA mDCA; + fillCascadeDCA(track, protonTrack, pionTrack, primaryVertex, isOmega, mDCA); LOGF(debug, "protonTrack (id: %d, pdg: %d) has mother %d", protonTrack.mcParticleId(), protonTrack.mcParticle().pdgCode(), protonTrack.mcParticle().has_mothers() ? protonTrack.mcParticle().mothersIds()[0] : -1); @@ -384,9 +544,9 @@ struct NonPromptCascadeTask { for (const auto& trackedCascadeData : trackedcascdata) { if (trackedCascadeData.mcParticleId() == mcid) { if (isOmega) { - registry.fill(HIST("h_massvsmass_Omega"), trackedCascade.omegaMass(), trackedCascadeData.mOmega()); + registry.fill(HIST("h_massvsmass_Omega"), massOmega, trackedCascadeData.mOmega()); } else { - registry.fill(HIST("h_massvsmass_Xi"), trackedCascade.omegaMass(), trackedCascadeData.mOmega()); + registry.fill(HIST("h_massvsmass_Xi"), massOmega, trackedCascadeData.mOmega()); } break; } @@ -397,7 +557,39 @@ struct NonPromptCascadeTask { continue; } } - fillDauDCA(trackedCascade, bachelor, protonTrack, pionTrack, primaryVertex, isOmega); + daughtersDCA dDCA; + fillDauDCA(trackedCascade, bachelor, protonTrack, pionTrack, primaryVertex, isOmega, dDCA); + + candidates.emplace_back(NPCascCandidate{static_cast(track.globalIndex()), + track.pt(), track.eta(), track.phi(), + mDCA.DCAxy, mDCA.DCAz, dDCA.protonDCAxy, dDCA.protonDCAz, dDCA.pionDCAxy, dDCA.pionDCAz, dDCA.bachDCAxy, dDCA.bachDCAz, + cascCpa, v0Cpa, + massXi, massOmega, v0mass, + std::hypot(trackedCascade.decayX(), trackedCascade.decayY()), std::hypot(v0Pos[0], v0Pos[1]), std::hypot(trackedCascade.decayX(), trackedCascade.decayY(), trackedCascade.decayZ()), std::hypot(v0Pos[0], v0Pos[1], v0Pos[2]), + track.itsNCls(), protonTrack.itsNCls(), pionTrack.itsNCls(), bachKaonNClusITS, bachPionNClusITS, protonTrack.tpcNClsFound(), pionTrack.tpcNClsFound(), bachKaonNClusTPC, bachPionNClusTPC, + protonTrack.tpcNSigmaPr(), pionTrack.tpcNSigmaPi(), bachelor.tpcNSigmaKa(), bachelor.tpcNSigmaPi(), + protonTrack.hasTOF(), pionTrack.hasTOF(), bachKaonHasTOF, bachPionHasTOF, + protonTrack.tofNSigmaPr(), pionTrack.tofNSigmaPi(), bachelor.tofNSigmaKa(), bachelor.tofNSigmaPi()}); + + } // end loop over tracked cascades + + for (auto& c : candidates) { + auto label = trackLabelsMC.iteratorAt(c.globalIndex); + if (label.mcParticleId() < -1 || label.mcParticleId() >= mcParticles.size()) { + continue; + } + auto particle = mcParticles.iteratorAt(label.mcParticleId()); + + NPCTableMC(c.cascPt, c.cascEta, c.cascPhi, + c.cascDCAxy, c.cascDCAz, c.protonDCAxy, c.protonDCAz, c.pionDCAxy, c.pionDCAz, c.bachDCAxy, c.bachDCAz, + c.casccosPA, c.v0cosPA, + c.massXi, c.massOmega, c.massV0, + c.cascRadius, c.v0radius, c.cascLength, c.v0length, + c.cascNClusITS, c.protonNClusITS, c.pionNClusITS, c.bachKaonNClusITS, c.bachPionNClusITS, c.protonNClusTPC, c.pionNClusTPC, c.bachKaonNClusTPC, c.bachPionNClusTPC, + c.protonTPCNSigma, c.pionTPCNSigma, c.bachKaonTPCNSigma, c.bachPionTPCNSigma, + c.protonHasTOF, c.pionHasTOF, c.bachKaonHasTOF, c.bachPionHasTOF, + c.protonTOFNSigma, c.pionTOFNSigma, c.bachKaonTOFNSigma, c.bachPionTOFNSigma, + particle.pt(), particle.eta(), particle.phi(), particle.pdgCode()); } } PROCESS_SWITCH(NonPromptCascadeTask, processTrackedCascadesMC, "process cascades from strangeness tracking: MC analysis", true); @@ -407,7 +599,7 @@ struct NonPromptCascadeTask { aod::V0s const& v0s, TracksExtData const& tracks, aod::BCsWithTimestamps const&) { - + candidates.clear(); bool isOmega{false}; auto bc = collision.bc_as(); @@ -415,11 +607,20 @@ struct NonPromptCascadeTask { const auto primaryVertex = getPrimaryVertex(collision); + o2::vertexing::DCAFitterN<2> df2; + df2.setBz(bz); + df2.setPropagateToPCA(propToDCA); + df2.setMaxR(maxR); + df2.setMaxDZIni(maxDZIni); + df2.setMinParamChange(minParamChange); + df2.setMinRelChi2Change(minRelChi2Change); + df2.setUseAbsDCA(useAbsDCA); + for (const auto& trackedCascade : trackedCascades) { isOmega = false; - const auto track = trackedCascade.track_as(); + const auto& track = trackedCascade.track_as(); const auto& casc = trackedCascade.cascade(); const auto& bachelor = casc.bachelor_as(); const auto& v0 = casc.v0(); @@ -430,13 +631,51 @@ struct NonPromptCascadeTask { std::array, 2> momenta; std::array masses; - momenta[0] = {protonTrack.px() + pionTrack.px(), protonTrack.py() + pionTrack.py(), protonTrack.pz() + pionTrack.pz()}; - momenta[1] = {bachelor.px(), bachelor.py(), bachelor.pz()}; - masses = {constants::physics::MassLambda, constants::physics::MassKaonCharged}; + + // track propagation + o2::track::TrackParCov trackParCovV0; + o2::track::TrackPar trackParV0; + o2::track::TrackPar trackParBachelor; + + float cascCpa = -1; + float v0Cpa = -1; + + std::array v0Pos = {-999., -999., -999.}; + + if (df2.process(getTrackParCov(pionTrack), getTrackParCov(protonTrack))) { + trackParCovV0 = df2.createParentTrackParCov(0); // V0 track retrieved from p and pi daughters + v0Pos = {trackParCovV0.getX(), trackParCovV0.getY(), trackParCovV0.getZ()}; + if (df2.process(trackParCovV0, getTrackParCov(bachelor))) { + trackParV0 = df2.getTrackParamAtPCA(0); + trackParBachelor = df2.getTrackParamAtPCA(1); + trackParV0.getPxPyPzGlo(momenta[0]); // getting the V0 momentum + trackParBachelor.getPxPyPzGlo(momenta[1]); // getting the bachelor momentum + std::array pVec; + df2.createParentTrackParCov().getPxPyPzGlo(pVec); + std::array pvPos = {primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}; + cascCpa = RecoDecay::cpa(pvPos, df2.getPCACandidate(), pVec); + v0Cpa = RecoDecay::cpa(pvPos, df2.getPCACandidate(), momenta[0]); + } else { + continue; + } + } else { + continue; + } + + // Omega + masses = {o2::constants::physics::MassLambda0, o2::constants::physics::MassKPlus}; const auto massOmega = RecoDecay::m(momenta, masses); - masses = {constants::physics::MassLambda, constants::physics::MassPionCharged}; + + // Xi + masses = {o2::constants::physics::MassLambda0, o2::constants::physics::MassPiPlus}; const auto massXi = RecoDecay::m(momenta, masses); + // Lambda + masses = {o2::constants::physics::MassProton, o2::constants::physics::MassPiMinus}; + momenta[0] = {protonTrack.px(), protonTrack.py(), protonTrack.pz()}; + momenta[1] = {pionTrack.px(), pionTrack.py(), pionTrack.pz()}; + const auto v0mass = RecoDecay::m(momenta, masses); + ////Omega hypohesis -> rejecting Xi if (TMath::Abs(massXi - constants::physics::MassXiMinus) > 0.005) { isOmega = true; @@ -444,10 +683,29 @@ struct NonPromptCascadeTask { } invMassBCXi->Fill(massXi); + invMassBCV0->Fill(v0mass); registry.fill(HIST("h_PIDcutsXi"), 0, massXi); registry.fill(HIST("h_PIDcutsOmega"), 0, massOmega); + int bachKaonNClusTPC = -1; + int bachPionNClusTPC = -1; + int bachKaonNClusITS = -1; + int bachPionNClusITS = -1; + if (isOmega) { + bachKaonNClusTPC = bachelor.tpcNClsFound(); + bachKaonNClusITS = bachelor.itsNCls(); + } + bachPionNClusTPC = bachelor.tpcNClsFound(); /// by default cascade = Xi + bachPionNClusITS = bachelor.itsNCls(); /// by default cascade = Xi + + bool bachKaonHasTOF = 0; + bool bachPionHasTOF = 0; + if (isOmega) { + bachKaonHasTOF = bachelor.hasTOF(); + } + bachPionHasTOF = bachelor.hasTOF(); + // if (!bachelor.hasTOF() && !ptrack.hasTOF() && !ntrack.hasTOF() ) { // LOG(debug)<< "no TOF: "<Fill(massOmega); + registry.fill(HIST("h_massvspt_Omega"), massOmega, track.pt()); + } + registry.fill(HIST("h_PIDcutsXi"), 5, massXi); - registry.fill(HIST("h_PIDcutsOmega"), 5, massOmega); invMassACXi->Fill(massXi); - invMassACOmega->Fill(massOmega); - - fillCascadeDCA(trackedCascade, track, bachelor, protonTrack, pionTrack, primaryVertex, isOmega); - fillDauDCA(trackedCascade, bachelor, protonTrack, pionTrack, primaryVertex, isOmega); + registry.fill(HIST("h_massvspt_Xi"), massXi, track.pt()); + + invMassACV0->Fill(v0mass); + registry.fill(HIST("h_massvspt_V0"), v0mass, track.pt()); + + motherDCA mDCA; + fillCascadeDCA(track, protonTrack, pionTrack, primaryVertex, isOmega, mDCA); + daughtersDCA dDCA; + fillDauDCA(trackedCascade, bachelor, protonTrack, pionTrack, primaryVertex, isOmega, dDCA); + + candidates.emplace_back(NPCascCandidate{static_cast(track.globalIndex()), + track.pt(), track.eta(), track.phi(), + mDCA.DCAxy, mDCA.DCAz, dDCA.protonDCAxy, dDCA.protonDCAz, dDCA.pionDCAxy, dDCA.pionDCAz, dDCA.bachDCAxy, dDCA.bachDCAz, + cascCpa, v0Cpa, + massXi, massOmega, v0mass, + std::hypot(trackedCascade.decayX(), trackedCascade.decayY()), std::hypot(v0Pos[0], v0Pos[1]), std::hypot(trackedCascade.decayX(), trackedCascade.decayY(), trackedCascade.decayZ()), std::hypot(v0Pos[0], v0Pos[1], v0Pos[2]), + track.itsNCls(), protonTrack.itsNCls(), pionTrack.itsNCls(), bachKaonNClusITS, bachPionNClusITS, protonTrack.tpcNClsFound(), pionTrack.tpcNClsFound(), bachKaonNClusTPC, bachPionNClusTPC, + protonTrack.tpcNSigmaPr(), pionTrack.tpcNSigmaPi(), bachelor.tpcNSigmaKa(), bachelor.tpcNSigmaPi(), + protonTrack.hasTOF(), pionTrack.hasTOF(), bachKaonHasTOF, bachPionHasTOF, + protonTrack.tofNSigmaPr(), pionTrack.tofNSigmaPi(), bachelor.tofNSigmaKa(), bachelor.tofNSigmaPi()}); + + } // end loop over tracked cascades + + for (auto& c : candidates) { + + NPCTable(c.cascPt, c.cascEta, c.cascPhi, + c.cascDCAxy, c.cascDCAz, c.protonDCAxy, c.protonDCAz, c.pionDCAxy, c.pionDCAz, c.bachDCAxy, c.bachDCAz, + c.casccosPA, c.v0cosPA, + c.massXi, c.massOmega, c.massV0, + c.cascRadius, c.v0radius, c.cascLength, c.v0length, + c.cascNClusITS, c.protonNClusITS, c.pionNClusITS, c.bachKaonNClusITS, c.bachPionNClusITS, c.protonNClusTPC, c.pionNClusTPC, c.bachKaonNClusTPC, c.bachPionNClusTPC, + c.protonTPCNSigma, c.pionTPCNSigma, c.bachKaonTPCNSigma, c.bachPionTPCNSigma, + c.protonHasTOF, c.pionHasTOF, c.bachKaonHasTOF, c.bachPionHasTOF, + c.protonTOFNSigma, c.pionTOFNSigma, c.bachKaonTOFNSigma, c.bachPionTOFNSigma); } } PROCESS_SWITCH(NonPromptCascadeTask, processTrackedCascadesData, "process cascades from strangeness tracking: Data analysis", false); From c9c56aadea5ab9dd4b54ffd481d3367ecb7101a1 Mon Sep 17 00:00:00 2001 From: eloviyo <38348689+Eloviyo@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:14:20 +0100 Subject: [PATCH 130/156] PWGCF: FemtoUniverse -- fixed nSigmaPIDMax from int to float and changed pT to p for PID (#4246) * fixed nSigmaPIDMax from int to float * particle identification from pT to p --------- Co-authored-by: Shirajum Monira --- PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h | 2 +- PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h | 4 ++-- .../Tasks/femtoUniversePairTaskTrackV0Extended.cxx | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h index 8494da318b9..7c4d6a10354 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h @@ -197,7 +197,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection auto diffAntiLambda = abs(antiLambdaMassHypothesis - lambdaMassHypothesis); float sign = 0.; - int nSigmaPIDMax = PosDaughTrack.getSigmaPIDMax(); + float nSigmaPIDMax = PosDaughTrack.getSigmaPIDMax(); auto nSigmaPrNeg = negTrack.tpcNSigmaPr(); auto nSigmaPiPos = posTrack.tpcNSigmaPi(); auto nSigmaPiNeg = negTrack.tpcNSigmaPi(); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index 0ebf2cce07c..1e801a5937c 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -114,7 +114,7 @@ struct femtoUniversePairTaskTrackV0Extended { bool IsParticleNSigma(float mom, float nsigmaTPCParticle, float nsigmaTOFParticle) { - if (mom < Confmom) { + if (mom <= Confmom) { if (TMath::Abs(nsigmaTPCParticle) < ConfNsigmaTPCParticle) { return true; } else { @@ -178,7 +178,7 @@ struct femtoUniversePairTaskTrackV0Extended { const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; - if (!IsParticleNSigma(part.pt(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + if (!IsParticleNSigma(part.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; } qaRegistry.fill(HIST("Tracks_one/nSigmaTPC"), part.p(), tpcNSigmas[ConfTrackChoicePartOne]); @@ -202,7 +202,7 @@ struct femtoUniversePairTaskTrackV0Extended { const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; const float tofNSigmas[3] = {unPackInTable(p1.tofNSigmaStorePr()), unPackInTable(p1.tofNSigmaStorePi()), unPackInTable(p1.tofNSigmaStoreKa())}; - if (!IsParticleNSigma(p1.pt(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + if (!IsParticleNSigma(p1.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; } sameEventCont.setPair(p1, p2, multCol, ConfUse3D); @@ -244,7 +244,7 @@ struct femtoUniversePairTaskTrackV0Extended { const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; const float tofNSigmas[3] = {unPackInTable(p1.tofNSigmaStorePr()), unPackInTable(p1.tofNSigmaStorePi()), unPackInTable(p1.tofNSigmaStoreKa())}; - if (!IsParticleNSigma(p1.pt(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + if (!IsParticleNSigma(p1.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; } mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); From 20cda28b3dbbdd5fa86ae8c91cf2b12d89f62c96 Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Mon, 8 Jan 2024 22:45:23 +0100 Subject: [PATCH 131/156] PWGCF: FemtoUniverse -- QA plots for Phi daughters (#4250) * Fixing Delta Eta Delta Phi* cut for h-Phi correlations * Fixing error * Fixing errors (2) * QA plots for Phi daughters --- .../femtoUniverseProducerTask.cxx | 4 +- .../Tasks/femtoUniversePairTaskTrackPhi.cxx | 47 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 2812bd46246..a7bec60149c 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -920,7 +920,7 @@ struct femtoUniverseProducerTask { p1.dcaXY(), childIDs, 0, - 0); + 1); // sign, workaround for now const int rowOfPosTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(p1, o2::aod::femtouniverseparticle::ParticleType::kPhiChild); @@ -940,7 +940,7 @@ struct femtoUniverseProducerTask { p2.dcaXY(), childIDs, 0, - 0); + -1); // sign, workaround for now const int rowOfNegTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(p2, o2::aod::femtouniverseparticle::ParticleType::kPhiChild); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index b2aedbfa996..869089d19fc 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -104,6 +104,10 @@ struct femtoUniversePairTaskTrackPhi { Partition partsPhi = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kPhi)); Partition> partsPhiMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kPhi)); + /// Partitions for Phi daughters kPhiChild + Partition partsPhiDaugh = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kPhiChild)); + Partition> partsPhiDaughMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kPhiChild)); + /// Histogramming for particle 1 FemtoUniverseParticleHisto trackHistoPartTrack; @@ -270,6 +274,17 @@ struct femtoUniversePairTaskTrackPhi { void init(InitContext&) { eventHisto.init(&qaRegistry); + qaRegistry.add("PhiDaugh_pos/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("PhiDaugh_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("PhiDaugh_pos/pt", "; #it{p_T} (GeV/#it{c}); Counts", kTH1F, {{100, 0, 10}}); + qaRegistry.add("PhiDaugh_pos/eta", "; #it{eta}; Counts", kTH1F, {{200, -1.5, 1.5}}); + qaRegistry.add("PhiDaugh_pos/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, 2. * M_PI}}); + qaRegistry.add("PhiDaugh_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("PhiDaugh_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("PhiDaugh_neg/pt", "; #it{p_T} (GeV/#it{c}); Counts", kTH1F, {{100, 0, 10}}); + qaRegistry.add("PhiDaugh_neg/eta", "; #it{eta}; Counts", kTH1F, {{200, -1.5, 1.5}}); + qaRegistry.add("PhiDaugh_neg/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, 2. * M_PI}}); + trackHistoPartPhi.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarInvMassBins, ConfBothTracks.ConfIsMC, ConfPhi.ConfPDGCodePhi); if (!ConfTrack.ConfIsSame) { trackHistoPartTrack.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfBothTracks.ConfIsMC, ConfTrack.ConfPDGCodeTrack); @@ -316,7 +331,7 @@ struct femtoUniversePairTaskTrackPhi { /// @param magFieldTesla magnetic field of the collision /// @param multCol multiplicity of the collision template - void doSameEvent(PartitionType groupPartsTrack, PartitionType groupPartsPhi, PartType parts, float magFieldTesla, int multCol) + void doSameEvent(PartitionType groupPartsTrack, PartitionType groupPartsPhi, PartitionType groupPartsPhiDaugh, PartType parts, float magFieldTesla, int multCol) { /// Histogramming same event @@ -324,6 +339,30 @@ struct femtoUniversePairTaskTrackPhi { trackHistoPartPhi.fillQA(phicandidate); } + float tpcNSigma; + float tofNSigma; + for (auto& phidaugh : groupPartsPhiDaugh) { + if (phidaugh.mAntiLambda() == 1) { // workaround + tpcNSigma = trackCuts.getNsigmaTPC(phidaugh, o2::track::PID::Kaon); + tofNSigma = trackCuts.getNsigmaTOF(phidaugh, o2::track::PID::Kaon); + + qaRegistry.fill(HIST("PhiDaugh_pos/nSigmaTPC"), phidaugh.p(), tpcNSigma); + qaRegistry.fill(HIST("PhiDaugh_pos/nSigmaTOF"), phidaugh.p(), tofNSigma); + qaRegistry.fill(HIST("PhiDaugh_pos/pt"), phidaugh.pt()); + qaRegistry.fill(HIST("PhiDaugh_pos/eta"), phidaugh.eta()); + qaRegistry.fill(HIST("PhiDaugh_pos/phi"), phidaugh.phi()); + } else if (phidaugh.mAntiLambda() == -1) { // workaround + tpcNSigma = trackCuts.getNsigmaTPC(phidaugh, o2::track::PID::Kaon); + tofNSigma = trackCuts.getNsigmaTOF(phidaugh, o2::track::PID::Kaon); + + qaRegistry.fill(HIST("PhiDaugh_neg/nSigmaTPC"), phidaugh.p(), tpcNSigma); + qaRegistry.fill(HIST("PhiDaugh_neg/nSigmaTOF"), phidaugh.p(), tofNSigma); + qaRegistry.fill(HIST("PhiDaugh_neg/pt"), phidaugh.pt()); + qaRegistry.fill(HIST("PhiDaugh_neg/eta"), phidaugh.eta()); + qaRegistry.fill(HIST("PhiDaugh_neg/phi"), phidaugh.phi()); + } + } + if (!ConfTrack.ConfIsSame) { for (auto& track : groupPartsTrack) { // if (track.p() > ConfBothTracks.ConfCutTable->get("Track", "MaxP") || track.pt() > ConfBothTracks.ConfCutTable->get("Track", "MaxPt")) { @@ -401,8 +440,9 @@ struct femtoUniversePairTaskTrackPhi { auto thegroupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsPhi = partsPhi->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsPhiDaugh = partsPhiDaugh->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(thegroupPartsTrack, thegroupPartsPhi, parts, col.magField(), col.multNtr()); + doSameEvent(thegroupPartsTrack, thegroupPartsPhi, thegroupPartsPhiDaugh, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processSameEvent, "Enable processing same event", true); @@ -418,8 +458,9 @@ struct femtoUniversePairTaskTrackPhi { auto thegroupPartsPhi = partsPhiMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsTrack = partsTrackMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsPhiDaugh = partsPhiDaughMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(thegroupPartsTrack, thegroupPartsPhi, parts, col.magField(), col.multNtr()); + doSameEvent(thegroupPartsTrack, thegroupPartsPhi, thegroupPartsPhiDaugh, parts, col.magField(), col.multNtr()); } PROCESS_SWITCH(femtoUniversePairTaskTrackPhi, processSameEventMC, "Enable processing same event for Monte Carlo", false); From 69071acaaeb970308b3454995176436b4832beaa Mon Sep 17 00:00:00 2001 From: feisenhu <53603353+feisenhu@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:57:13 +0100 Subject: [PATCH 132/156] PWGEM: Add some new triggers to study (#4252) --- PWGDQ/Core/CutsLibrary.cxx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 4d0a5ce9485..6f5d616e5e4 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -2045,6 +2045,16 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("pairMass1_5to2_7")) { + cut->AddCut(GetAnalysisCut("pairMass1_5to2_7")); + return cut; + } + + if (!nameStr.compare("pairMass1_5to3_5")) { + cut->AddCut(GetAnalysisCut("pairMass1_5to3_5")); + return cut; + } + if (!nameStr.compare("pairDalitz1")) { cut->AddCut(GetAnalysisCut("pairDalitz1")); return cut; @@ -4092,6 +4102,16 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("pairMass1_5to2_7")) { + cut->AddCut(VarManager::kMass, 1.5, 2.7); + return cut; + } + + if (!nameStr.compare("pairMass1_5to3_5")) { + cut->AddCut(VarManager::kMass, 1.5, 3.5); + return cut; + } + if (!nameStr.compare("pairJpsi")) { cut->AddCut(VarManager::kMass, 2.8, 3.3); return cut; From e662a30c71231d193d47f1e34f39edca76fa2713 Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Tue, 9 Jan 2024 19:40:31 +0100 Subject: [PATCH 133/156] Phi meson its only and modified mixed event (#4253) * Modification of mixing and ITS only study * clang --- PWGLF/Tasks/phianalysisrun3.cxx | 87 +++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/PWGLF/Tasks/phianalysisrun3.cxx b/PWGLF/Tasks/phianalysisrun3.cxx index a19162f8562..c1c97c7256e 100644 --- a/PWGLF/Tasks/phianalysisrun3.cxx +++ b/PWGLF/Tasks/phianalysisrun3.cxx @@ -68,13 +68,16 @@ struct phianalysisrun3 { Configurable isEtaAssym{"isEtaAssym", false, "isEtaAssym"}; Configurable cfgMultFT0{"cfgMultFT0", true, "cfgMultFT0"}; Configurable iscustomDCAcut{"iscustomDCAcut", false, "iscustomDCAcut"}; + Configurable ismanualDCAcut{"ismanualDCAcut", true, "ismanualDCAcut"}; + Configurable isITSOnlycut{"isITSOnlycut", true, "isITSOnlycut"}; + Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; // MC Configurable isMC{"isMC", false, "Run MC"}; void init(o2::framework::InitContext&) { histos.add("hCentrality", "Centrality distribution", kTH1F, {{2001, -0.5, 2000.5}}); histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); - histos.add("hNcontributor", "Number of primary vertex contributor", kTH1F, {{2000, 0.0f, 2000.0f}}); + histos.add("hNcontributor", "Number of primary vertex contributor", kTH1F, {{20000, 0.0f, 20000.0f}}); histos.add("hEta", "Eta distribution", kTH1F, {{200, -1.0f, 1.0f}}); histos.add("hDcaxy", "Dcaxy distribution", kTH1F, {{200, -1.0f, 1.0f}}); histos.add("hDcaz", "Dcaz distribution", kTH1F, {{200, -1.0f, 1.0f}}); @@ -85,6 +88,7 @@ struct phianalysisrun3 { histos.add("h3PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); histos.add("h3PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); + histos.add("h3PhiInvMassRotation", "Invariant mass of Phi meson Rotation", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); if (isEtaAssym) { histos.add("h3PhiInvMassUnlikeSignAside", "Invariant mass of Phi meson Unlike Sign A side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); histos.add("h3PhiInvMassLikeSignAside", "Invariant mass of Phi meson Like Sign A side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); @@ -104,40 +108,48 @@ struct phianalysisrun3 { double rapidity; double genMass, recMass, resolution; double mass{0.}; + double massrotation{0.}; double pT{0.}; array pvec0; array pvec1; + array pvec1rotation; template bool selectionTrack(const T& candidate) { - if (iscustomDCAcut && !(candidate.isGlobalTrack() || candidate.isPVContributor())) { + if (iscustomDCAcut && !(candidate.isGlobalTrack() || candidate.isPVContributor() || candidate.itsNCls() > cfgITScluster)) { + return false; + } + if (ismanualDCAcut && !(candidate.isGlobalTrackWoDCA() || candidate.isPVContributor() || std::abs(candidate.dcaXY()) < cfgCutDCAxy || std::abs(candidate.dcaZ()) < cfgCutDCAz || candidate.itsNCls() > cfgITScluster)) { + return false; + } + if (isITSOnlycut && !(candidate.isPVContributor() || std::abs(candidate.dcaXY()) < cfgCutDCAxy || std::abs(candidate.dcaZ()) < cfgCutDCAz || candidate.itsNCls() > cfgITScluster)) { return false; - } else { - if (!candidate.isGlobalTrackWoDCA() || std::abs(candidate.dcaXY()) > cfgCutDCAxy || std::abs(candidate.dcaZ()) > cfgCutDCAz || !candidate.isPVContributor()) { - return false; - } } return true; } template bool selectionPID(const T& candidate) { - if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (2.0 * nsigmaCutCombined * nsigmaCutCombined)) { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (nsigmaCutCombined * nsigmaCutCombined)) { return true; - } else if (std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } return false; } template - void FillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, bool likesign, float massd1, float massd2) + void FillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, bool likesign, bool rotation, float massd1, float massd2) { pvec0 = array{candidate1.px(), candidate1.py(), candidate1.pz()}; pvec1 = array{candidate2.px(), candidate2.py(), candidate2.pz()}; + pvec1rotation = array{-candidate2.px(), -candidate2.py(), candidate2.pz()}; auto arrMom = array{pvec0, pvec1}; + auto arrMomrotation = array{pvec0, pvec1rotation}; int track1Sign = candidate1.sign(); int track2Sign = candidate2.sign(); mass = RecoDecay::m(arrMom, array{massd1, massd2}); + massrotation = RecoDecay::m(arrMomrotation, array{massd1, massd2}); pT = RecoDecay::pt(array{candidate1.px() + candidate2.px(), candidate1.py() + candidate2.py()}); rapidity = RecoDecay::y(array{candidate1.px() + candidate2.px(), candidate1.py() + candidate2.py(), candidate1.pz() + candidate2.pz()}, mass); if (isEtaAssym && unlike && track1Sign * track2Sign < 0) { @@ -162,11 +174,19 @@ struct phianalysisrun3 { } } - if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign < 0 && unlike) { - histos.fill(HIST("h3PhiInvMassUnlikeSign"), multiplicity, pT, mass); - } else if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign < 0 && mix) { - histos.fill(HIST("h3PhiInvMassMixed"), multiplicity, pT, mass); - } else if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign > 0 && likesign) { + // default filling + if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign < 0) { + if (unlike) { + histos.fill(HIST("h3PhiInvMassUnlikeSign"), multiplicity, pT, mass); + } + if (mix) { + histos.fill(HIST("h3PhiInvMassMixed"), multiplicity, pT, mass); + } + if (rotation) { + histos.fill(HIST("h3PhiInvMassRotation"), multiplicity, pT, massrotation); + } + } + if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign > 0 && likesign) { if (track1Sign > 0 && track2Sign > 0) { histos.fill(HIST("h3PhiInvMassLikeSignPP"), multiplicity, pT, mass); } else { @@ -190,12 +210,14 @@ struct phianalysisrun3 { ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {20, 0, 100}, "multiplicity percentile for bin"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0.0, 2.750, 5.250, 7.750, 12.750, 17.750, 22.750, 27.750, 32.750, 37.750, 42.750, 47.750, 52.750, 57.750, 62.750, 67.750, 72.750, 77.750, 82.750, 87.750, 92.750, 97.750, 250.1}, "multiplicity axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {2000, 0, 10000}, "TPC multiplicity for bin"}; // using BinningType = BinningPolicy>; // BinningType binningOnPositions{{axisVertex, axisMultiplicityClass}, true}; - using BinningType = ColumnBinningPolicy; + // using BinningTypeTPCMultiplicity = ColumnBinningPolicy; + using BinningTypeVertexContributor = ColumnBinningPolicy; + // using BinningTypeCentrality = ColumnBinningPolicy; // using BinningType = ColumnBinningPolicy; // BinningType binningOnPositions{{axisVertex, axisMultiplicity}, true}; @@ -209,7 +231,7 @@ struct phianalysisrun3 { if (cfgMultFT0) multiplicity = collision.multZeqFT0A() + collision.multZeqFT0C(); if (!cfgMultFT0) - multiplicity = collision.centFT0M() - 0.5; + multiplicity = collision.centFT0M(); histos.fill(HIST("hCentrality"), multiplicity); histos.fill(HIST("hNcontributor"), collision.numContrib()); histos.fill(HIST("hVtxZ"), collision.posZ()); @@ -234,8 +256,12 @@ struct phianalysisrun3 { bool unlike = true; bool mix = false; bool likesign = true; - if (selectionPID(track1) && selectionPID(track2)) { - FillinvMass(track1, track2, multiplicity, unlike, mix, likesign, massKa, massKa); + bool rotation = true; + if (isITSOnlycut) { + FillinvMass(track1, track2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); + } + if (!isITSOnlycut && selectionPID(track1) && selectionPID(track2)) { + FillinvMass(track1, track2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); } } } @@ -245,8 +271,9 @@ struct phianalysisrun3 { void processMixedEvent(EventCandidates const& collisions, TrackCandidates const& tracks) { auto tracksTuple = std::make_tuple(tracks); - BinningType binningOnPositions{{axisVertex, axisMultiplicityClass}, true}; - SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + //////// currently mixing the event with similar TPC multiplicity //////// + BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicity}, true}; + SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; for (auto& [c1, tracks1, c2, tracks2] : pair) { if (!c1.sel8()) { continue; @@ -259,20 +286,24 @@ struct phianalysisrun3 { if (cfgMultFT0) multiplicity = c1.multZeqFT0A() + c1.multZeqFT0C(); if (!cfgMultFT0) - multiplicity = c1.centFT0M() - 0.5; + multiplicity = c1.centFT0M(); for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; bool mix = true; bool likesign = false; + bool rotation = false; if (!selectionTrack(t1)) { continue; } if (!selectionTrack(t2)) { continue; } - if (selectionPID(t1) && selectionPID(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); + if (isITSOnlycut) { + FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); + } + if (!isITSOnlycut && selectionPID(t1) && selectionPID(t2)) { + FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); } } } @@ -370,11 +401,15 @@ struct phianalysisrun3 { if (std::abs(mothertrack1.y()) > 0.5) { continue; } - if (selectionPID(track1) && selectionPID(track2)) { + if (isITSOnlycut) { if (std::abs(mothertrack1.pdgCode()) != 333) { continue; } - + if (!isITSOnlycut && selectionPID(track1) && selectionPID(track2)) { + if (std::abs(mothertrack1.pdgCode()) != 333) { + continue; + } + } pvec0 = array{track1.px(), track1.py(), track1.pz()}; pvec1 = array{track2.px(), track2.py(), track2.pz()}; auto arrMomrec = array{pvec0, pvec1}; From 0ab6db7e9fe0b979e864da7546b7818ae1f27214 Mon Sep 17 00:00:00 2001 From: kgwizdzi <116073883+kgwizdzi@users.noreply.github.com> Date: Wed, 10 Jan 2024 09:42:04 +0100 Subject: [PATCH 134/156] PWGCF: FemtoUniverse - D mesons update (#4254) * PWGCF: FemtoUniverse - D mesons update * PWGCF: FemtoUniverse - D0Task - fixing clang --- .../femtoUniverseProducerTask.cxx | 20 +++-- .../Tasks/femtoUniversePairTaskTrackD0.cxx | 90 +++++++++++-------- 2 files changed, 64 insertions(+), 46 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index a7bec60149c..a0b5e8e1725 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -243,10 +243,10 @@ struct femtoUniverseProducerTask { // D0/D0bar mesons struct : o2::framework::ConfigurableGroup { - Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable yCandMax{"yCandMax", 4.0, "max. cand. rapidity"}; - Configurable ptCandMin{"ptCandMin", -1., "min. cand. pT"}; + Configurable ConfD0SelectionFlag{"ConfD0SelectionFlag", 1, "Selection Flag for D0"}; + Configurable ConfD0barSelectionFlag{"ConfD0barSelectionFlag", 1, "Selection Flag for D0bar"}; + Configurable ConfD0D0barCandMaxY{"ConfD0D0barCandMaxY", 4.0, "max. cand. rapidity"}; + Configurable ConfD0D0barMinPt{"ConfD0D0barMinPt", 0., "min. cand. pT"}; } ConfD0Selection; HfHelper hfHelper; @@ -766,7 +766,11 @@ struct femtoUniverseProducerTask { continue; } - if (ConfD0Selection.yCandMax >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.yCandMax) { + if (ConfD0Selection.ConfD0D0barCandMaxY >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.ConfD0D0barCandMaxY) { + continue; + } + + if (hfCand.pt() > ConfD0Selection.ConfD0D0barMinPt) { continue; } @@ -778,13 +782,13 @@ struct femtoUniverseProducerTask { auto postrack = hfCand.template prong0_as(); auto negtrack = hfCand.template prong1_as(); - if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { + if (hfCand.isSelD0() == ConfD0Selection.ConfD0SelectionFlag && hfCand.isSelD0bar() != ConfD0Selection.ConfD0barSelectionFlag) { invMassD0 = hfHelper.invMassD0ToPiK(hfCand); invMassD0bar = -hfHelper.invMassD0ToPiK(hfCand); - } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { + } else if (hfCand.isSelD0() != ConfD0Selection.ConfD0SelectionFlag && hfCand.isSelD0bar() == ConfD0Selection.ConfD0barSelectionFlag) { invMassD0 = -hfHelper.invMassD0ToPiK(hfCand); invMassD0bar = hfHelper.invMassD0ToPiK(hfCand); - } else if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 1) { + } else if (hfCand.isSelD0() == ConfD0Selection.ConfD0SelectionFlag && hfCand.isSelD0bar() == ConfD0Selection.ConfD0barSelectionFlag) { invMassD0 = hfHelper.invMassD0ToPiK(hfCand); invMassD0bar = hfHelper.invMassD0ToPiK(hfCand); } else { diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index 5d49ed1abc2..2c0ffa487be 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -100,10 +100,13 @@ struct femtoUniversePairTaskTrackD0 { Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)); /// Partitions for particle 2 - Partition partsD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f); - // Partition partsD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); + Partition partsAllDmesons = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0); + Partition partsOnlyD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f); Partition> partsD0D0barMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); + /// Partition for D0/D0bar daughters + Partition partsDmesonsChildren = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0Child); + /// Histogramming for particle 1 FemtoUniverseParticleHisto trackHistoPartTrack; @@ -134,6 +137,10 @@ struct femtoUniversePairTaskTrackD0 { ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis ConfPtBins{"ConfPtBins", {360, 0., 36.}, "binning pT"}; + ConfigurableAxis ConfInvMassBins{"ConfInvMassBins", {500, 0., 5.0}, "binning inv. mass"}; + ConfigurableAxis ConfInvMassFinerBins{"ConfInvMassFinerBins", {120, 1.5848, 2.1848}, "finer binning of inv. mass"}; + Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; @@ -155,18 +162,22 @@ struct femtoUniversePairTaskTrackD0 { HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry registry{"registry", - {{"hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{400, 1.65, 2.05}}}}, - {"hInvMassD0bar", ";#it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{400, 1.65, 2.05}}}}, - {"hMassVsPt", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {{500, 0.0, 5.0}, {400, 0., 20.}}}}, - {"hInvMassVsPt", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {{400, 1.65, 2.05}, {400, 0., 20.}}}}, - {"hPtD0", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{400, 0., 20.}}}}, - {"hPtD0bar", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{400, 0., 20.}}}}, + {{"hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {ConfInvMassBins}}}, + {"hInvMassD0bar", ";#it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {ConfInvMassBins}}}, + {"hMassVsPt", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {ConfInvMassBins, ConfPtBins}}}, + {"hMassVsPtFiner", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {ConfInvMassFinerBins, ConfPtBins}}}, + {"hInvMassVsPtOnlyD0D0bar", "; #it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2}); p_{T} (GeV/#it{c})", {HistType::kTH2F, {ConfInvMassBins, ConfPtBins}}}, + {"hPtDmesonCand", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {ConfPtBins}}}, + {"hPtD0", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {ConfPtBins}}}, + {"hPtD0bar", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {ConfPtBins}}}, + {"hPhiDmesonCand", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, {"hPhiD0", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, {"hPhiD0bar", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., 2. * o2::constants::math::PI}}}}, + {"hEtaDmesonCand", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, {"hEtaD0", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, {"hEtaD0bar", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, - {"hDecayLengthD0", ";decay length (cm);counts", {HistType::kTH1F, {{100, 0., 0.5}}}}, - {"hDecayLengthD0bar", ";decay length (cm);counts", {HistType::kTH1F, {{100, 0., 0.5}}}}, + {"hDecayLengthD0", ";decay length (cm);counts", {HistType::kTH1F, {{800, 0., 4.}}}}, + {"hDecayLengthD0bar", ";decay length (cm);counts", {HistType::kTH1F, {{800, 0., 4.}}}}, {"hDeltaPhi", "; #Delta #varphi (rad);counts", {HistType::kTH1F, {{80, -0.5 * o2::constants::math::PI, 2. * o2::constants::math::PI}}}}, {"hPtDaughters", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 12.}}}}, {"hMomentumDaughters", ";#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{300, 0., 15.}}}}, @@ -328,51 +339,54 @@ struct femtoUniversePairTaskTrackD0 { void processD0mesons(o2::aod::FDCollision& col, FemtoFullParticles& parts) { - auto groupPartsD0D0bar = partsD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - // auto groupPartsD0D0barDaugh = partsD0D0barDaughters->sliceByCached(aod::femtoworldparticle::femtoWorldCollisionId, col.globalIndex(), cache); + auto groupPartsOnlyD0D0bar = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsAllDmesons = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsD0D0barChildren = partsDmesonsChildren->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + // loop over all D mesons + for (auto const& dmeson : groupPartsAllDmesons) { + + if (dmeson.mLambda() > 0.0f) { + registry.fill(HIST("hMassVsPt"), dmeson.mLambda(), dmeson.pt()); + registry.fill(HIST("hMassVsPtFiner"), dmeson.mLambda(), dmeson.pt()); + } + + if (dmeson.mAntiLambda() > 0.0f) { + registry.fill(HIST("hMassVsPt"), dmeson.mLambda(), dmeson.pt()); + registry.fill(HIST("hMassVsPtFiner"), dmeson.mLambda(), dmeson.pt()); + } + + registry.fill(HIST("hPtDmesonCand"), dmeson.pt()); + registry.fill(HIST("hPhiDmesonCand"), dmeson.phi()); + registry.fill(HIST("hEtaDmesonCand"), dmeson.eta()); + } - for (auto& d0d0bar : groupPartsD0D0bar) { - registry.fill(HIST("hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); + // loop over D0/D0bar mesons (ONLY) + for (auto const& d0d0bar : groupPartsOnlyD0D0bar) { if (d0d0bar.mLambda() > 0.0f && d0d0bar.mAntiLambda() < 0.0f) { + registry.fill(HIST("hInvMassVsPtOnlyD0D0bar"), d0d0bar.mLambda(), d0d0bar.pt()); if (d0d0bar.mLambda() > ConfDmesons.ConfMinInvMassD0D0bar && d0d0bar.mLambda() < ConfDmesons.ConfMaxInvMassD0D0bar) { registry.fill(HIST("hInvMassD0"), d0d0bar.mLambda()); } - registry.fill(HIST("hInvMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); registry.fill(HIST("hPtD0"), d0d0bar.pt()); registry.fill(HIST("hPhiD0"), d0d0bar.phi()); registry.fill(HIST("hEtaD0"), d0d0bar.eta()); } if (d0d0bar.mLambda() < 0.0f && d0d0bar.mAntiLambda() > 0.0f) { + registry.fill(HIST("hInvMassVsPtOnlyD0D0bar"), d0d0bar.mLambda(), d0d0bar.pt()); if (d0d0bar.mAntiLambda() > ConfDmesons.ConfMinInvMassD0D0bar && d0d0bar.mAntiLambda() < ConfDmesons.ConfMaxInvMassD0D0bar) { registry.fill(HIST("hInvMassD0bar"), d0d0bar.mAntiLambda()); } - registry.fill(HIST("hInvMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); } } - /*for (auto& daughD0D0bar : groupPartsD0D0barDaugh) { - if (daughD0D0bar.flagD0() == 1) { - registry.fill(HIST("hMomentumDaughters"), daughD0D0bar.p()); - registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); - registry.fill(HIST("hSignDaughters"), daughD0D0bar.sign()); - registry.fill(HIST("hbetaDaughters"), daughD0D0bar.beta(), daughD0D0bar.p()); - registry.fill(HIST("hdEdxDaughters"), daughD0D0bar.tpcSignal(), daughD0D0bar.p()); - registry.fill(HIST("hDCAxyDaughters"), daughD0D0bar.dcaXY()); - registry.fill(HIST("hDCAzDaughters"), daughD0D0bar.dcaZ()); - } - if (daughD0D0bar.flagD0bar() == 1) { - registry.fill(HIST("hMomentumDaughters"), daughD0D0bar.p()); - registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); - registry.fill(HIST("hSignDaughters"), daughD0D0bar.sign()); - registry.fill(HIST("hbetaDaughters"), daughD0D0bar.beta(), daughD0D0bar.p()); - registry.fill(HIST("hdEdxDaughters"), daughD0D0bar.tpcSignal(), daughD0D0bar.p()); - registry.fill(HIST("hDCAxyDaughters"), daughD0D0bar.dcaXY()); - registry.fill(HIST("hDCAzDaughters"), daughD0D0bar.dcaZ()); - } - }*/ + // loop over D mesons childen + for (auto const& daughD0D0bar : groupPartsD0D0barChildren) { + registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); + } } PROCESS_SWITCH(femtoUniversePairTaskTrackD0, processD0mesons, "Enable processing D0 mesons", true); @@ -437,7 +451,7 @@ struct femtoUniversePairTaskTrackD0 { fillCollision(col); auto thegroupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsD0 = partsD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsD0 = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); doSameEvent(thegroupPartsTrack, thegroupPartsD0, parts, col.magField(), col.multNtr()); } @@ -503,7 +517,7 @@ struct femtoUniversePairTaskTrackD0 { MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); auto groupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); - auto groupPartsD0 = partsD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsD0 = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); From a80754a83e2fea38117c4bc27befbf5f821366a4 Mon Sep 17 00:00:00 2001 From: Deependra Sharma <38365215+deependra170598@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:18:47 +0530 Subject: [PATCH 135/156] PWGHF: Adding D2H task for D* Analysis. (#4234) * Adding First version of D2H task for D* Analysis. * Formatting changes and suggestion by Fabrizio * Removing TracksDCA, TracksExtra subscription. Keeping only Tracks & TracksWMc for track properties --- PWGHF/D2H/Tasks/CMakeLists.txt | 5 + PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx | 275 ++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index 87e4cb40fa8..6a5c13a2cf3 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -49,6 +49,11 @@ o2physics_add_dpl_workflow(task-ds PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-dstar-to-d0-pi + SOURCES taskDstarToD0Pi.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-lb SOURCES taskLb.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx new file mode 100644 index 00000000000..a2dfd30ae67 --- /dev/null +++ b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx @@ -0,0 +1,275 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskDstarToD0Pi.cxx +/// \file D* analysis task + +/// \author Deependra Sharma , IITB +/// \author Fabrizio Grosa , CERN + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +using namespace o2; +using namespace o2::analysis; +using namespace o2::framework; +using namespace o2::framework::expressions; + +/// Dstar analysis task +struct HfTaskDstarToD0Pi { + Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 & Pi"}; + Configurable yCandDstarRecoMax{"yCandDstarRecoMax", 0.8, "max. candidate Dstar rapidity"}; + Configurable yCandDstarGenMax{"yCandDstarGenMax", 0.5, "max. rapidity of Generator level Particle"}; + Configurable selectionFlagHfD0ToPiK{"selectionFlagHfD0ToPiK", true, "Selection Flag for HF flagged candidates"}; + Configurable> ptBins{"ptBins", std::vector{hf_cuts_dstar_to_d0_pi::vecBinsPt}, "pT bin limits for Dstar"}; + + using CandDstarWSelFlag = soa::Join; + /// @brief specially for MC data + // full reconstructed Dstar candidate + using CandDstarWSelFlagMcRec = soa::Join; + using CandDstarMcGen = soa::Join; + + Partition rowsSelectedCandDstar = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == selectionFlagDstarToD0Pi; + Partition rowsSelectedCandDstarMcRec = aod::hf_sel_candidate_dstar::isRecoD0Flag == selectionFlagHfD0ToPiK; + + HistogramRegistry registry{ + "registry", + {{"QA/hPtDstar", "Dstar Candidates; Dstar candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"QA/hPtD0", "D0 Candiades; D0 Candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"QA/hPtProng0D0", "Prong0 of D0 Candidates; Prong0 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"QA/hPtProng1D0", "Prong1 of D0 Candidates; Prong1 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"QA/hPtProng0D0Bar", "Prong0 of D0Bar Candidates; Prong0 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"QA/hPtProng1D0Bar", "Prong1 of D0Bar Candidates; Prong1 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"QA/hPtSoftPi", "Soft Pi ; Soft Pi #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{100, 0., 1.}}}}}}; + + void init(InitContext&) + { + auto vecPtBins = (std::vector)ptBins; + + registry.add("Yield/hDeltaInvMassDstar2D", "#Delta #it{M}_{inv} D* Candidate; inv. mass (#pi #pi k) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, 0.13, 0.16}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + registry.add("Yield/hDeltaInvMassDstar1D", "#Delta #it{M}_{inv} D* Candidate; inv. mass (#pi #pi k) (GeV/#it{c}^{2}); entries", {HistType::kTH1F, {{100, 0.13, 0.16}}}, true); + registry.add("Yield/hInvMassDstar", "#Delta #it{M}_{inv} D* Candidate; inv. mass (#pi #pi k) (GeV/#it{c}^{2}); entries", {HistType::kTH1F, {{500, 0., 5.0}}}, true); + registry.add("Yield/hInvMassD0", "#it{M}_{inv}D^{0} candidate;#it{M}_{inv} D^{0} (GeV/#it{c});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{500, 0., 5.0}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + // only QA + registry.add("QA/hEtaDstar", "D* Candidate; D* Candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hCtD0", "D0 Candidate; D0 Candidate's proper life time #it{c}#tau (cm) ; entries ", {HistType::kTH2F, {{120, -20., 100.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthD0", "D0 Candidate; D0 Candidate's decay length (cm); entries", {HistType::kTH2F, {{800, 0., 4.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthXYD0", "D0 Candidate; D0 Candidate's decay length xy (cm); entries", {HistType::kTH2F, {{800, 0., 4.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthNormalisedD0", "D0 Candidates;Do Candidate's normalised decay length (cm); entries", {HistType::kTH2F, {{800, 0., 40.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthXYNormalisedD0", "D0 candidate; D0 Candidate's normalised decay length xy (cm); entries", {HistType::kTH2F, {{800, 0., 40.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hCPAD0", "D0 Candidates; D0 Candidate's cosine pointing angle; entries", {HistType::kTH2F, {{110, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hCPAxyD0", "D0 candidates; D0 Candidate's cosine of pointing angle xy; entries", {HistType::kTH2F, {{110, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hImpactParameterXYD0", "D0 Candidates; D0 Candidate's reconstructed impact parameter xy (cm); entries", {HistType::kTH2F, {{200, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDeltaIPMaxNormalisedD0", "D0 Candidate; D0 Candidate's Norm. Delta IP; entries", {HistType::kTH2F, {{200, -20., 20.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hSqSumProngesImpactParameterD0", "D0 Candidates; Sqr Sum of Impact params of D0 Pronges; enteries ", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthErrorD0", "D0 Candidates; D0 Candidate's Decay Lenth Error (cm); entries", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthXYErrorD0", "D0 Candidates; D0 Candidate's Decay Length Error XY (cm); entries", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hImpactParameterError", "D0 Pronges; Impactparam error of different D0 Pronges (cm); entries", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hd0Prong0", "Prong0; DCAxy of Prong0 (cm); entries", {HistType::kTH2F, {{100, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hd0Prong1", "Prong1; DCAxy of Prong1 (cm); entries", {HistType::kTH2F, {{100, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hd0ProngSoftPi", "ProngSoftPi; DCAxy of Prong Soft Pi (cm); entries", {HistType::kTH2F, {{100, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // MC Matching at Reconstruction Level Successful + registry.add("QA/hCPASkimD0RecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; cosine of pointing angle", {HistType::kTH1F, {{110, -1.1, 1.1}}}); + registry.add("QA/hEtaSkimD0RecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{#eta} of D0 Prong", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hEtaSkimDstarRecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{#eta} of D* Candidate", {HistType::kTH1F, {{100, -2., 2.}}}); + // pt vs y + registry.add("QA/hPtSkimDstarGenSig", "MC Matched Skimed D* Reconstructed Candidates at Generator Level; #it{p}_{T} of D* at Generator Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hPtVsYSkimDstarRecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoTopolDstarRecSig", "MC Matched RecoTopol D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoPidDstarRecSig", "MC Matched RecoPid D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtFullRecoDstarRecSig", "MC Matched FullReco D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // Only Prompt RecSig + registry.add("QA/hPtVsYSkimPromptDstarRecSig", "MC Matched Skimed Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}; #it{y})", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoTopolPromptDstarRecSig", "MC Matched RecoTopol Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoPidPromptDstarRecSig", "MC Matched RecoPid Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtFullRecoPromptDstarRecSig", "MC Matched FullReco Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // Only Non-Prompt RecSig + registry.add("QA/hPtVsYSkimNonPromptDstarRecSig", "MC Matched Skimed Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoTopolNonPromptDstarRecSig", "MC Matched RecoTopol Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoPidNonPromptDstarRecSig", "MC Matched RecoPid Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYFullRecoNonPromptDstarRecSig", "MC Matched FullReco Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // MC Matching UnSuccessful + registry.add("QA/hCPASkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; cosine of pointing angle", {HistType::kTH1F, {{110, -1., 1.}}}); + registry.add("QA/hEtaSkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; #it{#eta} of D0 Prong", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hEtaSkimDstarRecBg", "MC UnMatched Skimmed D* Candidates at Reconstruction Level; #it{#eta} of D* Candidate", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hPtSkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; #it{p}_{T} of D0", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hPtSkimDstarRecBg", "MC UnMatched Skimmed D* Candidates at Reconstruction Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // MC Matching at Generator level Successful + registry.add("QA/hEtaDstarGen", "MC Matched D* Candidates at Generator Level; #it{#eta}", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hPtDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hPtVsYDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + // Prompt Gen + registry.add("QA/hPtPromptDstarGen", "MC Matched Prompt D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hPtVsYPromptDstarGen", "MC Matched Prompt D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + // Non Prmpt Gen + registry.add("QA/hPtNonPromptDstarGen", "MC Matched Non-Prompt D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hPtVsYNonPromptDstarGen", "MC Matched Non-Prompt D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + } + + void process(aod::Tracks const&, + CandDstarWSelFlag const&) + { + for (const auto& candDstar : rowsSelectedCandDstar) { + auto yDstar = candDstar.y(constants::physics::MassDStar); + if (yCandDstarRecoMax >= 0. && std::abs(yDstar) > yCandDstarRecoMax) { + continue; + } + registry.fill(HIST("QA/hPtDstar"), candDstar.pt()); + registry.fill(HIST("QA/hPtD0"), candDstar.ptD0()); + registry.fill(HIST("QA/hPtSoftPi"), candDstar.ptSoftPi()); + registry.fill(HIST("QA/hEtaDstar"), candDstar.eta(), candDstar.pt()); + registry.fill(HIST("QA/hCtD0"), candDstar.ctD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthD0"), candDstar.decayLengthD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthXYD0"), candDstar.decayLengthXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthNormalisedD0"), candDstar.decayLengthNormalisedD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthXYNormalisedD0"), candDstar.decayLengthXYNormalisedD0(), candDstar.pt()); + registry.fill(HIST("QA/hCPAD0"), candDstar.cpaD0(), candDstar.pt()); + registry.fill(HIST("QA/hCPAxyD0"), candDstar.cpaXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterXYD0"), candDstar.impactParameterXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hDeltaIPMaxNormalisedD0"), candDstar.deltaIPNormalisedMaxD0(), candDstar.pt()); + registry.fill(HIST("QA/hSqSumProngesImpactParameterD0"), candDstar.impactParameterProngSqSumD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthErrorD0"), candDstar.errorDecayLengthD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthXYErrorD0"), candDstar.errorDecayLengthXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpactParameter0(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpactParameter1(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpParamSoftPi(), candDstar.pt()); + registry.fill(HIST("QA/hd0Prong0"), candDstar.impactParameter0(), candDstar.pt()); + registry.fill(HIST("QA/hd0Prong1"), candDstar.impactParameter1(), candDstar.pt()); + registry.fill(HIST("QA/hd0ProngSoftPi"), candDstar.impParamSoftPi(), candDstar.pt()); + + auto invDstar = candDstar.invMassDstar(); + auto invAntiDstar = candDstar.invMassAntiDstar(); + auto invD0 = candDstar.invMassD0(); + auto invD0Bar = candDstar.invMassD0Bar(); + + auto prongSoftPi = candDstar.prongPi_as(); + if (prongSoftPi.sign() > 0) { + registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), (invDstar - invD0), candDstar.pt()); + registry.fill(HIST("Yield/hInvMassD0"), invD0, candDstar.ptD0()); + registry.fill(HIST("Yield/hDeltaInvMassDstar1D"), (invDstar - invD0)); + registry.fill(HIST("Yield/hInvMassDstar"), invDstar); + // filling pt of two pronges of D0 + registry.fill(HIST("QA/hPtProng0D0"), candDstar.ptProng0()); + registry.fill(HIST("QA/hPtProng1D0"), candDstar.ptProng1()); + } else if (prongSoftPi.sign() < 0) { + registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), (invAntiDstar - invD0Bar), candDstar.pt()); + registry.fill(HIST("Yield/hInvMassD0"), invD0Bar, candDstar.ptD0()); + registry.fill(HIST("Yield/hDeltaInvMassDstar1D"), (invAntiDstar - invD0Bar)); + registry.fill(HIST("Yield/hInvMassDstar"), invAntiDstar); + // filling pt of two pronges of D0Bar + registry.fill(HIST("QA/hPtProng0D0Bar"), candDstar.ptProng0()); + registry.fill(HIST("QA/hPtProng1D0Bar"), candDstar.ptProng1()); + } + } + } + + void processMC(CandDstarWSelFlagMcRec const&, + CandDstarMcGen const& rowsMcPartilces, + aod::TracksWMc const&) + { + + int8_t signDstar = 0; + // MC at Reconstruction level + for (const auto& candDstarMcRec : rowsSelectedCandDstarMcRec) { + auto ptDstarRecSig = candDstarMcRec.pt(); + auto yDstarRecSig = candDstarMcRec.y(constants::physics::MassDStar); + if (yCandDstarRecoMax >= 0. && std::abs(yDstarRecSig) > yCandDstarRecoMax) { + continue; + } + if (TESTBIT(std::abs(candDstarMcRec.flagMcMatchRec()), aod::hf_cand_dstar::DecayType::DstarToD0Pi)) { // if MC matching is successful at Reconstruction Level + // get MC Mother particle + auto indexMother = RecoDecay::getMother(rowsMcPartilces, candDstarMcRec.prong0_as().mcParticle_as(), o2::constants::physics::Pdg::kDStar, true, &signDstar, 2); + auto particleMother = rowsMcPartilces.rawIteratorAt(indexMother); // What is difference between rawIterator() or iteratorAt() methods? + registry.fill(HIST("QA/hPtDstarGenSig"), particleMother.pt()); // generator level pt + + registry.fill(HIST("QA/hPtVsYSkimDstarRecSig"), ptDstarRecSig, yDstarRecSig); // Skimed at level of trackIndexSkimCreator + if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed + registry.fill(HIST("QA/hPtVsYRecoTopolDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoPid()) { // if PID selection is passed + registry.fill(HIST("QA/hPtVsYRecoPidDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoCand()) { // if all selection passed + registry.fill(HIST("QA/hPtFullRecoDstarRecSig"), ptDstarRecSig); + } + registry.fill(HIST("QA/hCPASkimD0RecSig"), candDstarMcRec.cpaD0()); + registry.fill(HIST("QA/hEtaSkimD0RecSig"), candDstarMcRec.etaD0()); + registry.fill(HIST("QA/hEtaSkimDstarRecSig"), candDstarMcRec.eta()); + + // only prompt signal at reconstruction level + if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("QA/hPtVsYSkimPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); // Skimed at level of trackIndexSkimCreator + if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed + registry.fill(HIST("QA/hPtVsYRecoTopolPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoPid()) { // if PID selection is passed + registry.fill(HIST("QA/hPtVsYRecoPidPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoCand()) { // if all selection passed + registry.fill(HIST("QA/hPtFullRecoPromptDstarRecSig"), ptDstarRecSig); + } + + } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { // only non-prompt signal at reconstruction level + registry.fill(HIST("QA/hPtVsYSkimNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed + registry.fill(HIST("QA/hPtVsYRecoTopolNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoPid()) { + registry.fill(HIST("QA/PtVsYRecoPidNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoCand()) { + registry.fill(HIST("QA/PtFullRecoPromptDstarRecSig"), ptDstarRecSig); + } + } + } else { // MC Unmatched (Baground at Reconstruction Level) + registry.fill(HIST("QA/hCPASkimD0RecBg"), candDstarMcRec.cpaD0()); + registry.fill(HIST("QA/hEtaSkimD0RecBg"), candDstarMcRec.etaD0()); + registry.fill(HIST("QA/hEtaSkimDstarRecBg"), candDstarMcRec.eta()); + registry.fill(HIST("QA/hPtSkimD0RecBg"), candDstarMcRec.ptD0()); + registry.fill(HIST("QA/hPtSkimDstarRecBg"), candDstarMcRec.pt()); + } + } + + // MC at Generator Level + for (const auto& mcParticle : rowsMcPartilces) { + if (TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_dstar::DecayType::DstarToD0Pi)) { // MC Matching is successful at Generator Level + auto ptGen = mcParticle.pt(); + // auto yGen = mcParticle.y(); // Can we use this definition? + auto yGen = RecoDecay::y(std::array{mcParticle.px(), mcParticle.py(), mcParticle.pz()}, o2::constants::physics::MassDStar); + if (yCandDstarGenMax >= 0. && std::abs(yGen) > yCandDstarGenMax) { + continue; + } + registry.fill(HIST("QA/hEtaDstarGen"), mcParticle.eta()); + registry.fill(HIST("QA/hPtDstarGen"), ptGen); + registry.fill(HIST("QA/hPtVsYDstarGen"), ptGen, yGen); + // only promt Dstar candidate at Generator level + if (mcParticle.originMcGen() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("QA/hPtPromptDstarGen"), ptGen); + registry.fill(HIST("QA/hPtVsYPromptDstarGen"), ptGen, yGen); + } else if (mcParticle.originMcGen() == RecoDecay::OriginType::NonPrompt) { // only non-prompt Dstar candidate at Generator level + registry.fill(HIST("QA/hPtNonPromptDstarGen"), ptGen); + registry.fill(HIST("QA/hPtVsYNonPromptDstarGen"), ptGen, yGen); + } + } + } + } + PROCESS_SWITCH(HfTaskDstarToD0Pi, processMC, "Process MC Data", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 3f30d7fb3a3cd84153f4fdf97b7cf04578858127 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Wed, 10 Jan 2024 18:55:27 +0900 Subject: [PATCH 136/156] EventFiltering/PWGEM: add software trigger for photons (#4223) * EventFiltering/PWGEM: add software trigger for photons * MegaLinter fixes * Revert "[MegaLinter] Apply linters automatic fixes to #4223" --------- Co-authored-by: ALICE Action Bot --- EventFiltering/CMakeLists.txt | 11 +- EventFiltering/PWGEM/EMPhotonFilter.cxx | 318 ++++++++++++++++++ EventFiltering/PWGEM/EMPhotonFilterQC.cxx | 171 ++++++++++ EventFiltering/PWGEM/photonFilter.cxx | 139 -------- EventFiltering/cefpTask.cxx | 10 +- EventFiltering/filterTables.h | 29 +- .../TableProducer/skimmerDalitzEE.cxx | 57 +++- .../TableProducer/skimmerPrimaryElectron.cxx | 14 +- .../TableProducer/skimmerPrimaryMuon.cxx | 10 +- PWGEM/Tasks/phosTrigQA.cxx | 38 +-- 10 files changed, 601 insertions(+), 196 deletions(-) create mode 100644 EventFiltering/PWGEM/EMPhotonFilter.cxx create mode 100644 EventFiltering/PWGEM/EMPhotonFilterQC.cxx delete mode 100644 EventFiltering/PWGEM/photonFilter.cxx diff --git a/EventFiltering/CMakeLists.txt b/EventFiltering/CMakeLists.txt index 21884728f44..4a3e3074816 100644 --- a/EventFiltering/CMakeLists.txt +++ b/EventFiltering/CMakeLists.txt @@ -82,9 +82,14 @@ o2physics_add_dpl_workflow(mult-filter PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(em-filter - SOURCES PWGEM/photonFilter.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase +o2physics_add_dpl_workflow(em-photon-filter + SOURCES PWGEM/EMPhotonFilter.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase O2Physics::PWGEMPhotonMesonCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(em-photon-filter-qc + SOURCES PWGEM/EMPhotonFilterQC.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase O2Physics::PWGEMPhotonMesonCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(lf-f1proton-filter diff --git a/EventFiltering/PWGEM/EMPhotonFilter.cxx b/EventFiltering/PWGEM/EMPhotonFilter.cxx new file mode 100644 index 00000000000..390646f6140 --- /dev/null +++ b/EventFiltering/PWGEM/EMPhotonFilter.cxx @@ -0,0 +1,318 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// \brief software trigger for EM photon +// \author daiki.sekihata@cern.ch + +#include "Math/Vector4D.h" +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Common/DataModel/CaloClusters.h" +#include "DataFormatsPHOS/TriggerRecord.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "EventFiltering/filterTables.h" +#include "Framework/HistogramRegistry.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using MyCollisions = soa::Join; +using MyCollision = MyCollisions::iterator; + +// using MyPrimaryElectrons = soa::Join; +// using MyPrimaryElectron = MyPrimaryElectrons::iterator; + +struct EMPhotonFilter { + + enum EM_Filter_PhotonType { + kPCM = 0x1, + kPHOS = 0x2, + kEMC = 0x4, + }; + + enum trigs { + kPHOS_Photon = 0, + kPHOS_El = 1, + kPHOS_Pair = 2, + kPHOS_Nbar = 3, + kPCM_HighPtPhoton = 4, + kPCM_MatCalib = 5, + kPCM_EtaDalitz = 6, + kPCM_EtaGG = 7, + kPCM_EE = 8, + kNtrg + }; + + Produces tags; + + Configurable ePhot{"ePhot", 2.2, "Minimal photon energy (GeV)"}; + Configurable eEl{"eEl", 1., "Minimal electron energy (GeV)"}; + Configurable ePair{"ePair", 0.35, "Minimal photon pair mass (GeV)"}; + Configurable nNbar{"nNbar", 2, "Minimal number of nbar clusters"}; + + // for PCM + Configurable min_pt_tagging{"min_pt_tagging", 0.f, "min. pT for tagging"}; + Configurable max_mee_pi0_dalitz{"max_mee_pi0_dalitz", 0.12, "max. mee for pi0 dalitz decay"}; + Configurable min_meeg_pi0{"min_meeg_pi0", 0.04, "min. meeg for pi0"}; + Configurable max_meeg_pi0{"max_meeg_pi0", 0.24, "max. meeg for pi0"}; + Configurable max_mee_eta_dalitz{"max_mee_eta_dalitz", 0.5, "max. mee for eta dalitz decay"}; + Configurable min_meeg_eta{"min_meeg_eta", 0.35, "min. meeg for eta"}; + Configurable max_meeg_eta{"max_meeg_eta", 0.75, "max. meeg for eta"}; + Configurable slope{"slope", 0.0185, "slope for m vs. phiv"}; + Configurable intercept{"intercept", -0.0280, "intercept for m vs. phiv"}; + Configurable min_pt_pcm_photon{"min_pt_pcm_photon", 4.f, "min. pT for PCM photon"}; + + HistogramRegistry mHistManager{"events", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + void init(o2::framework::InitContext&) + { + auto scalers{std::get>(mHistManager.add("hEventCounter", "Number of filtered events", HistType::kTH1F, {{20, 0.5, 20.5}}))}; + scalers->GetXaxis()->SetBinLabel(1, "all events"); + scalers->GetXaxis()->SetBinLabel(2, "sel8"); + scalers->GetXaxis()->SetBinLabel(3, "|Z_{vtx}| < 10 cm"); + scalers->GetXaxis()->SetBinLabel(4, "sel8 && |Z_{vtx}| < 10 cm"); + scalers->GetXaxis()->SetBinLabel(5, "PHOS photon"); + scalers->GetXaxis()->SetBinLabel(6, "PHOS electron"); + scalers->GetXaxis()->SetBinLabel(7, "PHOS pair"); + scalers->GetXaxis()->SetBinLabel(8, "PHOS nbar"); + scalers->GetXaxis()->SetBinLabel(9, "PHOS photon & electron"); + scalers->GetXaxis()->SetBinLabel(10, "PHOS photon & pair"); + scalers->GetXaxis()->SetBinLabel(11, "events with PHOS"); + scalers->GetXaxis()->SetBinLabel(12, "PCM high p_{T} photon"); + scalers->GetXaxis()->SetBinLabel(13, "PCM Material budget calibration"); + scalers->GetXaxis()->SetBinLabel(14, "PCM #eta #rightarrow ee#gamma"); + scalers->GetXaxis()->SetBinLabel(15, "PCM #eta #rightarrow #gamma#gamma"); + scalers->GetXaxis()->SetBinLabel(16, "PCM DalitzEE #gamma-#gamma^{*} BEC"); + } + + Preslice perCollision_pcm = aod::v0photonkf::collisionId; + // Preslice perCollision_ee = aod::dalitzee::collisionId; + Preslice perCollision_phos = aod::calocluster::collisionId; + // Preslice perCollision_emc = aod::skimmedcluster::collisionId; + + template + void runFilter(TCollisions const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPhotons3 const& photons3, TV0Legs const&, TDielectrons const& dielectrons, TEMPrimaryElectrons const& emprimaryelectrons) + { + for (auto& collision : collisions) { + mHistManager.fill(HIST("hEventCounter"), 1.); + bool keepEvent[kNtrg]{false}; + + if (collision.sel8()) { + mHistManager.fill(HIST("hEventCounter"), 2.); + } + if (abs(collision.posZ()) < 10.f) { + mHistManager.fill(HIST("hEventCounter"), 3.); + } + if (collision.sel8() && abs(collision.posZ()) < 10.f) { + mHistManager.fill(HIST("hEventCounter"), 4.); + } + + if constexpr (static_cast(system & EM_Filter_PhotonType::kPCM)) { + auto photons1_per_coll = photons1.sliceBy(perCollision_pcm, collision.globalIndex()); + // auto dielectrons_per_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); + + for (auto& v0photon : photons1_per_coll) { + if (v0photon.pt() > min_pt_pcm_photon) { + keepEvent[kPCM_HighPtPhoton] = true; + mHistManager.fill(HIST("hEventCounter"), 12); + break; + } + } // end of single v0 photon loop + + // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { + // if (g2.pt() < min_pt_tagging) { // this is only to increase rejection factor + // continue; + // } + // if (g2.mass() > max_mee_pi0_dalitz) { // select only pi0 candidates + // continue; + // } + // if (g2.mass() < slope * g2.phiv() + intercept) { + // continue; + // } + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + // if (min_meeg_pi0 < v12.M() && v12.M() < max_meeg_pi0) { + // keepEvent[kPCM_MatCalib] = true; + // mHistManager.fill(HIST("hEventCounter"), 13); + // break; + // } + + // } // end of dielectron-photon pair loop + + // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { + // if (g2.mass() > max_mee_eta_dalitz) { // select only eta candidates + // continue; + // } + // if (g2.mass() < slope * g2.phiv() + intercept) { + // continue; + // } + + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + // if (min_meeg_eta < v12.M() && v12.M() < max_meeg_eta) { // eta -> eeg + // keepEvent[kPCM_EtaDalitz] = true; + // mHistManager.fill(HIST("hEventCounter"), 14); + // break; + // } + // } // end of dielectron-photon pair loop + + // for (auto& [g1, g2] : combinations(CombinationsStrictlyUpperIndexPolicy(photons1_per_coll, photons1_per_coll))) { + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + // if (min_meeg_eta < v12.M() && v12.M() < max_meeg_eta) { // eta -> gg + // keepEvent[kPCM_EtaGG] = true; + // mHistManager.fill(HIST("hEventCounter"), 15); + // break; + // } + // } // end of photon-photon pair loop + + // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { + // if (g2.mass() < slope * g2.phiv() + intercept) { + // continue; + // } + // keepEvent[kPCM_EE] = true; + // mHistManager.fill(HIST("hEventCounter"), 16); + // break; + // } // end of dielectron-photon pair loop + + } // end of PCM decision + + if constexpr (static_cast(system & EM_Filter_PhotonType::kPHOS)) { + int nPHOSclu = 0; + int nPHOSnbar = 0; + auto photons2_coll = photons2.sliceBy(perCollision_phos, collision.globalIndex()); + for (const auto& clu : photons2_coll) { + nPHOSclu++; + + // Scan current cluster + // photons + keepEvent[kPHOS_Photon] |= (clu.e() > ePhot); + // charged clusters above threshold + keepEvent[kPHOS_El] |= (clu.trackdist() < 2. && clu.e() > eEl); // 2: Distance to CPV cluster in sigmas + // antineutrons + if ((clu.ncell() > 2 && clu.m02() > 0.2 && clu.e() > 0.7 && clu.trackdist() > 2.) && + ((clu.e() < 2. && clu.m02() > 4.5 - clu.m20()) || + (clu.e() > 2. && clu.m02() > 4. - clu.m20()))) { + nPHOSnbar++; + } + + // inv mass + if (clu.trackdist() < 1.) { + auto clu2 = clu; + ++clu2; + for (; !keepEvent[kPHOS_Pair] && clu2 != photons2.end(); clu2++) { + // cluster selections + if (clu2.trackdist() < 1.) { // select neutral clusters. Disp, Ncell cuts? + continue; + } + double m = pow(clu.e() + clu2.e(), 2) - pow(clu.px() + clu2.px(), 2) - + pow(clu.py() + clu2.py(), 2) - pow(clu.pz() + clu2.pz(), 2); + if (m > ePair * ePair) { + keepEvent[kPHOS_Pair] |= true; + break; + } + } + } + } // end of cluster loop + keepEvent[kPHOS_Nbar] = (nPHOSnbar >= nNbar); + + // Collision processed, fill scalers here + if (nPHOSclu) { + mHistManager.fill(HIST("hEventCounter"), 11.); + } + // Can not fill with variable, have to fill manually + if (keepEvent[kPHOS_Photon]) { + mHistManager.fill(HIST("hEventCounter"), 5.); + if (keepEvent[kPHOS_El]) { + mHistManager.fill(HIST("hEventCounter"), 9.); + } + if (keepEvent[kPHOS_Pair]) { + mHistManager.fill(HIST("hEventCounter"), 10.); + } + } + if (keepEvent[kPHOS_El]) { + mHistManager.fill(HIST("hEventCounter"), 6.); + } + if (keepEvent[kPHOS_Pair]) { + mHistManager.fill(HIST("hEventCounter"), 7.); + } + if (keepEvent[kPHOS_Nbar]) { + mHistManager.fill(HIST("hEventCounter"), 8.); + } + } + + // // EMC decision + // if constexpr (static_cast(system & EM_Filter_PhotonType::kEMC)) { + // // so far, do nothing. + // } + tags(keepEvent[kPHOS_Photon], keepEvent[kPHOS_Nbar], keepEvent[kPCM_HighPtPhoton]); + } // end of collision loop + } + + // void process_PCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, aod::DalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + void process_PCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs) + { + const uint8_t system = EM_Filter_PhotonType::kPCM; + runFilter(collisions, v0photons, nullptr, nullptr, v0legs, nullptr, nullptr); + } + + Filter phosCluFilter = (o2::aod::calocluster::e > 0.3f); + using CluCandidates = o2::soa::Filtered; + void process_PHOS(MyCollisions const& collisions, CluCandidates const& clusters) + { + const uint8_t system = EM_Filter_PhotonType::kPHOS; + runFilter(collisions, nullptr, clusters, nullptr, nullptr, nullptr, nullptr); + } + + void process_EMC(MyCollisions const& collisions, aod::SkimEMCClusters const& clusters) + { + const uint8_t system = EM_Filter_PhotonType::kEMC; + runFilter(collisions, nullptr, nullptr, clusters, nullptr, nullptr, nullptr); + } + + // void process_PCM_PHOS(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, aod::DalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons, CluCandidates const& clusters) + void process_PCM_PHOS(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, CluCandidates const& clusters) + { + const uint8_t system = EM_Filter_PhotonType::kPCM | EM_Filter_PhotonType::kPHOS; + // runFilter(collisions, v0photons, clusters, nullptr, v0legs, dielectrons, emprimaryelectrons); + runFilter(collisions, v0photons, clusters, nullptr, v0legs, nullptr, nullptr); + } + + void processDummy(MyCollisions const& collisions) + { + for (int i = 0; i < collisions.size(); i++) { + tags(false, false, false); + } + } + + PROCESS_SWITCH(EMPhotonFilter, process_PCM, "Process PCM software trigger decision", false); + PROCESS_SWITCH(EMPhotonFilter, process_PHOS, "Process PHOS software trigger decision", false); + PROCESS_SWITCH(EMPhotonFilter, process_EMC, "Process EMC software trigger decision", false); + PROCESS_SWITCH(EMPhotonFilter, process_PCM_PHOS, "Process PCM and PHOS software trigger decision", false); + PROCESS_SWITCH(EMPhotonFilter, processDummy, "Process dummy", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfg) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfg, TaskName{"em-photon-filter"})}; +} diff --git a/EventFiltering/PWGEM/EMPhotonFilterQC.cxx b/EventFiltering/PWGEM/EMPhotonFilterQC.cxx new file mode 100644 index 00000000000..65a0cbbce47 --- /dev/null +++ b/EventFiltering/PWGEM/EMPhotonFilterQC.cxx @@ -0,0 +1,171 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// \brief Quick QC task for CEFP for EM photon +// \author daiki.sekihata@cern.ch + +#include "Math/Vector4D.h" +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Common/DataModel/CaloClusters.h" +#include "DataFormatsPHOS/TriggerRecord.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/Core/CutsLibrary.h" +#include "EventFiltering/filterTables.h" +#include "Framework/HistogramRegistry.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using MyCollisions = soa::Join; +using MyCollision = MyCollisions::iterator; + +struct EMPhotonFilterQC { + HistogramRegistry registry{"registry"}; + + void init(o2::framework::InitContext&) + { + addhistograms(); + } + + void addhistograms() + { + auto hEventCounter = registry.add("hEventCounter", "hEventCounter", kTH1F, {{20, 0.5f, 20.5f}}); + hEventCounter->GetXaxis()->SetBinLabel(1, "all"); + hEventCounter->GetXaxis()->SetBinLabel(2, "sel8 && |Z_{vtx}| < 10 cm"); + hEventCounter->GetXaxis()->SetBinLabel(3, "PCM High p_{T} photon"); + hEventCounter->GetXaxis()->SetBinLabel(4, "PCM High p_{T} photon && sel8 && |Z_{vtx}| < 10 cm"); + hEventCounter->GetXaxis()->SetBinLabel(5, "PCM MB calibration"); + hEventCounter->GetXaxis()->SetBinLabel(6, "PCM MB calibration && sel8 && |Z_{vtx}| < 10 cm"); + hEventCounter->GetXaxis()->SetBinLabel(7, "PCM #eta #rightarrow ee#gamma"); + hEventCounter->GetXaxis()->SetBinLabel(8, "PCM #eta #rightarrow ee#gamma && sel8 && |Z_{vtx}| < 10 cm"); + hEventCounter->GetXaxis()->SetBinLabel(9, "PCM #eta #rightarrow #gamma#gamma"); + hEventCounter->GetXaxis()->SetBinLabel(10, "PCM #eta #rightarrow #gamma#gamma && sel8 && |Z_{vtx}| < 10 cm"); + hEventCounter->GetXaxis()->SetBinLabel(11, "PCM and ee"); + hEventCounter->GetXaxis()->SetBinLabel(12, "PCM and ee && sel8 && |Z_{vtx}| < 10 cm"); + + registry.add("PCM_HighPt/hPt", "pT of PCM photon;p_{T,#gamma} (GeV/c)", kTH1F, {{200, 0, 20}}); + registry.add("PCM_HighPt/hEtaPhi", "#eta vs. #varphi of PCM photon", kTH2F, {{72, 0, TMath::TwoPi()}, {40, -2, +2}}); + registry.add("PCM_MBCalib/hMeePt", "mass ee#gamma;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{50, 0.f, 0.5f}, {100, 0, 10}}); + registry.add("PCM_MBCalib/hMeegPt", "mass ee#gamma;m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c)", kTH2F, {{200, 0.f, 0.4f}, {100, 0, 10}}); + registry.add("PCM_EtaDalitz/hMeePt", "mass ee;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0.f, 4.f}, {100, 0, 10}}); + registry.add("PCM_EtaDalitz/hMeegPt", "mass ee#gamma;m_{ee#gamma} (GeV/c^{2});p_{T,ee#gamma} (GeV/c)", kTH2F, {{400, 0.f, 0.8f}, {100, 0, 10}}); + registry.add("PCM_EtaGG/hMggPt", "mass ee#gamma;m_{#gamma#gamma} (GeV/c^{2});p_{T,#gamma#gamma} (GeV/c)", kTH2F, {{400, 0.f, 0.8f}, {100, 0, 10}}); + registry.add("PCM_EE/hMeePt", "mass ee;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0.f, 4.f}, {100, 0, 10}}); + registry.add("PCM_EE/hMeegPt", "mass ee#gamma;m_{ee#gamma} (GeV/c^{2});p_{T,ee#gamma} (GeV/c)", kTH2F, {{400, 0.f, 0.8f}, {100, 0, 10}}); + } + + Preslice perCollision_pcm = aod::v0photonkf::collisionId; + // Preslice perCollision_ee = aod::dalitzee::collisionId; + // void processPCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::DalitzEEs const& dielectrons) + void processPCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons) + { + for (auto& collision : collisions) { + registry.fill(HIST("hEventCounter"), 1); + if (collision.sel8() && abs(collision.posZ()) < 10.f) { + registry.fill(HIST("hEventCounter"), 2); + } + auto v0photons_coll = v0photons.sliceBy(perCollision_pcm, collision.globalIndex()); + // auto dielectrons_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); + + if (collision.hasPCMHighPtPhoton()) { + registry.fill(HIST("hEventCounter"), 3); + if (collision.sel8() && abs(collision.posZ()) < 10.f) { + registry.fill(HIST("hEventCounter"), 4); + } + for (auto& v0photon : v0photons_coll) { + registry.fill(HIST("PCM_HighPt/hPt"), v0photon.pt()); + registry.fill(HIST("PCM_HighPt/hEtaPhi"), v0photon.phi(), v0photon.eta()); + } // end of v0 photon loop + } + + // if (collision.hasPCMMatCalib()) { + // registry.fill(HIST("hEventCounter"), 5); + // if (collision.sel8() && abs(collision.posZ()) < 10.f) { + // registry.fill(HIST("hEventCounter"), 6); + // } + // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { + // registry.fill(HIST("PCM_MBCalib/hMeePt"), g2.mass(), g2.pt()); + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + // registry.fill(HIST("PCM_MBCalib/hMeegPt"), v12.M(), g1.pt()); + // } // end of dielectron-photon pair loop + // } + + // if (collision.hasPCMEtaDalitz()) { + // registry.fill(HIST("hEventCounter"), 7); + // if (collision.sel8() && abs(collision.posZ()) < 10.f) { + // registry.fill(HIST("hEventCounter"), 8); + // } + // for (auto& dielectron : dielectrons_coll) { + // registry.fill(HIST("PCM_EtaDalitz/hMeePt"), dielectron.mass(), dielectron.pt()); + // } + // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + // registry.fill(HIST("PCM_EtaDalitz/hMeegPt"), v12.M(), v12.Pt()); + // } // end of dielectron-photon pair loop + // } + + // if (collision.hasPCMEtaGG()) { + // registry.fill(HIST("hEventCounter"), 9); + // if (collision.sel8() && abs(collision.posZ()) < 10.f) { + // registry.fill(HIST("hEventCounter"), 10); + // } + // for (auto& [g1, g2] : combinations(CombinationsStrictlyUpperIndexPolicy(v0photons_coll, v0photons_coll))) { + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + // registry.fill(HIST("PCM_EtaGG/hMggPt"), v12.M(), v12.Pt()); + // } // end of dielectron-photon pair loop + // } + + // if (collision.hasPCMandEE()) { + // registry.fill(HIST("hEventCounter"), 11); + // if (collision.sel8() && abs(collision.posZ()) < 10.f) { + // registry.fill(HIST("hEventCounter"), 12); + // } + + // for (auto& dielectron : dielectrons_coll) { + // registry.fill(HIST("PCM_EE/hMeePt"), dielectron.mass(), dielectron.pt()); + // } + // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { + // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + // registry.fill(HIST("PCM_EE/hMeegPt"), v12.M(), v12.Pt()); + // } // end of dielectron-photon pair loop + // } + + } // end of collision loop + } + + void processPHOS(MyCollisions const& collisions) {} + void processEMC(MyCollisions const& collisions) {} + + PROCESS_SWITCH(EMPhotonFilterQC, processPCM, "Process PCM software trigger QC", true); + PROCESS_SWITCH(EMPhotonFilterQC, processPHOS, "Process PHOS software trigger QC", false); + PROCESS_SWITCH(EMPhotonFilterQC, processEMC, "Process EMC software trigger QC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfg) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfg, TaskName{"em-photon-filter-qc"})}; +} diff --git a/EventFiltering/PWGEM/photonFilter.cxx b/EventFiltering/PWGEM/photonFilter.cxx deleted file mode 100644 index 52b75a3e809..00000000000 --- a/EventFiltering/PWGEM/photonFilter.cxx +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// O2 includes - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Common/DataModel/CaloClusters.h" -#include "DataFormatsPHOS/TriggerRecord.h" - -#include "../filterTables.h" - -#include "Framework/HistogramRegistry.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -struct photonFilter { - static constexpr int nTrigs{4}; - enum trigs { kPhot, - kEl, - kPair, - kNbar }; - - Produces tags; - - Configurable ePhot{"ePhot", 2.2, "Minimal photon energy (GeV)"}; - Configurable eEl{"eEl", 1., "Minimal electron energy (GeV)"}; - Configurable ePair{"ePair", 0.35, "Minimal photon pair mass (GeV)"}; - Configurable nNbar{"nNbar", 2, "Minimal number of nbar clusters"}; - - HistogramRegistry mHistManager{"events", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - - void init(o2::framework::InitContext&) - { - auto scalers{std::get>(mHistManager.add("fProcessedEvents", "Number of filtered events", HistType::kTH1F, {{8, -0.5, 7.5}}))}; - scalers->GetXaxis()->SetBinLabel(1, "Processed events"); - scalers->GetXaxis()->SetBinLabel(2, "PHOS photon"); - scalers->GetXaxis()->SetBinLabel(3, "PHOS electron"); - scalers->GetXaxis()->SetBinLabel(4, "PHOS pair"); - scalers->GetXaxis()->SetBinLabel(5, "PHOS nbar"); - scalers->GetXaxis()->SetBinLabel(6, "PHOS photon & electron"); - scalers->GetXaxis()->SetBinLabel(7, "PHOS photon & pair"); - scalers->GetXaxis()->SetBinLabel(8, "events with PHOS"); - } - - Filter phosCluFilter = (o2::aod::calocluster::e > 0.3f); - - using CluCandidates = o2::soa::Filtered; - - void process(aod::Collisions::iterator const& collision, - CluCandidates const& clusters) - { - // Process all clusters per TF and fill corresponding collisions - bool keepEvent[nTrigs]{false}; - - mHistManager.fill(HIST("fProcessedEvents"), 0); - - // PHOS part - int nPHOSclu = 0; - int nPHOSnbar = 0; - for (const auto& clu : clusters) { - nPHOSclu++; - - // Scan current cluster - // photons - keepEvent[kPhot] |= (clu.e() > ePhot); - // charged clusters above threshold - keepEvent[kEl] |= (clu.trackdist() < 2. && clu.e() > eEl); // 2: Distance to CPV cluster in sigmas - // antineutrons - if ((clu.ncell() > 2 && clu.m02() > 0.2 && clu.e() > 0.7 && clu.trackdist() > 2.) && - ((clu.e() < 2. && clu.m02() > 4.5 - clu.m20()) || - (clu.e() > 2. && clu.m02() > 4. - clu.m20()))) { - nPHOSnbar++; - } - - // inv mass - if (clu.trackdist() < 1.) { - auto clu2 = clu; - ++clu2; - for (; !keepEvent[kPair] && clu2 != clusters.end(); clu2++) { - // cluster selections - if (clu2.trackdist() < 1.) { // select neutral clusters. Disp, Ncell cuts? - continue; - } - double m = pow(clu.e() + clu2.e(), 2) - pow(clu.px() + clu2.px(), 2) - - pow(clu.py() + clu2.py(), 2) - pow(clu.pz() + clu2.pz(), 2); - if (m > ePair * ePair) { - keepEvent[kPair] |= true; - break; - } - } - } - } - keepEvent[kNbar] = (nPHOSnbar >= nNbar); - - // Collision processed, fill scalers here - if (nPHOSclu) { - mHistManager.fill(HIST("fProcessedEvents"), 7.); - } - // Can not fill with variable, have to fill manually - if (keepEvent[kPhot]) { - mHistManager.fill(HIST("fProcessedEvents"), 1.); - if (keepEvent[kEl]) { - mHistManager.fill(HIST("fProcessedEvents"), 5.); - } - if (keepEvent[kPair]) { - mHistManager.fill(HIST("fProcessedEvents"), 6.); - } - } - if (keepEvent[kEl]) { - mHistManager.fill(HIST("fProcessedEvents"), 2.); - } - if (keepEvent[kPair]) { - mHistManager.fill(HIST("fProcessedEvents"), 3.); - } - if (keepEvent[kNbar]) { - mHistManager.fill(HIST("fProcessedEvents"), 4.); - } - // fill - tags(keepEvent[kPhot], keepEvent[kEl], keepEvent[kPair], keepEvent[kNbar]); - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfg) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfg)}; -} diff --git a/EventFiltering/cefpTask.cxx b/EventFiltering/cefpTask.cxx index 718a857d7dc..33c1d4d1d12 100644 --- a/EventFiltering/cefpTask.cxx +++ b/EventFiltering/cefpTask.cxx @@ -10,6 +10,10 @@ // or submit itself to any jurisdiction. // O2 includes +#include +#include +#include + #include #include #include @@ -17,10 +21,6 @@ #include #include -#include -#include -#include - #include "filterTables.h" #include "CCDB/BasicCCDBManager.h" @@ -226,7 +226,7 @@ struct centralEventFilterTask { FILTER_CONFIGURABLE(StrangenessFilters); FILTER_CONFIGURABLE(MultFilters); FILTER_CONFIGURABLE(FullJetFilters); - FILTER_CONFIGURABLE(PhotFilters); + FILTER_CONFIGURABLE(PhotonFilters); int mRunNumber{-1}; o2::InteractionRecord mEndOfITSramp{0, 0}; diff --git a/EventFiltering/filterTables.h b/EventFiltering/filterTables.h index 52b5856597e..1dfd08cc23f 100644 --- a/EventFiltering/filterTables.h +++ b/EventFiltering/filterTables.h @@ -21,7 +21,7 @@ namespace o2::aod { namespace filtering { -DECLARE_SOA_COLUMN(He, hasHe, bool); //! +DECLARE_SOA_COLUMN(He, hasHe, bool); //! DECLARE_SOA_COLUMN(H3L3Body, hasH3L3Body, bool); //! hypertriton 3body // diffraction @@ -105,10 +105,15 @@ DECLARE_SOA_COLUMN(HighFt0cFv0Flat, hasHighFt0cFv0Flat, bool); //! isotropic eve DECLARE_SOA_COLUMN(LeadingPtTrack, hasLeadingPtTrack, bool); //! event contains leading track // photons -DECLARE_SOA_COLUMN(PHOSPhoton, hasPHOSPhoton, bool); //! PHOS single photons -DECLARE_SOA_COLUMN(PHOSElectron, hasPHOSElectron, bool); //! PHOS single electron -DECLARE_SOA_COLUMN(PHOSPair, hasPHOSpair, bool); //! PHOS photon pair -DECLARE_SOA_COLUMN(PHOSnbar, hasPHOSnbar, bool); //! PHOS antineutrons +DECLARE_SOA_COLUMN(PHOSPhoton, hasPHOSPhoton, bool); //! PHOS single photons +DECLARE_SOA_COLUMN(PHOSnbar, hasPHOSnbar, bool); //! PHOS antineutrons +// DECLARE_SOA_COLUMN(PHOSElectron, hasPHOSElectron, bool); //! PHOS single electron +// DECLARE_SOA_COLUMN(PHOSPair, hasPHOSpair, bool); //! PHOS photon pair +DECLARE_SOA_COLUMN(PCMHighPtPhoton, hasPCMHighPtPhoton, bool); //! PCM high pT photon +// DECLARE_SOA_COLUMN(PCMMatCalib, hasPCMMatCalib, bool); //! PCM material budget calibration +// DECLARE_SOA_COLUMN(PCMEtaDalitz, hasPCMEtaDalitz, bool); //! PCM eta -> ee gamma +// DECLARE_SOA_COLUMN(PCMEtaGG, hasPCMEtaGG, bool); //! PCM eta -> ee gamma +// DECLARE_SOA_COLUMN(PCMandEE, hasPCMandEE, bool); //! PCM and ee } // namespace filtering namespace decision @@ -190,10 +195,10 @@ DECLARE_SOA_TABLE(MultFilters, "AOD", "MultFilters", //! using MultFilter = MultFilters::iterator; // photons -DECLARE_SOA_TABLE(PhotFilters, "AOD", "PhotFilters", //! - filtering::PHOSPhoton, filtering::PHOSElectron, filtering::PHOSPair, filtering::PHOSnbar); +DECLARE_SOA_TABLE(PhotonFilters, "AOD", "PhotonFilters", //! + filtering::PHOSPhoton, filtering::PHOSnbar, filtering::PCMHighPtPhoton); -using PhotFilter = PhotFilters::iterator; +using PhotonFilter = PhotonFilters::iterator; // cefp decision DECLARE_SOA_TABLE(CefpDecisions, "AOD", "CefpDecision", //! @@ -207,10 +212,10 @@ using BCRange = BCRanges::iterator; /// List of the available filters, the description of their tables and the name of the tasks constexpr int NumberOfFilters{11}; -constexpr std::array AvailableFilters{"NucleiFilters", "DiffractionFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "FullJetFilters", "StrangenessFilters", "MultFilters", "PhotFilters", "F1ProtonFilters"}; -constexpr std::array FilterDescriptions{"NucleiFilters", "DiffFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "FullJetFilters", "LFStrgFilters", "MultFilters", "PhotFilters", "F1ProtonFilters"}; -constexpr std::array FilteringTaskNames{"o2-analysis-nuclei-filter", "o2-analysis-diffraction-filter", "o2-analysis-dq-filter-pp-with-association", "o2-analysis-hf-filter", "o2-analysis-cf-filter", "o2-analysis-je-filter", "o2-analysis-fje-filter", "o2-analysis-lf-strangeness-filter", "o2-analysis-mult-filter", "o2-analysis-em-filter", "o2-analysis-lf-f1proton-filter"}; -constexpr o2::framework::pack FiltersPack; +constexpr std::array AvailableFilters{"NucleiFilters", "DiffractionFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "FullJetFilters", "StrangenessFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters"}; +constexpr std::array FilterDescriptions{"NucleiFilters", "DiffFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "FullJetFilters", "LFStrgFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters"}; +constexpr std::array FilteringTaskNames{"o2-analysis-nuclei-filter", "o2-analysis-diffraction-filter", "o2-analysis-dq-filter-pp-with-association", "o2-analysis-hf-filter", "o2-analysis-cf-filter", "o2-analysis-je-filter", "o2-analysis-fje-filter", "o2-analysis-lf-strangeness-filter", "o2-analysis-mult-filter", "o2-analysis-em-photon-filter", "o2-analysis-lf-f1proton-filter"}; +constexpr o2::framework::pack FiltersPack; static_assert(o2::framework::pack_size(FiltersPack) == NumberOfFilters); template diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx index ffaf845876f..1b674acdfcb 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx @@ -41,6 +41,10 @@ struct skimmerDalitzEE { SliceCache cache; Preslice perCol = o2::aod::emprimaryelectron::emreducedeventId; + + SliceCache cache_cefp; + Preslice perCol_cefp = o2::aod::emprimaryelectron::collisionId; + Produces dalitzees; Produces dalitz_ee_eventid; Produces event_nee; @@ -58,7 +62,7 @@ struct skimmerDalitzEE { void init(InitContext const&) {} - template + template int fillPairTable(TCollision const& collision, TTracks1 const& tracks1, TTracks2 const& tracks2) { int npair = 0; @@ -77,8 +81,15 @@ struct skimmerDalitzEE { float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); float dcaeez = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); - dalitz_ee_eventid(collision.globalIndex()); + + if constexpr (isCEFP) { + dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitz_ee_eventid(collision.globalIndex()); + } else { // for analysis + dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitz_ee_eventid(collision.globalIndex()); + } + fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); npair++; } // end of pairing loop @@ -97,8 +108,15 @@ struct skimmerDalitzEE { float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); float dcaeez = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); - dalitz_ee_eventid(collision.globalIndex()); + + if constexpr (isCEFP) { + dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitz_ee_eventid(collision.globalIndex()); + } else { // for analysis + dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitz_ee_eventid(collision.globalIndex()); + } + fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); npair++; } // end of pairing loop @@ -108,22 +126,41 @@ struct skimmerDalitzEE { Partition posTracks = o2::aod::emprimaryelectron::sign > 0; Partition negTracks = o2::aod::emprimaryelectron::sign < 0; - - void process(MyCollisions const& collisions, MyTracks const& tracks) + void processAnalysis(MyCollisions const& collisions, MyTracks const& tracks) { for (auto& collision : collisions) { auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::emprimaryelectron::emreducedeventId, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::emprimaryelectron::emreducedeventId, collision.globalIndex(), cache); int npair_uls = 0, npair_lspp = 0, npair_lsmm = 0; - npair_uls = fillPairTable(collision, posTracks_per_coll, negTracks_per_coll); // ULS + npair_uls = fillPairTable(collision, posTracks_per_coll, negTracks_per_coll); // ULS + if (storeLS) { + npair_lspp = fillPairTable(collision, posTracks_per_coll, posTracks_per_coll); // LS++ + npair_lsmm = fillPairTable(collision, negTracks_per_coll, negTracks_per_coll); // LS-- + } + event_nee(npair_uls, npair_lspp, npair_lsmm); + } // end of collision loop + } + PROCESS_SWITCH(skimmerDalitzEE, processAnalysis, "Process dalitz ee for analysis", true); + + Partition posTracks_cefp = o2::aod::emprimaryelectron::sign > 0; + Partition negTracks_cefp = o2::aod::emprimaryelectron::sign < 0; + void processCEFP(soa::Join const& collisions, aod::EMPrimaryElectrons const& tracks) + { + for (auto& collision : collisions) { + auto posTracks_per_coll = posTracks_cefp->sliceByCached(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache_cefp); + auto negTracks_per_coll = negTracks_cefp->sliceByCached(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache_cefp); + + int npair_uls = 0, npair_lspp = 0, npair_lsmm = 0; + npair_uls = fillPairTable(collision, posTracks_per_coll, negTracks_per_coll); // ULS if (storeLS) { - npair_lspp = fillPairTable(collision, posTracks_per_coll, posTracks_per_coll); // LS++ - npair_lsmm = fillPairTable(collision, negTracks_per_coll, negTracks_per_coll); // LS-- + npair_lspp = fillPairTable(collision, posTracks_per_coll, posTracks_per_coll); // LS++ + npair_lsmm = fillPairTable(collision, negTracks_per_coll, negTracks_per_coll); // LS-- } event_nee(npair_uls, npair_lspp, npair_lsmm); } // end of collision loop } + PROCESS_SWITCH(skimmerDalitzEE, processCEFP, "Process dalitz ee for CEFP", false); // for central event filter processing }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx index 0abacc3a387..678a97b9212 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx @@ -68,8 +68,8 @@ struct skimmerPrimaryElectron { Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; Configurable dca_xy_max{"dca_xy_max", 1.0f, "max DCAxy in cm"}; Configurable dca_z_max{"dca_z_max", 1.0f, "max DCAz in cm"}; - Configurable min_tpcdEdx{"min_tpcdEdx", 40.0, "min TPC dE/dx"}; - Configurable max_tpcdEdx{"max_tpcdEdx", 110.0, "max TPC dE/dx"}; + Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1.0f, "max DCA 3D in sigma"}; + Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -4.0, "min. TPC n sigma for electron inclusion"}; Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 4.0, "max. TPC n sigma for electron inclusion"}; Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", 4.0, "max. TOF n sigma for electron inclusion"}; Configurable maxTPCNsigmaPi{"maxTPCNsigmaPi", 2.0, "max. TPC n sigma for pion exclusion"}; @@ -186,6 +186,11 @@ struct skimmerPrimaryElectron { return false; } + float dca_3d = std::sqrt(std::pow(track.dcaXY() / std::sqrt(track.cYY()), 2) + std::pow(track.dcaZ() / std::sqrt(track.cZZ()), 2)); + if (dca_3d > dca_3d_sigma_max) { + return false; + } + return true; } @@ -299,9 +304,10 @@ struct skimmerPrimaryElectron { // ============================ FUNCTION DEFINITIONS ==================================================== std::vector stored_trackIds; - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& nabs(o2::aod::track::dcaXY) < dca_xy_max&& nabs(o2::aod::track::dcaZ) < dca_z_max&& o2::aod::track::tpcChi2NCl < maxchi2tpc&& o2::aod::track::itsChi2NCl < maxchi2its&& min_tpcdEdx < o2::aod::track::tpcSignal&& o2::aod::track::tpcSignal < max_tpcdEdx; - + Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& nabs(o2::aod::track::dcaXY) < dca_xy_max&& nabs(o2::aod::track::dcaZ) < dca_z_max&& o2::aod::track::tpcChi2NCl < maxchi2tpc&& o2::aod::track::itsChi2NCl < maxchi2its; + Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl && ((0.95f < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < 1.05f) || o2::aod::pidtofbeta::beta < 0.f); using MyFilteredTracks = soa::Filtered; + Partition posTracks = o2::aod::track::signed1Pt > 0.f; Partition negTracks = o2::aod::track::signed1Pt < 0.f; void processRec(aod::Collisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks) diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx index 4ac362d71e3..51801581c47 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx @@ -54,6 +54,7 @@ struct skimmerPrimaryMuon { Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; Configurable dca_xy_max{"dca_xy_max", 1.0f, "max DCAxy in cm"}; Configurable dca_z_max{"dca_z_max", 1.0f, "max DCAz in cm"}; + Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1.0f, "max DCA 3D in sigma"}; Configurable min_tpcdEdx{"min_tpcdEdx", 30.0, "min TPC dE/dx"}; Configurable max_tpcdEdx{"max_tpcdEdx", 1e+10, "max TPC dE/dx"}; Configurable maxPin{"maxPin", 1.0, "max pin for PID"}; @@ -144,10 +145,6 @@ struct skimmerPrimaryMuon { return false; } - // if(abs(track.dcaXY()) > dca_xy_max || abs(track.dcaZ()) > dca_z_max){ - // return false; - // } - if (track.itsNCls() < minitsncls) { return false; } @@ -165,6 +162,11 @@ struct skimmerPrimaryMuon { return false; } + float dca_3d = std::sqrt(std::pow(track.dcaXY() / std::sqrt(track.cYY()), 2) + std::pow(track.dcaZ() / std::sqrt(track.cZZ()), 2)); + if (dca_3d > dca_3d_sigma_max) { + return false; + } + return true; } diff --git a/PWGEM/Tasks/phosTrigQA.cxx b/PWGEM/Tasks/phosTrigQA.cxx index 40ea10b7794..b0b0949cfb5 100644 --- a/PWGEM/Tasks/phosTrigQA.cxx +++ b/PWGEM/Tasks/phosTrigQA.cxx @@ -138,7 +138,7 @@ struct phosTrigQA { ccdb->setLocalObjectValidityChecking(); } - using SelCollisions = soa::Join; + using SelCollisions = soa::Join; /// \brief Process PHOS data void process(o2::aod::BCs const& bcs, @@ -372,18 +372,18 @@ struct phosTrigQA { mHistManager.fill(HIST("elSpTr"), clu.e(), 6.5); } } - if (clu.collision_as().hasPHOSElectron()) { - mHistManager.fill(HIST("cluSpTr"), clu.e(), 7.5); - if (clu.trackdist() < 2.) { // 2: Distance to CPV cluster in sigmas - mHistManager.fill(HIST("elSpTr"), clu.e(), 7.5); - } - } - if (clu.collision_as().hasPHOSpair()) { - mHistManager.fill(HIST("cluSpTr"), clu.e(), 8.5); - if (clu.trackdist() < 2.) { // 2: Distance to CPV cluster in sigmas - mHistManager.fill(HIST("elSpTr"), clu.e(), 8.5); - } - } + // if (clu.collision_as().hasPHOSElectron()) { + // mHistManager.fill(HIST("cluSpTr"), clu.e(), 7.5); + // if (clu.trackdist() < 2.) { // 2: Distance to CPV cluster in sigmas + // mHistManager.fill(HIST("elSpTr"), clu.e(), 7.5); + // } + // } + // if (clu.collision_as().hasPHOSpair()) { + // mHistManager.fill(HIST("cluSpTr"), clu.e(), 8.5); + // if (clu.trackdist() < 2.) { // 2: Distance to CPV cluster in sigmas + // mHistManager.fill(HIST("elSpTr"), clu.e(), 8.5); + // } + // } if (clu.collision_as().hasPHOSnbar()) { mHistManager.fill(HIST("cluSpTr"), clu.e(), 9.5); if (clu.trackdist() < 2.) { // 2: Distance to CPV cluster in sigmas @@ -503,12 +503,12 @@ struct phosTrigQA { if (clu1.collision_as().hasPHOSPhoton()) { selections |= 1 << 6; } - if (clu1.collision_as().hasPHOSElectron()) { - selections |= 1 << 7; - } - if (clu1.collision_as().hasPHOSpair()) { - selections |= 1 << 8; - } + // if (clu1.collision_as().hasPHOSElectron()) { + // selections |= 1 << 7; + // } + // if (clu1.collision_as().hasPHOSpair()) { + // selections |= 1 << 8; + // } if (clu1.collision_as().hasPHOSnbar()) { selections |= 1 << 9; } From 56a33f68da917fbea3210236729f5eeba2b868d2 Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:48:01 +0100 Subject: [PATCH 137/156] Phi interaction rate study (#4258) * Modification of mixing and ITS only study * clang * Fix histogram binning --- PWGLF/Tasks/phianalysisrun3.cxx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/PWGLF/Tasks/phianalysisrun3.cxx b/PWGLF/Tasks/phianalysisrun3.cxx index c1c97c7256e..25259a611fb 100644 --- a/PWGLF/Tasks/phianalysisrun3.cxx +++ b/PWGLF/Tasks/phianalysisrun3.cxx @@ -75,27 +75,27 @@ struct phianalysisrun3 { Configurable isMC{"isMC", false, "Run MC"}; void init(o2::framework::InitContext&) { - histos.add("hCentrality", "Centrality distribution", kTH1F, {{2001, -0.5, 2000.5}}); + histos.add("hCentrality", "Centrality distribution", kTH1F, {{201, -0.5, 200.5}}); histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); - histos.add("hNcontributor", "Number of primary vertex contributor", kTH1F, {{20000, 0.0f, 20000.0f}}); + histos.add("hNcontributor", "Number of primary vertex contributor", kTH1F, {{2000, 0.0f, 10000.0f}}); histos.add("hEta", "Eta distribution", kTH1F, {{200, -1.0f, 1.0f}}); histos.add("hDcaxy", "Dcaxy distribution", kTH1F, {{200, -1.0f, 1.0f}}); histos.add("hDcaz", "Dcaz distribution", kTH1F, {{200, -1.0f, 1.0f}}); histos.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH1F, {{200, -10.0f, 10.0f}}); histos.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH1F, {{200, -10.0f, 10.0f}}); if (!isMC) { - histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassRotation", "Invariant mass of Phi meson Rotation", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); + histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassRotation", "Invariant mass of Phi meson Rotation", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); if (isEtaAssym) { - histos.add("h3PhiInvMassUnlikeSignAside", "Invariant mass of Phi meson Unlike Sign A side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassLikeSignAside", "Invariant mass of Phi meson Like Sign A side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassMixedAside", "Invariant mass of Phi meson Mixed A side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassUnlikeSignCside", "Invariant mass of Phi meson Unlike Sign C side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassLikeSignCside", "Invariant mass of Phi meson Like Sign C side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); - histos.add("h3PhiInvMassMixedCside", "Invariant mass of Phi meson Mixed C side", kTH3F, {{2001, -0.5, 2000.5}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}}); + histos.add("h3PhiInvMassUnlikeSignAside", "Invariant mass of Phi meson Unlike Sign A side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassLikeSignAside", "Invariant mass of Phi meson Like Sign A side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassMixedAside", "Invariant mass of Phi meson Mixed A side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassUnlikeSignCside", "Invariant mass of Phi meson Unlike Sign C side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassLikeSignCside", "Invariant mass of Phi meson Like Sign C side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); + histos.add("h3PhiInvMassMixedCside", "Invariant mass of Phi meson Mixed C side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); } } else if (isMC) { histos.add("hMC", "MC Event statistics", kTH1F, {{2, 0.0f, 2.0f}}); From 0d4033f5a0d8e03033653dbf8c65a79d379285bd Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Wed, 10 Jan 2024 21:21:13 +0900 Subject: [PATCH 138/156] PWGEM/PhotonMeson: update PCM analysis (#4259) --- PWGEM/PhotonMeson/Core/CutsLibrary.cxx | 64 +++++- PWGEM/PhotonMeson/Core/DalitzEECut.cxx | 9 +- PWGEM/PhotonMeson/Core/DalitzEECut.h | 15 +- PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx | 83 +++++-- PWGEM/PhotonMeson/Core/HistogramsLibrary.h | 4 + PWGEM/PhotonMeson/Core/V0PhotonCut.h | 40 ++-- PWGEM/PhotonMeson/DataModel/gammaTables.h | 6 +- PWGEM/PhotonMeson/TableProducer/createPCM.cxx | 7 + .../TableProducer/skimmerDalitzEE.cxx | 10 +- .../TableProducer/skimmerDalitzMuMu.cxx | 6 +- .../TableProducer/skimmerPrimaryMuon.cxx | 15 +- PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx | 123 ++++------- PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx | 128 +++++------ PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx | 204 ++++++++++++++---- PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx | 18 ++ PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx | 11 + PWGEM/PhotonMeson/Utils/PCMUtilities.h | 7 + 17 files changed, 503 insertions(+), 247 deletions(-) diff --git a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx index bbd3f65ee35..dbdae5bc015 100644 --- a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx @@ -50,6 +50,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetMinCosPA(0.99); cut->SetMaxPCA(1.5); cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("qc_ITSTPC")) { @@ -112,7 +113,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); - cut->SetTPCNsigmaElRange(-4, +4); + cut->SetTPCNsigmaElRange(-3, +3); cut->SetNClustersITS(2, 4); // cut->SetIsWithinBeamPipe(true); // for v0 @@ -178,7 +179,8 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); cut->SetMaxPCA(1.5); - cut->SetRxyRange(1, 180); + cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("nocut")) { @@ -195,7 +197,8 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); cut->SetMaxPCA(1.5); - cut->SetRxyRange(1, 180); + cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("tag_track")) { @@ -214,6 +217,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetMinCosPA(0.995); cut->SetMaxPCA(0.5); cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); return cut; } @@ -309,7 +313,34 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMuonExclusionTPC(true); return cut; } + if (!nameStr.compare("mee_all_tpchadrejortofreq_prompt_lowB")) { + // for pair + cut->SetMaxPhivPairMeeDep([](float mee) { + return (mee - -0.028) / 0.0185; + }); + // for track + cut->SetTrackPtRange(0.05f, 1e10f); + cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); + cut->SetChi2PerClusterTPC(0.0, 4.0); + cut->SetChi2PerClusterITS(0.0, 5.0); + cut->SetNClustersITS(4, 7); + cut->SetDca3DRange(0.0, 1.0); + + // for PID + cut->SetPIDScheme(DalitzEECut::PIDSchemes::kTPChadrejORTOFreq_lowB); + cut->SetTOFbetaRange(true, 0.0, 0.95); + cut->SetTPCNsigmaElRange(-2, +3); + cut->SetTOFNsigmaElRange(-3, +3); + cut->SetTPCNsigmaMuRange(-2, +2); + cut->SetTPCNsigmaPiRange(-3, +3); + cut->SetTPCNsigmaKaRange(-3, +3); + cut->SetTPCNsigmaPrRange(-3, +3); + cut->SetMuonExclusionTPC(true); + return cut; + } if (!nameStr.compare("mee_all_tpchadrej_lowB")) { // for pair cut->SetMaxPhivPairMeeDep([](float mee) { @@ -851,7 +882,6 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetTOFNsigmaPiRange(-3, +1e+10); return cut; } - if (!nameStr.compare("mee_all_tpchadrejortofreq")) { // for pair cut->SetMaxPhivPairMeeDep([](float mee) { @@ -879,6 +909,32 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetTOFNsigmaElRange(-3, +3); return cut; } + if (!nameStr.compare("mee_all_tpchadrejortofreq_prompt")) { + // for pair + cut->SetMaxPhivPairMeeDep([](float mee) { + return (mee - -0.028) / 0.0185; + }); + + // for track + cut->SetTrackPtRange(0.2f, 1e10f); + cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); + cut->SetChi2PerClusterTPC(0.0, 4.0); + cut->SetChi2PerClusterITS(0.0, 5.0); + cut->SetNClustersITS(4, 7); + cut->SetDca3DRange(0.0, 1.0); // in sigma + + // for PID + cut->SetPIDScheme(DalitzEECut::PIDSchemes::kTPChadrejORTOFreq); + cut->SetTOFbetaRange(true, 0.0, 0.95); + cut->SetTPCNsigmaElRange(-2, +3); + cut->SetTPCNsigmaPiRange(-1e+10, +3); + cut->SetTPCNsigmaKaRange(-3, +3); + cut->SetTPCNsigmaPrRange(-3, +3); + cut->SetTOFNsigmaElRange(-3, +3); + return cut; + } if (!nameStr.compare("mee_0_120_tpchadrejortofreq")) { // for pair cut->SetMeeRange(0, 0.12); diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.cxx b/PWGEM/PhotonMeson/Core/DalitzEECut.cxx index f61e01917c4..d6ec8536f8f 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.cxx +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.cxx @@ -18,7 +18,7 @@ ClassImp(DalitzEECut); -const char* DalitzEECut::mCutNames[static_cast(DalitzEECut::DalitzEECuts::kNCuts)] = {"Mee", "PairPtRange", "PairEtaRange", "PhivPair", "TrackPtRange", "TrackEtaRange", "TPCNCls", "TPCCrossedRows", "TPCCrossedRowsOverNCls", "TPCChi2NDF", "TPCNsigmaEl", "TPCNsigmaMu", "TPCNsigmaPi", "TPCNsigmaKa", "TPCNsigmaPr", "TOFNsigmaEl", "TOFNsigmaMu", "TOFNsigmaPi", "TOFNsigmaKa", "TOFNsigmaPr", "DCAxy", "DCAz", "ITSNCls", "ITSChi2NDF"}; +const char* DalitzEECut::mCutNames[static_cast(DalitzEECut::DalitzEECuts::kNCuts)] = {"Mee", "PairPtRange", "PairEtaRange", "PhivPair", "TrackPtRange", "TrackEtaRange", "TPCNCls", "TPCCrossedRows", "TPCCrossedRowsOverNCls", "TPCChi2NDF", "TPCNsigmaEl", "TPCNsigmaMu", "TPCNsigmaPi", "TPCNsigmaKa", "TPCNsigmaPr", "TOFNsigmaEl", "TOFNsigmaMu", "TOFNsigmaPi", "TOFNsigmaKa", "TOFNsigmaPr", "DCA3Dsigma", "DCAxy", "DCAz", "ITSNCls", "ITSChi2NDF"}; void DalitzEECut::SetPairPtRange(float minPt, float maxPt) { @@ -89,7 +89,12 @@ void DalitzEECut::SetChi2PerClusterITS(float min, float max) mMaxChi2PerClusterITS = max; LOG(info) << "DalitzEE Cut, set chi2 per cluster ITS range: " << mMinChi2PerClusterITS << " - " << mMaxChi2PerClusterITS; } - +void DalitzEECut::SetDca3DRange(float min, float max) +{ + mMinDca3D = min; + mMaxDca3D = max; + LOG(info) << "DalitzEE Cut, set DCA 3D range in sigma: " << mMinDca3D << " - " << mMaxDca3D; +} void DalitzEECut::SetMaxDcaXY(float maxDcaXY) { mMaxDcaXY = maxDcaXY; diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.h b/PWGEM/PhotonMeson/Core/DalitzEECut.h index 1a1ecddb33f..763687533d6 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.h +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.h @@ -56,6 +56,7 @@ class DalitzEECut : public TNamed kTOFNsigmaPi, kTOFNsigmaKa, kTOFNsigmaPr, + kDCA3Dsigma, kDCAxy, kDCAz, kITSNCls, @@ -141,6 +142,9 @@ class DalitzEECut : public TNamed if (!IsSelectedTrack(track, DalitzEECuts::kTrackEtaRange)) { return false; } + if (!IsSelectedTrack(track, DalitzEECuts::kDCA3Dsigma)) { + return false; + } if (!IsSelectedTrack(track, DalitzEECuts::kDCAxy)) { return false; } @@ -345,6 +349,10 @@ class DalitzEECut : public TNamed case DalitzEECuts::kTPCChi2NDF: return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; + case DalitzEECuts::kDCA3Dsigma: { + float dca_3d = std::sqrt(std::pow(track.dcaXY() / std::sqrt(track.cYY()), 2) + std::pow(track.dcaZ() / std::sqrt(track.cZZ()), 2)); + return mMinDca3D <= dca_3d && dca_3d <= mMaxDca3D; // in sigma + } case DalitzEECuts::kDCAxy: return abs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); @@ -396,8 +404,9 @@ class DalitzEECut : public TNamed void SetTOFNsigmaPrRange(float min = -1e+10, float max = 1e+10); void SetMaxPinMuonTPConly(float max); - void SetMaxDcaXY(float maxDcaXY); - void SetMaxDcaZ(float maxDcaZ); + void SetDca3DRange(float min, float max); // in sigma + void SetMaxDcaXY(float maxDcaXY); // in cm + void SetMaxDcaZ(float maxDcaZ); // in cm void SetMaxDcaXYPtDep(std::function ptDepCut); void ApplyPrefilter(bool flag); @@ -425,6 +434,8 @@ class DalitzEECut : public TNamed float mMinChi2PerClusterITS{-1e10f}, mMaxChi2PerClusterITS{1e10f}; // max its fit chi2 per ITS cluster float mMaxPinMuonTPConly{0.2f}; // max pin cut for muon ID with TPConly + float mMinDca3D{0.0f}; // min dca in 3D in units of sigma + float mMaxDca3D{1e+10}; // max dca in 3D in units of sigma float mMaxDcaXY{1.0f}; // max dca in xy plane float mMaxDcaZ{1.0f}; // max dca in z direction std::function mMaxDcaXYPtDep{}; // max dca in xy plane as function of pT diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx index 938f88ce7af..3ba7460794b 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx @@ -40,9 +40,12 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH1F("hZvtx_after", "vertex z; Zvtx (cm)", 100, -50, +50)); list->Add(new TH1F("hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", 5001, -0.5, 5000.5)); list->Add(new TH1F("hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", 5001, -0.5, 5000.5)); - list->Add(new TH2F("hMultFT0", "hMultFT0;mult FT0A;multFT0C", 500, 0, 5000, 500, 0, 5000)); + list->Add(new TH2F("hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", 200, 0, 6000, 200, 0, 6000)); + list->Add(new TH1F("hCentFT0A", "hCentFT0A;centrality FT0A (%)", 110, 0, 110)); + list->Add(new TH1F("hCentFT0C", "hCentFT0C;centrality FT0C (%)", 110, 0, 110)); list->Add(new TH1F("hCentFT0M", "hCentFT0M;centrality FT0M (%)", 110, 0, 110)); - list->Add(new TH2F("hCentFT0MvsMultNTracksPV", "hCentFT0MvsMultNTracksPV;centrality FT0M (%);N_{track} to PV", 110, 0, 110, 1001, -0.5, 1000.5)); + list->Add(new TH2F("hCentFT0MvsMultNTracksPV", "hCentFT0MvsMultNTracksPV;centrality FT0M (%);N_{track} to PV", 110, 0, 110, 500, 0, 5000)); + list->Add(new TH2F("hMultFT0MvsMultNTracksPV", "hMultFT0MvsMultNTracksPV;mult. FT0M;N_{track} to PV", 600, 0, 6000, 500, 0, 5000)); } if (TString(histClass) == "V0Leg") { list->Add(new TH1F("hPt", "pT;p_{T} (GeV/c)", 1000, 0.0f, 10)); @@ -127,13 +130,19 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* THnSparseF* hs_dilepton_lsmm_same = nullptr; if (TString(histClass).Contains("EE")) { - const int nm = 147; + const int nm = 162; double mee[nm] = {0.f}; - for (int i = 0; i < 40; i++) { - mee[i] = 0.001 * (i - 0) + 0.0; + for (int i = 0; i < 110; i++) { + mee[i] = 0.01 * (i - 0) + 0.0; // every 0.01 GeV/c2 up to 1.1 GeV/c2 } - for (int i = 40; i < nm; i++) { - mee[i] = 0.01 * (i - 40) + 0.04; + for (int i = 110; i < 128; i++) { + mee[i] = 0.1 * (i - 110) + 1.1; // every 0.1 GeV/c2 from 1.1 to 2.9 GeV/c2 + } + for (int i = 128; i < 158; i++) { + mee[i] = 0.01 * (i - 128) + 2.9; // every 0.01 GeV/c2 from 2.9 to 3.2 GeV/c2 + } + for (int i = 158; i < nm; i++) { + mee[i] = 0.1 * (i - 158) + 3.2; // every 0.01 GeV/c2 from 3.2 to 3.5 GeV/c2 } const int npt = 61; @@ -148,7 +157,7 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* const int ndim = 4; // m, pt, dca, phiv const int nbins[ndim] = {nm - 1, npt - 1, 50, 32}; const double xmin[ndim] = {0.0, 0.0, 0.0, 0.0}; - const double xmax[ndim] = {1.1, 10.0, 5.0, 3.2}; + const double xmax[ndim] = {3.5, 10.0, 5.0, 3.2}; hs_dilepton_uls_same = new THnSparseF("hs_dilepton_uls_same", "hs_dilepton_uls;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{xy,ee} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_uls_same->SetBinEdges(0, mee); @@ -168,11 +177,32 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* hs_dilepton_lsmm_same->Sumw2(); list->Add(hs_dilepton_lsmm_same); + const int ndim_dca = 3; // mee, dca1, dca2 + const int nbins_dca[ndim_dca] = {nm - 1, 50, 50}; + const double xmin_dca[ndim_dca] = {0.0, 0.0, 0.0}; + const double xmax_dca[ndim_dca] = {3.5, 5.0, 5.0}; + + THnSparseF* hs_dilepton_uls_dca_same = new THnSparseF("hs_dilepton_uls_dca_same", "hs_dilepton_uls_dca;m_{ee} (GeV/c^{2});DCA_{e^{+}}^{3D} (#sigma);DCA_{e^{-}}^{3D} (#sigma);", ndim_dca, nbins_dca, xmin_dca, xmax_dca); + hs_dilepton_uls_dca_same->SetBinEdges(0, mee); + hs_dilepton_uls_dca_same->Sumw2(); + list->Add(hs_dilepton_uls_dca_same); + + THnSparseF* hs_dilepton_lspp_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lspp_dca_same")); + THnSparseF* hs_dilepton_lsmm_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lsmm_dca_same")); + list->Add(hs_dilepton_lspp_dca_same); + list->Add(hs_dilepton_lsmm_dca_same); + if (TString(subGroup) == "mc") { // create phiv template list->Add(new TH2F("hMvsPhiV_Pi0", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", 32, 0, 3.2, 100, 0.0f, 0.1f)); // ee from pi0 dalitz decay + list->Add(new TH2F("hMvsPhiV_Eta", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", 32, 0, 3.2, 100, 0.0f, 0.1f)); // ee from eta dalitz decay list->Add(new TH2F("hMvsPhiV_Photon", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", 32, 0, 3.2, 100, 0.0f, 0.1f)); // ee from photon conversion - } // end of mc + + list->Add(new TH2F("hMvsOPA_Pi0", "m_{ee} vs. opening angle;opening angle (rad.);m_{ee} (GeV/c^{2})", 100, 0, 0.1, 100, 0.0f, 0.1f)); // ee from pi0 dalitz decay + list->Add(new TH2F("hMvsOPA_Eta", "m_{ee} vs. opening angle;opening angle (rad.);m_{ee} (GeV/c^{2})", 100, 0, 0.1, 100, 0.0f, 0.1f)); // ee from eta dalitz decay + list->Add(new TH2F("hMvsOPA_Photon", "m_{ee} vs. opening angle;opening angle (rad.);m_{ee} (GeV/c^{2})", 100, 0, 0.1, 100, 0.0f, 0.1f)); // ee from photon conversion + + } // end of mc } else if (TString(histClass).Contains("MuMu")) { const int ndim = 4; // m, pt, dca, phiv const int nbins[ndim] = {90, 20, 50, 1}; @@ -218,6 +248,7 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH1F("hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", 400, -20, 20)); list->Add(new TH2F("hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", 180, 0, TMath::TwoPi(), 40, -2.0f, 2.0f)); list->Add(new TH2F("hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", 200, -1.0f, 1.0f, 200, -1.0f, 1.0f)); + list->Add(new TH2F("hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", 200, -10.0f, 10.0f, 200, -10.0f, 10.0f)); list->Add(new TH2F("hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", 1000, 0, maxP, 100, 0., 1000)); list->Add(new TH2F("hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", 1000, 0, maxP, 100, 0., 1000)); list->Add(new TH1F("hNclsTPC", "number of TPC clusters", 161, -0.5, 160.5)); @@ -326,16 +357,16 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* } if (TString(histClass) == "material_budget_study") { - const int npt = 71; + const int npt = 70; double pt[npt] = {0.f}; for (int i = 0; i < 10; i++) { - pt[i] = 0.01 * i; + pt[i] = 0.01 * (i - 0) + 0.0; } - for (int i = 10; i < 60; i++) { + for (int i = 10; i < 59; i++) { pt[i] = 0.1 * (i - 10) + 0.1; } - for (int i = 60; i < npt; i++) { - pt[i] = 0.5 * (i - 60) + 5.0; + for (int i = 59; i < npt; i++) { + pt[i] = 0.5 * (i - 59) + 5.0; } if (TString(subGroup) == "V0") { const int ndim = 4; // pt, r, phi, eta @@ -352,13 +383,13 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* const double xmin[ndim] = {0.0, 0.0, 0.0, 0, 0, -2}; const double xmax[ndim] = {0.4, 10.0, 10.0, 90.0, TMath::TwoPi(), +2}; - THnSparseF* hs_conv_point_same = new THnSparseF("hs_conv_point_same", "hs_conv_point;m_{ee#gamma} (GeV/c^{2});p_{T,ee}^{tag} (GeV/c);p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); + THnSparseF* hs_conv_point_same = new THnSparseF("hs_conv_point_same", "hs_conv_point;m_{#gamma#gamma} (GeV/c^{2});p_{T,#gamma}^{tag} (GeV/c);p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); hs_conv_point_same->SetBinEdges(1, pt); hs_conv_point_same->SetBinEdges(2, pt); hs_conv_point_same->Sumw2(); list->Add(hs_conv_point_same); - THnSparseF* hs_conv_point_mix = new THnSparseF("hs_conv_point_mix", "hs_conv_point;m_{ee#gamma} (GeV/c^{2});p_{T,ee}^{tag} (GeV/c);p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); + THnSparseF* hs_conv_point_mix = new THnSparseF("hs_conv_point_mix", "hs_conv_point;m_{#gamma#gamma} (GeV/c^{2});p_{T,#gamma}^{tag} (GeV/c);p_{T,#gamma}^{probe} (GeV/c);R_{xy}^{probe} (cm);#varphi^{probe} (rad.);#eta^{probe};", ndim, nbins, xmin, xmax); hs_conv_point_mix->SetBinEdges(1, pt); hs_conv_point_mix->SetBinEdges(2, pt); hs_conv_point_mix->Sumw2(); @@ -452,15 +483,23 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* } if (TString(histClass) == "photon_hbt") { - const int ndim = 5; // qinv, qlong, qout, qside, kt - const int nbins[ndim] = {40, 80, 80, 80, 10}; - const double xmin[ndim] = {0.0, -0.4, -0.4, -0.4, 0.0}; - const double xmax[ndim] = {0.4, +0.4, +0.4, +0.4, 1.0}; + const int nm_hbt = 6; + double m_hbt[nm_hbt] = {0.0, 0.14, 0.5, 1.1, 2.0, 2.7}; - THnSparseF* hs_q_same = new THnSparseF("hs_q_same", "hs_q_same;q_{inv} (GeV/c);q_{long} (GeV/c);q_{out} (GeV/c);q_{side} (GeV/c);k_{T} (GeV/c);", ndim, nbins, xmin, xmax); - THnSparseF* hs_q_mix = new THnSparseF("hs_q_mix", "hs_q_mix;q_{inv} (GeV/c);q_{long} (GeV/c);q_{out} (GeV/c);q_{side} (GeV/c);k_{T} (GeV/c);", ndim, nbins, xmin, xmax); + const int ndim = 9; // m1, m2, kt, qinv, qlong_cms, qout_cms, qside_cms, qt_cms, qlong_lcms + const int nbins[ndim] = {nm_hbt - 1, nm_hbt - 1, 10, 40, 80, 80, 80, 40, 80}; + const double xmin[ndim] = {0.0, 0.0, 0.0, 0.0, -0.4, -0.4, -0.4, 0.0, -0.4}; + const double xmax[ndim] = {2.7, 2.7, 1.0, 0.4, +0.4, +0.4, +0.4, +0.4, +0.4}; + + THnSparseF* hs_q_same = new THnSparseF("hs_q_same", "hs_q_same;m_{1} (GeV/c^{2});m_{2} (GeV/c^{2});k_{T} (GeV/c);q_{inv} (GeV/c);q_{long}^{CMS} (GeV/c);q_{out}^{CMS} (GeV/c);q_{side}^{CMS} (GeV/c);q_{T}^{CMS} (GeV/c);q_{long}^{LCMS} (GeV/c);", ndim, nbins, xmin, xmax); + THnSparseF* hs_q_mix = new THnSparseF("hs_q_mix", "hs_q_mix;m_{1} (GeV/c^{2});m_{2} (GeV/c^{2});k_{T} (GeV/c);q_{inv} (GeV/c);q_{long}^{CMS} (GeV/c);q_{out}^{CMS} (GeV/c);q_{side}^{CMS} (GeV/c);q_{T}^{CMS} (GeV/c);q_{long}^{LCMS} (GeV/c);", ndim, nbins, xmin, xmax); hs_q_same->Sumw2(); hs_q_mix->Sumw2(); + hs_q_same->SetBinEdges(0, m_hbt); + hs_q_same->SetBinEdges(1, m_hbt); + hs_q_mix->Sumw2(); + hs_q_mix->SetBinEdges(0, m_hbt); + hs_q_mix->SetBinEdges(1, m_hbt); list->Add(hs_q_same); list->Add(hs_q_mix); } diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.h b/PWGEM/PhotonMeson/Core/HistogramsLibrary.h index c01abdbe294..93fdafbe105 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.h +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.h @@ -59,8 +59,11 @@ void FillHistClass(THashList* list, const char* subGroup, T const& obj) reinterpret_cast(list->FindObject("hMultNTracksPV"))->Fill(obj.multNTracksPV()); reinterpret_cast(list->FindObject("hMultNTracksPVeta1"))->Fill(obj.multNTracksPVeta1()); reinterpret_cast(list->FindObject("hMultFT0"))->Fill(obj.multFT0A(), obj.multFT0C()); + reinterpret_cast(list->FindObject("hCentFT0A"))->Fill(obj.centFT0A()); + reinterpret_cast(list->FindObject("hCentFT0C"))->Fill(obj.centFT0C()); reinterpret_cast(list->FindObject("hCentFT0M"))->Fill(obj.centFT0M()); reinterpret_cast(list->FindObject("hCentFT0MvsMultNTracksPV"))->Fill(obj.centFT0M(), obj.multNTracksPV()); + reinterpret_cast(list->FindObject("hMultFT0MvsMultNTracksPV"))->Fill(obj.multFT0A() + obj.multFT0C(), obj.multNTracksPV()); } else if constexpr (htype == EMHistType::kPhoton) { // ROOT::Math::PtEtaPhiMVector reinterpret_cast(list->FindObject("hPt"))->Fill(obj.Pt()); reinterpret_cast(list->FindObject("hY"))->Fill(obj.Rapidity()); @@ -110,6 +113,7 @@ void FillHistClass(THashList* list, const char* subGroup, T const& obj) reinterpret_cast(list->FindObject("hQoverPt"))->Fill(obj.sign() / obj.pt()); reinterpret_cast(list->FindObject("hEtaPhi"))->Fill(obj.phi(), obj.eta()); reinterpret_cast(list->FindObject("hDCAxyz"))->Fill(obj.dcaXY(), obj.dcaZ()); + reinterpret_cast(list->FindObject("hDCAxyzSigma"))->Fill(obj.dcaXY() / sqrt(obj.cYY()), obj.dcaZ() / sqrt(obj.cZZ())); reinterpret_cast(list->FindObject("hDCAxyRes_Pt"))->Fill(obj.pt(), sqrt(obj.cYY()) * 1e+4); // convert cm to um reinterpret_cast(list->FindObject("hDCAzRes_Pt"))->Fill(obj.pt(), sqrt(obj.cZZ()) * 1e+4); // convert cm to um reinterpret_cast(list->FindObject("hNclsITS"))->Fill(obj.itsNCls()); diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index 149e871a977..1a2132cc640 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -304,7 +304,7 @@ class V0PhotonCut : public TNamed // float z = v0.vz(); // cm, measured secondary vertex of gamma->ee float rxy = sqrt(x * x + y * y); - if (rxy < 7.5 || 15.0 < rxy) { + if (rxy < 7.0 || 16.0 < rxy) { return false; } @@ -317,27 +317,23 @@ class V0PhotonCut : public TNamed return !(dxy > margin_xy); } case V0PhotonCuts::kOnWwireOB: { - const float margin_x = 2.0; // cm - const float margin_y = 0.5; // cm - const float margin_z = 5.0; // cm - const float rxy_exp = 30.8; // cm - const float x_exp = rxy_exp * TMath::Cos(-1.3 * TMath::DegToRad()); // cm, expected position x of W wire - const float y_exp = rxy_exp * TMath::Sin(-1.3 * TMath::DegToRad()); // cm, expected position y of W wire - const float z_min = -47.0; // cm - const float z_max = +47.0; // cm - float x = v0.vx(); // cm, measured secondary vertex of gamma->ee - float y = v0.vy(); // cm, measured secondary vertex of gamma->ee - float z = v0.vz(); // cm, measured secondary vertex of gamma->ee - if (z + margin_z < z_min || z_max < z - margin_z) { - return false; - } - if (abs(x - x_exp) > margin_x) { - return false; - } - if (abs(y - y_exp) > margin_y) { - return false; - } - return true; + const float margin_xy = 1.0; // cm + const float rxy_exp = 30.8; // cm + const float x_exp = rxy_exp * std::cos(-1.3 * TMath::DegToRad()); // cm, expected position x of W wire + const float y_exp = rxy_exp * std::sin(-1.3 * TMath::DegToRad()); // cm, expected position y of W wire + // const float z_min = -47.0; // cm + // const float z_max = +47.0; // cm + float x = v0.vx(); // cm, measured secondary vertex of gamma->ee + float y = v0.vy(); // cm, measured secondary vertex of gamma->ee + // float z = v0.vz(); // cm, measured secondary vertex of gamma->ee + + // float rxy = sqrt(x * x + y * y); + // if (rxy < 28.0 || 33.0 < rxy) { + // return false; + // } + + float dxy = std::sqrt(std::pow(x - x_exp, 2) + std::pow(y - y_exp, 2)); + return !(dxy > margin_xy); } default: return false; diff --git a/PWGEM/PhotonMeson/DataModel/gammaTables.h b/PWGEM/PhotonMeson/DataModel/gammaTables.h index 351ed4d0ae9..3209ca952e2 100644 --- a/PWGEM/PhotonMeson/DataModel/gammaTables.h +++ b/PWGEM/PhotonMeson/DataModel/gammaTables.h @@ -364,6 +364,7 @@ DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(PhiV, phiv, float); +DECLARE_SOA_COLUMN(OpeningAngle, opangle, float); DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); DECLARE_SOA_COLUMN(DCAZ, dcaZ, float); DECLARE_SOA_COLUMN(Sign, sign, int); //! @@ -371,7 +372,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Energy, e, [](float pt, float eta, float m) { return } // namespace dalitzee DECLARE_SOA_TABLE(DalitzEEs, "AOD", "DALITZEE", //! o2::soa::Index<>, dalitzee::CollisionId, dalitzee::PosTrackId, dalitzee::NegTrackId, - dalitzee::Pt, dalitzee::Eta, dalitzee::Phi, dalitzee::Mass, dalitzee::PhiV, dalitzee::DCAXY, dalitzee::DCAZ, dalitzee::Sign, + dalitzee::Pt, dalitzee::Eta, dalitzee::Phi, dalitzee::Mass, dalitzee::PhiV, dalitzee::OpeningAngle, dalitzee::DCAXY, dalitzee::DCAZ, dalitzee::Sign, dalitzee::Energy); // iterators using DalitzEE = DalitzEEs::iterator; @@ -434,6 +435,7 @@ DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(PhiV, phiv, float); +DECLARE_SOA_COLUMN(OpeningAngle, opangle, float); DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); DECLARE_SOA_COLUMN(DCAZ, dcaZ, float); DECLARE_SOA_COLUMN(Sign, sign, int); //! @@ -441,7 +443,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Energy, e, [](float pt, float eta, float m) { return } // namespace dalitzmumu DECLARE_SOA_TABLE(DalitzMuMus, "AOD", "DALITZMUMU", //! o2::soa::Index<>, dalitzmumu::CollisionId, dalitzmumu::PosTrackId, dalitzmumu::NegTrackId, - dalitzmumu::Pt, dalitzmumu::Eta, dalitzmumu::Phi, dalitzmumu::Mass, dalitzmumu::PhiV, dalitzmumu::DCAXY, dalitzmumu::DCAZ, dalitzmumu::Sign, + dalitzmumu::Pt, dalitzmumu::Eta, dalitzmumu::Phi, dalitzmumu::Mass, dalitzmumu::PhiV, dalitzmumu::OpeningAngle, dalitzmumu::DCAXY, dalitzmumu::DCAZ, dalitzmumu::Sign, dalitzmumu::Energy); // iterators using DalitzMuMu = DalitzMuMus::iterator; diff --git a/PWGEM/PhotonMeson/TableProducer/createPCM.cxx b/PWGEM/PhotonMeson/TableProducer/createPCM.cxx index aad89e2ab67..7cc7318733d 100644 --- a/PWGEM/PhotonMeson/TableProducer/createPCM.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createPCM.cxx @@ -57,6 +57,8 @@ struct createPCM { "createPCM", { {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{5, 0.5f, 5.5f}}}}, + {"hV0xy", "hV0xy;X (cm);Y(cm)", {HistType::kTH2F, {{400, -100, +100}, {400, -100, +100}}}}, + {"hV0xy_recalculated", "hV0xy_recalculated;X (cm);Y(cm)", {HistType::kTH2F, {{400, -100, +100}, {400, -100, +100}}}}, }, }; @@ -303,6 +305,11 @@ struct createPCM { return; } + registry.fill(HIST("hV0xy"), svpos[0], svpos[1]); // this should have worst resolution + float xyz_tmp[3] = {0.f, 0.f, 0.f}; + Vtx_recalculation(o2::base::Propagator::Instance(), pos, ele, xyz_tmp, matCorr); + registry.fill(HIST("hV0xy_recalculated"), xyz_tmp[0], xyz_tmp[1]); // this should have good resolution + // populates the various tables that comprise V0Datas v0indices(pos.globalIndex(), ele.globalIndex(), collision.globalIndex(), -1); v0trackXs(fitter.getTrack(0).getX(), fitter.getTrack(1).getX()); diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx index 1b674acdfcb..725fa86e9ac 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx @@ -75,6 +75,7 @@ struct skimmerDalitzEE { continue; } float phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision.bz()); + float opangle = getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); float dcaeexy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); @@ -83,10 +84,10 @@ struct skimmerDalitzEE { float dcaeez = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); if constexpr (isCEFP) { - dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } else { // for analysis - dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } @@ -102,6 +103,7 @@ struct skimmerDalitzEE { continue; } float phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision.bz()); + float opangle = getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); float dcaeexy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); @@ -110,10 +112,10 @@ struct skimmerDalitzEE { float dcaeez = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); if constexpr (isCEFP) { - dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } else { // for analysis - dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx index b74f037f558..2d8c8093510 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx @@ -71,13 +71,14 @@ struct skimmerDalitzMuMu { continue; } float phiv = 0.f; + float opangle = 0.f; float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); float dcamumuxy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); float dcamumuz = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcamumuxy, dcamumuz, static_cast(pairtype)); + dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcamumuxy, dcamumuz, static_cast(pairtype)); dalitz_mumu_eventid(collision.globalIndex()); fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); npair++; @@ -91,13 +92,14 @@ struct skimmerDalitzMuMu { continue; } float phiv = 0.f; + float opangle = 0.f; float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); float dcamumuxy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); float dcamumuz = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, dcamumuxy, dcamumuz, static_cast(pairtype)); + dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcamumuxy, dcamumuz, static_cast(pairtype)); dalitz_mumu_eventid(collision.globalIndex()); fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); npair++; diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx index 51801581c47..4ef6297ae7c 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx @@ -55,8 +55,8 @@ struct skimmerPrimaryMuon { Configurable dca_xy_max{"dca_xy_max", 1.0f, "max DCAxy in cm"}; Configurable dca_z_max{"dca_z_max", 1.0f, "max DCAz in cm"}; Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1.0f, "max DCA 3D in sigma"}; - Configurable min_tpcdEdx{"min_tpcdEdx", 30.0, "min TPC dE/dx"}; - Configurable max_tpcdEdx{"max_tpcdEdx", 1e+10, "max TPC dE/dx"}; + Configurable minTPCNsigmaMu{"minTPCNsigmaMu", -4.0, "min. TPC n sigma for muon inclusion"}; + Configurable maxTPCNsigmaMu{"maxTPCNsigmaMu", 4.0, "max. TPC n sigma for muon inclusion"}; Configurable maxPin{"maxPin", 1.0, "max pin for PID"}; Configurable maxPin_TPC{"maxPin_TPC", 0.2, "max pin for TPC pid only"}; Configurable maxTPCNsigmaMu_lowPin{"maxTPCNsigmaMu_lowPin", +4.0, "max. TPC n sigma for muon inclusion at low pin"}; @@ -101,6 +101,8 @@ struct skimmerPrimaryMuon { {"MC/Primary/hNfTPC", "Nfindable TPC;N_{f}^{TPC}", {HistType::kTH1F, {{161, -0.5f, +160.5f}}}}, {"MC/Primary/hChi2TPC", "chi2 TPC;#chi^{2}/N_{cls}^{TPC}", {HistType::kTH1F, {{100, 0.f, 10.f}}}}, {"MC/Primary/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", {HistType::kTH2F, {{200, -1.f, +1.f}, {200, -1.f, +1.f}}}}, + {"MC/Primary/hDCAxy_Pt", "DCA xy vs. p_{T};p_{T} (GeV/c);DCA_{xy} (cm)", {HistType::kTH2F, {{100, 0.f, +1.f}, {200, -1.f, +1.f}}}}, + {"MC/Primary/hDCAz_Pt", "DCA z vs. p_{T};p_{T} (GeV/c);DCA_{z} (cm)", {HistType::kTH2F, {{100, 0.f, +1.f}, {200, -1.f, +1.f}}}}, {"MC/Primary/hDCA3D", "DCA;DCA_{3D} (cm)", {HistType::kTH1F, {{100, 0.f, +1.f}}}}, {"MC/Primary/hDCAxy_resolution", "DCA xy resolution;DCA_{xy} resolution (cm)", {HistType::kTH1F, {{100, 0.f, +0.1f}}}}, {"MC/Primary/hDCAz_resolution", "DCA z resolution;DCA_{z} resolution (cm)", {HistType::kTH1F, {{100, 0.f, +0.1f}}}}, @@ -119,6 +121,8 @@ struct skimmerPrimaryMuon { {"MC/Secondary/hNfTPC", "Nfindable TPC;N_{f}^{TPC}", {HistType::kTH1F, {{161, -0.5f, +160.5f}}}}, {"MC/Secondary/hChi2TPC", "chi2 TPC;#chi^{2}/N_{cls}^{TPC}", {HistType::kTH1F, {{100, 0.f, 10.f}}}}, {"MC/Secondary/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", {HistType::kTH2F, {{200, -1.f, +1.f}, {200, -1.f, +1.f}}}}, + {"MC/Secondary/hDCAxy_Pt", "DCA xy vs. p_{T};p_{T} (GeV/c);DCA_{xy} (cm)", {HistType::kTH2F, {{100, 0.f, +1.f}, {200, -1.f, +1.f}}}}, + {"MC/Secondary/hDCAz_Pt", "DCA z vs. p_{T};p_{T} (GeV/c);DCA_{z} (cm)", {HistType::kTH2F, {{100, 0.f, +1.f}, {200, -1.f, +1.f}}}}, {"MC/Secondary/hDCA3D", "DCA;DCA_{3D} (cm)", {HistType::kTH1F, {{100, 0.f, +1.f}}}}, {"MC/Secondary/hDCAxy_resolution", "DCA xy resolution;DCA_{xy} resolution (cm)", {HistType::kTH1F, {{100, 0.f, +0.1f}}}}, {"MC/Secondary/hDCAz_resolution", "DCA z resolution;DCA_{z} resolution (cm)", {HistType::kTH1F, {{100, 0.f, +0.1f}}}}, @@ -226,6 +230,8 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Primary/hNfTPC"), track.tpcNClsFindable()); fRegistry.fill(HIST("MC/Primary/hChi2TPC"), track.tpcChi2NCl()); fRegistry.fill(HIST("MC/Primary/hDCAxyz"), track.dcaXY(), track.dcaZ()); + fRegistry.fill(HIST("MC/Primary/hDCAxy_Pt"), track.pt(), track.dcaXY()); + fRegistry.fill(HIST("MC/Primary/hDCAz_Pt"), track.pt(), track.dcaZ()); fRegistry.fill(HIST("MC/Primary/hDCA3D"), sqrt(pow(track.dcaXY(), 2) + pow(track.dcaZ(), 2))); fRegistry.fill(HIST("MC/Primary/hDCAxy_resolution"), sqrt(track.cYY())); fRegistry.fill(HIST("MC/Primary/hDCAz_resolution"), sqrt(track.cZZ())); @@ -245,6 +251,8 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Secondary/hNfTPC"), track.tpcNClsFindable()); fRegistry.fill(HIST("MC/Secondary/hChi2TPC"), track.tpcChi2NCl()); fRegistry.fill(HIST("MC/Secondary/hDCAxyz"), track.dcaXY(), track.dcaZ()); + fRegistry.fill(HIST("MC/Secondary/hDCAxy_Pt"), track.pt(), track.dcaXY()); + fRegistry.fill(HIST("MC/Secondary/hDCAz_Pt"), track.pt(), track.dcaZ()); fRegistry.fill(HIST("MC/Secondary/hDCA3D"), sqrt(pow(track.dcaXY(), 2) + pow(track.dcaZ(), 2))); fRegistry.fill(HIST("MC/Secondary/hDCAxy_resolution"), sqrt(track.cYY())); fRegistry.fill(HIST("MC/Secondary/hDCAz_resolution"), sqrt(track.cZZ())); @@ -331,7 +339,8 @@ struct skimmerPrimaryMuon { // ============================ FUNCTION DEFINITIONS ==================================================== std::vector stored_trackIds; - Filter trackFilter = minpt < o2::aod::track::pt && o2::aod::track::pt < maxpt && nabs(o2::aod::track::eta) < maxeta && nabs(o2::aod::track::dcaXY) < dca_xy_max && nabs(o2::aod::track::dcaZ) < dca_z_max && o2::aod::track::tpcChi2NCl < maxchi2tpc && o2::aod::track::itsChi2NCl < maxchi2its && min_tpcdEdx < o2::aod::track::tpcSignal && o2::aod::track::tpcSignal < max_tpcdEdx && o2::aod::track::tpcInnerParam < maxPin; + Filter trackFilter = minpt < o2::aod::track::pt && o2::aod::track::pt < maxpt && nabs(o2::aod::track::eta) < maxeta && nabs(o2::aod::track::dcaXY) < dca_xy_max && nabs(o2::aod::track::dcaZ) < dca_z_max && o2::aod::track::tpcChi2NCl < maxchi2tpc && o2::aod::track::itsChi2NCl < maxchi2its; + Filter pidFilter = minTPCNsigmaMu < o2::aod::pidtpc::tpcNSigmaMu && o2::aod::pidtpc::tpcNSigmaMu < maxTPCNsigmaMu && o2::aod::track::tpcInnerParam < maxPin; using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx index cdf1c1bd852..8fe9c101211 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx @@ -32,7 +32,6 @@ #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" #include "PWGEM/PhotonMeson/Utils/PairUtilities.h" #include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/DalitzEECut.h" #include "PWGEM/PhotonMeson/Core/PairCut.h" #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" @@ -44,25 +43,19 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; -using MyDalitzEEs = soa::Join; -using MyDalitzEE = MyDalitzEEs::iterator; - -using MyPrimaryElectrons = soa::Join; -using MyPrimaryElectron = MyPrimaryElectrons::iterator; - struct MaterialBudget { Configurable CentMin{"CentMin", -1, "min. centrality"}; Configurable CentMax{"CentMax", 999, "max. centrality"}; Configurable CentEstimator{"CentEstimator", "FT0M", "centrality estimator"}; - Configurable fConfigTagCuts{"cfgTagCuts", "mee_0_120_tpconly_lowB", "Comma separated list of DalitzEE cuts for tag"}; + Configurable fConfigTagCuts{"cfgTagCuts", "qc", "Comma separated list of V0 photon cuts for tag"}; Configurable fConfigProbeCuts{"cfgProbeCuts", "qc,wwire_ib", "Comma separated list of V0 photon cuts for probe"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; Configurable fDoMixing{"DoMixing", false, "do event mixing"}; @@ -72,7 +65,7 @@ struct MaterialBudget { OutputObj fOutputPair{"Pair"}; // 2-photon pair THashList* fMainList = new THashList(); - std::vector fTagCuts; + std::vector fTagCuts; std::vector fProbeCuts; std::vector fPairCuts; @@ -80,7 +73,7 @@ struct MaterialBudget { void init(InitContext& context) { if (context.mOptions.get("processMB")) { - fPairNames.push_back("PCMDalitzEE"); + fPairNames.push_back("PCMPCM"); } DefineTagCuts(); @@ -94,10 +87,10 @@ struct MaterialBudget { } template - void add_pair_histograms(THashList* list_pair, const std::string pairname, TCuts1 const& cuts1, TCuts2 const& cuts2, TCuts3 const& cuts3) + void add_pair_histograms(THashList* list_pair, const std::string pairname, TCuts1 const& tagcuts, TCuts2 const& probecuts, TCuts3 const& cuts3) { - for (auto& cut1 : cuts1) { - for (auto& cut2 : cuts2) { + for (auto& cut1 : tagcuts) { + for (auto& cut2 : probecuts) { std::string cutname1 = cut1.GetName(); std::string cutname2 = cut2.GetName(); @@ -148,7 +141,7 @@ struct MaterialBudget { o2::aod::emphotonhistograms::AddHistClass(list_pair, pairname.data()); - if (pairname == "PCMDalitzEE") { + if (pairname == "PCMPCM") { add_pair_histograms(list_pair, pairname, fTagCuts, fProbeCuts, fPairCuts); } @@ -163,7 +156,7 @@ struct MaterialBudget { for (int icut = 0; icut < objArray->GetEntries(); ++icut) { const char* cutname = objArray->At(icut)->GetName(); LOGF(info, "add cut : %s", cutname); - fTagCuts.push_back(*dalitzeecuts::GetCut(cutname)); + fTagCuts.push_back(*pcmcuts::GetCut(cutname)); } } LOGF(info, "Number of Tag cuts = %d", fTagCuts.size()); @@ -198,29 +191,36 @@ struct MaterialBudget { } Preslice perCollision_pcm = aod::v0photonkf::emreducedeventId; - Preslice perCollision_ee = aod::dalitzee::emreducedeventId; template bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) { - return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); + return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } - template + template void fillsinglephoton(TEvents const& collisions, TPhotons const& photons, TPreslice const& perCollision, TCuts const& cuts, TLegs const& legs) { + THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_v0 = static_cast(fMainList->FindObject("V0")); double value[4] = {0.f}; for (auto& collision : collisions) { + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_before"))->Fill(collision.posZ()); + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(1.0); // all if (!collision.sel8()) { continue; } + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(2.0); // FT0VX i.e. FT0and if (collision.numContrib() < 0.5) { continue; } + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(3.0); // Ncontrib > 0 if (abs(collision.posZ()) > 10.0) { continue; } + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_after"))->Fill(collision.posZ()); + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm + o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { @@ -243,43 +243,25 @@ struct MaterialBudget { } // end of collision loop } - template - void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) + template + void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& tagcuts, TCuts2 const& probecuts, TPairCuts const& paircuts, TLegs const& legs) { - THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); for (auto& collision : collisions) { - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_before"))->Fill(collision.posZ()); - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(1.0); // all - if (!collision.sel8()) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(2.0); // FT0VX i.e. FT0and - - if (collision.numContrib() < 0.5) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(3.0); // Ncontrib > 0 - - if (abs(collision.posZ()) > 10.0) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_after"))->Fill(collision.posZ()); - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm - - o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); double value[6] = {0.f}; float phi_cp2 = 0.f, eta_cp2 = 0.f; - for (auto& cut1 : cuts1) { - for (auto& cut2 : cuts2) { + for (auto& tagcut : tagcuts) { + for (auto& probecut : probecuts) { for (auto& g1 : photons1_coll) { for (auto& g2 : photons2_coll) { - if (!IsSelectedPair(g1, g2, cut1, cut2)) { + if (g1.globalIndex() == g2.globalIndex()) { + continue; + } + if (!IsSelectedPair(g1, g2, tagcut, probecut)) { continue; } for (auto& paircut : paircuts) { @@ -287,16 +269,8 @@ struct MaterialBudget { continue; } - auto pos1 = g1.template posTrack_as(); - auto ele1 = g1.template negTrack_as(); - auto pos2 = g2.template posTrack_as(); - auto ele2 = g2.template negTrack_as(); - if (pos1.trackId() == pos2.trackId() || ele1.trackId() == ele2.trackId()) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), g1.mass()); // tag - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // tag + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; phi_cp2 = atan2(g2.vy(), g2.vx()); eta_cp2 = std::atanh(g2.vz() / sqrt(pow(g2.vx(), 2) + pow(g2.vy(), 2) + pow(g2.vz(), 2))); @@ -306,12 +280,12 @@ struct MaterialBudget { value[3] = g2.v0radius(); value[4] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); value[5] = eta_cp2; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); } // end of pair cut loop } // end of g2 loop } // end of g1 loop - } // end of cut2 loop - } // end of cut1 loop + } // end of probecut loop + } // end of tagcut loop } // end of collision loop } @@ -321,8 +295,8 @@ struct MaterialBudget { using BinningType = ColumnBinningPolicy; BinningType colBinning{{ConfVtxBins, ConfMultBins}, true}; - template - void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) + template + void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& tagcuts, TCuts2 const& probecuts, TPairCuts const& paircuts, TLegs const& legs) { THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); @@ -338,11 +312,11 @@ struct MaterialBudget { double value[6] = {0.f}; float phi_cp2 = 0.f, eta_cp2 = 0.f; - for (auto& cut1 : cuts1) { - for (auto& cut2 : cuts2) { + for (auto& tagcut : tagcuts) { + for (auto& probecut : probecuts) { for (auto& g1 : photons_coll1) { for (auto& g2 : photons_coll2) { - if (!IsSelectedPair(g1, g2, cut1, cut2)) { + if (!IsSelectedPair(g1, g2, tagcut, probecut)) { continue; } // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); @@ -352,8 +326,8 @@ struct MaterialBudget { continue; } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), g1.mass()); // tag - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // tag + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; phi_cp2 = atan2(g2.vy(), g2.vx()); eta_cp2 = std::atanh(g2.vz() / sqrt(pow(g2.vx(), 2) + pow(g2.vy(), 2) + pow(g2.vz(), 2))); @@ -363,30 +337,27 @@ struct MaterialBudget { value[3] = g2.v0radius(); value[4] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); value[5] = eta_cp2; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_mix"))->Fill(value); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_mix"))->Fill(value); } // end of pair cut loop } // end of g2 loop } // end of g1 loop - } // end of cut2 loop - } // end of cut1 loop + } // end of probecut loop + } // end of tagcut loop } // end of different collision combinations } Partition grouped_collisions = CentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < CentMax; // this goes to same event. Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true && CentMin < o2::aod::cent::centFT0M&& o2::aod::cent::centFT0M < CentMax; - Filter collisionFilter_subsys = o2::aod::emreducedevent::ngpcm >= 1 || o2::aod::emreducedevent::neeuls >= 1; + Filter collisionFilter_subsys = o2::aod::emreducedevent::ngpcm >= 2; using MyFilteredCollisions = soa::Filtered; // this goes to mixed event. - Filter DalitzEEFilter = o2::aod::dalitzee::sign == 0; // analyze only uls - using MyFilteredDalitzEEs = soa::Filtered; - - void processMB(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + void processMB(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs) { - fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbeCuts, legs); - SameEventPairing(grouped_collisions, dielectrons, v0photons, perCollision_ee, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, emprimaryelectrons); + fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbeCuts, legs); + SameEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs); if (fDoMixing) { - MixedEventPairing(filtered_collisions, dielectrons, v0photons, perCollision_ee, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, emprimaryelectrons); + MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs); } } diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx index 46717f4b766..2551a4de068 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx @@ -33,7 +33,6 @@ #include "PWGEM/PhotonMeson/Utils/PairUtilities.h" #include "PWGEM/PhotonMeson/Utils/MCUtilities.h" #include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/DalitzEECut.h" #include "PWGEM/PhotonMeson/Core/PairCut.h" #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" @@ -45,7 +44,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; @@ -54,12 +53,6 @@ using MyV0Photon = MyV0Photons::iterator; using MyMCV0Legs = soa::Join; using MyMCV0Leg = MyMCV0Legs::iterator; -using MyDalitzEEs = soa::Join; -using MyDalitzEE = MyDalitzEEs::iterator; - -using MyMCElectrons = soa::Join; -using MyMCElectron = MyMCElectrons::iterator; - struct MaterialBudgetMC { Configurable CentMin{"CentMin", -1, "min. centrality"}; @@ -67,7 +60,7 @@ struct MaterialBudgetMC { Configurable CentEstimator{"CentEstimator", "FT0M", "centrality estimator"}; Configurable maxY{"maxY", 0.9, "maximum rapidity for generated particles"}; - Configurable fConfigTagCuts{"cfgTagCuts", "mee_0_120_tpconly_lowB", "Comma separated list of Dalitz EE cuts for tag"}; + Configurable fConfigTagCuts{"cfgTagCuts", "qc", "Comma separated list of V0 photon cuts for tag"}; Configurable fConfigProbeCuts{"cfgProbeCuts", "qc,wwire_ib", "Comma separated list of V0 photon cuts for probe"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; @@ -77,7 +70,7 @@ struct MaterialBudgetMC { OutputObj fOutputGen{"Generated"}; THashList* fMainList = new THashList(); - std::vector fTagCuts; + std::vector fTagCuts; std::vector fProbeCuts; std::vector fPairCuts; @@ -85,7 +78,7 @@ struct MaterialBudgetMC { void init(InitContext& context) { if (context.mOptions.get("processMBMC")) { - fPairNames.push_back("PCMDalitzEE"); + fPairNames.push_back("PCMPCM"); } DefineTagCuts(); @@ -100,12 +93,12 @@ struct MaterialBudgetMC { } template - void add_pair_histograms(THashList* list_pair, const std::string pairname, TCuts1 const& cuts1, TCuts2 const& cuts2, TCuts3 const& cuts3) + void add_pair_histograms(THashList* list_pair, const std::string pairname, TCuts1 const& tagcuts, TCuts2 const& probecuts, TCuts3 const& cuts3) { - for (auto& cut1 : cuts1) { - for (auto& cut2 : cuts2) { - std::string cutname1 = cut1.GetName(); - std::string cutname2 = cut2.GetName(); + for (auto& tagcut : tagcuts) { + for (auto& probecut : probecuts) { + std::string cutname1 = tagcut.GetName(); + std::string cutname2 = probecut.GetName(); // if (cutname1 == cutname2) { // continue; @@ -122,8 +115,8 @@ struct MaterialBudgetMC { THashList* list_pair_subsys_paircut = reinterpret_cast(list_pair_subsys_photoncut->FindObject(pair_cut_name.data())); o2::aod::emphotonhistograms::DefineHistograms(list_pair_subsys_paircut, "material_budget_study", "Pair"); } // end of cut3 loop pair cut - } // end of cut2 loop - } // end of cut1 loop + } // end of probecut loop + } // end of tagcut loop } static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; @@ -158,7 +151,7 @@ struct MaterialBudgetMC { o2::aod::emphotonhistograms::AddHistClass(list_pair, pairname.data()); - if (pairname == "PCMDalitzEE") { + if (pairname == "PCMPCM") { add_pair_histograms(list_pair, pairname, fTagCuts, fProbeCuts, fPairCuts); } @@ -178,7 +171,7 @@ struct MaterialBudgetMC { for (int icut = 0; icut < objArray->GetEntries(); ++icut) { const char* cutname = objArray->At(icut)->GetName(); LOGF(info, "add cut : %s", cutname); - fTagCuts.push_back(*dalitzeecuts::GetCut(cutname)); + fTagCuts.push_back(*pcmcuts::GetCut(cutname)); } } LOGF(info, "Number of Tag PCM cuts = %d", fTagCuts.size()); @@ -213,29 +206,39 @@ struct MaterialBudgetMC { } Preslice perCollision_pcm = aod::v0photonkf::emreducedeventId; - Preslice perCollision_ee = aod::dalitzee::emreducedeventId; template - bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) + bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& tagcut, TCut2 const& probecut) { - return o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); + return o2::aod::photonpair::IsSelectedPair(g1, g2, tagcut, probecut); } - template + template void fillsinglephoton(TEvents const& collisions, TPhotons const& photons, TPreslice const& perCollision, TCuts const& cuts, TLegs const& legs, TMCParticles const& mcparticles, TMCEvents const&) { + THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_v0 = static_cast(fMainList->FindObject("V0")); double value[4] = {0.f}; for (auto& collision : collisions) { + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_before"))->Fill(collision.posZ()); + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(1.0); // all if (!collision.sel8()) { continue; } + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(2.0); // FT0VX i.e. FT0and + if (collision.numContrib() < 0.5) { continue; } + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(3.0); // Ncontrib > 0 + if (abs(collision.posZ()) > 10.0) { continue; } + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_after"))->Fill(collision.posZ()); + reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm + + o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); auto photons_coll = photons.sliceBy(perCollision, collision.globalIndex()); for (auto& cut : cuts) { @@ -274,43 +277,25 @@ struct MaterialBudgetMC { } // end of collision loop } - template - void TruePairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TMCParticles const& mcparticles, TMCEvents const&, TEMPrimaryElectrons const& emprimaryelectrons) + template + void TruePairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& tagcuts, TCuts2 const& probecuts, TPairCuts const& paircuts, TLegs const& legs, TMCParticles const& mcparticles, TMCEvents const&) { - THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); for (auto& collision : collisions) { - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_before"))->Fill(collision.posZ()); - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(1.0); // all - if (!collision.sel8()) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(2.0); // FT0VX i.e. FT0and - - if (collision.numContrib() < 0.5) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(3.0); // Ncontrib > 0 - - if (abs(collision.posZ()) > 10.0) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hZvtx_after"))->Fill(collision.posZ()); - reinterpret_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject("hCollisionCounter"))->Fill(4.0); // |Zvtx| < 10 cm - - o2::aod::emphotonhistograms::FillHistClass(list_ev_pair, "", collision); - auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); double value[6] = {0.f}; float phi_cp2 = 0.f, eta_cp2 = 0.f; - for (auto& cut1 : cuts1) { - for (auto& cut2 : cuts2) { + for (auto& tagcut : tagcuts) { + for (auto& probecut : probecuts) { for (auto& g1 : photons1_coll) { for (auto& g2 : photons2_coll) { - if (!IsSelectedPair(g1, g2, cut1, cut2)) { + if (g1.globalIndex() == g2.globalIndex()) { + continue; + } + if (!IsSelectedPair(g1, g2, tagcut, probecut)) { continue; } @@ -319,13 +304,10 @@ struct MaterialBudgetMC { continue; } - auto pos1 = g1.template posTrack_as(); - auto ele1 = g1.template negTrack_as(); + auto pos1 = g1.template posTrack_as(); + auto ele1 = g1.template negTrack_as(); auto pos2 = g2.template posTrack_as(); auto ele2 = g2.template negTrack_as(); - if (pos1.trackId() == pos2.trackId() || ele1.trackId() == ele2.trackId()) { - continue; - } auto pos1mc = pos1.template emmcparticle_as(); auto ele1mc = ele1.template emmcparticle_as(); @@ -333,24 +315,29 @@ struct MaterialBudgetMC { auto ele2mc = ele2.template emmcparticle_as(); // LOGF(info,"pos1mc.globalIndex() = %d , ele1mc.globalIndex() = %d , pos2mc.globalIndex() = %d , ele2mc.globalIndex() = %d", pos1mc.globalIndex(), ele1mc.globalIndex(), pos2mc.globalIndex(), ele2mc.globalIndex()); + int photonid1 = FindCommonMotherFrom2Prongs(pos1mc, ele1mc, -11, 11, 22, mcparticles); + if (photonid1 < 0) { + continue; + } + auto g1mc = mcparticles.iteratorAt(photonid1); + int photonid2 = FindCommonMotherFrom2Prongs(pos2mc, ele2mc, -11, 11, 22, mcparticles); if (photonid2 < 0) { continue; } auto g2mc = mcparticles.iteratorAt(photonid2); - int pi0id = FindCommonMotherFrom3Prongs(g2mc, pos1mc, ele1mc, 22, -11, 11, 111, mcparticles); - bool is_pi0_physical_primary = false; - if (pi0id > 0) { - auto pi0mc = mcparticles.iteratorAt(pi0id); - is_pi0_physical_primary = IsPhysicalPrimary(pi0mc.emreducedmcevent(), pi0mc, mcparticles); + int pi0id = FindCommonMotherFrom2Prongs(g1mc, g2mc, 22, 22, 111, mcparticles); + if (pi0id < 0) { + continue; } - if (!is_pi0_physical_primary) { + auto pi0mc = mcparticles.iteratorAt(pi0id); + if (!IsPhysicalPrimary(pi0mc.emreducedmcevent(), pi0mc, mcparticles)) { continue; } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), g1.mass()); // tag - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // tag + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); // probe ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; phi_cp2 = atan2(g2.vy(), g2.vx()); eta_cp2 = std::atanh(g2.vz() / sqrt(pow(g2.vx(), 2) + pow(g2.vy(), 2) + pow(g2.vz(), 2))); @@ -360,21 +347,24 @@ struct MaterialBudgetMC { value[3] = g2.v0radius(); value[4] = phi_cp2 > 0.f ? phi_cp2 : phi_cp2 + TMath::TwoPi(); value[5] = eta_cp2; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); } // end of pair cut loop } // end of g2 loop } // end of g1 loop - } // end of cut2 loop - } // end of cut1 loop + } // end of probecut loop + } // end of tagcut loop } // end of collision loop } Partition grouped_collisions = CentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < CentMax; // this goes to same event. + Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true && CentMin < o2::aod::cent::centFT0M&& o2::aod::cent::centFT0M < CentMax; + Filter collisionFilter_subsys = o2::aod::emreducedevent::ngpcm >= 2; + using MyFilteredCollisions = soa::Filtered; // this goes to mixed event. - void processMBMC(MyCollisions const& collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions, MyDalitzEEs const& dielectrons, MyMCElectrons const& primaryelectrons) + void processMBMC(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions) { - fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbeCuts, legs, mcparticles, mccollisions); - TruePairing(grouped_collisions, dielectrons, v0photons, perCollision_ee, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, mcparticles, mccollisions, primaryelectrons); + fillsinglephoton(grouped_collisions, v0photons, perCollision_pcm, fProbeCuts, legs, mcparticles, mccollisions); + TruePairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fTagCuts, fProbeCuts, fPairCuts, legs, mcparticles, mccollisions); } PresliceUnsorted perMcCollision = aod::emmcparticle::emreducedmceventId; diff --git a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx index 707e8030cef..59a776ad5b1 100644 --- a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx +++ b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx @@ -38,6 +38,7 @@ #include "PWGEM/PhotonMeson/Utils/PairUtilities.h" #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" #include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/Core/DalitzEECut.h" #include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" #include "PWGEM/PhotonMeson/Core/PairCut.h" #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" @@ -50,15 +51,22 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; +using MyDalitzEEs = soa::Join; +using MyDalitzEE = MyDalitzEEs::iterator; + +using MyPrimaryElectrons = soa::Join; +using MyPrimaryElectron = MyPrimaryElectrons::iterator; + struct PhotonHBT { Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis,qc,nocut", "Comma separated list of V0 photon cuts"}; + Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_all_tpchadrejortofreq_prompt", "Comma separated list of DalitzEE cuts"}; Configurable fConfigPHOSCuts{"cfgPHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; @@ -67,6 +75,7 @@ struct PhotonHBT { THashList* fMainList = new THashList(); std::vector fPCMCuts; + std::vector fDalitzEECuts; std::vector fPHOSCuts; std::vector fPairCuts; @@ -76,6 +85,9 @@ struct PhotonHBT { if (context.mOptions.get("processPCMPCM")) { fPairNames.push_back("PCMPCM"); } + if (context.mOptions.get("processPCMDalitzEE")) { + fPairNames.push_back("PCMDalitzEE"); + } if (context.mOptions.get("processPHOSPHOS")) { fPairNames.push_back("PHOSPHOS"); } @@ -84,6 +96,7 @@ struct PhotonHBT { } DefinePCMCuts(); + DefineDalitzEECuts(); DefinePHOSCuts(); DefinePairCuts(); addhistograms(); @@ -118,7 +131,7 @@ struct PhotonHBT { } // end of cut1 loop } - static constexpr std::string_view pairnames[6] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PHOSEMC"}; + static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; void addhistograms() { fMainList->SetOwner(true); @@ -143,6 +156,9 @@ struct PhotonHBT { if (pairname == "PCMPCM") { add_pair_histograms(list_pair, pairname, fPCMCuts, fPCMCuts, fPairCuts); } + if (pairname == "PCMDalitzEE") { + add_pair_histograms(list_pair, pairname, fPCMCuts, fDalitzEECuts, fPairCuts); + } if (pairname == "PHOSPHOS") { add_pair_histograms(list_pair, pairname, fPHOSCuts, fPHOSCuts, fPairCuts); } @@ -166,6 +182,21 @@ struct PhotonHBT { } LOGF(info, "Number of PCM cuts = %d", fPCMCuts.size()); } + + void DefineDalitzEECuts() + { + TString cutNamesStr = fConfigDalitzEECuts.value; + if (!cutNamesStr.IsNull()) { + std::unique_ptr objArray(cutNamesStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + const char* cutname = objArray->At(icut)->GetName(); + LOGF(info, "add cut : %s", cutname); + fDalitzEECuts.push_back(*dalitzeecuts::GetCut(cutname)); + } + } + LOGF(info, "Number of DalitzEE cuts = %d", fDalitzEECuts.size()); + } + void DefinePHOSCuts() { TString cutNamesStr = fConfigPHOSCuts.value; @@ -200,6 +231,8 @@ struct PhotonHBT { bool is_selected_pair = false; if constexpr (pairtype == PairType::kPCMPCM) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); + } else if constexpr (pairtype == PairType::kPCMDalitzEE) { + is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } else if constexpr (pairtype == PairType::kPHOSPHOS) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); // dummy, because track matching is not ready. } else if constexpr (pairtype == PairType::kPCMPHOS) { @@ -210,8 +243,8 @@ struct PhotonHBT { return is_selected_pair; } - template - void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs) + template + void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) { THashList* list_ev_pair = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())); THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); @@ -244,6 +277,7 @@ struct PhotonHBT { auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); + double values[9] = {0.f}; if constexpr (pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) { for (auto& cut : cuts1) { for (auto& paircut : paircuts) { @@ -252,21 +286,53 @@ struct PhotonHBT { continue; } - // longitudinally co-moving system (LCMS) + values[0] = 0.0; + values[1] = 0.0; + // center-of-mass system (CMS) ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + if constexpr (pairtype == PairType::kPCMDalitzEE) { + v2.SetM(g2.mass()); + values[1] = g2.mass(); + } ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); float kt = k12.Pt(); - ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector - ROOT::Math::XYZVector uv_out = k12.Vect() / k12.P(); // unit vector for out - ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis - ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - float qout = q_3d.Dot(uv_out); - float qlong = q_3d.Dot(uv_long); - float qside = q_3d.Dot(uv_side); - double values[5] = {qinv, qlong, qout, qside, kt}; + float qt = q12.Pt(); + float qlong_cms = q12.Pz(); + + ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector + ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt + ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis + ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side + float qout_cms = q_3d.Dot(uv_out); + float qside_cms = q_3d.Dot(uv_side); + + // longitudinally co-moving system (LCMS) + ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); + ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); + ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; + float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); + ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector + ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); + float qlong_lcms = q12_lcms.Pz(); + + // ROOT::Math::PxPyPzEVector v1_lcms_cartesian = bst_z(v1_cartesian); + // ROOT::Math::PxPyPzEVector v2_lcms_cartesian = bst_z(v2_cartesian); + // ROOT::Math::PxPyPzEVector q12_lcms_cartesian = bst_z(q12_cartesian); + // LOGF(info, "q12.Pz() = %f, q12_cartesian.Pz() = %f",q12.Pz(), q12_cartesian.Pz()); + // LOGF(info, "v1.Pz() = %f, v2.Pz() = %f",v1.Pz(), v2.Pz()); + // LOGF(info, "v1_lcms_cartesian.Pz() = %f, v2_lcms_cartesian.Pz() = %f",v1_lcms_cartesian.Pz(), v2_lcms_cartesian.Pz()); + // LOGF(info, "q12_lcms_cartesian.Pz() = %f", q12_lcms_cartesian.Pz()); + + values[2] = kt; + values[3] = qinv; + values[4] = qlong_cms; + values[5] = qout_cms; + values[6] = qside_cms; + values[7] = qt; + values[8] = qlong_lcms; reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut.GetName(), cut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values); } // end of combination } // end of pair cut loop @@ -289,20 +355,46 @@ struct PhotonHBT { continue; } } + + values[0] = 0.0; + values[1] = 0.0; + // center-of-mass system (CMS) ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + if constexpr (pairtype == PairType::kPCMDalitzEE) { + v2.SetM(g2.mass()); + values[1] = g2.mass(); + } ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); float kt = k12.Pt(); - ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector - ROOT::Math::XYZVector uv_out = k12.Vect() / k12.P(); // unit vector for out - ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis - ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - float qout = q_3d.Dot(uv_out); - float qlong = q_3d.Dot(uv_long); - float qside = q_3d.Dot(uv_side); - double values[5] = {qinv, qlong, qout, qside, kt}; + float qt = q12.Pt(); + float qlong_cms = q12.Pz(); + + ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector + ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt + ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis + ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side + float qout_cms = q_3d.Dot(uv_out); + float qside_cms = q_3d.Dot(uv_side); + + // longitudinally co-moving system (LCMS) + ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); + ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); + ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; + float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); + ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector + ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); + float qlong_lcms = q12_lcms.Pz(); + + values[2] = kt; + values[3] = qinv; + values[4] = qlong_cms; + values[5] = qout_cms; + values[6] = qside_cms; + values[7] = qt; + values[8] = qlong_lcms; reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values); } // end of combination } // end of pair cut loop @@ -318,8 +410,8 @@ struct PhotonHBT { using BinningType = ColumnBinningPolicy; BinningType colBinning{{ConfVtxBins, ConfMultBins}, true}; - template - void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs) + template + void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TPairCuts const& paircuts, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) { THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); // LOGF(info, "Number of collisions after filtering: %d", collisions.size()); @@ -332,6 +424,7 @@ struct PhotonHBT { // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); + double values[9] = {0.f}; for (auto& cut1 : cuts1) { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { @@ -347,22 +440,47 @@ struct PhotonHBT { if (!paircut.IsSelected(g1, g2)) { continue; } + + // center-of-mass system (CMS) + values[0] = 0.0; + values[1] = 0.0; ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + if constexpr (pairtype == PairType::kPCMDalitzEE) { + v2.SetM(g2.mass()); + values[1] = g2.mass(); + } ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); float kt = k12.Pt(); - ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector - ROOT::Math::XYZVector uv_out = k12.Vect() / k12.P(); // unit vector for out - ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis - ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - float qout = q_3d.Dot(uv_out); - float qlong = q_3d.Dot(uv_long); - float qside = q_3d.Dot(uv_side); - double values[5] = {qinv, qlong, qout, qside, kt}; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_mix"))->Fill(values); + float qt = q12.Pt(); + float qlong_cms = q12.Pz(); + + ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector + ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt + ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis + ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side + float qout_cms = q_3d.Dot(uv_out); + float qside_cms = q_3d.Dot(uv_side); + // longitudinally co-moving system (LCMS) + ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); + ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); + ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; + float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); + ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector + ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); + float qlong_lcms = q12_lcms.Pz(); + + values[2] = kt; + values[3] = qinv; + values[4] = qlong_cms; + values[5] = qout_cms; + values[6] = qside_cms; + values[7] = qt; + values[8] = qlong_lcms; + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_mix"))->Fill(values); } // end of different photon combinations } // end of pair cut loop } // end of cut2 loop @@ -371,33 +489,41 @@ struct PhotonHBT { } Preslice perCollision_pcm = aod::v0photonkf::emreducedeventId; + Preslice perCollision_dalitzee = aod::dalitzee::emreducedeventId; Preslice perCollision_phos = aod::skimmedcluster::collisionId; Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; - // Filter collisionFilter_subsys = (o2::aod::emreducedevent::ngpcm >= 1) || (o2::aod::emreducedevent::ngphos >= 1); + Filter collisionFilter_subsys = (o2::aod::emreducedevent::ngpcm >= 1) || (o2::aod::emreducedevent::neeuls >= 1); using MyFilteredCollisions = soa::Filtered; void processPCMPCM(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs) { - SameEventPairing(collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMCuts, fPairCuts, legs); - MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMCuts, fPairCuts, legs); + SameEventPairing(collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMCuts, fPairCuts, legs, nullptr); + MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMCuts, fPairCuts, legs, nullptr); + } + + void processPCMDalitzEE(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + { + SameEventPairing(collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitzee, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons); + MixedEventPairing(filtered_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitzee, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons); } void processPHOSPHOS(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, aod::PHOSClusters const& phosclusters) { - SameEventPairing(collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fPHOSCuts, fPHOSCuts, fPairCuts, nullptr); - MixedEventPairing(filtered_collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fPHOSCuts, fPHOSCuts, fPairCuts, nullptr); + SameEventPairing(collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fPHOSCuts, fPHOSCuts, fPairCuts, nullptr, nullptr); + MixedEventPairing(filtered_collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fPHOSCuts, fPHOSCuts, fPairCuts, nullptr, nullptr); } void processPCMPHOS(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::PHOSClusters const& phosclusters, aod::V0Legs const& legs) { - SameEventPairing(collisions, v0photons, phosclusters, perCollision_pcm, perCollision_phos, fPCMCuts, fPHOSCuts, fPairCuts, legs); - MixedEventPairing(filtered_collisions, v0photons, phosclusters, perCollision_pcm, perCollision_phos, fPCMCuts, fPHOSCuts, fPairCuts, legs); + SameEventPairing(collisions, v0photons, phosclusters, perCollision_pcm, perCollision_phos, fPCMCuts, fPHOSCuts, fPairCuts, legs, nullptr); + MixedEventPairing(filtered_collisions, v0photons, phosclusters, perCollision_pcm, perCollision_phos, fPCMCuts, fPHOSCuts, fPairCuts, legs, nullptr); } void processDummy(MyCollisions::iterator const& collision) {} PROCESS_SWITCH(PhotonHBT, processPCMPCM, "pairing PCM-PCM", false); + PROCESS_SWITCH(PhotonHBT, processPCMDalitzEE, "pairing PCM-DalitzEE", false); PROCESS_SWITCH(PhotonHBT, processPHOSPHOS, "pairing PHOS-PHOS", false); PROCESS_SWITCH(PhotonHBT, processPCMPHOS, "pairing PCM-PHOS", false); PROCESS_SWITCH(PhotonHBT, processDummy, "Dummy function", true); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx index f247032e60f..b5f4757e987 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx @@ -140,6 +140,7 @@ struct DalitzEEQC { THashList* list_dalitzee = static_cast(fMainList->FindObject("DalitzEE")); THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; + double values_single[3] = {0, 0, 0}; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -180,6 +181,11 @@ struct DalitzEEQC { values[2] = uls_pair.dcaXY(); values[3] = uls_pair.phiv(); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_same"))->Fill(values); + + values_single[0] = uls_pair.mass(); + values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); nuls++; for (auto& track : {pos, ele}) { if (std::find(used_trackIds.begin(), used_trackIds.end(), track.globalIndex()) == used_trackIds.end()) { @@ -192,6 +198,8 @@ struct DalitzEEQC { reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_uls"))->Fill(nuls); for (auto& lspp_pair : lspp_pairs_per_coll) { + auto pos = lspp_pair.template posTrack_as(); + auto ele = lspp_pair.template negTrack_as(); if (cut.IsSelected(lspp_pair)) { values[0] = lspp_pair.mass(); values[1] = lspp_pair.pt(); @@ -199,11 +207,17 @@ struct DalitzEEQC { values[3] = lspp_pair.phiv(); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_same"))->Fill(values); nlspp++; + values_single[0] = lspp_pair.mass(); + values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_dca_same"))->Fill(values_single); } } // end of lspp pair loop reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_lspp"))->Fill(nlspp); for (auto& lsmm_pair : lsmm_pairs_per_coll) { + auto pos = lsmm_pair.template posTrack_as(); + auto ele = lsmm_pair.template negTrack_as(); if (cut.IsSelected(lsmm_pair)) { values[0] = lsmm_pair.mass(); values[1] = lsmm_pair.pt(); @@ -211,6 +225,10 @@ struct DalitzEEQC { values[3] = lsmm_pair.phiv(); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_same"))->Fill(values); nlsmm++; + values_single[0] = lsmm_pair.mass(); + values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_dca_same"))->Fill(values_single); } } // end of lsmm pair loop reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_lsmm"))->Fill(nlsmm); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx index 9b329e827f1..9fcf81df934 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx @@ -145,6 +145,7 @@ struct DalitzEEQCMC { THashList* list_dalitzee = static_cast(fMainList->FindObject("DalitzEE")); THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; + double values_single[3] = {0, 0, 0}; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -198,8 +199,17 @@ struct DalitzEEQCMC { values[3] = uls_pair.phiv(); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_same"))->Fill(values); + values_single[0] = uls_pair.mass(); + values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + if (mcmother.pdgCode() == 111) { reinterpret_cast(list_dalitzee_cut->FindObject("hMvsPhiV_Pi0"))->Fill(uls_pair.phiv(), uls_pair.mass()); + reinterpret_cast(list_dalitzee_cut->FindObject("hMvsOPA_Pi0"))->Fill(uls_pair.opangle(), uls_pair.mass()); + } else if (mcmother.pdgCode() == 221) { + reinterpret_cast(list_dalitzee_cut->FindObject("hMvsPhiV_Eta"))->Fill(uls_pair.phiv(), uls_pair.mass()); + reinterpret_cast(list_dalitzee_cut->FindObject("hMvsOPA_Eta"))->Fill(uls_pair.opangle(), uls_pair.mass()); } nuls++; @@ -218,6 +228,7 @@ struct DalitzEEQCMC { auto mcphoton = mcparticles.iteratorAt(photonid); if (IsPhysicalPrimary(mcphoton.emreducedmcevent(), mcphoton, mcparticles) && IsEleFromPC(elemc, mcparticles) && IsEleFromPC(posmc, mcparticles)) { reinterpret_cast(list_dalitzee_cut->FindObject("hMvsPhiV_Photon"))->Fill(uls_pair.phiv(), uls_pair.mass()); + reinterpret_cast(list_dalitzee_cut->FindObject("hMvsOPA_Photon"))->Fill(uls_pair.opangle(), uls_pair.mass()); } } } // end of uls pair loop diff --git a/PWGEM/PhotonMeson/Utils/PCMUtilities.h b/PWGEM/PhotonMeson/Utils/PCMUtilities.h index 599ae087fbe..3493abb6434 100644 --- a/PWGEM/PhotonMeson/Utils/PCMUtilities.h +++ b/PWGEM/PhotonMeson/Utils/PCMUtilities.h @@ -194,4 +194,11 @@ float getPsiPair(float pxpos, float pypos, float pzpos, float pxneg, float pyneg return std::asin(clipToPM1(argsin)); } //_______________________________________________________________________ +float getOpeningAngle(float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) +{ + float ptot2 = RecoDecay::p2(pxpos, pypos, pzpos) * RecoDecay::p2(pxneg, pyneg, pzneg); + float argcos = RecoDecay::dotProd(std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}) / std::sqrt(ptot2); + return std::acos(argcos); +} +//_______________________________________________________________________ #endif // PWGEM_PHOTONMESON_UTILS_PCMUTILITIES_H_ From 61d71193e12246b9b14a2cd8ad0901607c8aa627 Mon Sep 17 00:00:00 2001 From: alicja-pp <101565842+alicja-pp@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:40:11 +0100 Subject: [PATCH 139/156] PWGCF: add TOFMatching histograms for different particles (#4257) * Remove printing in output (#3584) * add new histograms for bkg study in mc * add new histograms for bkg study in mc + min pt cut for sigmas in data * remove printing in output * adding TOFMatching histograms for different particles * correct file name --------- Co-authored-by: pganoti <44636794+pganoti@users.noreply.github.com> --- .../Tasks/femtoWorldEfficiencyTask.cxx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx index 141fb5e9ef6..3e4ff0c98a3 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx @@ -159,6 +159,15 @@ struct femtoWorldEficiencyTask { registryPri.add("plus/TOFmatchingAll", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); registryPri.add("minus/TOFmatchingAll", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryPri.add("plus/TOFmatchingPi", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryPri.add("minus/TOFmatchingPi", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + + registryPri.add("plus/TOFmatchingKa", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryPri.add("minus/TOFmatchingKa", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + + registryPri.add("plus/TOFmatchingPr", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryPri.add("minus/TOFmatchingPr", ";#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + // Pri our tracking cuts only registryPriCuts.add("plus/PiPriPt", "PiPri;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); registryPriCuts.add("plus/KaPriPt", "KaPri;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); @@ -411,7 +420,17 @@ struct femtoWorldEficiencyTask { // histogram pt TOF matching if (track.hasTOF()) { registryPri.fill(HIST("plus/TOFmatchingAll"), mcParticle.pt()); + if (mcParticle.pdgCode() == 211) { + registryPri.fill(HIST("plus/TOFmatchingPi"), mcParticle.pt()); + } + if (mcParticle.pdgCode() == 321) { + registryPri.fill(HIST("plus/TOFmatchingKa"), mcParticle.pt()); + } + if (mcParticle.pdgCode() == 2212) { + registryPri.fill(HIST("plus/TOFmatchingPr"), mcParticle.pt()); + } } + if (IsNSigmaAccept(std::abs(track.tpcNSigmaPi()), std::abs(track.tofNSigmaPi()), track.pt()) && mcParticle.pdgCode() == 211) { registryPri.fill(HIST("plus/PiPri"), track.pt(), track.eta()); registryPri.fill(HIST("plus/PiPriPt"), mcParticle.pt()); @@ -442,7 +461,17 @@ struct femtoWorldEficiencyTask { // histogram pt TOF matching if (track.hasTOF()) { registryPri.fill(HIST("minus/TOFmatchingAll"), mcParticle.pt()); + if (mcParticle.pdgCode() == -211) { + registryPri.fill(HIST("minus/TOFmatchingPi"), mcParticle.pt()); + } + if (mcParticle.pdgCode() == -321) { + registryPri.fill(HIST("minus/TOFmatchingKa"), mcParticle.pt()); + } + if (mcParticle.pdgCode() == -2212) { + registryPri.fill(HIST("minus/TOFmatchingPr"), mcParticle.pt()); + } } + if (IsNSigmaAccept(std::abs(track.tpcNSigmaPi()), std::abs(track.tofNSigmaPi()), track.pt()) && mcParticle.pdgCode() == -211) { registryPri.fill(HIST("minus/PiPri"), track.pt(), track.eta()); registryPri.fill(HIST("minus/PiPriPt"), mcParticle.pt()); From 557353916068c5f06448c2c2f74d2e6c5ab2c860 Mon Sep 17 00:00:00 2001 From: prchakra <47203359+prchakra@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:04:40 +0100 Subject: [PATCH 140/156] PWGCF: FemtoUniverse -- task for 3D Femtoscopy (#4260) * Adding function to compute 3d rel. pair momentum * Adding container to store 3d rel. pair momentum * Adding task for 3D Femtoscopy * Adding task for 3D Femtoscopy * Adding container to store 3d rel. pair momentum * Adding function to compute 3d rel. pair momentum * Adding task for 3D Femtoscopy * Adding task for 3D Femtoscopy * Adding function to compute 3d rel. pair momentum * Adding container to store 3d rel. pair momentum --- .../Core/FemtoUniverse3DContainer.h | 264 +++++++ PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h | 105 +++ PWGCF/FemtoUniverse/Tasks/CMakeLists.txt | 5 + ...ersePairTaskTrackTrack3DMultKtExtended.cxx | 717 ++++++++++++++++++ 4 files changed, 1091 insertions(+) create mode 100644 PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h create mode 100644 PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h new file mode 100644 index 00000000000..57f9bea89d3 --- /dev/null +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h @@ -0,0 +1,264 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file FemtoUniverse3DContainer.h +/// \brief Definition of the FemtoUniverse3DContainer +/// \remark This file is inherited from ~/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h on 10/01/2024 +/// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl8 + +#ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSE3DCONTAINER_H_ +#define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSE3DCONTAINER_H_ + +#include +#include +#include + +#include "Framework/HistogramRegistry.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "Math/Vector4D.h" +#include "TMath.h" +#include "TDatabasePDG.h" + +using namespace o2::framework; + +namespace o2::analysis::femtoUniverse +{ + +namespace femtoUniverse3DContainer +{ +/// Femtoscopic observable to be computed +enum Observable { kstar ///< kstar +}; + +/// Type of the event processind +enum EventType { same, ///< Pair from same event + mixed ///< Pair from mixed event +}; +}; // namespace femtoUniverse3DContainer + +/// \class FemtoUniverse3DContainer +/// \brief Container for all histogramming related to the correlation function. The two +/// particles of the pair are passed here, and the correlation function and QA histograms +/// are filled according to the specified observable +/// \tparam eventType Type of the event (same/mixed) +/// \tparam obs Observable to be computed (k*/Q_inv/...) +template +class FemtoUniverse3DContainer +{ + public: + /// Destructor + virtual ~FemtoUniverse3DContainer() = default; + + /// Initializes histograms for the task + /// Called by init both in case of reconstructed data/ Monte Carlo, and for Monte Carlo Truth + /// \tparam T type of the axis Object + /// \param folderName Name of the directory in the output file (no suffix for reconstructed data/ Monte Carlo; "_MC" for Monte Carlo Truth) + /// \param femtoObs1D Title of the femto observable kstar + /// \param femtoObsKout Title of the femto observable kout + /// \param femtoObsKside Title of the femto observable kside + /// \param femtoObsKlong Title of the femto observable klong + /// \param femtoObsAxis1D axis object for the femto observable kstar + /// \param femtoObsAxisOut axis object for the femto observable kout + /// \param femtoObsAxisSide axis object for the femto observable kside + /// \param femtoObsAxisLong axis object for the femto observable klong + /// \param multAxis axis object for the multiplicity axis + /// \param kTAxis axis object for the kT axis + /// \param mTAxis axis object for the mT axis + /// \param use3dplots Flag to fill 3D plots + /// \param isiden Identical or non-identical particle pair + /// \param islcms LCMS or PRF + template + void init_base(std::string folderName, std::string femtoObs1D, std::string femtoObsKout, std::string femtoObsKside, std::string femtoObsKlong, T femtoObsAxis1D, T femtoObsAxisOut, T femtoObsAxisSide, T femtoObsAxisLong, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, bool use3dplots, bool isiden) + { + mHistogramRegistry->add((folderName + "/relPairMom3D").c_str(), ("; " + femtoObsKout + "; " + femtoObsKside + "; " + femtoObsKlong).c_str(), kTH3F, {femtoObsAxisOut, femtoObsAxisSide, femtoObsAxisLong}); + mHistogramRegistry->add((folderName + "/relPairMomOut").c_str(), ("; " + femtoObsKout + "; Entries").c_str(), kTH1F, {femtoObsAxisOut}); + mHistogramRegistry->add((folderName + "/relPairMomSide").c_str(), ("; " + femtoObsKside + "; Entries").c_str(), kTH1F, {femtoObsAxisSide}); + mHistogramRegistry->add((folderName + "/relPairMomLong").c_str(), ("; " + femtoObsKlong + "; Entries").c_str(), kTH1F, {femtoObsAxisLong}); + mHistogramRegistry->add((folderName + "/relPairMom1D").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + if (!isiden) { + mHistogramRegistry->add((folderName + "/KStarOutP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarSideP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarLongP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarOutN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarSideN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarLongN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + } + mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs1D + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis1D, kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs1D + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis1D, mTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs1D + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis1D, multAxis}); + mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs1D + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis1D, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs1D + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis1D, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); + if (use3dplots) { + mHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs1D + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTH3F, {femtoObsAxis1D, mTAxis3D, multAxis3D}); + } + } + + /// Templated function to initialize the histograms for the task + /// Always calls init_base to initialize the histograms for data/ Monte Carlo reconstructed + /// \tparam T type of the configurable for the axis configuration + /// \param registry Histogram registry to be passed + /// \param kstarBins k* binning for the histograms + /// \param multBins multiplicity binning for the histograms + /// \param kTBins kT binning for the histograms + /// \param mTBins mT binning for the histograms + /// \param isMC add Monte Carlo truth histograms to the output file + /// \param use3dplots Flag to fill 3D plots + /// \param isiden Identical or non-identical particle pair + template + void init(HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, bool isMC, bool use3dplots, bool isiden) + { + mHistogramRegistry = registry; + std::string femtoObs1D, femtoObsKout, femtoObsKside, femtoObsKlong; + + if (isiden) { + femtoObs1D = "#it{q} (GeV/#it{c})"; + femtoObsKout = "#it{q}_{out} (GeV/#it{c})"; + femtoObsKside = "#it{q}_{side} (GeV/#it{c})"; + femtoObsKlong = "#it{q}_{long} (GeV/#it{c})"; + } else { + femtoObs1D = "#it{k*} (GeV/#it{c})"; + femtoObsKout = "#it{k*}_{out} (GeV/#it{c})"; + femtoObsKside = "#it{k*}_{side} (GeV/#it{c})"; + femtoObsKlong = "#it{k*}_{long} (GeV/#it{c})"; + } + framework::AxisSpec femtoObsAxis1D = {kstarBins, femtoObs1D.c_str()}; + framework::AxisSpec femtoObsAxisOut = {kstarBins, femtoObsKout.c_str()}; + framework::AxisSpec femtoObsAxisSide = {kstarBins, femtoObsKside.c_str()}; + framework::AxisSpec femtoObsAxisLong = {kstarBins, femtoObsKlong.c_str()}; + + std::vector tmpVecMult = multBins; + framework::AxisSpec multAxis = {tmpVecMult, "Multiplicity"}; + framework::AxisSpec kTAxis = {kTBins, "#it{k}_{T} (GeV/#it{c})"}; + framework::AxisSpec mTAxis = {mTBins, "#it{m}_{T} (GeV/#it{c}^{2})"}; + + framework::AxisSpec multAxis3D = {multBins3D, "Multiplicity"}; + framework::AxisSpec mTAxis3D = {mTBins3D, "#it{m}_{T} (GeV/#it{c})"}; + + std::string folderName = static_cast(mFolderSuffix[mEventType]) + static_cast(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]); + + init_base(folderName, femtoObs1D, femtoObsKout, femtoObsKside, femtoObsKlong, femtoObsAxis1D, femtoObsAxisOut, femtoObsAxisSide, femtoObsAxisLong, multAxis, kTAxis, mTAxis, multAxis3D, mTAxis3D, use3dplots, isiden); + } + + /// Set the PDG codes of the two particles involved + /// \param pdg1 PDG code of particle one + /// \param pdg2 PDG code of particle two + void setPDGCodes(const int pdg1, const int pdg2) + { + mMassOne = TDatabasePDG::Instance()->GetParticle(pdg1)->Mass(); + mMassTwo = TDatabasePDG::Instance()->GetParticle(pdg2)->Mass(); + mPDGOne = pdg1; + mPDGTwo = pdg2; + } + + /// Pass a pair to the container and compute all the relevant observables + /// Called by setPair + /// \tparam T type of the femtouniverseparticle + /// \param part1 Particle one + /// \param part2 Particle two + /// \param mult Multiplicity of the event + template + void setPair_base(const float femtoObsKout, const float femtoObsKside, const float femtoObsKlong, const float femtoObs1D, const float kT, const float mT, T const& part1, T const& part2, const int mult, bool use3dplots, const float isiden) + { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairMomOut"), femtoObsKout); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairMomSide"), femtoObsKside); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairMomLong"), femtoObsKlong); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairMom3D"), femtoObsKout, femtoObsKside, femtoObsKlong); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/MultPtPart1"), part1.pt(), mult); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/MultPtPart2"), part2.pt(), mult); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/PtPart1PtPart2"), part1.pt(), part2.pt()); + + if (isiden) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairMom1D"), (2.0 * femtoObs1D)); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkT"), kT); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarkT"), (2.0 * femtoObs1D), kT); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmT"), (2.0 * femtoObs1D), mT); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarMult"), (2.0 * femtoObs1D), mult); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/kstarPtPart1"), (2.0 * femtoObs1D), part1.pt()); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/kstarPtPart2"), (2.0 * femtoObs1D), part2.pt()); + if (use3dplots) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmTMult"), (2.0 * femtoObs1D), mT, mult); + } + } else { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairMom1D"), femtoObs1D); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkT"), kT); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarkT"), femtoObs1D, kT); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmT"), femtoObs1D, mT); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarMult"), femtoObs1D, mult); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/kstarPtPart1"), femtoObs1D, part1.pt()); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/kstarPtPart2"), femtoObs1D, part2.pt()); + if (use3dplots) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmTMult"), femtoObs1D, mT, mult); + } + } + } + + /// Templated function to compute the necessary observables and fill the respective histograms + /// Always calls setPair_base to compute the observables with reconstructed data + /// \tparam T type of the femtouniverseparticle + /// \param part1 Particle one + /// \param part2 Particle two + /// \param mult Multiplicity of the event + /// \param use3dplots Flag to fill 3D plots + /// \param isiden Choosing identical or non-identical pairs + /// \param islcm Choosing LCMS or PRF + template + void setPair(T const& part1, T const& part2, const int mult, bool use3dplots, bool isiden, bool islcms) + { + std::vector f3d; + const float kT = FemtoUniverseMath::getkT(part1, mMassOne, part2, mMassTwo); + const float mT = FemtoUniverseMath::getmT(part1, mMassOne, part2, mMassTwo); + + f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo, isiden, islcms); + + const float femtoObs1D = f3d[0]; + const float femtoObsKout = f3d[1]; + const float femtoObsKside = f3d[2]; + const float femtoObsKlong = f3d[3]; + + if (mHistogramRegistry) { + setPair_base(femtoObsKout, femtoObsKside, femtoObsKlong, femtoObs1D, kT, mT, part1, part2, mult, use3dplots, isiden); + if (!isiden) { + if (femtoObsKout > 0.0) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]) + HIST("/KStarOutP"), femtoObs1D); + } else { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]) + HIST("/KStarOutN"), femtoObs1D); + } + if (femtoObsKside > 0.0) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]) + HIST("/KStarSideP"), femtoObs1D); + } else { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]) + HIST("/KStarSideN"), femtoObs1D); + } + if (femtoObsKlong > 0.0) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]) + HIST("/KStarLongP"), femtoObs1D); + } else { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtouniverseMCparticle::MCTypeName[o2::aod::femtouniverseMCparticle::MCType::kRecon]) + HIST("/KStarLongN"), femtoObs1D); + } + } + } + } + + protected: + HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + static constexpr std::string_view mFolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to mEventType + static constexpr int mEventType = eventType; ///< Type of the event (same/mixed, according to femtoUniverse3DContainer::EventType) + float mMassOne = 0.f; ///< PDG mass of particle 1 + float mMassTwo = 0.f; ///< PDG mass of particle 2 + int mPDGOne = 0; ///< PDG code of particle 1 + int mPDGTwo = 0; ///< PDG code of particle 2 +}; + +} // namespace o2::analysis::femtoUniverse + +#endif // PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSE3DCONTAINER_H_ diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h index f0243942279..e5c381d9db6 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h @@ -14,11 +14,14 @@ /// \author Valentina Mantovani Sarti, TU München, valentina.mantovani-sarti@tum.de /// \author Laura Serksnyte, TU München, laura.serksnyte@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw, zuzanna.chochulska.stud@pw.edu.pl +/// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEMATH_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEMATH_H_ #include +#include +#include #include "Math/Vector4D.h" #include "Math/Boost.h" @@ -61,6 +64,7 @@ class FemtoUniverseMath const ROOT::Math::PxPyPzMVector trackRelK = PartOneCMS - PartTwoCMS; return 0.5 * trackRelK.P(); } + /// Compute the qij of a pair of particles /// \tparam T type of tracks /// \param vecparti Particle i PxPyPzMVector @@ -137,6 +141,107 @@ class FemtoUniverseMath { return std::sqrt(std::pow(getkT(part1, mass1, part2, mass2), 2.) + std::pow(0.5 * (mass1 + mass2), 2.)); } + + /// Compute the 3d components of the pair momentum in LCMS and PRF + /// \tparam T type of tracks + /// \param part1 Particle 1 + /// \param mass1 Mass of particle 1 + /// \param part2 Particle 2 + /// \param mass2 Mass of particle 2 + /// \param isiden Identical or non-identical particle pair + /// \param islcms LCMS or PRF + template + static std::vector getpairmom3d(const T& part1, const float mass1, const T& part2, const float mass2, bool isiden, bool islcms) + { + const double E1 = sqrt(pow(part1.px(), 2) + pow(part1.py(), 2) + pow(part1.pz(), 2) + pow(mass1, 2)); + const double E2 = sqrt(pow(part2.px(), 2) + pow(part2.py(), 2) + pow(part2.pz(), 2) + pow(mass2, 2)); + + const ROOT::Math::PxPyPzEVector vecpart1(part1.px(), part1.py(), part1.pz(), E1); + const ROOT::Math::PxPyPzEVector vecpart2(part2.px(), part2.py(), part2.pz(), E2); + const ROOT::Math::PxPyPzEVector trackSum = vecpart1 + vecpart2; + + std::vector vect; + + const double tPx = trackSum.px(); + const double tPy = trackSum.py(); + const double tPz = trackSum.pz(); + const double tPE = trackSum.E(); + + const double tPt = trackSum.pt(); + const double tMt = trackSum.mt(); + const double tPinv = std::sqrt((tMt * tMt) - (tPt * tPt)); + + float nullmass = 0.0; + const double m1 = std::max(nullmass, mass1); + const double m2 = std::max(nullmass, mass2); + + const double tQinvL = std::pow((E1 - E2), 2) - std::pow((part1.px() - part2.px()), 2) - + std::pow((part1.py() - part2.py()), 2) - std::pow((part1.pz() - part2.pz()), 2); + + double tQ = (m1 - m2) / tPinv; + tQ = ::sqrt(tQ * tQ - tQinvL); + + const double fKStarCalc = tQ / 2.0; + vect.push_back(fKStarCalc); + + // Boost to LCMS + + const double beta = tPz / tPE; + const double gamma = tPE / tMt; + + const double px1L = (part1.px() * tPx + part1.py() * tPy) / tPt; + const double py1L = (-part1.px() * tPy + part1.py() * tPx) / tPt; + const double pz1L = gamma * (part1.pz() - beta * E1); + const double pE1L = gamma * (E1 - beta * part1.pz()); + + const double px2L = (part2.px() * tPx + part2.py() * tPy) / tPt; + const double py2L = (-part2.px() * tPy + part2.py() * tPx) / tPt; + const double pz2L = gamma * (part2.pz() - beta * E2); + const double pE2L = gamma * (E2 - beta * part2.pz()); + + double fDKOutLCMS; + double fDKSideLCMS; + double fDKLongLCMS; + + double fDKOutPRF; + double fDKSidePRF; + double fDKLongPRF; + + if (!isiden) { + fDKOutLCMS = px1L; + fDKSideLCMS = py1L; + fDKLongLCMS = pz1L; + } else { + fDKOutLCMS = px1L - px2L; + fDKSideLCMS = py1L - py2L; + fDKLongLCMS = pz1L - pz2L; + } + + // Boost to PRF + const double betaOut = tPt / tMt; + const double gammaOut = tMt / tPinv; + + if (!isiden) { + fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * pE1L); + fDKSidePRF = fDKSideLCMS; + fDKLongPRF = fDKLongLCMS; + } else { + fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * (pE1L - pE2L)); + fDKSidePRF = fDKSideLCMS; + fDKLongPRF = fDKLongLCMS; + } + + if (islcms) { + vect.push_back(fDKOutLCMS); + vect.push_back(fDKSideLCMS); + vect.push_back(fDKLongLCMS); + } else { + vect.push_back(fDKOutPRF); + vect.push_back(fDKSidePRF); + vect.push_back(fDKLongPRF); + } + return vect; + } }; } // namespace o2::analysis::femtoUniverse diff --git a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt index cdb28b6501a..93c2ad9cd59 100644 --- a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt @@ -29,6 +29,11 @@ o2physics_add_dpl_workflow(femtouniverse-pair-track-track-mult-kt-extended PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femtouniverse-pair-track-track-threedrelmom-mult-kt-extended + SOURCES femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femtouniverse-debug-track SOURCES femtoUniverseDebugTrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx new file mode 100644 index 00000000000..ad74d2e8bfc --- /dev/null +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx @@ -0,0 +1,717 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx +/// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks and compute relative pair-momentum in three dimesnions +/// \remark This file is inherited from ~/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx on 10/01/2024 +/// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl + +#include +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "TDatabasePDG.h" +#include "ReconstructionDataFormats/PID.h" +#include "Common/DataModel/PIDResponse.h" + +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUtils.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h" + +using namespace o2; +using namespace o2::analysis::femtoUniverse; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +namespace +{ +static constexpr int nPart = 2; +static constexpr int nCuts = 5; +static const std::vector partNames{"PartOne", "PartTwo"}; +static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; +static const float cutsTable[nPart][nCuts]{ + {4.05f, 1.f, 3.f, 3.f, 100.f}, + {4.05f, 1.f, 3.f, 3.f, 100.f}}; +} // namespace + +struct femtoUniversePairTaskTrackTrack3DMultKtExtended { + + Service pdg; + + /// Particle selection part + + /// Table for both particles + struct : o2::framework::ConfigurableGroup { + Configurable ConfNsigmaCombined{"ConfNsigmaCombined", 3.0f, "TPC and TOF Pion Sigma (combined) for momentum > ConfTOFPtMin"}; + Configurable ConfNsigmaTPC{"ConfNsigmaTPC", 3.0f, "TPC Pion Sigma for momentum < ConfTOFPtMin"}; + Configurable ConfTOFPtMin{"ConfTOFPtMin", 0.5f, "Min. Pt for which TOF is required for PID."}; + Configurable ConfEtaMax{"ConfEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; + + Configurable> ConfCutTable{"ConfCutTable", {cutsTable[0], nPart, nCuts, partNames, cutNames}, "Particle selections"}; + Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; + Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; + Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; + Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + + } twotracksconfigs; + + using FemtoFullParticles = soa::Join; + // Filters for selecting particles (both p1 and p2) + Filter trackAdditionalfilter = (nabs(aod::femtouniverseparticle::eta) < twotracksconfigs.ConfEtaMax); // example filtering on configurable + using FilteredFemtoFullParticles = soa::Filtered; + // using FilteredFemtoFullParticles = FemtoFullParticles; //if no filtering is applied uncomment this option + + SliceCache cache; + Preslice perCol = aod::femtouniverseparticle::fdCollisionId; + + /// Particle 1 + struct : o2::framework::ConfigurableGroup { + Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 211, "Particle 1 - PDG code"}; + // Configurable ConfCutPartOne{"ConfCutPartOne", 5542474, "Particle 1 - Selection bit from cutCulator"}; + Configurable ConfPIDPartOne{"ConfPIDPartOne", 2, "Particle 1 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector>int>> + Configurable ConfPtLowPart1{"ConfPtLowPart1", 0.14, "Lower limit for Pt for the first particle"}; + Configurable ConfPtHighPart1{"ConfPtHighPart1", 1.5, "Higher limit for Pt for the first particle"}; + Configurable ConfChargePart1{"ConfChargePart1", 1, "Particle 1 sign"}; + } trackonefilter; + + /// Partition for particle 1 + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == trackonefilter.ConfChargePart1 && aod::femtouniverseparticle::pt < trackonefilter.ConfPtHighPart1 && aod::femtouniverseparticle::pt > trackonefilter.ConfPtLowPart1; + + Partition> partsOneMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == trackonefilter.ConfChargePart1 && aod::femtouniverseparticle::pt < trackonefilter.ConfPtHighPart1 && aod::femtouniverseparticle::pt > trackonefilter.ConfPtLowPart1; + // + + /// Histogramming for particle 1 + FemtoUniverseParticleHisto trackHistoPartOne; + + /// Particle 2 + struct : o2::framework::ConfigurableGroup { + Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 211, "Particle 2 - PDG code"}; + // Configurable ConfCutPartTwo{"ConfCutPartTwo", 5542474, "Particle 2 - Selection bit"}; + Configurable ConfPIDPartTwo{"ConfPIDPartTwo", 2, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> + + Configurable ConfPtLowPart2{"ConfPtLowPart2", 0.14, "Lower limit for Pt for the second particle"}; + Configurable ConfPtHighPart2{"ConfPtHighPart2", 1.5, "Higher limit for Pt for the second particle"}; + Configurable ConfChargePart2{"ConfChargePart2", -1, "Particle 2 sign"}; + } tracktwofilter; + + /// Partition for particle 2 + Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == tracktwofilter.ConfChargePart2) && aod::femtouniverseparticle::pt < tracktwofilter.ConfPtHighPart2 && aod::femtouniverseparticle::pt > tracktwofilter.ConfPtLowPart2; + + Partition> partsTwoMC = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack) && (aod::femtouniverseparticle::sign == tracktwofilter.ConfChargePart2) && aod::femtouniverseparticle::pt < tracktwofilter.ConfPtHighPart2 && aod::femtouniverseparticle::pt > tracktwofilter.ConfPtLowPart2; + + /// Histogramming for particle 2 + FemtoUniverseParticleHisto trackHistoPartTwo; + + /// Histogramming for Event + FemtoUniverseEventHisto eventHisto; + + /// The configurables need to be passed to an std::vector + int vPIDPartOne, vPIDPartTwo; + std::vector kNsigma; + + /// Event part + Configurable ConfV0MLow{"ConfV0MLow", 0.0, "Lower limit for V0M multiplicity"}; + Configurable ConfV0MHigh{"ConfV0MHigh", 25000.0, "Upper limit for V0M multiplicity"}; + + Filter collV0Mfilter = ((o2::aod::femtouniversecollision::multV0M > ConfV0MLow) && (o2::aod::femtouniversecollision::multV0M < ConfV0MHigh)); + // Filter trackAdditionalfilter = (nabs(aod::femtouniverseparticle::eta) < twotracksconfigs.ConfEtaMax); // example filtering on configurable + + /// Particle part + ConfigurableAxis ConfTempFitVarBins{"ConfDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + + /// Correlation part + ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity or centrality"}; // \todo to be obtained from the hash task + ConfigurableAxis ConfMultKstarBins{"ConfMultKstarBins", {VARIABLE_WIDTH, 0.0f, 13.0f, 20.0f, 30.0f, 40.0f, 50.0f, 100.0f, 99999.f}, "Bins for kstar analysis in multiplicity or centrality bins (10 is maximum)"}; + ConfigurableAxis ConfKtKstarBins{"ConfKtKstarBins", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 2.0f, 99999.f}, "Bins for kstar analysis in kT bins (10 is maximum)"}; + 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 ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis ConfmultBins3D{"ConfmultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + + ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + + ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; + Configurable ConfIsIden{"ConfIsIden", true, "Choosing identical or non-identical pairs"}; + Configurable ConfIsLCMS{"ConfIsLCMS", true, "Choosing LCMS or PRF"}; + Configurable ConfNEventsMix{"ConfNEventsMix", 5, "Number of events for mixing"}; + Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; + Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCut{"ConfCPRdeltaPhiCut", 0.0, "Delta Phi cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCut{"ConfCPRdeltaEtaCut", 0.0, "Delta Eta cut for Close Pair Rejection"}; + Configurable cfgProcessPM{"cfgProcessPM", false, "Process particles of the opposite charge"}; + Configurable cfgProcessPP{"cfgProcessPP", true, "Process particles of the same, positice charge"}; + Configurable cfgProcessMM{"cfgProcessMM", true, "Process particles of the same, positice charge"}; + Configurable cfgProcessMultBins{"cfgProcessMultBins", true, "Process kstar histograms in multiplicity bins (in multiplicity bins)"}; + Configurable cfgProcessKtBins{"cfgProcessKtBins", true, "Process kstar histograms in kT bins (if cfgProcessMultBins is set false, this will not be processed regardless this Configurable state)"}; + + FemtoUniverse3DContainer sameEventCont; + FemtoUniverse3DContainer mixedEventCont; + + FemtoUniverse3DContainer sameEventContPP; + FemtoUniverse3DContainer mixedEventContPP; + + FemtoUniverse3DContainer sameEventContMM; + FemtoUniverse3DContainer mixedEventContMM; + + FemtoUniversePairCleaner pairCleaner; + FemtoUniverseDetaDphiStar pairCloseRejection; + FemtoUniverseTrackSelection trackCuts; + + PairWithCentMultKt sameEventMultCont; + PairWithCentMultKt mixedEventMultCont; + + PairWithCentMultKt sameEventMultContPP; + PairWithCentMultKt mixedEventMultContPP; + + PairWithCentMultKt sameEventMultContMM; + PairWithCentMultKt mixedEventMultContMM; + + float mass1 = -1; + float mass2 = -1; + + /// Histogram output + HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry resultRegistryPM{"CorrelationsPM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry resultRegistryPP{"CorrelationsPP", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry resultRegistryMM{"CorrelationsMM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + HistogramRegistry SameMultRegistryPM{"SameMultRegistryPM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MixedMultRegistryPM{"MixedMultRegistryPM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + HistogramRegistry SameMultRegistryPP{"SameMultRegistryPP", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MixedMultRegistryPP{"MixedMultRegistryPP", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + HistogramRegistry SameMultRegistryMM{"SameMultRegistryMM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MixedMultRegistryMM{"MixedMultRegistryMM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // PID for protons + bool IsProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx + { + //|nsigma_TPC| < 3 for p < 0.5 GeV/c + //|nsigma_combined| < 3 for p > 0.5 + + // using configurables: + // ConfTOFPtMin - momentum value when we start using TOF; set to 1000 if TOF not needed + // ConfNsigmaTPC -> TPC Sigma for momentum < 0.5 + // ConfNsigmaCombined -> TPC and TOF Sigma (combined) for momentum > 0.5 + + if (mom < twotracksconfigs.ConfTOFPtMin) { + if (TMath::Abs(nsigmaTPCPr) < twotracksconfigs.ConfNsigmaTPC) { + return true; + } else { + return false; + } + } else { + if (TMath::Hypot(nsigmaTOFPr, nsigmaTPCPr) < twotracksconfigs.ConfNsigmaCombined) { + return true; + } else { + return false; + } + } + return false; + } + + bool IsKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) + { + //|nsigma_TPC| < 3 for p < 0.5 GeV/c + //|nsigma_combined| < 3 for p > 0.5 + + // using configurables: + // ConfTOFPtMin - momentum value when we start using TOF; set to 1000 if TOF not needed + // ConfNsigmaTPCTOFKaon -> are we doing TPC TOF PID for Kaons? (boolean) + // ConfNsigmaTPC -> TPC Kaon Sigma for momentum < 0.5 + // ConfNsigmaCombined -> TPC and TOF Sigma (combined) for momentum > 0.5 + if (true) { + if (mom < twotracksconfigs.ConfTOFPtMin) { + if (TMath::Abs(nsigmaTPCK) < twotracksconfigs.ConfNsigmaTPC) { + return true; + } else { + return false; + } + } else { + if (TMath::Hypot(nsigmaTOFK, nsigmaTPCK) < twotracksconfigs.ConfNsigmaCombined) { + return true; + } else { + return false; + } + } + } + return false; + } + + bool IsPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) + { + //|nsigma_TPC| < 3 for p < 0.5 GeV/c + //|nsigma_combined| < 3 for p > 0.5 + + // using configurables: + // ConfTOFPtMin - momentum value when we start using TOF; set to 1000 if TOF not needed + // ConfNsigmaTPC -> TPC Sigma for momentum < 0.5 + // ConfNsigmaCombined -> TPC and TOF Pion Sigma (combined) for momentum > 0.5 + if (true) { + if (mom < twotracksconfigs.ConfTOFPtMin) { + if (TMath::Abs(nsigmaTPCPi) < twotracksconfigs.ConfNsigmaTPC) { + return true; + } else { + return false; + } + } else { + if (TMath::Hypot(nsigmaTOFPi, nsigmaTPCPi) < twotracksconfigs.ConfNsigmaCombined) { + return true; + } else { + return false; + } + } + } + return false; + } + + bool IsParticleNSigma(int8_t particle_number, float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK) + { + if (particle_number == 1) { + switch (trackonefilter.ConfPDGCodePartOne) { + case 2212: // Proton + case -2212: // Antiproton + return IsProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); + break; + case 211: // Pion+ + case -211: // Pion- + return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + break; + case 321: // Kaon+ + case -321: // Kaon- + return IsKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + break; + default: + return false; + } + return false; + } else if (particle_number == 2) { + switch (tracktwofilter.ConfPDGCodePartTwo) { + case 2212: // Proton + case -2212: // Antiproton + return IsProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); + break; + case 211: // Pion+ + case -211: // Pion- + return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + break; + case 321: // Kaon+ + case -321: // Kaon- + return IsKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + break; + default: + return false; + } + return false; + } else { + LOGF(fatal, "Wrong number of particle chosen! It should be 1 or 2. It is -> %d", particle_number); + } + return false; + } + + void init(InitContext&) + { + eventHisto.init(&qaRegistry); + trackHistoPartOne.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, twotracksconfigs.ConfIsMC, trackonefilter.ConfPDGCodePartOne, true); + + trackHistoPartTwo.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, twotracksconfigs.ConfIsMC, tracktwofilter.ConfPDGCodePartTwo, true); + + MixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + MixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + + mass1 = pdg->Mass(trackonefilter.ConfPDGCodePartOne); + mass2 = pdg->Mass(tracktwofilter.ConfPDGCodePartTwo); + + if (cfgProcessPM) { + sameEventCont.init(&resultRegistryPM, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D, ConfIsIden); + mixedEventCont.init(&resultRegistryPM, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D, ConfIsIden); + + sameEventCont.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); + mixedEventCont.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); + + if (cfgProcessMultBins) { + sameEventMultCont.init(&SameMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + mixedEventMultCont.init(&MixedMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + } + } + + if (cfgProcessPP) { + sameEventContPP.init(&resultRegistryPP, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D, ConfIsIden); + mixedEventContPP.init(&resultRegistryPP, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D, ConfIsIden); + sameEventContPP.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); + mixedEventContPP.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); + + if (cfgProcessMultBins) { + sameEventMultContPP.init(&SameMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + mixedEventMultContPP.init(&MixedMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + } + } + + if (cfgProcessMM) { + sameEventContMM.init(&resultRegistryMM, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D, ConfIsIden); + mixedEventContMM.init(&resultRegistryMM, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D, ConfIsIden); + sameEventContMM.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); + mixedEventContMM.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); + + if (cfgProcessMultBins) { + sameEventMultContMM.init(&SameMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + mixedEventMultContMM.init(&MixedMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + } + } + + pairCleaner.init(&qaRegistry); + if (ConfIsCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRdeltaPhiCut.value, ConfCPRdeltaEtaCut.value, ConfCPRPlotPerRadii.value); + } + + vPIDPartOne = trackonefilter.ConfPIDPartOne.value; + vPIDPartTwo = tracktwofilter.ConfPIDPartTwo.value; + kNsigma = twotracksconfigs.ConfTrkPIDnSigmaMax.value; + } + + template + void fillCollision(CollisionType col) + { + MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); + eventHisto.fillQA(col); + } + + /// This function processes the same event and takes care of all the histogramming + /// \todo the trivial loops over the tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... + /// @tparam PartitionType + /// @tparam PartType + /// @tparam isMC: enables Monte Carlo truth specific histograms + /// @param groupPartsOne partition for the first particle passed by the process function + /// @param groupPartsTwo partition for the second particle passed by the process function + /// @param parts femtoUniverseParticles table (in case of Monte Carlo joined with FemtoUniverseMCLabels) + /// @param magFieldTesla magnetic field of the collision + /// @param multCol multiplicity of the collision + template + void doSameEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartType parts, float magFieldTesla, int multCol, int ContType, bool fillQA) + { + + /// Histogramming same event + if ((ContType == 1 || ContType == 2) && fillQA) { + for (auto& part : groupPartsOne) { + if (!IsParticleNSigma((int8_t)1, part.pt(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + continue; + } + trackHistoPartOne.fillQA(part); + } + } + + if ((ContType == 1 || ContType == 3) && fillQA) { + for (auto& part : groupPartsTwo) { + if (!IsParticleNSigma((int8_t)2, part.pt(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + continue; + } + trackHistoPartTwo.fillQA(part); + } + } + + if (ContType == 1) { + + /// Now build the combinations for non-identical particle pairs + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + + if (!IsParticleNSigma((int8_t)1, p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { + continue; + } + + if (!IsParticleNSigma((int8_t)2, p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon))) { + continue; + } + + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + } + + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + + float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass2); + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); + + sameEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + if (cfgProcessMultBins) + sameEventMultCont.fill(kstar, multCol, kT); + } + } else { + /// Now build the combinations for identical particles pairs + for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsOne))) { + + if (!IsParticleNSigma((int8_t)2, p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { + continue; + } + + if (!IsParticleNSigma((int8_t)2, p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon))) { + continue; + } + + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + } + + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + + switch (ContType) { + case 2: { + float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass1); + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass1); + + sameEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + if (cfgProcessMultBins) + sameEventMultContPP.fill(kstar, multCol, kT); + break; + } + + case 3: { + float kstar = FemtoUniverseMath::getkstar(p1, mass2, p2, mass2); + float kT = FemtoUniverseMath::getkT(p1, mass2, p2, mass2); + + sameEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + if (cfgProcessMultBins) + sameEventMultContMM.fill(kstar, multCol, kT); + break; + } + default: + break; + } + } + } + } + + /// process function for to call doSameEvent with Data + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoUniverseParticleTable + void processSameEvent(soa::Filtered::iterator& col, + FilteredFemtoFullParticles& parts) + { + fillCollision(col); + + auto thegroupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + bool fillQA = true; + + if (cfgProcessPM) { + doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 1, fillQA); + fillQA = false; + } + if (cfgProcessPP) + doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multNtr(), 2, fillQA); + if (cfgProcessMM) + doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackTrack3DMultKtExtended, processSameEvent, "Enable processing same event", true); + + /// process function for to call doSameEvent with Monte Carlo + /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) + /// \param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth + /// \param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table + void processSameEventMC(o2::aod::FDCollision& col, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + fillCollision(col); + + auto thegroupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + bool fillQA = true; + if (cfgProcessPM) { + doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 1, fillQA); + fillQA = false; + } + if (cfgProcessPP) + doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multNtr(), 2, fillQA); + if (cfgProcessMM) + doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackTrack3DMultKtExtended, processSameEventMC, "Enable processing same event for Monte Carlo", false); + + /// This function processes the mixed event + /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... + /// \tparam PartitionType + /// \tparam PartType + /// \tparam isMC: enables Monte Carlo truth specific histograms + /// \param groupPartsOne partition for the first particle passed by the process function + /// \param groupPartsTwo partition for the second particle passed by the process function + /// \param parts femtoUniverseParticles table (in case of Monte Carlo joined with FemtoUniverseMCLabels) + /// \param magFieldTesla magnetic field of the collision + /// \param multCol multiplicity of the collision + template + void doMixedEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartType parts, float magFieldTesla, int multCol, int ContType) + { + + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + + if (!IsParticleNSigma((int8_t)2, p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { + continue; + } + + if (!IsParticleNSigma((int8_t)2, p2.pt(), trackCuts.getNsigmaTPC(p2, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p2, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p2, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p2, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p2, o2::track::PID::Kaon))) { + continue; + } + + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + } + + switch (ContType) { + case 1: { + float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass2); + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); + mixedEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + if (cfgProcessMultBins) + mixedEventMultCont.fill(kstar, multCol, kT); + break; + } + case 2: { + float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass1); + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass1); + mixedEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + if (cfgProcessMultBins) + mixedEventMultContPP.fill(kstar, multCol, kT); + break; + } + + case 3: { + float kstar = FemtoUniverseMath::getkstar(p1, mass2, p2, mass2); + float kT = FemtoUniverseMath::getkT(p1, mass2, p2, mass2); + mixedEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + if (cfgProcessMultBins) + mixedEventMultContMM.fill(kstar, multCol, kT); + break; + } + default: + break; + } + } + } + + /// process function for to call doMixedEvent with Data + /// @param cols subscribe to the collisions table (Data) + /// @param parts subscribe to the femtoUniverseParticleTable + void processMixedEvent(soa::Filtered& cols, + FilteredFemtoFullParticles& parts) + { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + + const int multiplicityCol = collision1.multNtr(); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + + if (cfgProcessPM) { + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol, 1); + } + if (cfgProcessPP) { + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol, 2); + } + if (cfgProcessMM) { + auto groupPartsOne = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol, 3); + } + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackTrack3DMultKtExtended, processMixedEvent, "Enable processing mixed events", true); + + /// brief process function for to call doMixedEvent with Monte Carlo + /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) + /// @param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth + /// @param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table + void processMixedEventMC(o2::aod::FDCollisions& cols, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + + const int multiplicityCol = collision1.multNtr(); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + /// \todo before mixing we should check whether both collisions contain a pair of particles! + // if (partsOne.size() == 0 || nPart2Evt1 == 0 || nPart1Evt2 == 0 || partsTwo.size() == 0 ) continue; + + if (cfgProcessPM) { + auto groupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol, 1); + } + if (cfgProcessPP) { + auto groupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol, 2); + } + if (cfgProcessMM) { + auto groupPartsOne = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol, 3); + } + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackTrack3DMultKtExtended, processMixedEventMC, "Enable processing mixed events MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} From f4d483e93f14e873c12f0c76518539d5e082eb80 Mon Sep 17 00:00:00 2001 From: lucamicheletti93 <38209984+lucamicheletti93@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:23:38 +0100 Subject: [PATCH 141/156] Adding histogram for centrality studies (#4266) Co-authored-by: Luca Micheletti --- PWGDQ/Core/HistogramsLibrary.cxx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index 1955e110123..f02422d8bb9 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -657,9 +657,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "VtxingChi2PCA", "", false, 100, 0.0, 10.0, VarManager::kVertexingChi2PCA); } if (subGroupStr.Contains("pbpb")) { - hm->AddHistogram(histClass, "Mass_Cent", "", false, 750, 0.0, 15.0, VarManager::kMass, 100, 0., 100., VarManager::kCentVZERO); - hm->AddHistogram(histClass, "Pt_Cent", "", false, 120, 0.0, 30.0, VarManager::kPt, 100, 0., 100., VarManager::kCentVZERO); - hm->AddHistogram(histClass, "Rapidity_Cent", "", false, 200, 2.5, 4.0, VarManager::kRap, 100, 0., 100., VarManager::kCentVZERO); + hm->AddHistogram(histClass, "Mass_CentVZERO", "", false, 750, 0.0, 15.0, VarManager::kMass, 100, 0., 100., VarManager::kCentVZERO); + hm->AddHistogram(histClass, "Pt_CentVZERO", "", false, 120, 0.0, 30.0, VarManager::kPt, 100, 0., 100., VarManager::kCentVZERO); + hm->AddHistogram(histClass, "Rapidity_CentVZERO", "", false, 200, 2.5, 4.0, VarManager::kRap, 100, 0., 100., VarManager::kCentVZERO); + hm->AddHistogram(histClass, "Mass_CentFT0C", "", false, 750, 0.0, 15.0, VarManager::kMass, 100, 0., 100., VarManager::kCentFT0C); + hm->AddHistogram(histClass, "Pt_CentFT0C", "", false, 120, 0.0, 30.0, VarManager::kPt, 100, 0., 100., VarManager::kCentFT0C); + hm->AddHistogram(histClass, "Rapidity_CentFT0C", "", false, 200, 2.5, 4.0, VarManager::kRap, 100, 0., 100., VarManager::kCentFT0C); } if (subGroupStr.Contains("lowmass")) { hm->AddHistogram(histClass, "MassLow", "", false, 400, 0.0, 2.0, VarManager::kMass); From 9922e8c430512597420ef9a2ff522bf525827ce8 Mon Sep 17 00:00:00 2001 From: prchakra <47203359+prchakra@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:42:40 +0100 Subject: [PATCH 142/156] Changing the binning of nsigma for TPC and TOF (#4265) --- .../Core/FemtoUniverseTrackSelection.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h index 7c4d6a10354..ac285287a64 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h @@ -318,21 +318,21 @@ void FemtoUniverseTrackSelection::init(HistogramRegistry* registry) mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); mHistogramRegistry->add((folderName + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); mHistogramRegistry->add((folderName + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.0255}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); } /// set cuts nPtMinSel = getNSelections(femtoUniverseTrackSelection::kpTMin); From 9110a4390095300d5185d1dc34a69ffbf1e2cb07 Mon Sep 17 00:00:00 2001 From: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:11:24 +0100 Subject: [PATCH 143/156] PWGCF: Fix FemtoDream (#4264) * Feat: use track variables from v0 table For v0 daughters, certain track variables get recomputed by the lambdakzero-builder. Since these values are used to fill the femto tables, these values should also explicitly be used for the daughter selections. * Fix: fix formating * Fix: fix formating * Fix: fix comment --- PWGCF/FemtoDream/FemtoDreamTrackSelection.h | 20 +++++++++++-------- PWGCF/FemtoDream/FemtoDreamV0Selection.h | 4 ++-- PWGCF/FemtoDream/femtoDreamDebugV0.cxx | 7 ++++--- .../femtoDreamProducerReducedTask.cxx | 2 +- PWGCF/FemtoDream/femtoDreamProducerTask.cxx | 10 +++++----- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/PWGCF/FemtoDream/FemtoDreamTrackSelection.h b/PWGCF/FemtoDream/FemtoDreamTrackSelection.h index e8b8c260825..1dc749e3fbb 100644 --- a/PWGCF/FemtoDream/FemtoDreamTrackSelection.h +++ b/PWGCF/FemtoDream/FemtoDreamTrackSelection.h @@ -137,13 +137,17 @@ class FemtoDreamTrackSelection : public FemtoDreamObjectSelection - std::array getCutContainer(T const& track); + template + std::array getCutContainer(T const& track, R Pt, R Eta, R Dcaxy); /// Some basic QA histograms /// \tparam part Type of the particle for proper naming of the folders for QA @@ -478,15 +482,15 @@ bool FemtoDreamTrackSelection::isSelectedMinimal(T const& track) return true; } -template -std::array FemtoDreamTrackSelection::getCutContainer(T const& track) +template +std::array FemtoDreamTrackSelection::getCutContainer(T const& track, R Pt, R Eta, R Dca) { cutContainerType output = 0; size_t counter = 0; cutContainerType outputPID = 0; const auto sign = track.sign(); - const auto pT = track.pt(); - const auto eta = track.eta(); + const auto pt = Pt; + const auto eta = Eta; const auto tpcNClsF = track.tpcNClsFound(); const auto tpcRClsC = track.tpcCrossedRowsOverFindableCls(); const auto tpcNClsC = track.tpcNClsCrossedRows(); @@ -495,7 +499,7 @@ std::array FemtoDreamTrackSelection::getCutContainer(T cons const auto itsNClsIB = track.itsNClsInnerBarrel(); const auto dcaXY = track.dcaXY(); const auto dcaZ = track.dcaZ(); - const auto dca = std::sqrt(pow(dcaXY, 2.) + pow(dcaZ, 2.)); + const auto dca = Dca; std::vector pidTPC, pidTOF; for (auto it : mPIDspecies) { @@ -523,7 +527,7 @@ std::array FemtoDreamTrackSelection::getCutContainer(T cons break; case (femtoDreamTrackSelection::kpTMin): case (femtoDreamTrackSelection::kpTMax): - observable = pT; + observable = pt; break; case (femtoDreamTrackSelection::kEtaMax): observable = eta; diff --git a/PWGCF/FemtoDream/FemtoDreamV0Selection.h b/PWGCF/FemtoDream/FemtoDreamV0Selection.h index 6ba357dceab..73ad22e2a26 100644 --- a/PWGCF/FemtoDream/FemtoDreamV0Selection.h +++ b/PWGCF/FemtoDream/FemtoDreamV0Selection.h @@ -552,8 +552,8 @@ template std::array FemtoDreamV0Selection::getCutContainer(C const& col, V const& v0, T const& posTrack, T const& negTrack) { - auto outputPosTrack = PosDaughTrack.getCutContainer(posTrack); - auto outputNegTrack = NegDaughTrack.getCutContainer(negTrack); + auto outputPosTrack = PosDaughTrack.getCutContainer(posTrack, v0.positivept(), v0.positiveeta(), v0.dcapostopv()); + auto outputNegTrack = NegDaughTrack.getCutContainer(negTrack, v0.negativept(), v0.negativeeta(), v0.dcanegtopv()); cutContainerType output = 0; size_t counter = 0; diff --git a/PWGCF/FemtoDream/femtoDreamDebugV0.cxx b/PWGCF/FemtoDream/femtoDreamDebugV0.cxx index 538e58e2352..1992a17bde3 100644 --- a/PWGCF/FemtoDream/femtoDreamDebugV0.cxx +++ b/PWGCF/FemtoDream/femtoDreamDebugV0.cxx @@ -41,7 +41,7 @@ struct femtoDreamDebugV0 { Configurable ConfV01_PDGCode{"ConfV01_PDGCode", 3122, "V0 - PDG code"}; Configurable ConfV01_ChildPos_PDGCode{"ConfV01_PosChild_PDGCode", 2212, "Positive Child - PDG code"}; - Configurable ConfV01_NegChild_PDGCode{"ConfV01_NegChild_PDGCode", 211, "Negative Child- PDG code"}; + Configurable ConfV01_ChildNeg_PDGCode{"ConfV01_NegChild_PDGCode", 211, "Negative Child- PDG code"}; Configurable ConfV01_CutBit{"ConfV01_CutBit", 338, "V0 - Selection bit from cutCulator"}; ConfigurableAxis ConfV0TempFitVarBins{"ConfV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfV0TempFitVarMomentumBins{"ConfV0TempFitVarMomentumBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; @@ -57,6 +57,7 @@ struct femtoDreamDebugV0 { Configurable ConfV01_ChildPos_CutBit{"ConfV01_ChildPos_CutBit", 150, "Positive Child of V0 - Selection bit from cutCulator"}; Configurable ConfV01_ChildPos_TPCBit{"ConfV01_ChildPos_TPCBit", 4, "Positive Child of V0 - PID bit from cutCulator"}; + Configurable ConfV01_ChildNeg_CutBit{"ConfV01_ChildNeg_CutBit", 149, "Negative Child of V0 - PID bit from cutCulator"}; Configurable ConfV01_ChildNeg_TPCBit{"ConfV01_ChildNeg_TPCBit", 8, "Negative Child of V0 - PID bit from cutCulator"}; ConfigurableAxis ConfChildTempFitVarBins{"ConfChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis ConfChildTempFitVarpTBins{"ConfChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; @@ -79,7 +80,7 @@ struct femtoDreamDebugV0 { { eventHisto.init(&EventRegistry); posChildHistos.init(&V0Registry, ConfV0ChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_ChildPos_PDGCode.value, true); - negChildHistos.init(&V0Registry, ConfV0ChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_NegChild_PDGCode, true); + negChildHistos.init(&V0Registry, ConfV0ChildTempFitVarMomentumBins, ConfChildTempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_ChildNeg_PDGCode, true); V0Histos.init(&V0Registry, ConfV0TempFitVarMomentumBins, ConfV0TempFitVarBins, ConfV0ChildNsigmaTPCBins, ConfV0ChildNsigmaTOFBins, ConfV0ChildNsigmaTPCTOFBins, ConfV0InvMassBins, false, ConfV01_PDGCode.value, true); } @@ -107,7 +108,7 @@ struct femtoDreamDebugV0 { (posChild.cut() & ConfV01_ChildPos_CutBit) == ConfV01_ChildPos_CutBit && (posChild.pidcut() & ConfV01_ChildPos_TPCBit) == ConfV01_ChildPos_TPCBit && negChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kV0Child) && - (negChild.cut() & ConfV01_ChildNeg_TPCBit) == ConfV01_ChildNeg_TPCBit && + (negChild.cut() & ConfV01_ChildNeg_CutBit) == ConfV01_ChildNeg_CutBit && (negChild.pidcut() & ConfV01_ChildNeg_TPCBit) == ConfV01_ChildNeg_TPCBit) { V0Histos.fillQA(part, static_cast(ConfV0TempFitVarMomentum.value)); posChildHistos.fillQA(posChild, static_cast(ConfV0TempFitVarMomentum.value)); diff --git a/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx index 3a56b7bf907..25f08a71c2d 100644 --- a/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx @@ -259,7 +259,7 @@ struct femtoDreamProducerReducedTask { trackCuts.fillQA(track); // an array of two bit-wise containers of the systematic variations is obtained // one container for the track quality cuts and one for the PID cuts - auto cutContainer = trackCuts.getCutContainer(track); + auto cutContainer = trackCuts.getCutContainer(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f))); // now the table is filled outputParts(outputCollision.lastIndex(), diff --git a/PWGCF/FemtoDream/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/femtoDreamProducerTask.cxx index 58f7ca12545..a498340ee17 100644 --- a/PWGCF/FemtoDream/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/femtoDreamProducerTask.cxx @@ -390,7 +390,7 @@ struct femtoDreamProducerTask { } trackCuts.fillQA(track); // the bit-wise container of the systematic variations is obtained - auto cutContainer = trackCuts.getCutContainer(track); + auto cutContainer = trackCuts.getCutContainer(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f))); // now the table is filled outputParts(outputCollision.lastIndex(), @@ -442,12 +442,12 @@ struct femtoDreamProducerTask { rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); childIDs[0] = rowInPrimaryTrackTablePos; childIDs[1] = 0; - outputParts(outputCollision.lastIndex(), v0.positivept(), - v0.positiveeta(), v0.positivephi(), + outputParts(outputCollision.lastIndex(), + v0.positivept(), v0.positiveeta(), v0.positivephi(), aod::femtodreamparticle::ParticleType::kV0Child, cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kPosCuts), cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kPosPID), - 0., + postrack.dcaXY(), childIDs, 0, 0); @@ -467,7 +467,7 @@ struct femtoDreamProducerTask { aod::femtodreamparticle::ParticleType::kV0Child, cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kNegCuts), cutContainerV0.at(femtoDreamV0Selection::V0ContainerPosition::kNegPID), - 0., + negtrack.dcaXY(), childIDs, 0, 0); From e74c471eac9ca7a7b23def413464432bf11a58fd Mon Sep 17 00:00:00 2001 From: feisenhu <53603353+feisenhu@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:12:11 +0100 Subject: [PATCH 144/156] PWGEM: adjust TOF PID cut, momentum dependent (#4268) --- PWGDQ/Core/CutsLibrary.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 6f5d616e5e4..a3e84f500cc 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -3663,11 +3663,13 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) if (!nameStr.compare(Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data()))) { if (icase == 0) { cut->AddCut(VarManager::kTPCnSigmaEl, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); - cut->AddCut(VarManager::kTPCnSigmaPi, -99., 2.5, true, VarManager::kPin, 0.0, 1e+10, false); + cut->AddCut(VarManager::kTPCnSigmaPi, -99., 3., true, VarManager::kPin, 0.0, 4.0, false); + cut->AddCut(VarManager::kTPCnSigmaPi, -99., 2.5, true, VarManager::kPin, 4.0, 1e+10, false); cut->AddCut(VarManager::kTOFnSigmaEl, -4., 4., false, VarManager::kPin, 0.3, 1e+10, false); } else if (icase == 1 || icase == 2) { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); - cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -99., 2.5, true, VarManager::kPin, 0.0, 1e+10, false); + cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -99., 3., true, VarManager::kPin, 0.0, 4.0, false); + cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -99., 2.5, true, VarManager::kPin, 4.0, 1e+10, false); cut->AddCut(VarManager::kTOFnSigmaEl, -4., 4., false, VarManager::kPin, 0.3, 1e+10, false); } return cut; From ed306e1022ab40c39cc49daeb797e5734b5a1124 Mon Sep 17 00:00:00 2001 From: glromane <95305986+glromane@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:33:33 +0100 Subject: [PATCH 145/156] adding 3D k* calculation and new flags for mult./cent. (#4267) --- PWGCF/Femto3D/Core/femto3dPairTask.h | 33 +++ .../TableProducer/singleTrackSelector.cxx | 189 ++++++++++++++++-- PWGCF/Femto3D/Tasks/femto3dPairTask.cxx | 115 ++++++++--- PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx | 4 +- PWGCF/Femto3D/Tasks/femto3dQA.cxx | 4 +- 5 files changed, 298 insertions(+), 47 deletions(-) diff --git a/PWGCF/Femto3D/Core/femto3dPairTask.h b/PWGCF/Femto3D/Core/femto3dPairTask.h index c1ff8ecd3ed..7aef523d3f3 100755 --- a/PWGCF/Femto3D/Core/femto3dPairTask.h +++ b/PWGCF/Femto3D/Core/femto3dPairTask.h @@ -81,6 +81,20 @@ float GetKstarFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& secon //==================================================================================== +TVector3 Get3dKstarFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& second4momentum) +{ + TLorentzVector fourmomentasum = first4momentum + second4momentum; + first4momentum.Boost(0.0, 0.0, (-1) * fourmomentasum.BoostVector().Z()); // boost to LCMS + second4momentum.Boost(0.0, 0.0, (-1) * fourmomentasum.BoostVector().Z()); // boost to LCMS + + TVector3 qinv = first4momentum.Vect() - second4momentum.Vect(); + qinv.RotateZ((-1) * fourmomentasum.Phi()); // rotate so the X axis is along pair's kT + + return 0.5 * qinv; +} + +//==================================================================================== + template class FemtoPair { @@ -153,6 +167,7 @@ class FemtoPair return 1000; } float GetKstar() const; + TVector3 Get3dKstar() const; float GetKt() const; private: @@ -213,6 +228,24 @@ float FemtoPair::GetKstar() const return GetKstarFrom4vectors(first4momentum, second4momentum, _isidentical); } +template +TVector3 FemtoPair::Get3dKstar() const +{ + if (_first == NULL || _second == NULL) + return TVector3(-1000, -1000, -1000); + if (!(_magfield1 * _magfield2)) + return TVector3(-1000, -1000, -1000); + if (!(_PDG1 * _PDG2)) + return TVector3(-1000, -1000, -1000); + + TLorentzVector first4momentum; + first4momentum.SetPtEtaPhiM(_first->pt(), _first->eta(), _first->phi(), particle_mass(_PDG1)); + TLorentzVector second4momentum; + second4momentum.SetPtEtaPhiM(_second->pt(), _second->eta(), _second->phi(), particle_mass(_PDG2)); + + return Get3dKstarFrom4vectors(first4momentum, second4momentum); +} + template float FemtoPair::GetKt() const { diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx index 89b21efb5ff..78cff22588c 100755 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -49,10 +49,13 @@ struct singleTrackSelector { Configurable applyEvSel{"applyEvSel", 2, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"}; // Configurable trackSelection{"trackSelection", 1, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; + Configurable centTableToUse{"centTableToUse", 1, "Flag to choose cent./mult.perc. estimator (Run3 only [FTOC for PbPb; FTOM for pp], for Run2 the V0M is used): 0 -> CentFV0As, 1 -> CentFT0Ms, 2 -> CentFT0As, 3 -> CentFT0Cs, 4 -> CentFDDMs, 5 -> CentNTPVs"}; + Configurable multTableToUse{"multTableToUse", 1, "Flag to choose mult. estimator (Run3 only): 0 -> TPCMults, 1 -> MultNTracksPV, 2 -> MultNTracksPVeta1"}; + Configurable rejectNotPropagatedTrks{"rejectNotPropagatedTrks", true, "rejects tracks that are not propagated to the primary vertex"}; Configurable> _particlesToKeep{"particlesToKeepPDGs", std::vector{2212, 1000010020}, "PDG codes of perticles for which the 'singletrackselector' tables will be created (only proton and deurton are supported now)"}; Configurable> keepWithinNsigmaTPC{"keepWithinNsigmaTPC", std::vector{-4.0f, 4.0f}, "TPC range for preselection of particles specified with PDG"}; - Configurable> _particlesToReject{"particlesToRejectPDGs", std::vector{}, "PDG codes of perticles that will be rejected with TOF (only pion, kaon, proton and deurton are supported now)"}; + Configurable> _particlesToReject{"particlesToRejectPDGs", std::vector{211}, "PDG codes of particles that will be rejected with TOF (only pion, kaon, proton and deurton are supported now)"}; Configurable> rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-5.0f, 5.0f}, "TOF rejection Nsigma range for particles specified with PDG to be rejected"}; Configurable _min_P{"min_P", 0.f, "lower mometum limit"}; @@ -60,6 +63,7 @@ struct singleTrackSelector { Configurable _eta{"eta", 100.f, "abs eta value limit"}; Configurable _dcaXY{"dcaXY", 1000.f, "Maximum dca of track in xy"}; Configurable _dcaZ{"dcaZ", 1000.f, "Maximum dca of track in xy"}; + Configurable _maxTofChi2{"maxTofChi2", 10.f, "Maximum TOF Chi2 value -> to remove mismatched tracks"}; using Trks = soa::Join; - using Coll = soa::Join; + using CollRun2 = soa::Join; + using CollRun3 = soa::Join; Produces tableRow; Produces tableRowColl; @@ -84,6 +89,7 @@ struct singleTrackSelector { Filter pFilter = o2::aod::track::p > _min_P&& o2::aod::track::p < _max_P; Filter etaFilter = nabs(o2::aod::track::eta) < _eta; Filter dcaFilter = (o2::aod::track::dcaXY <= _dcaXY) && (o2::aod::track::dcaZ <= _dcaZ); + Filter tofChi2Filter = o2::aod::track::tofChi2 < _maxTofChi2; int mRunNumber = 0; float d_bz = 0.f; @@ -132,25 +138,20 @@ struct singleTrackSelector { d_bz = 0.1 * d_bz; } - template - inline void fillTheTables(Col collision, Trks const& tracks) + template + inline void fillTrackTables(Trks const& tracks) { bool skip_track = false; // flag used for track rejection - tableRowColl(collision.multTPC(), - collision.centFT0M(), - collision.posZ(), - d_bz); - for (auto& track : tracks) { if constexpr (isMC) { if (!track.has_mcParticle()) continue; } - skip_track = false; - if (Configurable{"rejectNotPropagatedTrks", true, "rejects tracks that are not propagated to the primary vertex"} && track.trackType() != aod::track::Track) { + if (rejectNotPropagatedTrks && track.trackType() != aod::track::Track) { continue; } + skip_track = false; for (auto i : particlesToReject) { // if satisfied, want to continue in the upper loop (over tracks) -- skip the current track // cannot use simple 'continue' since it will be applied to the current loop, so have to use a flag @@ -216,25 +217,179 @@ struct singleTrackSelector { } } - void processData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, aod::BCsWithTimestamps const&) + void processDataRun2(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, aod::BCsWithTimestamps const&) { + auto bc = collision.bc_as(); + initCCDB(bc); + + int multValue = -1; + + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } + + tableRowColl(multValue, + collision.centRun2V0M(), + collision.posZ(), + d_bz); + fillTrackTables(tracks); + } + PROCESS_SWITCH(singleTrackSelector, processDataRun2, "process data Run2", false); + + void processDataRun3(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, aod::BCsWithTimestamps const&) + { auto bc = collision.bc_as(); initCCDB(bc); - fillTheTables(collision, tracks); + float centValue = -100.0f; + int multValue = -1; + + switch (centTableToUse) { + case 0: + centValue = collision.centFV0A(); + break; + case 1: + centValue = collision.centFT0M(); + break; + case 2: + centValue = collision.centFT0A(); + break; + case 3: + centValue = collision.centFT0C(); + break; + case 4: + centValue = collision.centFDDM(); + break; + case 5: + centValue = collision.centNTPV(); + break; + default: + LOGF(fatal, "Invalid flag for cent./mult.perc. estimator has been choosen. Please check."); + break; + } + + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } + + tableRowColl(multValue, + centValue, + collision.posZ(), + d_bz); + + fillTrackTables(tracks); } - PROCESS_SWITCH(singleTrackSelector, processData, "process data", true); + PROCESS_SWITCH(singleTrackSelector, processDataRun3, "process data Run3", true); - void processMC(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles const&, aod::BCsWithTimestamps const&) + void processMCRun2(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles const&, aod::BCsWithTimestamps const&) { + auto bc = collision.bc_as(); + initCCDB(bc); + + int multValue = -1; + + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } + tableRowColl(multValue, + collision.centRun2V0M(), + collision.posZ(), + d_bz); + + fillTrackTables(tracks); + } + PROCESS_SWITCH(singleTrackSelector, processMCRun2, "process MC Run2", false); + + void processMCRun3(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles const&, aod::BCsWithTimestamps const&) + { auto bc = collision.bc_as(); initCCDB(bc); - fillTheTables(collision, tracks); + float centValue = -100.0f; + int multValue = -1; + + switch (centTableToUse) { + case 0: + centValue = collision.centFV0A(); + break; + case 1: + centValue = collision.centFT0M(); + break; + case 2: + centValue = collision.centFT0A(); + break; + case 3: + centValue = collision.centFT0C(); + break; + case 4: + centValue = collision.centFDDM(); + break; + case 5: + centValue = collision.centNTPV(); + break; + default: + LOGF(fatal, "Invalid flag for cent./mult.perc. estimator has been choosen. Please check."); + break; + } + + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } + + tableRowColl(multValue, + centValue, + collision.posZ(), + d_bz); + + fillTrackTables(tracks); } - PROCESS_SWITCH(singleTrackSelector, processMC, "process MC", false); + PROCESS_SWITCH(singleTrackSelector, processMCRun3, "process MC Run3", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx index d469eb78bf9..46608d09d75 100755 --- a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -57,13 +57,13 @@ struct FemtoCorrelations { Configurable _vertexZ{"VertexZ", 10.0, "abs vertexZ value limit"}; Configurable _sign_1{"sign_1", 1, "sign of the first particle in a pair"}; - Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only pion, kaon, proton and deurton are supported now)"}; Configurable> _tpcNSigma_1{"tpcNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TPC before the TOF is used"}; Configurable _PIDtrshld_1{"PIDtrshld_1", 10.0, "first particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; Configurable> _tofNSigma_1{"tofNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TOF"}; Configurable _sign_2{"sign_2", 1, "sign of the second particle in a pair"}; - Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only pion, kaon, proton and deurton are supported now)"}; Configurable> _tpcNSigma_2{"tpcNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TPC before the TOF is used"}; Configurable _PIDtrshld_2{"PIDtrshld_2", 10.0, "second particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; Configurable> _tofNSigma_2{"tofNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TOF"}; @@ -81,6 +81,9 @@ struct FemtoCorrelations { Configurable> _kTbins{"kTbins", std::vector{0.0f, 100.0f}, "pair transverse momentum kT binning"}; ConfigurableAxis CFkStarBinning{"CFkStarBinning", {500, 0.005, 5.005}, "k* binning of the CF (Nbins, lowlimit, uplimit)"}; + Configurable _fill3dCF{"fill3dCF", false, "flag for filling 3D LCMS histos: true -- fill; false -- not"}; + ConfigurableAxis CF3DkStarBinning{"CF3DkStarBinning", {100, -0.25, 0.25}, "k* binning of the CF 3D in LCMS (Nbins, lowlimit, uplimit)"}; + bool IsIdentical; std::pair> TPCcuts_1; @@ -117,8 +120,12 @@ struct FemtoCorrelations { std::vector> MultHistos; std::vector>> kThistos; - std::vector>> SEhistos; - std::vector>> MEhistos; + std::vector>> SEhistos_1D; + std::vector>> MEhistos_1D; + + std::vector>> SEhistos_3D; + std::vector>> MEhistos_3D; + std::vector>> kStarVSkStar3D; void init(o2::framework::InitContext&) { @@ -141,28 +148,44 @@ struct FemtoCorrelations { TPCcuts_2 = std::make_pair(_particlePDG_2, _tpcNSigma_2); TOFcuts_2 = std::make_pair(_particlePDG_2, _tofNSigma_2); - const AxisSpec kStarAxis{CFkStarBinning, "k* (GeV/c)"}; - for (int i = 0; i < _centBins.value.size() - 1; i++) { - std::vector> SEperMult; - std::vector> MEperMult; + std::vector> SEperMult_1D; + std::vector> MEperMult_1D; std::vector> kTperMult; - auto hMult = registry.add(Form("Cent%i/Mult_vs_cent%i", i, i), Form("Mult_vs_cent%i", i), kTH1F, {{5001, -0.5, 5000.5, "Nch"}}); + auto hMult = registry.add(Form("Cent%i/TPCMult_cent%i", i, i), Form("TPCMult_cent%i", i), kTH1F, {{5001, -0.5, 5000.5, "Mult."}}); MultHistos.push_back(std::move(hMult)); for (int j = 0; j < _kTbins.value.size() - 1; j++) { - auto hSE = registry.add(Form("Cent%i/SE_cent%i_kT%i", i, i, j), Form("SE_cent%i_kT%i", i, j), kTH1F, {kStarAxis}); - auto hME = registry.add(Form("Cent%i/ME_cent%i_kT%i", i, i, j), Form("ME_cent%i_kT%i", i, j), kTH1F, {kStarAxis}); + auto hSE_1D = registry.add(Form("Cent%i/SE_1D_cent%i_kT%i", i, i, j), Form("SE_1D_cent%i_kT%i", i, j), kTH1F, {{CFkStarBinning, "k* (GeV/c)"}}); + auto hME_1D = registry.add(Form("Cent%i/ME_1D_cent%i_kT%i", i, i, j), Form("ME_1D_cent%i_kT%i", i, j), kTH1F, {{CFkStarBinning, "k* (GeV/c)"}}); auto hkT = registry.add(Form("Cent%i/kT_cent%i_kT%i", i, i, j), Form("kT_cent%i_kT%i", i, j), kTH1F, {{500, 0., 5., "kT"}}); - SEperMult.push_back(std::move(hSE)); - MEperMult.push_back(std::move(hME)); + SEperMult_1D.push_back(std::move(hSE_1D)); + MEperMult_1D.push_back(std::move(hME_1D)); kTperMult.push_back(std::move(hkT)); } - SEhistos.push_back(std::move(SEperMult)); - MEhistos.push_back(std::move(MEperMult)); + SEhistos_1D.push_back(std::move(SEperMult_1D)); + MEhistos_1D.push_back(std::move(MEperMult_1D)); kThistos.push_back(std::move(kTperMult)); + + if (_fill3dCF) { + std::vector> SEperMult_3D; + std::vector> MEperMult_3D; + std::vector> kStarVSkStar3DperMult; + + for (int j = 0; j < _kTbins.value.size() - 1; j++) { + auto hSE_3D = registry.add(Form("Cent%i/SE_3D_cent%i_kT%i", i, i, j), Form("SE_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DkStarBinning, "k*_out (GeV/c)"}, {CF3DkStarBinning, "k*_side (GeV/c)"}, {CF3DkStarBinning, "k*_long (GeV/c)"}}); + auto hME_3D = registry.add(Form("Cent%i/ME_3D_cent%i_kT%i", i, i, j), Form("ME_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DkStarBinning, "k*_out (GeV/c)"}, {CF3DkStarBinning, "k*_side (GeV/c)"}, {CF3DkStarBinning, "k*_long (GeV/c)"}}); + auto hkStarVSkStar3D = registry.add(Form("Cent%i/kStarVSkStar3D_cent%i_kT%i", i, i, j), Form("kStarVSkStar3D_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DkStarBinning, "k*_out (GeV/c)"}, {CF3DkStarBinning, "k*_side (GeV/c)"}, {CF3DkStarBinning, "k*_long (GeV/c)"}}); + SEperMult_3D.push_back(std::move(hSE_3D)); + MEperMult_3D.push_back(std::move(hME_3D)); + kStarVSkStar3DperMult.push_back(std::move(hkStarVSkStar3D)); + } + SEhistos_3D.push_back(std::move(SEperMult_3D)); + MEhistos_3D.push_back(std::move(MEperMult_3D)); + kStarVSkStar3D.push_back(std::move(kStarVSkStar3DperMult)); + } } registry.add("p_first", Form("p_%i", static_cast(_particlePDG_1)), kTH1F, {{100, 0., 5., "p"}}); @@ -178,8 +201,14 @@ struct FemtoCorrelations { template void mixTracks(Type const& tracks, int multBin) { // template for identical particles from the same collision - if (multBin < 0 && multBin > SEhistos.size()) - LOGF(fatal, "multBin value passed to the mixTracks function is less than 0 or exceeds the configured number of Cent. bins"); + if (multBin >= 0) { + if (multBin > SEhistos_1D.size()) + LOGF(fatal, "multBin value passed to the mixTracks function exceeds the configured number of Cent. bins (1D)"); + if (_fill3dCF && multBin > SEhistos_3D.size()) + LOGF(fatal, "multBin value passed to the mixTracks function exceeds the configured number of Cent. bins (3D)"); + } else { + LOGF(fatal, "multBin value passed to the mixTracks function is less than 0"); + } for (int ii = 0; ii < tracks.size(); ii++) { // nested loop for all the combinations for (int iii = ii + 1; iii < tracks.size(); iii++) { @@ -187,12 +216,23 @@ struct FemtoCorrelations { Pair->SetPair(tracks[ii], tracks[iii]); float pair_kT = Pair->GetKt(); int kTbin = o2::aod::singletrackselector::getBinIndex(pair_kT, _kTbins); - if (kTbin < 0 && kTbin > SEhistos[multBin].size()) - LOGF(fatal, "kTbin value obtained for a pair is less than 0 or exceeds the configured number of kT bins"); + if (kTbin >= 0) { + if (kTbin > SEhistos_1D[multBin].size()) + LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins (1D)"); + if (_fill3dCF && kTbin > SEhistos_3D[multBin].size()) + LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins (3D)"); + } else { + LOGF(fatal, "kTbin value obtained for a pair is less than 0"); + } if (!Pair->IsClosePair(_deta, _dphi, _radiusTPC)) { kThistos[multBin][kTbin]->Fill(pair_kT); - SEhistos[multBin][kTbin]->Fill(Pair->GetKstar()); // close pair rejection and fillig the SE histo + SEhistos_1D[multBin][kTbin]->Fill(Pair->GetKstar()); // close pair rejection and fillig the SE histo + + if (_fill3dCF) { + TVector3 KstarLCMS = Pair->Get3dKstar(); + SEhistos_3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z()); + } } Pair->ResetPair(); } @@ -202,8 +242,14 @@ struct FemtoCorrelations { template void mixTracks(Type const& tracks1, Type const& tracks2, int multBin) { // last value: 0 -- SE; 1 -- ME - if (multBin < 0 && multBin > SEhistos.size()) - LOGF(fatal, "multBin value passed to the mixTracks function is less than 0 or exceeds the configured number of Cent. bins"); + if (multBin >= 0) { + if (multBin > SEhistos_1D.size()) + LOGF(fatal, "multBin value passed to the mixTracks function exceeds the configured number of Cent. bins (1D)"); + if (_fill3dCF && multBin > SEhistos_3D.size()) + LOGF(fatal, "multBin value passed to the mixTracks function exceeds the configured number of Cent. bins (3D)"); + } else { + LOGF(fatal, "multBin value passed to the mixTracks function is less than 0"); + } for (auto ii : tracks1) { for (auto iii : tracks2) { @@ -211,15 +257,32 @@ struct FemtoCorrelations { Pair->SetPair(ii, iii); float pair_kT = Pair->GetKt(); int kTbin = o2::aod::singletrackselector::getBinIndex(pair_kT, _kTbins); - if (kTbin < 0 && kTbin > SEhistos[multBin].size()) - LOGF(fatal, "kTbin value obtained for a pair is less than 0 or exceeds the configured number of kT bins"); + if (kTbin >= 0) { + if (kTbin > SEhistos_1D[multBin].size()) + LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins (1D)"); + if (_fill3dCF && kTbin > SEhistos_3D[multBin].size()) + LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins (3D)"); + } else { + LOGF(fatal, "kTbin value obtained for a pair is less than 0"); + } if (!Pair->IsClosePair(_deta, _dphi, _radiusTPC)) { if (!SE_or_ME) { - SEhistos[multBin][kTbin]->Fill(Pair->GetKstar()); + SEhistos_1D[multBin][kTbin]->Fill(Pair->GetKstar()); kThistos[multBin][kTbin]->Fill(pair_kT); + + if (_fill3dCF) { + TVector3 KstarLCMS = Pair->Get3dKstar(); + SEhistos_3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z()); + } } else { - MEhistos[multBin][kTbin]->Fill(Pair->GetKstar()); + MEhistos_1D[multBin][kTbin]->Fill(Pair->GetKstar()); + + if (_fill3dCF) { + TVector3 KstarLCMS = Pair->Get3dKstar(); + MEhistos_3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z()); + kStarVSkStar3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z(), Pair->GetKstar()); + } } } Pair->ResetPair(); diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx index 882a1e2221f..9fbec4f8156 100755 --- a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -57,13 +57,13 @@ struct FemtoCorrelationsMC { Configurable _vertexZ{"VertexZ", 10.0, "abs vertexZ value limit"}; Configurable _sign_1{"sign_1", 1, "sign of the first particle in a pair"}; - Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only pion, kaon, proton and deurton are supported now)"}; Configurable> _tpcNSigma_1{"tpcNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TPC before the TOF is used"}; Configurable _PIDtrshld_1{"PIDtrshld_1", 10.0, "first particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; Configurable> _tofNSigma_1{"tofNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TOF"}; Configurable _sign_2{"sign_2", 1, "sign of the second particle in a pair"}; - Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only pion, kaon, proton and deurton are supported now)"}; Configurable> _tpcNSigma_2{"tpcNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TPC before the TOF is used"}; Configurable _PIDtrshld_2{"PIDtrshld_2", 10.0, "second particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; Configurable> _tofNSigma_2{"tofNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TOF"}; diff --git a/PWGCF/Femto3D/Tasks/femto3dQA.cxx b/PWGCF/Femto3D/Tasks/femto3dQA.cxx index d652d4d0d3f..671f2049f24 100755 --- a/PWGCF/Femto3D/Tasks/femto3dQA.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dQA.cxx @@ -53,12 +53,12 @@ struct QAHistograms { Configurable _tpcNClsShared{"maxTpcNClsShared", 0, "maximum allowed number of TPC shared clasters"}; Configurable _itsNCls{"minItsNCls", 0, "minimum allowed number of ITS clasters for a track"}; Configurable _itsChi2NCl{"itsChi2NCl", 100.0, "upper limit for chi2 value of a fit over ITS clasters for a track"}; - Configurable _particlePDG{"particlePDG", 2212, "PDG code of a particle to perform PID for (only proton and deurton are supported now)"}; + Configurable _particlePDG{"particlePDG", 2212, "PDG code of a particle to perform PID for (only pion, kaon, proton and deurton are supported now)"}; Configurable> _tpcNSigma{"tpcNSigma", std::vector{-4.0f, 4.0f}, "Nsigma range in TPC before the TOF is used"}; Configurable _PIDtrshld{"PIDtrshld", 10.0, "value of momentum from which the PID is done with TOF (before that only TPC is used)"}; Configurable> _tofNSigma{"tofNSigma", std::vector{-4.0f, 4.0f}, "Nsigma range in TOF"}; - Configurable _particlePDGtoReject{"particlePDGtoReject", 211, "PDG codes of perticles that will be rejected with TOF (only proton and deurton are supported now)"}; + Configurable _particlePDGtoReject{"particlePDGtoReject", 211, "PDG codes of perticles that will be rejected with TOF (only pion, kaon, proton and deurton are supported now)"}; Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for particles specified with PDG to be rejected"}; std::pair> TPCcuts; From 4acbc4ae6d57a12c98d62fc4922813a01098051d Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Wed, 10 Jan 2024 20:38:04 +0100 Subject: [PATCH 146/156] DPG/AOTTrack: add task for efficiency evaluation with tag-and-probe with D mesons (#4247) * Initial commit for tag and probe with D mesons * Complete struct for tag * Fix filters * Add struct to test the probe * Please consider the following formatting changes * Fix typo * Add newline at the end * Fix the possibility to run all the channels in one go * Add possibility to apply mass cuts in tagging * Minor details --------- Co-authored-by: ALICE Action Bot --- DPG/Tasks/AOTTrack/CMakeLists.txt | 5 + DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx | 720 ++++++++++++++++++++++ 2 files changed, 725 insertions(+) create mode 100644 DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx diff --git a/DPG/Tasks/AOTTrack/CMakeLists.txt b/DPG/Tasks/AOTTrack/CMakeLists.txt index 866dfbc5546..91e7ad91313 100644 --- a/DPG/Tasks/AOTTrack/CMakeLists.txt +++ b/DPG/Tasks/AOTTrack/CMakeLists.txt @@ -59,3 +59,8 @@ o2physics_add_dpl_workflow(qa-prim-vtx-vs-time SOURCES qaPrimVtxVsTime.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(tag-and-probe-dmesons + SOURCES tagAndProbeDmesons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) diff --git a/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx b/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx new file mode 100644 index 00000000000..47d6cb9f2ab --- /dev/null +++ b/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx @@ -0,0 +1,720 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file tagAndProbeDmesons.cxx +/// \brief Task for tracking efficiency studies with tag-and-probe using 3-prong D-meson decays +/// +/// \author Fabrizio Grosa , CERN + +#include "CCDB/BasicCCDBManager.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DCAFitter/DCAFitterN.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/Core/TrackSelection.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace o2::aod +{ +namespace tagandprobe +{ +enum TagChannels : uint8_t { + DplusToKPiPi = 0, + DsOrDplusToKKPi, + DstarPlusToDzeroPi, + DstarMinusToDzeroBarPi, + NTagChannels +}; + +enum TrackTypes : uint8_t { + GlobalWoDca = 0, + GlobalWoDcaWoIts, + GlobalWoDcaWoTpc, + NTrackTypes +}; + +static constexpr int nBinsPt = 7; +static constexpr int nCutVars = 6; +static constexpr int nCutVarsDzero = 9; +constexpr float binsPt[nBinsPt + 1] = {0., 1., 2., 4., 6., 10., 20., 1000.}; +auto vecBinsPt = std::vector{binsPt, binsPt + nBinsPt + 1}; + +// default values for the cuts +constexpr float cuts[nBinsPt][nCutVars] = {{0.1f, 1.5f, 0.01f, 0.01f, 2.f, 2.f}, + {0.1f, 1.5f, 0.01f, 0.01f, 2.f, 2.f}, + {0.1f, 1.5f, 0.02f, 0.02f, 2.f, 2.f}, + {0.1f, 1.5f, 0.02f, 0.02f, 2.f, 2.f}, + {0.1f, 1.5f, 0.04f, 0.04f, 2.f, 2.f}, + {0.1f, 1.5f, 0.04f, 0.04f, 2.f, 2.f}, + {0.1f, 1.5f, 0.06f, 0.06f, 2.f, 2.f}}; + +constexpr float cutsDzero[nBinsPt][nCutVarsDzero] = {{1.815f, 1.915f, 0.01f, 0.01f, 2.f, 2.f, 0.f, 0.90f, 0.90f}, + {1.815f, 1.915f, 0.01f, 0.01f, 2.f, 2.f, 0.f, 0.90f, 0.90f}, + {1.815f, 1.915f, 0.02f, 0.02f, 2.f, 2.f, 0.f, 0.90f, 0.90f}, + {1.815f, 1.915f, 0.02f, 0.02f, 2.f, 2.f, 0.f, 0.90f, 0.90f}, + {1.815f, 1.915f, 0.04f, 0.04f, 2.f, 2.f, 0.f, 0.95f, 0.95f}, + {1.815f, 1.915f, 0.04f, 0.04f, 2.f, 2.f, 0.f, 0.95f, 0.95f}, + {1.815f, 1.915f, 0.06f, 0.06f, 2.f, 2.f, 0.f, 0.95f, 0.95f}}; + +static const std::vector labelsPt{}; +static const std::vector labelsCutVar = {"minMass", "maxMass", "decayLength", "decayLengthXY", "normDecayLength", "normDecayLengthXY"}; +static const std::vector labelsCutVarDzero = {"minMass", "maxMass", "decayLength", "decayLengthXY", "normDecayLength", "normDecayLengthXY", "impParProd", "cosPointing", "cosPointingXY"}; + +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! Collision index +DECLARE_SOA_INDEX_COLUMN_FULL(Track0, track0, int, Tracks, "_0"); //! Index to first track +DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, Tracks, "_1"); //! Index to second track +} // namespace tagandprobe + +DECLARE_SOA_TABLE(PiPiFromDpTags, "AOD", "PIPIFROMDPTAG", //! Table for same sign 2-pion vertices used as tags + soa::Index<>, + aod::tagandprobe::CollisionId, + aod::tagandprobe::Track0Id, + aod::tagandprobe::Track1Id); +DECLARE_SOA_TABLE(KaKaFromDspTags, "AOD", "KAKAFROMDSPTAG", //! Table for opposite sign 2-kaon vertices used as tags + soa::Index<>, + aod::tagandprobe::CollisionId, + aod::tagandprobe::Track0Id, + aod::tagandprobe::Track1Id, + soa::Marker<1>); +DECLARE_SOA_TABLE(PiKaFromDzTags, "AOD", "PIKAFROMDZTAG", //! Table for opposite sign pion(+)-kaon(-) vertices used as tags + soa::Index<>, + aod::tagandprobe::CollisionId, + aod::tagandprobe::Track0Id, + aod::tagandprobe::Track1Id, + soa::Marker<2>); +DECLARE_SOA_TABLE(KaPiFromDzTags, "AOD", "KAPIFROMDZTAG", //! Table for opposite sign kaon(+)-pion(-) vertices used as tags + soa::Index<>, + aod::tagandprobe::CollisionId, + aod::tagandprobe::Track0Id, + aod::tagandprobe::Track1Id, + soa::Marker<3>); +} // namespace o2::aod + +/// Reconstruction of 2-prong displaced vertices (very good quality and purity) +/// 1) K∓K± for φ from Ds± or D± → φπ± decays +/// 2) π±π± for D± → K∓π±π± decays +/// 3) K∓π± for D0 from D±* → D0π± decays +struct TagTwoProngDisplacedVertices { + + Produces tagPiPiTable; + Produces tagKaKaTable; + Produces tagKaPiTable; + Produces tagPiKaTable; + SliceCache cache; + + Configurable applyTofPid{"applyTofPid", true, "flag to enable TOF PID selection"}; + Configurable trackNumSigmaTof{"trackNumSigmaTof", 3.f, "number of sigma for TOF PID compatibility"}; + Configurable trackNumSigmaTpc{"trackNumSigmaTpc", 3.f, "number of sigma for TOF PID compatibility"}; + Configurable trackDcaXyMin{"trackDcaXyMin", 0.002f, "minimum DCAxy for tracks with pT < 2 GeV/c"}; + Configurable trackPtMin{"trackPtMin", 0.4f, "minimum track pT"}; + + Configurable> binsPtPiPiFromDplus{"binsPtPiPiFromDplus", std::vector{aod::tagandprobe::vecBinsPt}, "pT bin limits for pipi pairs from D+ decays"}; + Configurable> binsKaKaFromDsOrDplus{"binsKaKaFromDsOrDplus", std::vector{aod::tagandprobe::vecBinsPt}, "pT bin limits for KK pairs from Ds or D+ decays"}; + Configurable> binsPtDzeroFromDstar{"binsPtDzeroFromDstar", std::vector{aod::tagandprobe::vecBinsPt}, "pT bin limits for Kpi pairs from D0 <- D*+ decays"}; + + Configurable> cutsPiPiFromDplus{"cutsPiPiFromDplus", {aod::tagandprobe::cuts[0], aod::tagandprobe::nBinsPt, aod::tagandprobe::nCutVars, aod::tagandprobe::labelsPt, aod::tagandprobe::labelsCutVar}, "Selections for pipi pairs from D+ decays"}; + Configurable> cutsKaKaFromDsOrDplus{"cutsKaKaFromDsOrDplus", {aod::tagandprobe::cuts[0], aod::tagandprobe::nBinsPt, aod::tagandprobe::nCutVars, aod::tagandprobe::labelsPt, aod::tagandprobe::labelsCutVar}, "Selections for KK pairs from Ds or D+ decays"}; + Configurable> cutsDzeroFromDstar{"cutsDzeroFromDstar", {aod::tagandprobe::cutsDzero[0], aod::tagandprobe::nBinsPt, aod::tagandprobe::nCutVarsDzero, aod::tagandprobe::labelsPt, aod::tagandprobe::labelsCutVarDzero}, "Selections for Kpi pairs from D0 <- D*+ decays"}; + + using TracksWithSelAndDca = soa::Join; + using CollisionsWithEvSel = soa::Join; + + Filter evSelFilter = aod::evsel::sel8 == true; // simple event selection + Filter collisionFilter = nabs(aod::collision::posZ) < 10.f; // simple event selection + Filter trackFilter = requireGlobalTrackWoDCAInFilter() && aod::track::pt > trackPtMin && (nabs(aod::track::dcaXY) > trackDcaXyMin || aod::track::pt > 2.f); // for the tag, we only consider global tracks with large dcaXY (low pT only) + using TracksWithSelAndDcaFiltered = soa::Filtered; + using CollisionsFiltered = soa::Filtered; + + // in the partition we only apply TPC PID + Preslice perCollision = aod::track::collisionId; + Partition positivePions = aod::track::signed1Pt > 0.f && nabs(aod::pidtpc::tpcNSigmaPi) < trackNumSigmaTpc; + Partition negativePions = aod::track::signed1Pt < 0.f && nabs(aod::pidtpc::tpcNSigmaPi) < trackNumSigmaTpc; + Partition positiveKaons = aod::track::signed1Pt > 0.f && nabs(aod::pidtpc::tpcNSigmaKa) < trackNumSigmaTpc; + Partition negativeKaons = aod::track::signed1Pt < 0.f && nabs(aod::pidtpc::tpcNSigmaKa) < trackNumSigmaTpc; + + ccdb::CcdbApi ccdbApi; + Service ccdb; + vertexing::DCAFitterN<2> vertexer; + int runNumber{0}; + + std::array, aod::tagandprobe::TagChannels::NTagChannels> masses = {std::array{constants::physics::MassPionCharged, constants::physics::MassPionCharged}, + std::array{constants::physics::MassKaonCharged, constants::physics::MassKaonCharged}, + std::array{constants::physics::MassPionCharged, constants::physics::MassKaonCharged}, + std::array{constants::physics::MassKaonCharged, constants::physics::MassPionCharged}}; + + std::array, aod::tagandprobe::TagChannels::NTagChannels> topologicalCuts{}; + std::array, aod::tagandprobe::TagChannels::NTagChannels> ptBinsForTopologicalCuts{}; + + HistogramRegistry registry{"registry"}; + + void init(InitContext&) + { + std::string ccdbUrl = "http://alice-ccdb.cern.ch"; + ccdb->setURL(ccdbUrl.data()); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdbUrl.data()); + + vertexer.setPropagateToPCA(true); + vertexer.setMaxR(200.f); + vertexer.setMaxDZIni(4.f); + vertexer.setMinParamChange(1.e-3); + vertexer.setMinRelChi2Change(0.9f); + vertexer.setUseAbsDCA(false); + + topologicalCuts = {cutsPiPiFromDplus, cutsKaKaFromDsOrDplus, cutsDzeroFromDstar, cutsDzeroFromDstar}; + ptBinsForTopologicalCuts = {binsPtPiPiFromDplus, binsKaKaFromDsOrDplus, binsPtDzeroFromDstar, binsPtDzeroFromDstar}; + + const AxisSpec axisPt{250, 0.f, 50.f}; + const AxisSpec axisMassPiPi{280, 0.1f, 1.5f}; + const AxisSpec axisMassKaKa{200, constants::physics::MassPhi - 0.04f, constants::physics::MassPhi + 0.04f}; + const AxisSpec axisMassKaPi{200, constants::physics::MassD0 - 0.05f, constants::physics::MassD0 + 0.05f}; + + if (doprocessPiPiFromDplus) { + registry.add("hMassPiPiVsPt", ";#it{p}_{T}(#pi#pi) (GeV/#it{c}); #it{M}(#pi#pi) (GeV/#it{c}^{2})", HistType::kTH2D, {axisPt, axisMassPiPi}); + } + if (doprocessKaKaFromDsOrDplus) { + registry.add("hMassKaKaVsPt", ";#it{p}_{T}(KK) (GeV/#it{c}); #it{M}(KK) (GeV/#it{c}^{2})", HistType::kTH2D, {axisPt, axisMassKaKa}); + } + if (doprocessKaPiFromDstar) { + registry.add("hMassKaPiVsPt", ";#it{p}_{T}(K#pi) (GeV/#it{c}); #it{M}(K#pi) (GeV/#it{c}^{2})", HistType::kTH2D, {axisPt, axisMassKaPi}); + } + } + + /// Finds pT bin in an array. + /// \param bins array of pT bins + /// \param value pT + /// \return index of the pT bin + template + int findBin(T1 const& binsPt, T2 value) + { + if (value < binsPt->front()) { + return -1; + } + if (value >= binsPt->back()) { + return -1; + } + return std::distance(binsPt->begin(), std::upper_bound(binsPt->begin(), binsPt->end(), value)) - 1; + } + + template + bool isSelectedInvariantMass(const Pvec& pVecTrackFirst, + const Pvec& pVecTrackSecond, + const uint8_t channel, + float& invMass2) + { + auto arrMomentum = std::array{pVecTrackFirst, pVecTrackSecond}; + auto pVec = RecoDecay::pVec(pVecTrackFirst, pVecTrackSecond); + auto ptBin = findBin(&ptBinsForTopologicalCuts[channel], RecoDecay::pt(pVec)); + if (ptBin == -1) { + return false; + } + + auto invMassMin = topologicalCuts[channel].get(ptBin, 0u); + auto invMassMax = topologicalCuts[channel].get(ptBin, 1u); + invMass2 = RecoDecay::m2(arrMomentum, masses[channel]); + if (invMass2 > invMassMax * invMassMax || invMass2 < invMassMin * invMassMin) { + return false; + } + return true; + } + + template + bool isSelectedPidTof(const TTrack& track, + const uint8_t channel) + { + if (!track.hasTOF()) { // TOF not forced anyway + return true; + } + + switch (channel) { + case aod::tagandprobe::TagChannels::DplusToKPiPi: { + if (std::abs(track.tofNSigmaPi()) < trackNumSigmaTof) { + return true; + } + } + case aod::tagandprobe::TagChannels::DsOrDplusToKKPi: { + if (std::abs(track.tofNSigmaKa()) < trackNumSigmaTof) { + return true; + } + } + case aod::tagandprobe::TagChannels::DstarPlusToDzeroPi: { + if ((track.signed1Pt() > 0 && std::abs(track.tofNSigmaPi()) < trackNumSigmaTof) || (track.signed1Pt() < 0 && std::abs(track.tofNSigmaKa()) < trackNumSigmaTof)) { + return true; + } + } + case aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi: { + if ((track.signed1Pt() < 0 && std::abs(track.tofNSigmaPi()) < trackNumSigmaTof) || (track.signed1Pt() > 0 && std::abs(track.tofNSigmaKa()) < trackNumSigmaTof)) { + return true; + } + } + } + return false; + } + + template + bool isSelectedTopology(const PV& primVtx, + const SV& secVtx, + const CovMatSV& covMatrixSecVtx, + const PVec& pVec, + std::array& trackDcaXy, + const uint8_t channel) + { + + auto ptBin = findBin(&ptBinsForTopologicalCuts[channel], RecoDecay::pt(pVec)); + if (ptBin == -1) { + return false; + } + + std::array pvCoord = {primVtx.getX(), primVtx.getY(), primVtx.getZ()}; + auto decLen = RecoDecay::distance(pvCoord, secVtx); + if (decLen < topologicalCuts[channel].get(ptBin, 2u)) { + return false; + } + + auto covMatrixPV = primVtx.getCov(); + + auto decLenXy = RecoDecay::distanceXY(pvCoord, secVtx); + if (decLenXy < topologicalCuts[channel].get(ptBin, 3u)) { + return false; + } + + float phi, theta; + getPointDirection(pvCoord, secVtx, phi, theta); + auto errorDecLen = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixSecVtx, phi, theta)); + if (decLen / errorDecLen < topologicalCuts[channel].get(ptBin, 4u)) { + return false; + } + + auto errorDecLenXy = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.f) + getRotatedCovMatrixXX(covMatrixSecVtx, phi, 0.f)); + if (decLenXy / errorDecLenXy < topologicalCuts[channel].get(ptBin, 5u)) { + return false; + } + + // only for D0 meson + if (channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi || channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi) { + if (trackDcaXy[0] * trackDcaXy[1] > topologicalCuts[channel].get(ptBin, 6u)) { + return false; + } + auto cpa = RecoDecay::cpa(pvCoord, secVtx, pVec); + if (cpa < topologicalCuts[channel].get(ptBin, 7u)) { + return false; + } + auto cpaXy = RecoDecay::cpaXY(pvCoord, secVtx, pVec); + if (cpaXy < topologicalCuts[channel].get(ptBin, 8u)) { + return false; + } + } + + return true; + } + + template + void computeCombinatorialSameCharge(CCollision const& collision, + TTracks const& tracks, // pool of tracks + const uint8_t channel, + float& bz) + { + for (auto trackFirst = tracks.begin(); trackFirst != tracks.end(); ++trackFirst) { + + if (applyTofPid && !isSelectedPidTof(trackFirst, channel)) { + continue; + } + + for (auto trackSecond = trackFirst + 1; trackSecond != tracks.end(); ++trackSecond) { + + if (applyTofPid && !isSelectedPidTof(trackSecond, channel)) { + continue; + } + + float invMass2{0.f}; + std::array pVecTrackFirst{trackFirst.px(), trackFirst.py(), trackFirst.pz()}; + std::array pVecTrackSecond{trackSecond.px(), trackSecond.py(), trackSecond.pz()}; + + if (!isSelectedInvariantMass(pVecTrackFirst, pVecTrackSecond, channel, invMass2)) { + continue; + } + + auto trackParCovFirst = getTrackParCov(trackFirst); + auto trackParCovSecond = getTrackParCov(trackSecond); + + int nVertices{0}; + try { + nVertices = vertexer.process(trackParCovFirst, trackParCovSecond); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call!"; + continue; + } + if (nVertices == 0) { + continue; + } + + auto pVec = RecoDecay::pVec(pVecTrackFirst, pVecTrackSecond); + auto primVtx = getPrimaryVertex(collision); + const auto& secVtx = vertexer.getPCACandidate(); + const auto& covMatrixPCA = vertexer.calcPCACovMatrixFlat(); + std::array trackDcaXy{trackFirst.dcaXY(), trackSecond.dcaXY()}; + if (!isSelectedTopology(primVtx, secVtx, covMatrixPCA, pVec, trackDcaXy, channel)) { + continue; + } + + registry.fill(HIST("hMassPiPiVsPt"), RecoDecay::pt(pVec), std::sqrt(invMass2)); // only channel with same sign tracks for the moment + tagPiPiTable(trackFirst.collisionId(), trackFirst.globalIndex(), trackSecond.globalIndex()); + } + } + } + + template + void computeCombinatorialOppositeCharge(CCollision const& collision, + TTracks const& tracksPos, + TTracks const& tracksNeg, + const uint8_t channel, + float& bz) + { + for (const auto& trackPos : tracksPos) { + + if (applyTofPid && !isSelectedPidTof(trackPos, channel)) { + continue; + } + + for (const auto& trackNeg : tracksNeg) { + + if (applyTofPid && !isSelectedPidTof(trackNeg, channel)) { + continue; + } + + float invMass2{0.f}; + std::array pVecTrackPos{trackPos.px(), trackPos.py(), trackPos.pz()}; + std::array pVecTrackNeg{trackNeg.px(), trackNeg.py(), trackNeg.pz()}; + if (!isSelectedInvariantMass(pVecTrackPos, pVecTrackNeg, channel, invMass2)) { + continue; + } + + auto trackParCovPos = getTrackParCov(trackPos); + auto trackParCovNeg = getTrackParCov(trackNeg); + + int nVertices{0}; + try { + nVertices = vertexer.process(trackParCovPos, trackParCovNeg); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call!"; + continue; + } + if (nVertices == 0) { + continue; + } + + auto pVec = RecoDecay::pVec(pVecTrackPos, pVecTrackNeg); + auto primVtx = getPrimaryVertex(collision); + const auto& secVtx = vertexer.getPCACandidate(); + const auto& covMatrixPCA = vertexer.calcPCACovMatrixFlat(); + std::array trackDcaXy{trackPos.dcaXY(), trackNeg.dcaXY()}; + if (!isSelectedTopology(primVtx, secVtx, covMatrixPCA, pVec, trackDcaXy, channel)) { + continue; + } + + if (channel == aod::tagandprobe::TagChannels::DsOrDplusToKKPi) { + registry.fill(HIST("hMassKaKaVsPt"), RecoDecay::pt(pVec), std::sqrt(invMass2)); + tagKaKaTable(trackPos.collisionId(), trackPos.globalIndex(), trackNeg.globalIndex()); + } else if (channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi) { + registry.fill(HIST("hMassKaPiVsPt"), RecoDecay::pt(pVec), std::sqrt(invMass2)); + tagPiKaTable(trackPos.collisionId(), trackPos.globalIndex(), trackNeg.globalIndex()); + } else if (channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi) { + registry.fill(HIST("hMassKaPiVsPt"), RecoDecay::pt(pVec), std::sqrt(invMass2)); + tagKaPiTable(trackPos.collisionId(), trackPos.globalIndex(), trackNeg.globalIndex()); + } + } + } + } + + void processPiPiFromDplus(CollisionsFiltered::iterator const& collision, + TracksWithSelAndDcaFiltered const& tracks, + aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + float bz{0}; + if (runNumber != bc.runNumber()) { + parameters::GRPMagField* grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", bc.timestamp()); + if (grpo != nullptr) { + base::Propagator::initFieldFromGRP(grpo); + bz = base::Propagator::Instance()->getNominalBz(); + } else { + LOGF(fatal, "GRP object is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + runNumber = bc.runNumber(); + } + + auto groupPositive = positivePions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + computeCombinatorialSameCharge(collision, groupPositive, aod::tagandprobe::TagChannels::DplusToKPiPi, bz); + + auto groupNegative = negativePions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + computeCombinatorialSameCharge(collision, groupNegative, aod::tagandprobe::TagChannels::DplusToKPiPi, bz); + } + PROCESS_SWITCH(TagTwoProngDisplacedVertices, processPiPiFromDplus, "Process pipi combinatorial to tag pion pairs from D+ decays", true); + + void processKaKaFromDsOrDplus(CollisionsFiltered::iterator const& collision, + TracksWithSelAndDcaFiltered const& tracks, + aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + float bz{0}; + if (runNumber != bc.runNumber()) { + parameters::GRPMagField* grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", bc.timestamp()); + if (grpo != nullptr) { + base::Propagator::initFieldFromGRP(grpo); + bz = base::Propagator::Instance()->getNominalBz(); + } else { + LOGF(fatal, "GRP object is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + runNumber = bc.runNumber(); + } + + auto groupPositive = positiveKaons->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto groupNegative = negativeKaons->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + computeCombinatorialOppositeCharge(collision, groupPositive, groupNegative, aod::tagandprobe::TagChannels::DsOrDplusToKKPi, bz); + } + PROCESS_SWITCH(TagTwoProngDisplacedVertices, processKaKaFromDsOrDplus, "Process KK combinatorial to tag kaon pairs from Ds+/D+ decays", false); + + void processKaPiFromDstar(CollisionsFiltered::iterator const& collision, + TracksWithSelAndDcaFiltered const& tracks, + aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + float bz{0}; + if (runNumber != bc.runNumber()) { + parameters::GRPMagField* grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", bc.timestamp()); + if (grpo != nullptr) { + base::Propagator::initFieldFromGRP(grpo); + bz = base::Propagator::Instance()->getNominalBz(); + } else { + LOGF(fatal, "GRP object is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + runNumber = bc.runNumber(); + } + + auto groupPionPositive = positivePions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto groupPionNegative = negativePions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto groupKaonPositive = positiveKaons->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto groupKaonNegative = negativeKaons->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + computeCombinatorialOppositeCharge(collision, groupPionPositive, groupKaonNegative, aod::tagandprobe::TagChannels::DstarPlusToDzeroPi, bz); + computeCombinatorialOppositeCharge(collision, groupKaonPositive, groupPionNegative, aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi, bz); + } + PROCESS_SWITCH(TagTwoProngDisplacedVertices, processKaPiFromDstar, "Process Kpi combinatorial to tag D0 from D*+ decays", false); +}; + +/// Probe third track reconstruction efficiency with different selections +struct ProbeThirdTrack { + + using TracksWithSelAndDca = soa::Join; + + Preslice tagsPiPiPerCollision = aod::tagandprobe::collisionId; + Preslice tagsKaKaPerCollision = aod::tagandprobe::collisionId; + Preslice tagsPiKaPerCollision = aod::tagandprobe::collisionId; + Preslice tagsKaPiPerCollision = aod::tagandprobe::collisionId; + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + + std::array, aod::tagandprobe::TagChannels::NTagChannels> masses = {std::array{constants::physics::MassPionCharged, constants::physics::MassPionCharged, constants::physics::MassKaonCharged}, + std::array{constants::physics::MassKaonCharged, constants::physics::MassKaonCharged, constants::physics::MassPionCharged}, + std::array{constants::physics::MassPionCharged, constants::physics::MassKaonCharged, constants::physics::MassPionCharged}, + std::array{constants::physics::MassKaonCharged, constants::physics::MassPionCharged, constants::physics::MassPionCharged}}; + + std::array trackSelector{}; // define the track selectors + + std::array, aod::tagandprobe::TrackTypes::NTrackTypes>, aod::tagandprobe::TagChannels::NTagChannels> histos{}; + HistogramRegistry registry{"registry"}; + + void init(InitContext&) + { + // ITS-TPC tracks (global tracks) + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetTrackType(o2::aod::track::TrackTypeEnum::Track); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetPtRange(0.1f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetEtaRange(-0.8f, 0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireITSRefit(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireTPCRefit(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireGoldenChi2(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMinNCrossedRowsTPC(70); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMinNCrossedRowsOverFindableClustersTPC(0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxChi2PerClusterTPC(4.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any IB layer + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxChi2PerClusterITS(36.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxDcaZ(2.f); + + // TPC tracks (global tracks without ITS requirements) + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetTrackType(o2::aod::track::TrackTypeEnum::Track); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetPtRange(0.1f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetEtaRange(-0.8f, 0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetRequireTPCRefit(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetRequireGoldenChi2(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMinNCrossedRowsTPC(70); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMinNCrossedRowsOverFindableClustersTPC(0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMaxChi2PerClusterTPC(4.f); + + // ITS tracks (global tracks without TPC requirements) + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetTrackType(o2::aod::track::TrackTypeEnum::Track); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetPtRange(0.1f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetEtaRange(-0.8f, 0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetRequireITSRefit(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any SPD layer + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetMaxChi2PerClusterITS(36.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetMaxDcaZ(2.f); + + const AxisSpec axisPt{250, 0.f, 25.f}; + std::array axisMass = {AxisSpec{450, 1.65f, 2.10f}, AxisSpec{450, 1.65f, 2.10f}, AxisSpec{360, 0.f, 0.18f}, AxisSpec{360, 0.f, 0.18f}}; + + std::string trackTypes[aod::tagandprobe::TrackTypes::NTrackTypes] = {"ItsTpc", "Tpc", "Its"}; + std::string tagChannels[aod::tagandprobe::TagChannels::NTagChannels] = {"DplusToKPiPi", "DsOrDplusToKKPi", "DstarPlusToDzeroPi", "DstarMinusToDzeroBarPi"}; + + for (int iChannel{0}; iChannel < aod::tagandprobe::TagChannels::NTagChannels; ++iChannel) { + for (int iTrackType{0}; iTrackType < aod::tagandprobe::TrackTypes::NTrackTypes; ++iTrackType) { + histos[iChannel][iTrackType] = registry.add(Form("h%sVsPtProbe_%s", tagChannels[iChannel].data(), trackTypes[iTrackType].data()), ";#it{p}_{T}(probe track) (GeV/#it{c}); #it{M} (GeV/#it{c}^{2})", HistType::kTH2D, {axisPt, axisMass[iChannel]}); + } + } + } + + template + float computeInvariantMass(TTrack const& trackFirst, TTrack const& trackSecond, TTrack const& trackThird, const uint8_t channel) + { + std::array pVecTrackFirst{trackFirst.px(), trackFirst.py(), trackFirst.pz()}; + std::array pVecTrackSecond{trackSecond.px(), trackSecond.py(), trackSecond.pz()}; + std::array pVecTrackThird{trackThird.px(), trackThird.py(), trackThird.pz()}; + auto arrMomentum = std::array{pVecTrackFirst, pVecTrackSecond, pVecTrackThird}; + float invMass = RecoDecay::m(arrMomentum, masses[channel]); + if (channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi || channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi) { + auto arrMomentumDzero = std::array{pVecTrackFirst, pVecTrackSecond}; + auto massesDzeroDau = std::array{masses[channel][0], masses[channel][1]}; + float invMassDzero = RecoDecay::m(arrMomentumDzero, massesDzeroDau); + invMass -= invMassDzero; + } + + return invMass; + } + + template + void loopOverThirdTrack(TTrackIndices const& groupedTrackThirdIndices, TTracks const& tracks, TTrack const& trackFirst, TTrack const& trackSecond, const uint8_t channel) + { + for (const auto& trackIndex : groupedTrackThirdIndices) { + auto trackThird = trackIndex.template track_as(); + if (trackThird.globalIndex() == trackFirst.globalIndex() || trackThird.globalIndex() == trackSecond.globalIndex()) { + continue; + } + if (channel == aod::tagandprobe::TagChannels::DplusToKPiPi && trackThird.signed1Pt() * trackFirst.signed1Pt() > 0.) { // must be opposite sign + continue; + } + if (channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi && trackThird.signed1Pt() < 0.) { // must be positive + continue; + } + if (channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi && trackThird.signed1Pt() > 0.) { // must be negative + continue; + } + auto ptTrackThird = trackThird.pt(); + auto invMass = computeInvariantMass(trackFirst, trackSecond, trackThird, channel); + if ((channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi || channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi) && invMass > 0.18f) { + continue; + } else if (invMass < 1.65f || invMass > 2.10f) { + continue; + } + for (int iTrackType{0}; iTrackType < aod::tagandprobe::TrackTypes::NTrackTypes; ++iTrackType) { + if (trackSelector[iTrackType].IsSelected(trackThird)) { + histos[channel][iTrackType]->Fill(ptTrackThird, invMass); + } + } + } + } + + void processCombinatorialDplusToKaPiPi(aod::Collisions const& collisions, + aod::PiPiFromDpTags const& tagsPiPi, + aod::TrackAssoc const& trackIndices, + TracksWithSelAndDca const& tracks) + { + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + // D+ -> pi+pi+K- and c.c. + auto groupedTagsPiPi = tagsPiPi.sliceBy(tagsPiPiPerCollision, thisCollId); + for (const auto& tagPiPi : groupedTagsPiPi) { + auto trackFirst = tagPiPi.track0_as(); + auto trackSecond = tagPiPi.track1_as(); + loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DplusToKPiPi); + } + } + } + PROCESS_SWITCH(ProbeThirdTrack, processCombinatorialDplusToKaPiPi, "Process combinatorial of tagged 2-pion vertices with additional track", true); + + void processCombinatorialDsToPhiPi(aod::Collisions const& collisions, + aod::KaKaFromDspTags const& tagsKaKa, + aod::TrackAssoc const& trackIndices, + TracksWithSelAndDca const& tracks) + { + for (const auto& collision : collisions) { + // Ds+/D+ -> phi(->K+K-)pi+ and c.c. + auto thisCollId = collision.globalIndex(); + auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + auto groupedTagsKaKa = tagsKaKa.sliceBy(tagsKaKaPerCollision, thisCollId); + for (const auto& tagKaKa : groupedTagsKaKa) { + auto trackFirst = tagKaKa.track0_as(); + auto trackSecond = tagKaKa.track1_as(); + loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DsOrDplusToKKPi); + } + } + } + PROCESS_SWITCH(ProbeThirdTrack, processCombinatorialDsToPhiPi, "Process combinatorial of tagged 2-kaon (phi) vertices with additional track", true); + + void processCombinatorialDstarToDzeroPi(aod::Collisions const& collisions, + aod::PiKaFromDzTags const& tagsPiKa, + aod::KaPiFromDzTags const& tagsKaPi, + aod::TrackAssoc const& trackIndices, + TracksWithSelAndDca const& tracks) + { + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + // D*+ -> D0(->pi+K-)pi+ + auto groupedTagsPiKa = tagsPiKa.sliceBy(tagsPiKaPerCollision, thisCollId); + for (const auto& tagPiKa : groupedTagsPiKa) { + auto trackFirst = tagPiKa.track0_as(); + auto trackSecond = tagPiKa.track1_as(); + loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DstarPlusToDzeroPi); + } + // D*- -> D0bar(->K+pi-)pi- + auto groupedTagsKaPi = tagsKaPi.sliceBy(tagsKaPiPerCollision, thisCollId); + for (const auto& tagKaPi : groupedTagsKaPi) { + auto trackFirst = tagKaPi.track0_as(); + auto trackSecond = tagKaPi.track1_as(); + loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi); + } + } + } + PROCESS_SWITCH(ProbeThirdTrack, processCombinatorialDstarToDzeroPi, "Process combinatorial of tagged pion-kaon (D0) vertices with additional track", true); + + void processDummy(aod::Collisions const&) {} + PROCESS_SWITCH(ProbeThirdTrack, processDummy, "Dummy process function that does nothing", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{}; + workflow.push_back(adaptAnalysisTask(cfgc)); + workflow.push_back(adaptAnalysisTask(cfgc)); + return workflow; +} From 970ab27efd0747aa4efe64da4955f2613c3165e3 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Thu, 11 Jan 2024 05:02:56 +0900 Subject: [PATCH 147/156] PWGEM/PhotonMeson: add DCA_3D for dielectrons (#4270) --- PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx | 24 ++++++++---- PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx | 39 ++++++++++++++------ PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx | 3 +- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx index 3ba7460794b..b022f25e3a3 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx @@ -128,6 +128,9 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* THnSparseF* hs_dilepton_uls_same = nullptr; THnSparseF* hs_dilepton_lspp_same = nullptr; THnSparseF* hs_dilepton_lsmm_same = nullptr; + THnSparseF* hs_dilepton_uls_dca_same = nullptr; + THnSparseF* hs_dilepton_lspp_dca_same = nullptr; + THnSparseF* hs_dilepton_lsmm_dca_same = nullptr; if (TString(histClass).Contains("EE")) { const int nm = 162; @@ -177,18 +180,18 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* hs_dilepton_lsmm_same->Sumw2(); list->Add(hs_dilepton_lsmm_same); - const int ndim_dca = 3; // mee, dca1, dca2 - const int nbins_dca[ndim_dca] = {nm - 1, 50, 50}; - const double xmin_dca[ndim_dca] = {0.0, 0.0, 0.0}; - const double xmax_dca[ndim_dca] = {3.5, 5.0, 5.0}; + const int ndim_dca = 4; // mee, dca1, dca2 + const int nbins_dca[ndim_dca] = {nm - 1, 50, 50, 50}; + const double xmin_dca[ndim_dca] = {0.0, 0.0, 0.0, 0.0}; + const double xmax_dca[ndim_dca] = {3.5, 5.0, 5.0, 5.0}; - THnSparseF* hs_dilepton_uls_dca_same = new THnSparseF("hs_dilepton_uls_dca_same", "hs_dilepton_uls_dca;m_{ee} (GeV/c^{2});DCA_{e^{+}}^{3D} (#sigma);DCA_{e^{-}}^{3D} (#sigma);", ndim_dca, nbins_dca, xmin_dca, xmax_dca); + hs_dilepton_uls_dca_same = new THnSparseF("hs_dilepton_uls_dca_same", "hs_dilepton_uls_dca;m_{ee} (GeV/c^{2});DCA_{e^{+}}^{3D} (#sigma);DCA_{e^{-}}^{3D} (#sigma);DCA_{ee}^{3D} (#sigma);", ndim_dca, nbins_dca, xmin_dca, xmax_dca); hs_dilepton_uls_dca_same->SetBinEdges(0, mee); hs_dilepton_uls_dca_same->Sumw2(); list->Add(hs_dilepton_uls_dca_same); - THnSparseF* hs_dilepton_lspp_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lspp_dca_same")); - THnSparseF* hs_dilepton_lsmm_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lsmm_dca_same")); + hs_dilepton_lspp_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lspp_dca_same")); + hs_dilepton_lsmm_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lsmm_dca_same")); list->Add(hs_dilepton_lspp_dca_same); list->Add(hs_dilepton_lsmm_dca_same); @@ -231,6 +234,13 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(hs_dilepton_uls_mix); list->Add(hs_dilepton_lspp_mix); list->Add(hs_dilepton_lsmm_mix); + + THnSparseF* hs_dilepton_uls_dca_mix = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_uls_dca_mix")); + THnSparseF* hs_dilepton_lspp_dca_mix = reinterpret_cast(hs_dilepton_lspp_dca_same->Clone("hs_dilepton_lspp_dca_mix")); + THnSparseF* hs_dilepton_lsmm_dca_mix = reinterpret_cast(hs_dilepton_lsmm_dca_same->Clone("hs_dilepton_lsmm_dca_mix")); + list->Add(hs_dilepton_uls_dca_mix); + list->Add(hs_dilepton_lspp_dca_mix); + list->Add(hs_dilepton_lsmm_dca_mix); } list->Add(new TH1F("hNpair_uls", "Number of ULS pairs per collision", 101, -0.5f, 100.5f)); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx index b5f4757e987..300d0811f91 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx @@ -140,7 +140,7 @@ struct DalitzEEQC { THashList* list_dalitzee = static_cast(fMainList->FindObject("DalitzEE")); THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; - double values_single[3] = {0, 0, 0}; + double values_single[4] = {0, 0, 0, 0}; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -185,6 +185,7 @@ struct DalitzEEQC { values_single[0] = uls_pair.mass(); values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); nuls++; for (auto& track : {pos, ele}) { @@ -210,6 +211,7 @@ struct DalitzEEQC { values_single[0] = lspp_pair.mass(); values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_dca_same"))->Fill(values_single); } } // end of lspp pair loop @@ -228,6 +230,7 @@ struct DalitzEEQC { values_single[0] = lsmm_pair.mass(); values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_dca_same"))->Fill(values_single); } } // end of lsmm pair loop @@ -256,6 +259,7 @@ struct DalitzEEQC { double values[4] = {0, 0, 0, 0}; ROOT::Math::PtEtaPhiMVector v1, v2, v12; float phiv = 0; + double values_single[4] = {0, 0, 0, 0}; for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. auto dileptons_coll1 = dileptons.sliceBy(perCollision, collision1.globalIndex()); @@ -274,17 +278,6 @@ struct DalitzEEQC { auto pos2 = dl2.template posTrack_as(); auto ele2 = dl2.template negTrack_as(); - // float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); - // float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); - // float dcamumuxy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); - // float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); - // float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); - // float dcamumuz = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - - // mix uls1 - // ROOT::Math::PtEtaPhiMVector v1(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassElectron); - // ROOT::Math::PtEtaPhiMVector v2(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassElectron); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; v1 = ROOT::Math::PtEtaPhiMVector(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassElectron); v2 = ROOT::Math::PtEtaPhiMVector(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassElectron); v12 = v1 + v2; @@ -293,8 +286,15 @@ struct DalitzEEQC { values[1] = v12.Pt(); values[2] = sqrt((pow(pos1.dcaXY() / sqrt(pos1.cYY()), 2) + pow(ele2.dcaXY() / sqrt(ele2.cYY()), 2)) / 2.); // pair DCAxy values[3] = phiv; + + values_single[0] = v12.M(); + values_single[1] = std::sqrt(std::pow(pos1.dcaXY() / std::sqrt(pos1.cYY()), 2) + std::pow(pos1.dcaZ() / std::sqrt(pos1.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele2.dcaXY() / std::sqrt(ele2.cYY()), 2) + std::pow(ele2.dcaZ() / std::sqrt(ele2.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); + if (cut.IsSelectedTrack(pos1) && cut.IsSelectedTrack(ele2) && cut.IsSelectedPair(v12.M(), phiv)) { reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_mix"))->Fill(values_single); } // mix uls2 @@ -306,8 +306,13 @@ struct DalitzEEQC { values[1] = v12.Pt(); values[2] = sqrt((pow(pos2.dcaXY() / sqrt(pos2.cYY()), 2) + pow(ele1.dcaXY() / sqrt(ele1.cYY()), 2)) / 2.); // pair DCAxy values[3] = phiv; + values_single[0] = v12.M(); + values_single[1] = std::sqrt(std::pow(pos2.dcaXY() / std::sqrt(pos2.cYY()), 2) + std::pow(pos2.dcaZ() / std::sqrt(pos2.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele1.dcaXY() / std::sqrt(ele1.cYY()), 2) + std::pow(ele1.dcaZ() / std::sqrt(ele1.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); if (cut.IsSelectedTrack(pos2) && cut.IsSelectedTrack(ele1) && cut.IsSelectedPair(v12.M(), phiv)) { reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_mix"))->Fill(values_single); } // mix lspp @@ -319,8 +324,13 @@ struct DalitzEEQC { values[1] = v12.Pt(); values[2] = sqrt((pow(pos1.dcaXY() / sqrt(pos1.cYY()), 2) + pow(pos2.dcaXY() / sqrt(pos2.cYY()), 2)) / 2.); // pair DCAxy values[3] = phiv; + values_single[0] = v12.M(); + values_single[1] = std::sqrt(std::pow(pos1.dcaXY() / std::sqrt(pos1.cYY()), 2) + std::pow(pos1.dcaZ() / std::sqrt(pos1.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(pos2.dcaXY() / std::sqrt(pos2.cYY()), 2) + std::pow(pos2.dcaZ() / std::sqrt(pos2.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); if (cut.IsSelectedTrack(pos1) && cut.IsSelectedTrack(pos2) && cut.IsSelectedPair(v12.M(), phiv)) { reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_dca_mix"))->Fill(values_single); } // mix lsmm @@ -332,8 +342,13 @@ struct DalitzEEQC { values[1] = v12.Pt(); values[2] = sqrt((pow(ele1.dcaXY() / sqrt(ele1.cYY()), 2) + pow(ele2.dcaXY() / sqrt(ele2.cYY()), 2)) / 2.); // pair DCAxy values[3] = phiv; + values_single[0] = v12.M(); + values_single[1] = std::sqrt(std::pow(ele1.dcaXY() / std::sqrt(ele1.cYY()), 2) + std::pow(ele1.dcaZ() / std::sqrt(ele1.cZZ()), 2)); + values_single[2] = std::sqrt(std::pow(ele2.dcaXY() / std::sqrt(ele2.cYY()), 2) + std::pow(ele2.dcaZ() / std::sqrt(ele2.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); if (cut.IsSelectedTrack(ele1) && cut.IsSelectedTrack(ele2) && cut.IsSelectedPair(v12.M(), phiv)) { reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_dca_mix"))->Fill(values_single); } } // end of different dileptn combinations diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx index 9fcf81df934..24de1d22dcc 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx @@ -145,7 +145,7 @@ struct DalitzEEQCMC { THashList* list_dalitzee = static_cast(fMainList->FindObject("DalitzEE")); THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; - double values_single[3] = {0, 0, 0}; + double values_single[4] = {0, 0, 0, 0}; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -202,6 +202,7 @@ struct DalitzEEQCMC { values_single[0] = uls_pair.mass(); values_single[1] = std::sqrt(std::pow(pos.dcaXY() / std::sqrt(pos.cYY()), 2) + std::pow(pos.dcaZ() / std::sqrt(pos.cZZ()), 2)); values_single[2] = std::sqrt(std::pow(ele.dcaXY() / std::sqrt(ele.cYY()), 2) + std::pow(ele.dcaZ() / std::sqrt(ele.cZZ()), 2)); + values_single[3] = std::sqrt((std::pow(values_single[1], 2) + std::pow(values_single[2], 2)) / 2.f); reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); if (mcmother.pdgCode() == 111) { From 2f136c8c3645191afdaa191cf12a43bc8ea649d0 Mon Sep 17 00:00:00 2001 From: prchakra <47203359+prchakra@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:09:09 +0100 Subject: [PATCH 148/156] Chaning the kstar binning (#4271) --- .../Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx index ad74d2e8bfc..f442a92735b 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx @@ -151,7 +151,7 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; - ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis ConfkstarBins{"ConfkstarBins", {300, -1.5, 1.5}, "binning kstar"}; ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; Configurable ConfIsIden{"ConfIsIden", true, "Choosing identical or non-identical pairs"}; From 58386287d06e00981e733f235e92049413fcab86 Mon Sep 17 00:00:00 2001 From: eloviyo <38348689+Eloviyo@users.noreply.github.com> Date: Thu, 11 Jan 2024 10:45:47 +0100 Subject: [PATCH 149/156] added full precision nSigmaTOF (#4269) Co-authored-by: Shirajum Monira --- PWGCF/FemtoUniverse/DataModel/FemtoDerived.h | 23 ++++++++++--------- .../femtoUniverseProducerTask.cxx | 10 ++++---- .../femtoUniversePairTaskTrackV0Extended.cxx | 7 +++--- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index b7fd3e34524..723db5fc069 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -124,6 +124,12 @@ DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex DECLARE_SOA_COLUMN(MKaon, mKaon, float); //! The invariant mass of V0 candidate, assuming kaon +DECLARE_SOA_COLUMN(TOFNSigmaEl, tofNSigmaEl, float); +DECLARE_SOA_COLUMN(TOFNSigmaPi, tofNSigmaPi, float); +DECLARE_SOA_COLUMN(TOFNSigmaKa, tofNSigmaKa, float); +DECLARE_SOA_COLUMN(TOFNSigmaPr, tofNSigmaPr, float); +DECLARE_SOA_COLUMN(TOFNSigmaDe, tofNSigmaDe, float); + } // namespace femtouniverseparticle DECLARE_SOA_TABLE(FDParticles, "AOD", "FDPARTICLE", o2::soa::Index<>, @@ -162,11 +168,11 @@ DECLARE_SOA_TABLE(FDExtParticles, "AOD", "FDEXTPARTICLE", pidtpc_tiny::TPCNSigmaStoreKa, pidtpc_tiny::TPCNSigmaStorePr, pidtpc_tiny::TPCNSigmaStoreDe, - pidtof_tiny::TOFNSigmaStoreEl, - pidtof_tiny::TOFNSigmaStorePi, - pidtof_tiny::TOFNSigmaStoreKa, - pidtof_tiny::TOFNSigmaStorePr, - pidtof_tiny::TOFNSigmaStoreDe, + femtouniverseparticle::TOFNSigmaEl, + femtouniverseparticle::TOFNSigmaPi, + femtouniverseparticle::TOFNSigmaKa, + femtouniverseparticle::TOFNSigmaPr, + femtouniverseparticle::TOFNSigmaDe, femtouniverseparticle::DaughDCA, femtouniverseparticle::TransRadius, femtouniverseparticle::DecayVtxX, @@ -178,12 +184,7 @@ DECLARE_SOA_TABLE(FDExtParticles, "AOD", "FDEXTPARTICLE", pidtpc_tiny::TPCNSigmaPi, pidtpc_tiny::TPCNSigmaKa, pidtpc_tiny::TPCNSigmaPr, - pidtpc_tiny::TPCNSigmaDe, - pidtof_tiny::TOFNSigmaEl, - pidtof_tiny::TOFNSigmaPi, - pidtof_tiny::TOFNSigmaKa, - pidtof_tiny::TOFNSigmaPr, - pidtof_tiny::TOFNSigmaDe); + pidtpc_tiny::TPCNSigmaDe); using FDFullParticle = FDExtParticles::iterator; /// FemtoUniverseTrackMC diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index a0b5e8e1725..2ce615b491e 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -65,8 +65,8 @@ using FemtoFullCollisionMC = soa::Join; + aod::pidTPCDe, aod::pidTOFFullEl, aod::pidTOFFullMu, aod::pidTOFFullPi, + aod::pidTOFFullKa, aod::pidTOFFullPr, aod::pidTOFFullDe>; // using FilteredFullV0s = soa::Filtered; /// predefined Join // table for o2::aod::V0s = soa::Join @@ -454,9 +454,9 @@ struct femtoUniverseProducerTask { particle.dcaXY(), particle.dcaZ(), particle.tpcSignal(), particle.tpcNSigmaStoreEl(), particle.tpcNSigmaStorePi(), particle.tpcNSigmaStoreKa(), particle.tpcNSigmaStorePr(), - particle.tpcNSigmaStoreDe(), particle.tofNSigmaStoreEl(), - particle.tofNSigmaStorePi(), particle.tofNSigmaStoreKa(), - particle.tofNSigmaStorePr(), particle.tofNSigmaStoreDe(), + particle.tpcNSigmaStoreDe(), particle.tofNSigmaEl(), + particle.tofNSigmaPi(), particle.tofNSigmaKa(), + particle.tofNSigmaPr(), particle.tofNSigmaDe(), -999., -999., -999., -999., -999., -999.); } else if constexpr (isPhiOrD0) { outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index 1e801a5937c..5697376630e 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -39,7 +39,6 @@ using namespace o2::aod::pidutils; struct femtoUniversePairTaskTrackV0Extended { SliceCache cache; - // using FemtoFullParticles = soa::Join; using FemtoFullParticles = soa::Join; Preslice perCol = aod::femtouniverseparticle::fdCollisionId; @@ -176,7 +175,7 @@ struct femtoUniversePairTaskTrackV0Extended { for (auto& part : groupPartsOne) { /// PID using stored binned nsigma const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; - const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + const float tofNSigmas[3] = {part.tofNSigmaPr(), part.tofNSigmaPi(), part.tofNSigmaKa()}; if (!IsParticleNSigma(part.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; @@ -200,7 +199,7 @@ struct femtoUniversePairTaskTrackV0Extended { } /// PID using stored binned nsigma const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; - const float tofNSigmas[3] = {unPackInTable(p1.tofNSigmaStorePr()), unPackInTable(p1.tofNSigmaStorePi()), unPackInTable(p1.tofNSigmaStoreKa())}; + const float tofNSigmas[3] = {p1.tofNSigmaPr(), p1.tofNSigmaPi(), p1.tofNSigmaKa()}; if (!IsParticleNSigma(p1.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; @@ -242,7 +241,7 @@ struct femtoUniversePairTaskTrackV0Extended { } /// PID using stored binned nsigma const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; - const float tofNSigmas[3] = {unPackInTable(p1.tofNSigmaStorePr()), unPackInTable(p1.tofNSigmaStorePi()), unPackInTable(p1.tofNSigmaStoreKa())}; + const float tofNSigmas[3] = {p1.tofNSigmaPr(), p1.tofNSigmaPi(), p1.tofNSigmaKa()}; if (!IsParticleNSigma(p1.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { continue; From 6ceacffd0f3734883b92756a630e6fe850596bf9 Mon Sep 17 00:00:00 2001 From: EmilGorm <50658075+EmilGorm@users.noreply.github.com> Date: Thu, 11 Jan 2024 11:59:12 +0100 Subject: [PATCH 150/156] Added vn-pt and other changes (#4262) * Moved QA plots from QA file to analysis file * Moved configurables used in filter to single-valued configurables * Added vn-pt and more * clang-format and whitespace * copyright header * MegaLinter * MegaLinter cont. * Removed streamer -> LOGF * Clang-format --------- Co-authored-by: Emil Gorm Nielsen --- .../Core/BootstrapProfile.cxx | 240 +++++++++ .../GenericFramework/Core/BootstrapProfile.h | 66 +++ PWGCF/GenericFramework/Core/CMakeLists.txt | 4 + PWGCF/GenericFramework/Core/FlowContainer.cxx | 2 +- .../GenericFramework/Core/FlowPtContainer.cxx | 473 ++++++++++++++++++ PWGCF/GenericFramework/Core/FlowPtContainer.h | 95 ++++ PWGCF/GenericFramework/Core/GFWConfig.h | 61 ++- .../Core/GenericFrameworkLinkDef.h | 2 + .../Tasks/flowGenericFramework.cxx | 190 +++---- 9 files changed, 1016 insertions(+), 117 deletions(-) create mode 100644 PWGCF/GenericFramework/Core/BootstrapProfile.cxx create mode 100644 PWGCF/GenericFramework/Core/BootstrapProfile.h create mode 100644 PWGCF/GenericFramework/Core/FlowPtContainer.cxx create mode 100644 PWGCF/GenericFramework/Core/FlowPtContainer.h diff --git a/PWGCF/GenericFramework/Core/BootstrapProfile.cxx b/PWGCF/GenericFramework/Core/BootstrapProfile.cxx new file mode 100644 index 00000000000..ae97bb67400 --- /dev/null +++ b/PWGCF/GenericFramework/Core/BootstrapProfile.cxx @@ -0,0 +1,240 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "BootstrapProfile.h" +BootstrapProfile::BootstrapProfile() : TProfile(), + fListOfEntries(0), + fProfInitialized(kFALSE), + fNSubs(0), + fMultiRebin(0), + fMultiRebinEdges(0), + fPresetWeights(0) {} +BootstrapProfile::~BootstrapProfile() +{ + delete fListOfEntries; +}; +BootstrapProfile::BootstrapProfile(const char* name, const char* title, Int_t nbinsx, const Double_t* xbins) : TProfile(name, title, nbinsx, xbins), + fListOfEntries(0), + fProfInitialized(kTRUE), + fNSubs(0), + fMultiRebin(0), + fMultiRebinEdges(0), + fPresetWeights(0) {} +BootstrapProfile::BootstrapProfile(const char* name, const char* title, Int_t nbinsx, Double_t xlow, Double_t xup) : TProfile(name, title, nbinsx, xlow, xup), + fListOfEntries(0), + fProfInitialized(kFALSE), + fNSubs(0), + fMultiRebin(0), + fMultiRebinEdges(0), + fPresetWeights(0) {} +void BootstrapProfile::InitializeSubsamples(Int_t nSub) +{ + if (nSub < 1) { + printf("Number of subprofiles has to be > 0!\n"); + return; + } + if (fListOfEntries) + delete fListOfEntries; + fListOfEntries = new TList(); + fListOfEntries->SetOwner(kTRUE); + TProfile* dummyPF = reinterpret_cast(this); + for (Int_t i = 0; i < nSub; i++) { + fListOfEntries->Add(reinterpret_cast(dummyPF->Clone(Form("%s_Subpf%i", dummyPF->GetName(), i)))); + reinterpret_cast(fListOfEntries->At(i))->Reset(); + } + fNSubs = nSub; +} +void BootstrapProfile::FillProfile(const Double_t& xv, const Double_t& yv, const Double_t& w, const Double_t& rn) +{ + TProfile::Fill(xv, yv, w); + if (!fNSubs) + return; + Int_t targetInd = rn * fNSubs; + if (targetInd >= fNSubs) + targetInd = 0; + reinterpret_cast(fListOfEntries->At(targetInd))->Fill(xv, yv, w); +} +void BootstrapProfile::FillProfile(const Double_t& xv, const Double_t& yv, const Double_t& w) +{ + TProfile::Fill(xv, yv, w); +} +void BootstrapProfile::RebinMulti(Int_t nbins) +{ + this->RebinX(nbins); + if (!fListOfEntries) + return; + for (Int_t i = 0; i < fListOfEntries->GetEntries(); i++) + reinterpret_cast(fListOfEntries->At(i))->RebinX(nbins); +} +TH1* BootstrapProfile::getHist(Int_t ind) +{ + if (fPresetWeights && fMultiRebin > 0) + return getWeightBasedRebin(ind); + if (ind < 0) { + if (reinterpret_cast(this)) { + return getHistRebinned(reinterpret_cast(this)); //((TProfile*)this)->ProjectionX(Form("%s_hist",this->GetName())); + } else { + printf("Empty BootstrapProfile addressed, cannot get a histogram\n"); + return 0; + } + } else { + if (!fListOfEntries) { + printf("No subprofiles exist!\n"); + return 0; + } + if (ind < fNSubs) { + return getHistRebinned(reinterpret_cast(fListOfEntries->At(ind))); ////((TProfile*)fListOfEntries->At(ind))->ProjectionX(Form("%s_sub%i",((TProfile*)fListOfEntries->At(ind))->GetName(),ind)); + } else { + printf("Trying to fetch subprofile no %i out of %i, not possible\n", ind, fNSubs); + return 0; + } + } + return 0; +} +TProfile* BootstrapProfile::getProfile(Int_t ind) +{ + if (ind < 0) { + if (reinterpret_cast(this)) { + return reinterpret_cast(this); + } else { + printf("Empty BootstrapProfile addressed, cannot get a histogram\n"); + return 0; + } + } else { + if (!fListOfEntries) { + printf("No subprofiles exist!\n"); + return 0; + } + if (ind < fNSubs) { + return reinterpret_cast(fListOfEntries->At(ind)); + } else { + printf("Trying to fetch subprofile no %i out of %i, not possible\n", ind, fNSubs); + return 0; + } + } +} +Long64_t BootstrapProfile::Merge(TCollection* collist) +{ + Long64_t nmergedpf = TProfile::Merge(collist); + Long64_t nmerged = 0; + BootstrapProfile* l_PBS = 0; + TIter all_PBS(collist); + while ((l_PBS = reinterpret_cast(all_PBS()))) { + reinterpret_cast(this)->Add(reinterpret_cast(l_PBS)); + TList* tarL = l_PBS->fListOfEntries; + if (!tarL) + continue; + if (!fListOfEntries) { + fListOfEntries = reinterpret_cast(tarL->Clone()); + for (Int_t i = 0; i < fListOfEntries->GetEntries(); i++) + reinterpret_cast(fListOfEntries->At(i))->Reset(); + } + for (Int_t i = 0; i < fListOfEntries->GetEntries(); i++) + reinterpret_cast(fListOfEntries->At(i))->Add(reinterpret_cast(tarL->At(i))); + nmerged++; + } + return nmergedpf; +}; +void BootstrapProfile::RebinMulti(Int_t nbins, Double_t* binedges) +{ + if (fMultiRebinEdges) { + delete[] fMultiRebinEdges; + fMultiRebinEdges = 0; + } + if (nbins <= 0) { + fMultiRebin = 0; + return; + } + fMultiRebin = nbins; + fMultiRebinEdges = new Double_t[nbins + 1]; + for (Int_t i = 0; i <= fMultiRebin; i++) + fMultiRebinEdges[i] = binedges[i]; +} +TH1* BootstrapProfile::getHistRebinned(TProfile* inpf) +{ + if (!inpf) + return 0; + if (fMultiRebin <= 0) + return reinterpret_cast(inpf)->ProjectionX(Form("%s_hist", inpf->GetName())); + TProfile* temppf = reinterpret_cast(inpf->Rebin(fMultiRebin, "tempProfile", fMultiRebinEdges)); + TH1* reth = reinterpret_cast(temppf->ProjectionX(Form("%s_hist", inpf->GetName()))); + delete temppf; + return reth; +} +TH1* BootstrapProfile::getWeightBasedRebin(Int_t ind) +{ + if (!fPresetWeights) { + printf("Weights are not preset!\n"); + return 0; + } + TProfile* lProf = getProfile(ind); + TH1* reth = getHistRebinned(lProf); + reth->Reset(); + TProfile* lW = fPresetWeights->getProfile(ind); + if (!lW) { + printf("Weight profile could not be found!\n"); + return 0; + } + for (Int_t i = 1; i <= lW->GetNbinsX(); i++) { + Int_t i_n = reth->FindBin(lW->GetBinCenter(i)); + Double_t bc2 = lProf->GetBinContent(i); + Double_t be2 = lW->GetBinEntries(i); + Double_t bc1 = reth->GetBinContent(i_n); + Double_t be1 = reth->GetBinError(i_n); + if (be2 == 0) + continue; + reth->SetBinContent(i_n, bc1 + bc2 * be2); + reth->SetBinError(i_n, be1 + be2); + } + for (Int_t i = 1; i <= reth->GetNbinsX(); i++) { + Double_t bc1 = reth->GetBinContent(i); + Double_t be1 = reth->GetBinError(i); + if (be1 == 0) + continue; + reth->SetBinContent(i, bc1 / be1); + reth->SetBinError(i, 1. / TMath::Sqrt(be1)); + } + return reth; +} +void BootstrapProfile::MergeBS(BootstrapProfile* target) +{ + this->Add(target); + TList* tarL = target->fListOfEntries; + if (!fListOfEntries) { + if (!target->fListOfEntries) + return; + fListOfEntries = reinterpret_cast(tarL->Clone()); + for (Int_t i = 0; i < fListOfEntries->GetEntries(); i++) + reinterpret_cast(fListOfEntries->At(i))->Reset(); + } + for (Int_t i = 0; i < fListOfEntries->GetEntries(); i++) + reinterpret_cast(fListOfEntries->At(i))->Add(reinterpret_cast(tarL->At(i))); +} +TProfile* BootstrapProfile::getSummedProfiles() +{ + if (!fListOfEntries || !fListOfEntries->GetEntries()) { + printf("No subprofiles initialized for the BootstrapProfile.\n"); + return 0; + } + TProfile* retpf = reinterpret_cast(fListOfEntries->At(0)->Clone("SummedProfile")); + for (Int_t i = 1; i < fListOfEntries->GetEntries(); i++) + retpf->Add(reinterpret_cast(fListOfEntries->At(i))); + return retpf; +} +void BootstrapProfile::OverrideMainWithSub() +{ + TProfile* sum = getSummedProfiles(); + if (!sum) + return; + reinterpret_cast(this)->Reset(); + reinterpret_cast(this)->Add(sum); + delete sum; +} diff --git a/PWGCF/GenericFramework/Core/BootstrapProfile.h b/PWGCF/GenericFramework/Core/BootstrapProfile.h new file mode 100644 index 00000000000..a0dfde08509 --- /dev/null +++ b/PWGCF/GenericFramework/Core/BootstrapProfile.h @@ -0,0 +1,66 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef PWGCF_GENERICFRAMEWORK_CORE_BOOTSTRAPPROFILE_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_BOOTSTRAPPROFILE_H_ + +#include "TProfile.h" +#include "TList.h" +#include "TString.h" +#include "TCollection.h" +#include "TMath.h" + +class BootstrapProfile : public TProfile +{ + public: + BootstrapProfile(); + ~BootstrapProfile(); + BootstrapProfile(const char* name, const char* title, Int_t nbinsx, const Double_t* xbins); + BootstrapProfile(const char* name, const char* title, Int_t nbinsx, Double_t xlow, Double_t xup); + TList* fListOfEntries; + void MergeBS(BootstrapProfile* target); + void InitializeSubsamples(Int_t nSub); + void FillProfile(const Double_t& xv, const Double_t& yv, const Double_t& w, const Double_t& rn); + void FillProfile(const Double_t& xv, const Double_t& yv, const Double_t& w); + Long64_t Merge(TCollection* collist); + void RebinMulti(Int_t nbins); + void RebinMulti(Int_t nbins, Double_t* binedges); + TH1* getHist(Int_t ind = -1); + TProfile* getProfile(Int_t ind = -1); + TProfile* getSummedProfiles(); + void OverrideMainWithSub(); + Int_t getNSubs() { return fListOfEntries->GetEntries(); } + void PresetWeights(BootstrapProfile* targetBS) { fPresetWeights = targetBS; } + void ResetBin(Int_t nbin) + { + ResetBin(reinterpret_cast(this), nbin); + for (Int_t i = 0; i < fListOfEntries->GetEntries(); i++) + ResetBin(reinterpret_cast(fListOfEntries->At(i)), nbin); + }; + ClassDef(BootstrapProfile, 2); + + protected: + TH1* getHistRebinned(TProfile* inpf); // Performs rebinning, if required, and returns a projection of profile + TH1* getWeightBasedRebin(Int_t ind = -1); + Bool_t fProfInitialized; + Int_t fNSubs; + Int_t fMultiRebin; //! externaly set runtime, no need to store + Double_t* fMultiRebinEdges; //! externaly set runtime, no need to store + BootstrapProfile* fPresetWeights; //! BootstrapProfile whose weights we should copy + void ResetBin(TProfile* tpf, Int_t nbin) + { + tpf->SetBinEntries(nbin, 0); + tpf->SetBinContent(nbin, 0); + tpf->SetBinError(nbin, 0); + }; +}; + +#endif // PWGCF_GENERICFRAMEWORK_CORE_BOOTSTRAPPROFILE_H_ diff --git a/PWGCF/GenericFramework/Core/CMakeLists.txt b/PWGCF/GenericFramework/Core/CMakeLists.txt index 0d53a69f45e..b7e0a916db0 100755 --- a/PWGCF/GenericFramework/Core/CMakeLists.txt +++ b/PWGCF/GenericFramework/Core/CMakeLists.txt @@ -16,6 +16,8 @@ o2physics_add_library(GFWCore ProfileSubset.cxx FlowContainer.cxx GFWWeights.cxx + FlowPtContainer.cxx + BootstrapProfile.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore) o2physics_target_root_dictionary(GFWCore @@ -26,4 +28,6 @@ o2physics_target_root_dictionary(GFWCore FlowContainer.h GFWWeights.h GFWConfig.h + FlowPtContainer.h + BootstrapProfile.h LINKDEF GenericFrameworkLinkDef.h) diff --git a/PWGCF/GenericFramework/Core/FlowContainer.cxx b/PWGCF/GenericFramework/Core/FlowContainer.cxx index 91b42d423eb..8a906ba2321 100644 --- a/PWGCF/GenericFramework/Core/FlowContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowContainer.cxx @@ -189,7 +189,7 @@ Long64_t FlowContainer::Merge(TCollection* collist) Long64_t nmerged = 0; FlowContainer* l_FC = 0; TIter all_FC(collist); - while (l_FC = dynamic_cast(all_FC())) { + while ((l_FC = dynamic_cast(all_FC()))) { if (!fProf) continue; TProfile2D* tpro = GetProfile(); diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx new file mode 100644 index 00000000000..8c586add9f9 --- /dev/null +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx @@ -0,0 +1,473 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "FlowPtContainer.h" + +FlowPtContainer::FlowPtContainer() : TNamed("name", "name"), + fCMTermList(0), + fCorrList(0), + fCovList(0), + fCumulantList(0), + fCentralMomentList(0), + mpar(0), + fillCounter(0), + fEventWeight(kEventWeight::kUnity), + corrNum(), + corrDen() {} +FlowPtContainer::~FlowPtContainer() +{ + delete fCMTermList; + delete fCorrList; +}; +FlowPtContainer::FlowPtContainer(const char* name) : TNamed(name, name), + fCMTermList(0), + fCorrList(0), + fCovList(0), + fCumulantList(0), + fCentralMomentList(0), + mpar(0), + fillCounter(0), + fEventWeight(kEventWeight::kUnity), + corrNum(), + corrDen() {} +FlowPtContainer::FlowPtContainer(const char* name, const char* title, int nbinsx, double* xbins, const int& m, const GFWCorrConfigs& configs) : TNamed(name, title), + fCMTermList(0), + fCorrList(0), + fCovList(0), + fCumulantList(0), + fCentralMomentList(0), + mpar(m), + fillCounter(0), + fEventWeight(kEventWeight::kUnity), + corrNum(), + corrDen() +{ + Initialise(nbinsx, xbins, m, configs); +}; +FlowPtContainer::FlowPtContainer(const char* name, const char* title, int nbinsx, double xlow, double xhigh, const int& m, const GFWCorrConfigs& configs) : TNamed(name, title), + fCMTermList(0), + fCorrList(0), + fCovList(0), + fCumulantList(0), + fCentralMomentList(0), + mpar(m), + fillCounter(0), + fEventWeight(kEventWeight::kUnity), + corrNum(), + corrDen() +{ + Initialise(nbinsx, xlow, xhigh, m, configs); +}; +void FlowPtContainer::Initialise(const o2::framework::AxisSpec axis, const int& m, const GFWCorrConfigs& configs, const int& nsub) +{ + if (!mpar) + mpar = m; + std::vector multiBins = axis.binEdges; + int nMultiBins = axis.nBins.value_or(0); + if (nMultiBins <= 0) + nMultiBins = multiBins.size() - 1; + if (nMultiBins <= 0) { + printf("Multiplicity axis does not exist"); + return; + } + if (fCMTermList) + delete fCMTermList; + fCMTermList = new TList(); + fCMTermList->SetOwner(kTRUE); + if (fCorrList) + delete fCorrList; + fCorrList = new TList(); + fCorrList->SetOwner(kTRUE); + if (fCovList) + delete fCovList; + fCovList = new TList(); + fCovList->SetOwner(kTRUE); + for (int m = 0; m < mpar; ++m) + fCorrList->Add(new BootstrapProfile(Form("mpt%i", m + 1), Form("corr_%ipar", m + 1), nMultiBins, &multiBins[0])); + for (int m = 0; m < 4; ++m) { + for (int i = 0; i <= m; ++i) + fCMTermList->Add(new BootstrapProfile(Form("cm%i_Mpt%i", m + 1, i), Form("cm%i_Mpt%i", m + 1, i), nMultiBins, &multiBins[0])); + } + for (int i = 0; i < configs.GetSize(); ++i) { + for (auto m(1); m <= mpar; ++m) { + if (!(configs.GetpTCorrMasks()[i] & (1 << (m - 1)))) + continue; + fCovList->Add(new BootstrapProfile(Form("%s_mpt%i", configs.GetHeads()[i].c_str(), m), Form("%s_mpt%i", configs.GetHeads()[i].c_str(), m), nMultiBins, &multiBins[0])); + } + } + if (nsub) { + for (int i = 0; i < fCorrList->GetEntries(); ++i) + dynamic_cast(fCorrList->At(i))->InitializeSubsamples(nsub); + for (int i = 0; i < fCMTermList->GetEntries(); ++i) + dynamic_cast(fCMTermList->At(i))->InitializeSubsamples(nsub); + for (int i = 0; i < fCovList->GetEntries(); ++i) + dynamic_cast(fCovList->At(i))->InitializeSubsamples(nsub); + } + printf("Container %s initialized with m = %i\n and %i subsamples", this->GetName(), mpar, nsub); + return; +}; +void FlowPtContainer::Initialise(int nbinsx, double* xbins, const int& m, const GFWCorrConfigs& configs, const int& nsub) +{ + if (!mpar) + mpar = m; + if (fCMTermList) + delete fCMTermList; + fCMTermList = new TList(); + fCMTermList->SetOwner(kTRUE); + if (fCorrList) + delete fCorrList; + fCorrList = new TList(); + fCorrList->SetOwner(kTRUE); + for (int m = 0; m < mpar; ++m) + fCorrList->Add(new BootstrapProfile(Form("mpt%i", m + 1), Form("mpt%i", m + 1), nbinsx, xbins)); + for (int m = 0; m < 4; ++m) { + for (int i = 0; i <= m; ++i) + fCMTermList->Add(new BootstrapProfile(Form("cm%i_Mpt%i", m + 1, i), Form("cm%i_Mpt%i", m + 1, i), nbinsx, xbins)); + } + for (int i = 0; i < configs.GetSize(); ++i) { + for (auto m(1); m <= mpar; ++m) { + if (!(configs.GetpTCorrMasks()[i] & (1 << (m - 1)))) + continue; + fCovList->Add(new BootstrapProfile(Form("%s_mpt%i", configs.GetHeads()[i].c_str(), m + 1), Form("%s_mpt%i", configs.GetHeads()[i].c_str(), m + 1), nbinsx, xbins)); + } + } + if (nsub) { + for (int i = 0; i < fCorrList->GetEntries(); ++i) + dynamic_cast(fCorrList->At(i))->InitializeSubsamples(nsub); + for (int i = 0; i < fCMTermList->GetEntries(); ++i) + dynamic_cast(fCMTermList->At(i))->InitializeSubsamples(nsub); + for (int i = 0; i < fCovList->GetEntries(); ++i) + dynamic_cast(fCovList->At(i))->InitializeSubsamples(nsub); + } + printf("Container %s initialized with m = %i\n", this->GetName(), mpar); +}; +void FlowPtContainer::Initialise(int nbinsx, double xlow, double xhigh, const int& m, const GFWCorrConfigs& configs, const int& nsub) +{ + if (!mpar) + mpar = m; + if (fCMTermList) + delete fCMTermList; + fCMTermList = new TList(); + fCMTermList->SetOwner(kTRUE); + if (fCorrList) + delete fCorrList; + fCorrList = new TList(); + fCorrList->SetOwner(kTRUE); + for (int m = 0; m < mpar; ++m) + fCorrList->Add(new BootstrapProfile(Form("mpt%i", m + 1), Form("mpt%i", m + 1), nbinsx, xlow, xhigh)); + for (int m = 0; m < 4; ++m) { + for (int i = 0; i <= m; ++i) + fCMTermList->Add(new BootstrapProfile(Form("cm%i_Mpt%i", m + 1, i), Form("cm%i_Mpt%i", m + 1, i), nbinsx, xlow, xhigh)); + } + for (int i = 0; i < configs.GetSize(); ++i) { + for (auto m(1); m <= mpar; ++m) { + if (!(configs.GetpTCorrMasks()[i] & (1 << (m - 1)))) + continue; + fCovList->Add(new BootstrapProfile(Form("%s_mpt%i", configs.GetHeads()[i].c_str(), m + 1), Form("%s_mpt%i", configs.GetHeads()[i].c_str(), m + 1), nbinsx, xlow, xhigh)); + } + } + if (nsub) { + for (int i = 0; i < fCorrList->GetEntries(); ++i) + dynamic_cast(fCorrList->At(i))->InitializeSubsamples(nsub); + for (int i = 0; i < fCMTermList->GetEntries(); ++i) + dynamic_cast(fCMTermList->At(i))->InitializeSubsamples(nsub); + for (int i = 0; i < fCovList->GetEntries(); ++i) + dynamic_cast(fCovList->At(i))->InitializeSubsamples(nsub); + } + printf("Container %s initialized with m = %i\n", this->GetName(), mpar); +}; +void FlowPtContainer::Fill(const double& w, const double& pt) +{ + for (auto i = 0; i < sumP.size(); ++i) { + sumP[i] += pow(w, i % (mpar + 1)) * pow(pt, i / (mpar + 1)); + } + return; +} +void FlowPtContainer::CalculateCorrelations() +{ + corrNum.clear(); + corrNum.resize(mpar + 1, 0); + corrNum[0] = 1.0; + corrDen.clear(); + corrDen.resize(mpar + 1, 0); + corrDen[0] = 1.0; + double sumNum = 0; + double sumDenum = 0; + std::vector valNum; + std::vector valDenum; + for (int m(1); m <= mpar; ++m) { + for (int k(1); k <= m; ++k) { + valNum.push_back(fSign[k - 1] * corrNum[m - k] * (fFactorial[m - 1] / fFactorial[m - k]) * sumP[GetVectorIndex(k, k)]); + valDenum.push_back(fSign[k - 1] * corrDen[m - k] * (fFactorial[m - 1] / fFactorial[m - k]) * sumP[GetVectorIndex(k, 0)]); + } + sumNum = OrderedAddition(valNum); + sumDenum = OrderedAddition(valDenum); + valNum.clear(); + valDenum.clear(); + + corrNum[m] = sumNum; + corrDen[m] = sumDenum; + } + return; +} +void FlowPtContainer::FillPtProfiles(const double& centmult, const double& rn) +{ + for (int m = 1; m <= mpar; ++m) { + if (corrDen[m] != 0) + dynamic_cast(fCorrList->At(m - 1))->FillProfile(centmult, corrNum[m] / corrDen[m], (fEventWeight == kEventWeight::kUnity) ? 1.0 : corrDen[m], rn); + } + return; +} +void FlowPtContainer::FillVnPtProfiles(const double& centmult, const double& flowval, const double& flowtuples, const double& rn, uint8_t mask) +{ + if (!mask) + return; + for (auto m(1); m <= mpar; ++m) { + if (!(mask & (1 << (m - 1)))) + continue; + if (corrDen[m] != 0) + dynamic_cast(fCovList->At(fillCounter))->FillProfile(centmult, flowval * corrNum[m] / corrDen[m], (fEventWeight == kUnity) ? 1.0 : flowtuples * corrDen[m], rn); + ++fillCounter; + } + return; +} +void FlowPtContainer::FillCMProfiles(const double& centmult, const double& rn) +{ + if (sumP[GetVectorIndex(0, 0)] == 0) + return; + double tau1 = sumP[GetVectorIndex(2, 0)] / pow(sumP[GetVectorIndex(1, 0)], 2); + double tau2 = sumP[GetVectorIndex(3, 0)] / pow(sumP[GetVectorIndex(1, 0)], 3); + double tau3 = sumP[GetVectorIndex(4, 0)] / pow(sumP[GetVectorIndex(1, 0)], 4); + // double tau4 = sumP[GetVectorIndex(5,0)]/pow(sumP[GetVectorIndex(1,0)],5); + double weight1 = 1 - tau1; + double weight2 = 1 - 3 * tau1 + 2 * tau2; + double weight3 = 1 - 6 * tau1 + 3 * tau1 * tau1 + 8 * tau2 - 6 * tau3; + // double weight4 = 1 - 10*tau1 + 15*tau1*tau1 + 20*tau2 - 20*tau1*tau2 - 30*tau3 + 24*tau4; + if (mpar < 1 || sumP[GetVectorIndex(1, 0)] == 0) + return; + dynamic_cast(fCMTermList->At(0))->FillProfile(centmult, sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)], (fEventWeight == kEventWeight::kUnity) ? 1.0 : sumP[GetVectorIndex(1, 0)], rn); + if (mpar < 2 || sumP[GetVectorIndex(2, 0)] == 0 || weight1 == 0) + return; + dynamic_cast(fCMTermList->At(1))->FillProfile(centmult, 1 / weight1 * (sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight1, rn); + dynamic_cast(fCMTermList->At(2))->FillProfile(centmult, 1 / weight1 * (-2 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 2 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight1, rn); + if (mpar < 3 || sumP[GetVectorIndex(3, 0)] == 0 || weight2 == 0) + return; + dynamic_cast(fCMTermList->At(3))->FillProfile(centmult, 1 / weight2 * (sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 3 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 2 * tau2 * sumP[GetVectorIndex(3, 3)] / sumP[GetVectorIndex(3, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight2, rn); + dynamic_cast(fCMTermList->At(4))->FillProfile(centmult, 1 / weight2 * (-3 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 3 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] + 6 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 6 * tau2 * sumP[GetVectorIndex(3, 2)] / sumP[GetVectorIndex(3, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight2, rn); + dynamic_cast(fCMTermList->At(5))->FillProfile(centmult, 1 / weight2 * (3 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 6 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] - 3 * tau1 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 6 * tau2 * sumP[GetVectorIndex(3, 1)] / sumP[GetVectorIndex(3, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight2, rn); + if (mpar < 4 || sumP[GetVectorIndex(4, 0)] == 0 || weight3 == 0) + return; + dynamic_cast(fCMTermList->At(6))->FillProfile(centmult, 1 / weight3 * (sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 6 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 3 * tau1 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] + 8 * tau2 * sumP[GetVectorIndex(3, 3)] / sumP[GetVectorIndex(3, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 6 * tau3 * sumP[GetVectorIndex(4, 4)] / sumP[GetVectorIndex(4, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight3, rn); + dynamic_cast(fCMTermList->At(7))->FillProfile(centmult, 1 / weight3 * (-4 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 12 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 12 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 12 * tau1 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] - 8 * tau2 * sumP[GetVectorIndex(3, 3)] / sumP[GetVectorIndex(3, 0)] - 24 * tau2 * sumP[GetVectorIndex(3, 2)] / sumP[GetVectorIndex(3, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 24 * tau3 * sumP[GetVectorIndex(4, 3)] / sumP[GetVectorIndex(4, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight3, rn); + dynamic_cast(fCMTermList->At(8))->FillProfile(centmult, 1 / weight3 * (6 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 6 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] - 24 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 6 * tau1 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 6 * tau1 * tau1 * sumP[GetVectorIndex(2, 2)] / sumP[GetVectorIndex(2, 0)] + 12 * tau1 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] + 24 * tau2 * sumP[GetVectorIndex(3, 2)] / sumP[GetVectorIndex(3, 0)] + 24 * tau2 * sumP[GetVectorIndex(3, 1)] / sumP[GetVectorIndex(3, 0)] * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 36 * tau3 * sumP[GetVectorIndex(4, 2)] / sumP[GetVectorIndex(4, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight3, rn); + dynamic_cast(fCMTermList->At(9))->FillProfile(centmult, 1 / weight3 * (-4 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 12 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] + 12 * tau1 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] - 12 * tau1 * tau1 * sumP[GetVectorIndex(2, 1)] / sumP[GetVectorIndex(2, 0)] - 24 * tau2 * sumP[GetVectorIndex(3, 1)] / sumP[GetVectorIndex(3, 0)] - 8 * tau2 * sumP[GetVectorIndex(1, 1)] / sumP[GetVectorIndex(1, 0)] + 24 * tau3 * sumP[GetVectorIndex(4, 1)] / sumP[GetVectorIndex(4, 0)]), (fEventWeight == kEventWeight::kUnity) ? 1.0 : weight3, rn); + return; +} +double FlowPtContainer::OrderedAddition(std::vector vec) +{ + double sum = 0; + std::sort(vec.begin(), vec.end()); + for (int i = 0; i < vec.size(); i++) { + sum += vec[i]; + } + return sum; +} +void FlowPtContainer::RebinMulti(Int_t nbins) +{ + if (fCMTermList) { + for (Int_t i = 0; i < fCMTermList->GetEntries(); i++) + dynamic_cast(fCMTermList->At(i))->RebinMulti(nbins); + } + if (fCorrList) { + for (Int_t i = 0; i < fCorrList->GetEntries(); i++) + dynamic_cast(fCorrList->At(i))->RebinMulti(nbins); + } + if (fCovList) { + for (Int_t i = 0; i < fCovList->GetEntries(); i++) + dynamic_cast(fCovList->At(i))->RebinMulti(nbins); + } + return; +} +void FlowPtContainer::RebinMulti(Int_t nbins, Double_t* binedges) +{ + if (fCMTermList) { + for (Int_t i = 0; i < fCMTermList->GetEntries(); i++) + dynamic_cast(fCMTermList->At(i))->RebinMulti(nbins, binedges); + } + if (fCorrList) { + for (Int_t i = 0; i < fCorrList->GetEntries(); i++) + dynamic_cast(fCorrList->At(i))->RebinMulti(nbins, binedges); + } + if (fCovList) { + for (Int_t i = 0; i < fCovList->GetEntries(); i++) + dynamic_cast(fCovList->At(i))->RebinMulti(nbins, binedges); + } + return; +} +TH1* FlowPtContainer::getCorrHist(int ind, int m) +{ + return dynamic_cast(fCorrList->FindObject(Form("corr_%ipar", m)))->getHist(ind); +} +TH1* FlowPtContainer::getCentralMomentHist(int ind, int m) +{ + if (!fCentralMomentList) + CreateCentralMomentList(); + if (!fCentralMomentList) + return 0; + if (ind + 1 < fCentralMomentList->GetEntries()) + return dynamic_cast(fCentralMomentList->FindObject(Form("cm%i_%i", m + 1, ind))); + return 0; +} +void FlowPtContainer::CreateCentralMomentList() +{ + if (fCentralMomentList) + delete fCentralMomentList; + fCentralMomentList = new TList(); + fCentralMomentList->SetOwner(); + for (auto m(1); m <= 4; ++m) { + for (int i = -1; i < reinterpret_cast(fCMTermList->At(0))->getNSubs(); ++i) { + TH1* hMpt = reinterpret_cast(fCMTermList->At(0))->getHist(i); + std::vector hTs; + for (int j = 0; j < m; ++j) { + dynamic_cast(fCMTermList->FindObject(Form("cm%i_Mpt%i", m, j)))->SetErrorOption("g"); + hTs.push_back(reinterpret_cast(fCMTermList->FindObject(Form("cm%i_Mpt%i", m, j)))->getHist(i)); + } + CalculateCentralMomentHists(hTs, i, m, hMpt); + } + } + return; +} +void FlowPtContainer::CalculateCentralMomentHists(std::vector inh, int ind, int m, TH1* hMpt) +{ + TH1* reth = reinterpret_cast(inh[0]->Clone(Form("cm%i_%i", m, ind))); + for (auto i(1); i < m; ++i) { + TH1* mptPow = raiseHistToPower(hMpt, i); + inh[i]->Multiply(mptPow); + reth->Add(inh[i]); + } + TH1* mptLast = raiseHistToPower(hMpt, m); + reth->Add(mptLast, (m % 2) ? (-1) : 1); + fCentralMomentList->Add(reth); + return; +} +TH1* FlowPtContainer::getCumulantHist(int ind, int m) +{ + if (!fCumulantList) + CreateCumulantList(); + if (!fCumulantList) + return 0; + if (ind + 1 < fCumulantList->GetEntries()) + return reinterpret_cast(fCumulantList->At((ind + 1) * mpar + m - 1)); +} +void FlowPtContainer::CreateCumulantList() +{ + if (fCumulantList) + delete fCumulantList; + fCumulantList = new TList(); + fCumulantList->SetOwner(); + //((BootstrapProfile*)fCorrList->At(0))->PresetWeights((BootstrapProfile*)fCorrList->At(mpar-1)); + for (int i = -1; i < reinterpret_cast(fCorrList->At(0))->getNSubs(); ++i) { + std::vector hTs; + for (int j = 0; j < mpar; ++j) { + dynamic_cast(fCorrList->FindObject(Form("corr_%ipar", j + 1)))->SetErrorOption("g"); + hTs.push_back(reinterpret_cast(fCorrList->FindObject(Form("corr_%ipar", j + 1)))->getHist(i)); + } + CalculateCumulantHists(hTs, i); + } + //((BootstrapProfile*)fCorrList->At(0))->PresetWeights(0); + return; +} +void FlowPtContainer::CalculateCumulantHists(std::vector inh, int ind) +{ + auto binomial = [&](const int n, const int m) { assert(n >= m); return fFactorial[n]/(fFactorial[m]*fFactorial[n-m]); }; + for (int m = 1; m <= mpar; ++m) { + TH1* reth = dynamic_cast(inh[m - 1]->Clone(Form("reth%i_%i", m, ind))); + // TH1* hWeights = (TH1*)inh[m-1]->Clone(Form("hWeights%i_%i",m,ind)); + for (int k = 1; k < m; ++k) { + TH1* corrh = dynamic_cast(inh[m - k - 1]->Clone(Form("hcorr%i%i_%i", m, k, ind))); + corrh->Multiply(dynamic_cast(fCumulantList->At((ind + 1) * mpar + k - 1))); + corrh->Scale(binomial(m - 1, k - 1)); + reth->Add(corrh, -1); + delete corrh; + } + // for(int i=1;i<=hWeights->GetNbinsX();++i) reth->SetBinError(i,hWeights->GetBinError(i)); + // delete hWeights; + fCumulantList->Add(dynamic_cast(reth->Clone(Form("kappa%i_%i", m, ind)))); + } + return; +} +Long64_t FlowPtContainer::Merge(TCollection* collist) +{ + if (!fCorrList || !fCMTermList) + return 0; + Long64_t nmerged = 0; + TIter all_PTC(collist); + FlowPtContainer* l_PTC = 0; + while ((l_PTC = dynamic_cast(all_PTC()))) { + TList* t_CMTerm = l_PTC->fCMTermList; + TList* t_Corr = l_PTC->fCorrList; + TList* t_Cum = l_PTC->fCumulantList; + TList* t_CM = l_PTC->fCentralMomentList; + if (t_CMTerm) { + if (!fCMTermList) + fCMTermList = dynamic_cast(t_CMTerm->Clone()); + else + MergeBSLists(fCMTermList, t_CMTerm); + nmerged++; + } + if (t_Corr) { + if (!fCorrList) + fCorrList = dynamic_cast(t_Corr->Clone()); + else + MergeBSLists(fCorrList, t_Corr); + } + if (t_Cum) { + if (!fCumulantList) + fCumulantList = dynamic_cast(t_Cum->Clone()); + else + MergeBSLists(fCumulantList, t_Cum); + } + if (t_CM) { + if (!fCentralMomentList) + fCentralMomentList = dynamic_cast(t_CM->Clone()); + else + MergeBSLists(fCentralMomentList, t_CM); + } + } + return nmerged; +} +void FlowPtContainer::MergeBSLists(TList* source, TList* target) +{ + if (source->GetEntries() != target->GetEntries()) { + printf("Number in lists to be merged are not the same, skipping...\n"); + return; + } + for (Int_t i = 0; i < source->GetEntries(); i++) { + BootstrapProfile* l_obj = dynamic_cast(source->At(i)); + BootstrapProfile* t_obj = dynamic_cast(target->At(i)); + l_obj->MergeBS(t_obj); + } +} +TH1* FlowPtContainer::raiseHistToPower(TH1* inh, double p) +{ + TH1D* reth = dynamic_cast(inh->Clone("reth")); + reth->SetName(Form("power%.2f_%s", p, inh->GetName())); + for (int i = 1; i <= inh->GetNbinsX(); i++) { + if (inh->GetBinContent(i) >= 0 || std::floor(p) == p) { + reth->SetBinContent(i, pow(inh->GetBinContent(i), p)); + reth->SetBinError(i, p * pow(reth->GetBinContent(i), p - 1) * inh->GetBinError(i)); + } else { + reth->SetBinContent(i, -999); + reth->SetBinError(i, 0.000000001); + } + } + return reth; +} diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.h b/PWGCF/GenericFramework/Core/FlowPtContainer.h new file mode 100644 index 00000000000..981c1d0540c --- /dev/null +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.h @@ -0,0 +1,95 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef PWGCF_GENERICFRAMEWORK_CORE_FLOWPTCONTAINER_H_ +#define PWGCF_GENERICFRAMEWORK_CORE_FLOWPTCONTAINER_H_ + +#include +#include +#include "BootstrapProfile.h" +#include "TNamed.h" +#include "TList.h" +#include "TCollection.h" +#include "Framework/HistogramSpec.h" +#include "GFW.h" +#include "GFWConfig.h" + +namespace o2::analysis::genericframework::eventweight +{ +enum kEventWeight { + kUnity, + kTuples +}; +}; + +using namespace o2::analysis::genericframework; +using namespace o2::analysis::genericframework::eventweight; + +class FlowPtContainer : public TNamed +{ + public: + FlowPtContainer(); + explicit FlowPtContainer(const char* name); + ~FlowPtContainer(); + FlowPtContainer(const char* name, const char* title, int nbinsx, double* xbins, const int& m, const GFWCorrConfigs& configs); + FlowPtContainer(const char* name, const char* title, int nbinsx, double xlow, double xhigh, const int& m, const GFWCorrConfigs& configs); + void Initialise(const o2::framework::AxisSpec axis, const int& m, const GFWCorrConfigs& configs, const int& nsub = 10); + void Initialise(int nbinsx, double* xbins, const int& m, const GFWCorrConfigs& configs, const int& nsub = 10); + void Initialise(int nbinsx, double xlow, double xhigh, const int& m, const GFWCorrConfigs& configs, const int& nsub = 10); + void Fill(const double& w, const double& pt); + int GetVectorIndex(const int i, const int j) { return j * (mpar + 1) + i; } + void CalculateCorrelations(); + void CalculateCMTerms(); + void FillPtProfiles(const Double_t& lMult, const Double_t& rn); + void FillVnPtProfiles(const double& lMult, const double& flowval, const double& flowtuples, const double& rn, uint8_t mask); + void FillCMProfiles(const double& lMult, const double& rn); + TList* GetCorrList() { return fCorrList; } + TList* GetCMTermList() { return fCMTermList; } + void SetEventWeight(const unsigned int& lWeight) { fEventWeight = lWeight; } + void RebinMulti(Int_t nbins); + void RebinMulti(Int_t nbins, double* binedges); + TH1* getCentralMomentHist(int ind, int m); + TH1* getCumulantHist(int ind, int m); + TH1* getCorrHist(int ind, int m); + Int_t getMpar() { return mpar; } + Long64_t Merge(TCollection* collist); + Double_t OrderedAddition(std::vector vec); + void CreateCentralMomentList(); + void CalculateCentralMomentHists(std::vector inh, int ind, int m, TH1* hMpt); + void CreateCumulantList(); + void CalculateCumulantHists(std::vector inh, Int_t ind); + void ClearVector() + { + sumP.clear(); + sumP.resize((mpar + 1) * (mpar + 1)); + fillCounter = 0; + }; + + private: + TList* fCMTermList; + TList* fCorrList; + TList* fCovList; + TList* fCumulantList; + TList* fCentralMomentList; + int mpar; + int fillCounter; + unsigned int fEventWeight; + void MergeBSLists(TList* source, TList* target); + TH1* raiseHistToPower(TH1* inh, double p); + std::vector sumP; //! + std::vector corrNum; //! + std::vector corrDen; //! + + static constexpr float fFactorial[9] = {1., 1., 2., 6., 24., 120., 720., 5040., 40320.}; + static constexpr int fSign[9] = {1, -1, 1, -1, 1, -1, 1, -1, 1}; + ClassDef(FlowPtContainer, 1); +}; +#endif // PWGCF_GENERICFRAMEWORK_CORE_FLOWPTCONTAINER_H_ diff --git a/PWGCF/GenericFramework/Core/GFWConfig.h b/PWGCF/GenericFramework/Core/GFWConfig.h index 80474125bbf..18d26024e45 100644 --- a/PWGCF/GenericFramework/Core/GFWConfig.h +++ b/PWGCF/GenericFramework/Core/GFWConfig.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include "GFW.h" @@ -48,13 +47,25 @@ int CheckSameSize(const std::vector& first, const std::vector&... rest) class GFWBinningCuts { public: - GFWBinningCuts(int vtxzbins = 40, float vtxzmin = -10., float vtxzmax = 10, float ptpoimin = 0.2, float ptpoimax = 10., - std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, - 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, - 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, - 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, - int etabins = 16, float etamin = -0.8, float etamax = 0.8, int phibins = 72, float ptrefmin = 0.2, float ptrefmax = 3., int nchbins = 300, - float nchmin = 0.5, float nchmax = 3000.5, std::vector centbinning = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0}) : mVtxZbins{vtxzbins}, mVtxZmin{vtxzmin}, mVtxZmax{vtxzmax}, mPTpoimin{ptpoimin}, mPTpoimax{ptpoimax}, mPTbinning{std::move(ptbinning)}, mEtabins{etabins}, mEtamin{etamin}, mEtamax{etamax}, mPhibins{phibins}, mPTrefmin{ptrefmin}, mPTrefmax{ptrefmax}, mNchbins{nchbins}, mNchmin{nchmin}, mNchmax{nchmax}, mCentbinning{std::move(centbinning)} {}; + GFWBinningCuts(int vtxzbins_ = 40, float vtxzmin_ = -10., float vtxzmax_ = 10, int etabins_ = 16, float etamin_ = -0.8, float etamax_ = 0.8, + int phibins_ = 72, int nchbins_ = 300, float nchmin_ = 0.5, float nchmax_ = 3000.5, + float ptpoimin_ = 0.2, float ptpoimax_ = 10., float ptrefmin_ = 0.2, float ptrefmax_ = 3., + std::vector ptbinning_ = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, + 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, + 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, + 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, + std::vector centbinning_ = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, + 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, + 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, + 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, + 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0}) : mVtxZbins{vtxzbins_}, mVtxZmin{vtxzmin_}, mVtxZmax{vtxzmax_}, mEtabins{etabins_}, mEtamin{etamin_}, mEtamax{etamax_}, mPhibins{phibins_}, mNchbins{nchbins_}, mNchmin{nchmin_}, mNchmax{nchmax_}, mPTpoimin{ptpoimin_}, mPTpoimax{ptpoimax_}, mPTrefmin{ptrefmin_}, mPTrefmax{ptrefmax_}, mPTbinning{std::move(ptbinning_)}, mCentbinning{std::move(centbinning_)} {}; + + auto Print() const + { + LOGF(info, "Vz: %d, %.1f, %.1f | Eta: %d, %.1f, %.1f | Phi: %d | Pt POI: %.2f, %.2f | Pt Ref: %.2f, %.2f | Nch: %d, %.1f, %.1f", mVtxZbins, mVtxZmin, mVtxZmax, mEtabins, mEtamin, mEtamax, mPhibins, mPTpoimin, mPTpoimax, mPTrefmin, mPTrefmax, mNchbins, mNchmin, mNchmax); + return; + } + void SetVtxZBinning(int vtxbins, float vtxmin, float vtxmax) { mVtxZbins = vtxbins; @@ -73,7 +84,7 @@ class GFWBinningCuts const auto& GetPtPOImin() const { return mPTpoimin; } const auto& GetPtPOImax() const { return mPTpoimax; } - void SetPtBinning(std::vector ptbinning) { mPTbinning = std::move(ptbinning); } + void SetPtBinning(std::vector ptbinning_) { mPTbinning = std::move(ptbinning_); } const auto& GetPtBinning() const { return mPTbinning; } void SetEtaBinning(int etabins, float etamin, float etamax) @@ -110,25 +121,25 @@ class GFWBinningCuts const auto& GetNchMin() const { return mNchmin; } const auto& GetNchMax() const { return mNchmax; } - void SetCentBinning(std::vector centbinning) { mCentbinning = std::move(centbinning); } + void SetCentBinning(std::vector centbinning_) { mCentbinning = std::move(centbinning_); } const auto& GetCentBinning() const { return mCentbinning; } private: int mVtxZbins; float mVtxZmin; float mVtxZmax; - float mPTpoimin; - float mPTpoimax; - std::vector mPTbinning; int mEtabins; float mEtamin; float mEtamax; int mPhibins; - float mPTrefmin; - float mPTrefmax; int mNchbins; float mNchmin; float mNchmax; + float mPTpoimin; + float mPTpoimax; + float mPTrefmin; + float mPTrefmax; + std::vector mPTbinning; std::vector mCentbinning; ClassDefNV(GFWBinningCuts, 1); }; @@ -147,13 +158,10 @@ class GFWRegions auto Print() const { - std::stringstream ss; for (auto i = 0; i < names.size(); ++i) { - ss << "{" << names[i] << ", " << etaminvals[i] << ", " << etamaxvals[i] << ", " << pTDifs[i] << ", " << bitmasks[i] << "}"; - if (i != names.size() - 1) - ss << "\n"; + LOGF(info, "{%s, %.1f, %.1f, %d, %d}", names[i].c_str(), etaminvals[i], etamaxvals[i], pTDifs[i], bitmasks[i]); } - return ss.str(); + return; } auto GetSize() const { return CheckSameSize(names, etaminvals, etamaxvals, pTDifs, bitmasks); } @@ -191,17 +199,14 @@ class GFWCorrConfigs GFWCorrConfigs(std::vector corrs_ = {"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, std::vector heads_ = {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, - std::vector pTDifs_ = {0, 0, 0, 0, 0}) : corrs{std::move(corrs_)}, heads{std::move(heads_)}, pTDifs{std::move(pTDifs_)} {}; + std::vector pTDifs_ = {0, 0, 0, 0, 0}, std::vector pTCorrMasks_ = {15, 1, 1, 0, 0}) : corrs{std::move(corrs_)}, heads{std::move(heads_)}, pTDifs{std::move(pTDifs_)}, pTCorrMasks{std::move(pTCorrMasks_)} {}; auto Print() const { - std::stringstream ss; for (auto i = 0; i < corrs.size(); ++i) { - ss << "{" << heads[i] << ", " << corrs[i] << ", " << pTDifs[i] << "}"; - if (i != corrs.size() - 1) - ss << "\n"; + LOGF(info, "{%s,%s,%d,%d}", heads[i].c_str(), corrs[i].c_str(), pTDifs[i], pTCorrMasks[i]); } - return ss.str(); + return; } auto GetSize() const { return CheckSameSize(corrs, heads, pTDifs); } @@ -215,10 +220,14 @@ class GFWCorrConfigs void SetpTDifs(std::vector pTDifs_) { pTDifs = std::move(pTDifs_); } const auto& GetpTDifs() const { return pTDifs; } + void SetpTCorrMasks(std::vector pTCorrMasks_) { pTCorrMasks = std::move(pTCorrMasks_); } + const auto& GetpTCorrMasks() const { return pTCorrMasks; } + private: std::vector corrs; std::vector heads; std::vector pTDifs; + std::vector pTCorrMasks; ClassDefNV(GFWCorrConfigs, 1); }; diff --git a/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h b/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h index ae931455101..2279a79b473 100755 --- a/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h +++ b/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h @@ -22,6 +22,8 @@ #pragma link C++ class ProfileSubset + ; #pragma link C++ class FlowContainer + ; #pragma link C++ class GFWWeights + ; +#pragma link C++ class BootstrapProfile + ; +#pragma link C++ class FlowPtContainer + ; #pragma link C++ class o2::analysis::genericframework::GFWBinningCuts + ; #pragma link C++ class o2::analysis::genericframework::GFWRegions + ; #pragma link C++ class o2::analysis::genericframework::GFWCorrConfigs + ; diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index fd67307c5c2..3bc17f5a005 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -30,6 +30,7 @@ #include "GFW.h" #include "GFWCumulant.h" #include "FlowContainer.h" +#include "FlowPtContainer.h" #include "GFWConfig.h" #include "GFWWeights.h" #include @@ -52,7 +53,7 @@ std::vector ptbinning = { 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; float ptpoilow = 0.2, ptpoiup = 10.0; float ptreflow = 0.2, ptrefup = 3.0; -float ptlow = 0.2, ptup = 3.0; +float ptlow = 0.2, ptup = 10.0; int etabins = 16; float etalow = -0.8, etaup = 0.8; int vtxZbins = 40; @@ -74,6 +75,7 @@ using namespace o2::analysis::genericframework; struct GenericFramework { O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") + O2_DEFINE_CONFIGURABLE(cfgMpar, int, 8, "Highest order of pt-pt correlations") O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Do correlations as function of Nch") O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") O2_DEFINE_CONFIGURABLE(cfgFillQA, bool, false, "Fill QA histograms") @@ -81,14 +83,13 @@ struct GenericFramework { O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") O2_DEFINE_CONFIGURABLE(cfgDCAxy, float, 0.2, "Cut on DCA in the transverse direction"); + O2_DEFINE_CONFIGURABLE(cfgPtmin, float, 0.2, "minimum pt"); + O2_DEFINE_CONFIGURABLE(cfgPtmax, float, 10, "maximum pt"); - Configurable cfgBinning{"cfgBinning", - {40, -10.0, 10.0, 0.2, 2.0, {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, 16, -0.8, 0.8, 72, 0.2, 5.0, 300, 0.5, 3000.5, {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}}, - "triplets - nbins, min, max - for z_vtx, PtPOI, eta - nbins for phi - ptRef min and max"}; - + Configurable cfgGFWBinning{"cfgGFWBinning", {40, -10.0, 10.0, 16, -0.8, 0.8, 72, 300, 0.5, 3000.5, 0.2, 10.0, 0.2, 3.0, {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}}, "Configuration for binning"}; Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; - Configurable cfgCorrConfig{"cfgCorrConfig", {{"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, {0, 0, 0, 0, 0}}, "Configurations for each correlation to calculate"}; + Configurable cfgCorrConfig{"cfgCorrConfig", {{"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, {0, 0, 0, 0, 0}, {15, 1, 1, 0, 0}}, "Configurations for each correlation to calculate"}; // #include "PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.cxx" // NOLINT // Connect to ccdb @@ -102,6 +103,7 @@ struct GenericFramework { // Define output OutputObj fFC{FlowContainer("FlowContainer")}; + OutputObj fFCpt{FlowPtContainer("FlowPtContainer")}; OutputObj fFC_gen{FlowContainer("FlowContainer_gen")}; OutputObj fWeights{GFWWeights("weights")}; HistogramRegistry registry{"registry"}; @@ -130,28 +132,30 @@ struct GenericFramework { configs.SetCorrs(cfgCorrConfig->GetCorrs()); configs.SetHeads(cfgCorrConfig->GetHeads()); configs.SetpTDifs(cfgCorrConfig->GetpTDifs()); - LOGF(info, "Regions:\n%s", regions.Print()); - LOGF(info, "CorrConfigs:\n%s", configs.Print()); - ptbinning = cfgBinning->GetPtBinning(); - ptpoilow = cfgBinning->GetPtPOImin(); - ptpoiup = cfgBinning->GetPtPOImax(); - ptreflow = cfgBinning->GetPtRefMin(); - ptrefup = cfgBinning->GetPtRefMax(); - ptlow = cfgBinning->GetPtMin(); - ptup = cfgBinning->GetPtMax(); - etabins = cfgBinning->GetEtaBins(); - etalow = cfgBinning->GetEtaMin(); - etaup = cfgBinning->GetEtaMax(); - vtxZbins = cfgBinning->GetVtxZbins(); - vtxZlow = cfgBinning->GetVtxZmin(); - vtxZup = cfgBinning->GetVtxZmax(); - phibins = cfgBinning->GetPhiBins(); + configs.SetpTCorrMasks(cfgCorrConfig->GetpTCorrMasks()); + regions.Print(); + configs.Print(); + ptbinning = cfgGFWBinning->GetPtBinning(); + ptpoilow = cfgGFWBinning->GetPtPOImin(); + ptpoiup = cfgGFWBinning->GetPtPOImax(); + ptreflow = cfgGFWBinning->GetPtRefMin(); + ptrefup = cfgGFWBinning->GetPtRefMax(); + ptlow = cfgPtmin; + ptup = cfgPtmax; + etabins = cfgGFWBinning->GetEtaBins(); + etalow = cfgGFWBinning->GetEtaMin(); + etaup = cfgGFWBinning->GetEtaMax(); + vtxZbins = cfgGFWBinning->GetVtxZbins(); + vtxZlow = cfgGFWBinning->GetVtxZmin(); + vtxZup = cfgGFWBinning->GetVtxZmax(); + phibins = cfgGFWBinning->GetPhiBins(); philow = 0.0f; phiup = constants::math::TwoPI; - nchbins = cfgBinning->GetNchBins(); - nchlow = cfgBinning->GetNchMin(); - nchup = cfgBinning->GetNchMax(); - centbinning = cfgBinning->GetCentBinning(); + nchbins = cfgGFWBinning->GetNchBins(); + nchlow = cfgGFWBinning->GetNchMin(); + nchup = cfgGFWBinning->GetNchMax(); + centbinning = cfgGFWBinning->GetCentBinning(); + cfgGFWBinning->Print(); AxisSpec phiAxis = {phibins, philow, phiup, "#phi"}; AxisSpec etaAxis = {etabins, etalow, etaup, "#eta"}; @@ -182,13 +186,13 @@ struct GenericFramework { fWeights->Init(true, false); } - if (doprocessGen) { + if (doprocessMCGen) { registry.add("pt_gen", "", {HistType::kTH1D, {ptAxis}}); registry.add("phi_gen", "", {HistType::kTH1D, {phiAxis}}); registry.add("eta_gen", "", {HistType::kTH1D, {etaAxis}}); registry.add("vtxZ_gen", "", {HistType::kTH1D, {vtxAxis}}); } - if (doprocessReco || doprocessData || doprocessRun2) { + if (doprocessMCReco || doprocessData || doprocessRun2) { registry.add("phi", "", {HistType::kTH1D, {phiAxis}}); registry.add("eta", "", {HistType::kTH1D, {etaAxis}}); registry.add("vtxZ", "", {HistType::kTH1D, {vtxAxis}}); @@ -211,18 +215,18 @@ struct GenericFramework { fGFW->CreateRegions(); TObjArray* oba = new TObjArray(); AddConfigObjectsToObjArray(oba, corrconfigs); - if (doprocessReco || doprocessData || doprocessRun2) { + if (doprocessData || doprocessRun2 || doprocessMCReco) { fFC->SetName("FlowContainer"); fFC->SetXAxis(fPtAxis); fFC->Initialize(oba, multAxis, cfgNbootstrap); } - if (doprocessGen) { + if (doprocessMCGen) { fFC_gen->SetName("FlowContainer_gen"); fFC_gen->SetXAxis(fPtAxis); fFC_gen->Initialize(oba, multAxis, cfgNbootstrap); } delete oba; - + fFCpt->Initialise(multAxis, cfgMpar, configs, cfgNbootstrap); // Event selection - Alex if (cfgUse22sEventCut) { fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); @@ -292,29 +296,6 @@ struct GenericFramework { return true; } - void FillFC(OutputObj fc, const GFW::CorrConfig& corrconf, const float& centmult, const double& rndm) - { - double dnx, val; - dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); - if (dnx == 0) - return; - if (!corrconf.pTDif) { - val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; - if (TMath::Abs(val) < 1) - fc->FillProfile(corrconf.Head.c_str(), centmult, val, dnx, rndm); - return; - } - for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { - dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); - if (dnx == 0) - continue; - val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; - if (TMath::Abs(val) < 1) - fc->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), centmult, val, dnx, rndm); - } - return; - } - template bool eventSelected(TCollision collision, const int& multTrk, const float& centrality) { @@ -351,11 +332,38 @@ struct GenericFramework { } enum datatype { - kData, - kDerivedData, + kReco, kGen }; + template + void FillOutputContainers(const GFW::CorrConfig& corrconf, const float& centmult, const double& rndm, uint8_t mask) + { + fFCpt->CalculateCorrelations(); + fFCpt->FillPtProfiles(centmult, rndm); + fFCpt->FillCMProfiles(centmult, rndm); + auto dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + auto val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) { + (dt == kGen) ? fFC_gen->FillProfile(corrconf.Head.c_str(), centmult, val, dnx, rndm) : fFC->FillProfile(corrconf.Head.c_str(), centmult, val, dnx, rndm); + fFCpt->FillVnPtProfiles(centmult, val, dnx, rndm, mask); + } + return; + } + for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { + dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); + if (dnx == 0) + continue; + auto val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + (dt == kGen) ? fFC_gen->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), centmult, val, dnx, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), centmult, val, dnx, rndm); + } + return; + } + template void processCollision(TCollision collision, TTracks tracks, const float& centrality) { @@ -367,12 +375,13 @@ struct GenericFramework { if (cfgFillQA) (dt == kGen) ? registry.fill(HIST("vtxZ_gen"), vtxz) : registry.fill(HIST("vtxZ"), vtxz); fGFW->Clear(); + fFCpt->ClearVector(); float l_Random = fRndm->Rndm(); for (auto& track : tracks) { ProcessTrack(track, centrality, vtxz); } - for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - FillFC((dt == kGen) ? fFC_gen : fFC, corrconfigs.at(l_ind), (cfgUseNch) ? tracks.size() : centrality, l_Random); + for (uint l_ind = 0; l_ind < corrconfigs.size(); ++l_ind) { + FillOutputContainers

(corrconfigs.at(l_ind), (cfgUseNch) ? tracks.size() : centrality, l_Random, configs.GetpTCorrMasks()[l_ind]); } } @@ -392,14 +401,14 @@ struct GenericFramework { return; registry.fill(HIST("phi_eta_vtxZ_corrected"), mcParticle.phi(), mcParticle.eta(), vtxz, wacc); if (cfgFillQA) - FillQA(mcParticle.phi(), mcParticle.eta(), mcParticle.pt(), track.dcaXY(), track.dcaZ()); - FillGFW(mcParticle.phi(), mcParticle.eta(), mcParticle.pt(), weff * wacc); + FillQA(track); + FillGFW(mcParticle, weff, wacc); } else if constexpr (framework::has_type_v) { if (!track.isPhysicalPrimary() || track.eta() < etalow || track.eta() > etaup || track.pt() < ptlow || track.pt() > ptup) return; if (cfgFillQA) - FillQA(track.phi(), track.eta(), track.pt()); - FillGFW(track.phi(), track.eta(), track.pt(), 1.); + FillQA(track); + FillGFW(track, 1., 1.); } else { if (cfgFillWeights) fWeights->Fill(track.phi(), track.eta(), vtxz, track.pt(), centrality, 0); @@ -407,41 +416,42 @@ struct GenericFramework { return; registry.fill(HIST("phi_eta_vtxZ_corrected"), track.phi(), track.eta(), vtxz, wacc); if (cfgFillQA) - FillQA(track.phi(), track.eta(), track.pt(), track.dcaXY(), track.dcaZ()); - FillGFW(track.phi(), track.eta(), track.pt(), weff * wacc); + FillQA(track); + FillGFW(track, weff, wacc); } } - template - inline void FillGFW(T phi, T eta, T pt, float w) + template + inline void FillGFW(TrackObject track, float weff, float wacc) { - bool WithinPtPOI = (ptpoilow < pt) && (pt < ptpoiup); // within POI pT range - bool WithinPtRef = (ptreflow < pt) && (pt < ptrefup); // within RF pT range + fFCpt->Fill(weff, track.pt()); + bool WithinPtPOI = (ptpoilow < track.pt()) && (track.pt() < ptpoiup); // within POI pT range + bool WithinPtRef = (ptreflow < track.pt()) && (track.pt() < ptrefup); // within RF pT range if (WithinPtRef) - fGFW->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, w, 1); + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 1); if (WithinPtPOI) - fGFW->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, w, 2); + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 2); if (WithinPtPOI && WithinPtRef) - fGFW->Fill(eta, fPtAxis->FindBin(pt) - 1, phi, w, 4); + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 4); return; } - template - inline void FillQA(T phi, T eta, T pt, T dcaxy = 0, T dcaz = 0) + template + inline void FillQA(TrackObject track) { - if (dt == kGen) { - registry.fill(HIST("phi_gen"), phi); - registry.fill(HIST("eta_gen"), eta); - registry.fill(HIST("pt_gen"), pt); + if constexpr (dt == kGen) { + registry.fill(HIST("phi_gen"), track.phi()); + registry.fill(HIST("eta_gen"), track.eta()); + registry.fill(HIST("pt_gen"), track.pt()); } else { - registry.fill(HIST("phi"), phi); - registry.fill(HIST("eta"), eta); - registry.fill(HIST("pt_dcaXY_dcaZ"), pt, dcaxy, dcaz); + registry.fill(HIST("phi"), track.phi()); + registry.fill(HIST("eta"), track.eta()); + registry.fill(HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); } } - Filter collisionFilter = aod::collision::posZ < cfgBinning->GetVtxZmax() && aod::collision::posZ > cfgBinning->GetVtxZmin(); - Filter trackFilter = aod::track::eta < cfgBinning->GetEtaMax() && aod::track::eta > cfgBinning->GetEtaMin() && aod::track::pt > cfgBinning->GetPtMin() && aod::track::pt < cfgBinning->GetPtMax() && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDCAxy; + Filter collisionFilter = aod::collision::posZ < cfgGFWBinning->GetVtxZmax() && aod::collision::posZ > cfgGFWBinning->GetVtxZmin(); + Filter trackFilter = aod::track::eta < cfgGFWBinning->GetEtaMax() && aod::track::eta > cfgGFWBinning->GetEtaMin() && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDCAxy; using myTracks = soa::Filtered>; void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) @@ -455,11 +465,11 @@ struct GenericFramework { registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); registry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); - processCollision(collision, tracks, centrality); + processCollision(collision, tracks, centrality); } PROCESS_SWITCH(GenericFramework, processData, "Process analysis for non-derived data", true); - void processReco(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks, aod::McParticles const&) + void processMCReco(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks, aod::McParticles const&) { if (!collision.sel8()) return; @@ -470,12 +480,12 @@ struct GenericFramework { registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); registry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); - processCollision(collision, tracks, centrality); + processCollision(collision, tracks, centrality); } - PROCESS_SWITCH(GenericFramework, processReco, "Process analysis for MC reconstructed events", false); + PROCESS_SWITCH(GenericFramework, processMCReco, "Process analysis for MC reconstructed events", false); - Filter mcCollFilter = aod::mccollision::posZ < cfgBinning->GetVtxZmax() && aod::mccollision::posZ > cfgBinning->GetVtxZmin(); - void processGen(soa::Filtered::iterator const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& particles) + Filter mcCollFilter = aod::mccollision::posZ < cfgGFWBinning->GetVtxZmax() && aod::mccollision::posZ > cfgGFWBinning->GetVtxZmin(); + void processMCGen(soa::Filtered::iterator const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& particles) { if (collisions.size() != 1) return; @@ -485,7 +495,7 @@ struct GenericFramework { } processCollision(mcCollision, particles, centrality); } - PROCESS_SWITCH(GenericFramework, processGen, "Process analysis for MC generated events", false); + PROCESS_SWITCH(GenericFramework, processMCGen, "Process analysis for MC generated events", false); void processRun2(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks) { @@ -498,7 +508,7 @@ struct GenericFramework { registry.fill(HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); registry.fill(HIST("cent_nch"), tracks.size(), centrality); loadCorrections(bc.timestamp()); - processCollision(collision, tracks, centrality); + processCollision(collision, tracks, centrality); } PROCESS_SWITCH(GenericFramework, processRun2, "Process analysis for Run 2 converted data", false); }; From e3116cf4f22e6b91bea93c3d35fba44fa76e5162 Mon Sep 17 00:00:00 2001 From: Paul Buehler Date: Thu, 11 Jan 2024 12:42:03 +0100 Subject: [PATCH 151/156] PWG-UD Enable different types of vetoes with FIT detectors: (#4273) * Enable different types of vetoes with FIT detectors: TVX, TSC. TCE. TOR * clang-format --- PWGUD/Core/DGCutparHolder.cxx | 20 +++++++++ PWGUD/Core/DGCutparHolder.h | 20 ++++++++- PWGUD/Core/DGSelector.h | 49 +++++++++++++++++--- PWGUD/Core/UDHelpers.h | 85 ++++++++++++++++++++++------------- 4 files changed, 136 insertions(+), 38 deletions(-) diff --git a/PWGUD/Core/DGCutparHolder.cxx b/PWGUD/Core/DGCutparHolder.cxx index 3e6e452a278..e572c611114 100644 --- a/PWGUD/Core/DGCutparHolder.cxx +++ b/PWGUD/Core/DGCutparHolder.cxx @@ -78,6 +78,22 @@ void DGCutparHolder::SetMaxNSigmaTOF(float maxnSigma) { mMaxNSigmaTOF = maxnSigma; } +void DGCutparHolder::SetTVX(bool tvx) +{ + mTVX = tvx; +} +void DGCutparHolder::SetTSC(bool tsc) +{ + mTSC = tsc; +} +void DGCutparHolder::SetTCE(bool tce) +{ + mTCE = tce; +} +void DGCutparHolder::SetTOR(bool tor) +{ + mTOR = tor; +} void DGCutparHolder::SetMaxFITtime(float maxFITtime) { mMaxFITtime = maxFITtime; @@ -108,5 +124,9 @@ float DGCutparHolder::minIVM() const { return mMinIVM; } float DGCutparHolder::maxIVM() const { return mMaxIVM; } float DGCutparHolder::maxNSigmaTPC() const { return mMaxNSigmaTPC; } float DGCutparHolder::maxNSigmaTOF() const { return mMaxNSigmaTOF; } +bool DGCutparHolder::withTVX() const { return mTVX; } +bool DGCutparHolder::withTSC() const { return mTSC; } +bool DGCutparHolder::withTCE() const { return mTCE; } +bool DGCutparHolder::withTOR() const { return mTOR; } float DGCutparHolder::maxFITtime() const { return mMaxFITtime; } std::vector DGCutparHolder::FITAmpLimits() const { return mFITAmpLimits; } diff --git a/PWGUD/Core/DGCutparHolder.h b/PWGUD/Core/DGCutparHolder.h index 64b832aa59e..02804b2de5c 100644 --- a/PWGUD/Core/DGCutparHolder.h +++ b/PWGUD/Core/DGCutparHolder.h @@ -33,8 +33,12 @@ class DGCutparHolder float minEta = -1.0, float maxEta = 1.0, float minIVM = 0.0, float maxIVM = 1000., float maxNSigmaTPC = 1000., float maxNSigmaTOF = 1000., + bool TVX = false, + bool TSC = false, + bool TCE = false, + bool TOR = true, float maxFITtime = 4, - std::vector FITAmpLimits = {0., 0., 0., 0., 0.}) : mNDtcoll{ndtcoll}, mMinNBCs{nMinBCs}, mWithFwdTracks{withFwdTracks}, mGlobalTracksOnly{globalTracksOnly}, mITSOnlyTracks{ITSonlyTracks}, mMinRgtrwTOF{minrgtrwTOF}, mMinNTracks{MinNTracks}, mMaxNTracks{MaxNTracks}, mNetCharges{NetCharges}, mPidHypo{pidHypo}, mMinVertexPosz{MinPosz}, mMaxVertexPosz{MaxPosz}, mMinPt{minPt}, mMaxPt{maxPt}, mMinEta{minEta}, mMaxEta{maxEta}, mMinIVM{minIVM}, mMaxIVM{maxIVM}, mMaxNSigmaTPC{maxNSigmaTPC}, mMaxNSigmaTOF{maxNSigmaTOF}, mMaxFITtime{maxFITtime}, mFITAmpLimits{FITAmpLimits} + std::vector FITAmpLimits = {0., 0., 0., 0., 0.}) : mNDtcoll{ndtcoll}, mMinNBCs{nMinBCs}, mWithFwdTracks{withFwdTracks}, mGlobalTracksOnly{globalTracksOnly}, mITSOnlyTracks{ITSonlyTracks}, mMinRgtrwTOF{minrgtrwTOF}, mMinNTracks{MinNTracks}, mMaxNTracks{MaxNTracks}, mNetCharges{NetCharges}, mPidHypo{pidHypo}, mMinVertexPosz{MinPosz}, mMaxVertexPosz{MaxPosz}, mMinPt{minPt}, mMaxPt{maxPt}, mMinEta{minEta}, mMaxEta{maxEta}, mMinIVM{minIVM}, mMaxIVM{maxIVM}, mMaxNSigmaTPC{maxNSigmaTPC}, mMaxNSigmaTOF{maxNSigmaTOF}, mTVX{TVX}, mTSC{TSC}, mTCE{TCE}, mTOR{TOR}, mMaxFITtime{maxFITtime}, mFITAmpLimits{FITAmpLimits} { } @@ -54,6 +58,10 @@ class DGCutparHolder void SetIVMRange(float minIVM, float maxIVM); void SetMaxNSigmaTPC(float maxnSigma); void SetMaxNSigmaTOF(float maxnSigma); + void SetTVX(bool tvx); + void SetTSC(bool tsc); + void SetTCE(bool tce); + void SetTOR(bool tor); void SetMaxFITtime(float maxFITtime); void SetFITAmpLimits(std::vector FITAmpLimits); @@ -78,6 +86,10 @@ class DGCutparHolder float maxIVM() const; float maxNSigmaTPC() const; float maxNSigmaTOF() const; + bool withTVX() const; + bool withTSC() const; + bool withTCE() const; + bool withTOR() const; float maxFITtime() const; std::vector FITAmpLimits() const; @@ -117,6 +129,12 @@ class DGCutparHolder float mMaxNSigmaTPC; // maximum nSigma TPC float mMaxNSigmaTOF; // maximum nSigma TOF + // FIT vetoes + bool mTVX; + bool mTSC; + bool mTCE; + bool mTOR; + // maximum FIT time float mMaxFITtime; diff --git a/PWGUD/Core/DGSelector.h b/PWGUD/Core/DGSelector.h index c354a0c7297..0bb7e80bde2 100644 --- a/PWGUD/Core/DGSelector.h +++ b/PWGUD/Core/DGSelector.h @@ -43,11 +43,50 @@ class DGSelector LOGF(debug, "Collision %f", collision.collisionTime()); LOGF(debug, "Number of close BCs: %i", bcRange.size()); - // check that there are no FIT signals in any of the compatible BCs + // return if FIT veto is found in any of the compatible BCs // Double Gap (DG) condition - for (auto const& bc : bcRange) { - if (!udhelpers::cleanFIT(bc, diffCuts.maxFITtime(), diffCuts.FITAmpLimits())) { - return 1; + // 4 types of vetoes: + // 0 TVX + // 1 TSC + // 2 TCE + // 3 TOR + int vetoToApply = -1; + if (diffCuts.withTVX()) { + vetoToApply = 0; + } else if (diffCuts.withTSC()) { + vetoToApply = 1; + } else if (diffCuts.withTCE()) { + vetoToApply = 2; + } else if (diffCuts.withTOR()) { + vetoToApply = 3; + } + if (vetoToApply >= 0) { + for (auto const& bc : bcRange) { + switch (vetoToApply) { + case 0: + if (udhelpers::TVX(bc)) { + return 1; + } + break; + case 1: + if (udhelpers::TSC(bc)) { + return 1; + } + break; + case 2: + if (udhelpers::TCE(bc)) { + return 1; + } + break; + case 3: + if (!udhelpers::cleanFIT(bc, diffCuts.maxFITtime(), diffCuts.FITAmpLimits())) { + return 1; + } + break; + default: + LOGF(info, "Invalid veto trigger value: %d", vetoToApply); + break; + } } } @@ -55,7 +94,7 @@ class DGSelector LOGF(debug, "FwdTracks %i", fwdtracks.size()); if (!diffCuts.withFwdTracks()) { for (auto& fwdtrack : fwdtracks) { - LOGF(info, " %i / %f / %f / %f / %f", fwdtrack.trackType(), fwdtrack.eta(), fwdtrack.pt(), fwdtrack.p(), fwdtrack.trackTimeRes()); + LOGF(debug, " %i / %f / %f / %f / %f", fwdtrack.trackType(), fwdtrack.eta(), fwdtrack.pt(), fwdtrack.p(), fwdtrack.trackTimeRes()); // only consider tracks with MID (good timing) if (fwdtrack.trackType() == 0 || fwdtrack.trackType() == 3) { return 2; diff --git a/PWGUD/Core/UDHelpers.h b/PWGUD/Core/UDHelpers.h index 33c1cb967dd..408dce94f9f 100644 --- a/PWGUD/Core/UDHelpers.h +++ b/PWGUD/Core/UDHelpers.h @@ -21,6 +21,7 @@ #include "TLorentzVector.h" #include "Framework/Logger.h" #include "DataFormatsFT0/Digit.h" +#include "DataFormatsFIT/Triggers.h" #include "CommonConstants/LHCConstants.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -49,7 +50,6 @@ int8_t netCharge(TCs tracks) return nch; } -// ----------------------------------------------------------------------------- // return net charge of tracks template ::type* = nullptr, typename TCs> int8_t netCharge(TCs tracks) @@ -118,7 +118,7 @@ T compatibleBCs(I& bcIter, uint64_t meanBC, int deltaBC, T const& bcs) // check [min,max]BC to overlap with [bcs.iteratorAt([0,bcs.size() - 1]) if (maxBC < bcs.iteratorAt(0).globalBC() || minBC > bcs.iteratorAt(bcs.size() - 1).globalBC()) { - LOGF(info, " No overlap of [%d, %d] and [%d, %d]", minBC, maxBC, bcs.iteratorAt(0).globalBC(), bcs.iteratorAt(bcs.size() - 1).globalBC()); + LOGF(debug, " No overlap of [%d, %d] and [%d, %d]", minBC, maxBC, bcs.iteratorAt(0).globalBC(), bcs.iteratorAt(bcs.size() - 1).globalBC()); return T{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; } @@ -297,34 +297,22 @@ bool hasGoodPID(DGCutparHolder diffCuts, TC track) // ----------------------------------------------------------------------------- float FV0AmplitudeA(aod::FV0A&& fv0) { - float totAmplitude = 0; - for (auto amp : fv0.amplitude()) { - totAmplitude += amp; - } - - return totAmplitude; + const auto& ampsA = fv0.amplitude(); + return std::accumulate(ampsA.begin(), ampsA.end(), 0.f); } // ----------------------------------------------------------------------------- float FT0AmplitudeA(aod::FT0&& ft0) { - float totAmplitude = 0; - for (auto amp : ft0.amplitudeA()) { - totAmplitude += amp; - } - - return totAmplitude; + const auto& ampsA = ft0.amplitudeA(); + return std::accumulate(ampsA.begin(), ampsA.end(), 0.f); } // ----------------------------------------------------------------------------- float FT0AmplitudeC(aod::FT0&& ft0) { - float totAmplitude = 0; - for (auto amp : ft0.amplitudeC()) { - totAmplitude += amp; - } - - return totAmplitude; + const auto& ampsC = ft0.amplitudeC(); + return std::accumulate(ampsC.begin(), ampsC.end(), 0.f); } // ----------------------------------------------------------------------------- @@ -356,12 +344,6 @@ bool cleanFT0A(T& bc, float maxFITtime, float limitA) if (bc.has_foundFT0() && limitA >= 0.) { bool ota = std::abs(bc.foundFT0().timeA()) <= maxFITtime; bool oma = FT0AmplitudeA(bc.foundFT0()) <= limitA; - - // compare decisions with FT0 trigger decisions - std::bitset<8> triggers = bc.foundFT0().triggerMask(); - bool ora = !triggers[o2::ft0::Triggers::bitA]; - LOGF(debug, "ota %f ora/FT0AmplitudeA %d/%d", bc.foundFT0().timeA(), ora, oma); - return ota && oma; } else { return true; @@ -375,12 +357,6 @@ bool cleanFT0C(T& bc, float maxFITtime, float limitC) if (bc.has_foundFT0() && limitC >= 0.) { bool otc = std::abs(bc.foundFT0().timeC()) <= maxFITtime; bool omc = FT0AmplitudeC(bc.foundFT0()) <= limitC; - - // compare decisions with FT0 trigger decisions - std::bitset<8> triggers = bc.foundFT0().triggerMask(); - bool orc = !triggers[o2::ft0::Triggers::bitC]; - LOGF(debug, "otc %f orc/FT0AmplitudeC %d/%d", bc.foundFT0().timeC(), orc, omc); - return otc && omc; } else { return true; @@ -494,6 +470,51 @@ bool cleanFITC(T& bc, float maxFITtime, std::vector lims) cleanFDDC(bc, maxFITtime, lims[4]); } +// ----------------------------------------------------------------------------- +template +bool TVX(T& bc) +{ + bool tvx = false; + if (bc.has_foundFT0()) { + auto ft0 = bc.foundFT0(); + tvx = TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitVertex); + } + return tvx; +} + +// ----------------------------------------------------------------------------- +template +bool TSC(T& bc) +{ + bool tsc = false; + if (bc.has_foundFT0()) { + auto ft0 = bc.foundFT0(); + tsc = TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitSCen); + } + return tsc; +} + +// ----------------------------------------------------------------------------- +template +bool TCE(T& bc) +{ + bool tce = false; + if (bc.has_foundFT0()) { + auto ft0 = bc.foundFT0(); + tce = TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitCen); + } + return tce; +} + +// ----------------------------------------------------------------------------- +template +bool TOR(T& bc, float maxFITtime, std::vector lims) +{ + auto torA = !cleanFT0A(bc, maxFITtime, lims); + auto torC = !cleanFT0C(bc, maxFITtime, lims); + return torA || torC; +} + // ----------------------------------------------------------------------------- // fill BB and BG information into FITInfo template From c902c302ab29abe9984fef3d98825881f33c7aec Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:56:49 +0100 Subject: [PATCH 152/156] Update LF codeowners (#4256) --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 76206f02372..7dc6b8f5765 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -32,7 +32,7 @@ /PWGEM/Dilepton @alibuild @mikesas @rbailhac @dsekihat @ivorobye @feisenhu /PWGEM/PhotonMeson @alibuild @mikesas @rbailhac @m-c-danisch @novitzky @mhemmer-cern @dsekihat /PWGHF @alibuild @vkucera @fcolamar @fgrosa @fcatalan92 @mfaggin @mmazzilli @deepathoms @nzardosh @NicoleBastid -/PWGLF @alibuild @lramona @alcaliva @lbariogl @chiarapinto @BongHwi @lbarnby @mbombara @iravasen @njacazio @ChiaraDeMartin95 @skundu692 +/PWGLF @alibuild @fmazzasc @chiarapinto @BongHwi @smaff92 @mbombara @ChiaraDeMartin95 @njacazio @skundu692 /PWGMM @alibuild @aalkin /PWGMM/Lumi @alibuild @aalkin /PWGMM/Mult @alibuild @aalkin @aortizve @ddobrigk From 03a324a86f149353bbef839210eb82d9021760c3 Mon Sep 17 00:00:00 2001 From: Junlee Kim Date: Thu, 11 Jan 2024 20:58:22 +0900 Subject: [PATCH 153/156] [Event Plane] fine binning (#4251) * fine binning * Please consider the following formatting changes --------- Co-authored-by: junleekim Co-authored-by: ALICE Action Bot --- Common/Tasks/qVectorsCorrection.cxx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Common/Tasks/qVectorsCorrection.cxx b/Common/Tasks/qVectorsCorrection.cxx index 751f4af552d..b639d1e77df 100644 --- a/Common/Tasks/qVectorsCorrection.cxx +++ b/Common/Tasks/qVectorsCorrection.cxx @@ -107,7 +107,8 @@ struct qVectorsCorrection { // Fill the registry with the needed objects. const AxisSpec axisCent{110, 0., 110.}; - const AxisSpec axisQvec{1000, -5, 5}; + const AxisSpec axisQvec{1000, -3, 3}; + const AxisSpec axisQvecF{1000, -0.3, 0.3}; const AxisSpec axisConst{12, 0., 12.}; // 4 constants x 3 detectors. const AxisSpec axisEvtPl{360, -constants::math::PI, constants::math::PI}; @@ -117,19 +118,19 @@ struct qVectorsCorrection { histosQA.add("Centrality_0-5/histCent", "Centrality distribution", HistType::kTH1F, {axisCent}); - histosQA.add("Centrality_0-5/histQvecUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecUncor", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); + histosQA.add("Centrality_0-5/histQvecRectr", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); + histosQA.add("Centrality_0-5/histQvecTwist", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); histosQA.add("Centrality_0-5/histQvecFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRefAUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRefARectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRefATwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefAUncor", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); + histosQA.add("Centrality_0-5/histQvecRefARectr", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); + histosQA.add("Centrality_0-5/histQvecRefATwist", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); histosQA.add("Centrality_0-5/histQvecRefAFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRefBUncor", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRefBRectr", "", {HistType::kTH2F, {axisQvec, axisQvec}}); - histosQA.add("Centrality_0-5/histQvecRefBTwist", "", {HistType::kTH2F, {axisQvec, axisQvec}}); + histosQA.add("Centrality_0-5/histQvecRefBUncor", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); + histosQA.add("Centrality_0-5/histQvecRefBRectr", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); + histosQA.add("Centrality_0-5/histQvecRefBTwist", "", {HistType::kTH2F, {axisQvecF, axisQvecF}}); histosQA.add("Centrality_0-5/histQvecRefBFinal", "", {HistType::kTH2F, {axisQvec, axisQvec}}); histosQA.add("Centrality_0-5/histEvtPlUncor", "", {HistType::kTH1F, {axisEvtPl}}); From 656fa13ea70d50f9449b7ad974e5df574a142411 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Thu, 11 Jan 2024 13:25:31 +0100 Subject: [PATCH 154/156] make multiplicityTable CCDB settings configurable (#4275) --- Common/TableProducer/multiplicityTable.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Common/TableProducer/multiplicityTable.cxx b/Common/TableProducer/multiplicityTable.cxx index 416f8b1f83b..d605e974d7d 100644 --- a/Common/TableProducer/multiplicityTable.cxx +++ b/Common/TableProducer/multiplicityTable.cxx @@ -79,6 +79,10 @@ struct MultiplicityTableTaskIndexed { Configurable> enabledTables{"enabledTables", {defaultParameters[0], nTables, nParameters, tableNames, parameterNames}, "Produce tables depending on needs. Values different than -1 override the automatic setup: the corresponding table can be set off (0) or on (1)"}; + + Configurable ccdbUrl{"ccdburl", "http://alice-ccdb.cern.ch", "The CCDB endpoint url address"}; + Configurable ccdbPath{"ccdbpath", "Centrality/Calibration", "The CCDB path for centrality/multiplicity information"}; + int mRunNumber; bool lCalibLoaded; TList* lCalibObjects; @@ -138,7 +142,7 @@ struct MultiplicityTableTaskIndexed { hVtxZFDDC = nullptr; hVtxZNTracks = nullptr; - ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); // don't fatal, please - exception is caught explicitly (as it should) @@ -284,7 +288,7 @@ struct MultiplicityTableTaskIndexed { if (doVertexZeq > 0) { if (bc.runNumber() != mRunNumber) { mRunNumber = bc.runNumber(); // mark this run as at least tried - lCalibObjects = ccdb->getForTimeStamp("Centrality/Calibration", bc.timestamp()); + lCalibObjects = ccdb->getForTimeStamp(ccdbPath, bc.timestamp()); if (lCalibObjects) { hVtxZFV0A = static_cast(lCalibObjects->FindObject("hVtxZFV0A")); hVtxZFT0A = static_cast(lCalibObjects->FindObject("hVtxZFT0A")); From d6fdca8e4e50e22c6175e5fa65df3eb201a3f0f4 Mon Sep 17 00:00:00 2001 From: TomoIto-J <94591235+TomoIto-hu@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:40:53 +0900 Subject: [PATCH 155/156] Add new histgrams setup to PWGDQ/Core/HistgramsLibrary.cxx (#4263) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Secnod atemotion to update * Restoration * Add dimuon-vexncontrib hist * Add dimuon-vexncontrib hist * add new histgrams to dimuon-vtxncontrib to see Zv dependence of multiplicity * add new 3D-histgrams to dimuon-vtxncontrib to see Zv dependence of multiplicity --------- Co-authored-by: 伊藤友 Co-authored-by: 伊藤友 Co-authored-by: 伊藤友 --- PWGDQ/Core/HistogramsLibrary.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index f02422d8bb9..e30ef9b98a6 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -678,6 +678,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } if (subGroupStr.Contains("dimuon-vtxncontrib")) { hm->AddHistogram(histClass, "MassMult", "", false, 750, 0.0, 15.0, VarManager::kMass, 301, -0.5, 300.5, VarManager::kVtxNcontrib); + hm->AddHistogram(histClass, "MassVtxZMult", "", false, 300, 0.0, 6.0, VarManager::kMass, 60, -15.0, 15.0, VarManager::kVtxZ, 100, 0.0, 100.0, VarManager::kVtxNcontrib); } } else if (subGroupStr.Contains("electronmuon")) { hm->AddHistogram(histClass, "Mass", "", false, 750, 0.0, 30.0, VarManager::kMass); From 4293687fa9d8bc40f073e3a7eab1b1fee738d8d9 Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:52:54 +0100 Subject: [PATCH 156/156] PWGCF: FemtoUniverse -- Adding DCAxy plots for Phi daughters (#4276) * adding DCAxy plots for Phi daughters * fix configurable default value --- .../TableProducer/femtoUniverseProducerTask.cxx | 2 +- PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 2ce615b491e..86b7ce16430 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -118,7 +118,7 @@ struct femtoUniverseProducerTask { Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; Configurable ConfIsActivateV0{"ConfIsActivateV0", true, "Activate filling of V0 into femtouniverse tables"}; - Configurable ConfIsActivatePhi{"ConfIsActivatePhi", true, "Activate filling of Phi into femtouniverse tables"}; + Configurable ConfIsActivatePhi{"ConfIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; Configurable ConfMCTruthAnalysisWithPID{"ConfMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; Configurable> ConfMCTruthPDGCodes{"ConfMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; Configurable ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index 869089d19fc..9575dbe019e 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -279,11 +279,14 @@ struct femtoUniversePairTaskTrackPhi { qaRegistry.add("PhiDaugh_pos/pt", "; #it{p_T} (GeV/#it{c}); Counts", kTH1F, {{100, 0, 10}}); qaRegistry.add("PhiDaugh_pos/eta", "; #it{eta}; Counts", kTH1F, {{200, -1.5, 1.5}}); qaRegistry.add("PhiDaugh_pos/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, 2. * M_PI}}); + qaRegistry.add("PhiDaugh_pos/hDCAxy", "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); + qaRegistry.add("PhiDaugh_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); qaRegistry.add("PhiDaugh_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); qaRegistry.add("PhiDaugh_neg/pt", "; #it{p_T} (GeV/#it{c}); Counts", kTH1F, {{100, 0, 10}}); qaRegistry.add("PhiDaugh_neg/eta", "; #it{eta}; Counts", kTH1F, {{200, -1.5, 1.5}}); qaRegistry.add("PhiDaugh_neg/phi", "; #it{varphi}; Counts", kTH1F, {{200, 0, 2. * M_PI}}); + qaRegistry.add("PhiDaugh_neg/hDCAxy", "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); trackHistoPartPhi.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarInvMassBins, ConfBothTracks.ConfIsMC, ConfPhi.ConfPDGCodePhi); if (!ConfTrack.ConfIsSame) { @@ -348,6 +351,7 @@ struct femtoUniversePairTaskTrackPhi { qaRegistry.fill(HIST("PhiDaugh_pos/nSigmaTPC"), phidaugh.p(), tpcNSigma); qaRegistry.fill(HIST("PhiDaugh_pos/nSigmaTOF"), phidaugh.p(), tofNSigma); + qaRegistry.fill(HIST("PhiDaugh_pos/hDCAxy"), phidaugh.p(), phidaugh.tempFitVar()); qaRegistry.fill(HIST("PhiDaugh_pos/pt"), phidaugh.pt()); qaRegistry.fill(HIST("PhiDaugh_pos/eta"), phidaugh.eta()); qaRegistry.fill(HIST("PhiDaugh_pos/phi"), phidaugh.phi()); @@ -360,6 +364,7 @@ struct femtoUniversePairTaskTrackPhi { qaRegistry.fill(HIST("PhiDaugh_neg/pt"), phidaugh.pt()); qaRegistry.fill(HIST("PhiDaugh_neg/eta"), phidaugh.eta()); qaRegistry.fill(HIST("PhiDaugh_neg/phi"), phidaugh.phi()); + qaRegistry.fill(HIST("PhiDaugh_neg/hDCAxy"), phidaugh.p(), phidaugh.tempFitVar()); } }