diff --git a/PWGLF/DataModel/LFClusterStudiesTable.h b/PWGLF/DataModel/LFClusterStudiesTable.h index 5c4755bbfcc..c19cccc5174 100644 --- a/PWGLF/DataModel/LFClusterStudiesTable.h +++ b/PWGLF/DataModel/LFClusterStudiesTable.h @@ -67,6 +67,8 @@ DECLARE_SOA_COLUMN(Chi2tpc, chi2tpc, float); DECLARE_SOA_COLUMN(HasTPC, hasTPC, bool); DECLARE_SOA_COLUMN(McPdgCode, mcPdgCode, int); +DECLARE_SOA_COLUMN(RunNumber, runNumber, int); + } // namespace LFClusterStudiesTables DECLARE_SOA_TABLE( @@ -91,6 +93,10 @@ DECLARE_SOA_TABLE( LFClusterStudiesTables::CosPAMother, LFClusterStudiesTables::MassMother); +DECLARE_SOA_TABLE( + ClStTableColl, "AOD", "CLSTTABLECOLL", + LFClusterStudiesTables::RunNumber); + } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFCLUSTERSTUDIESTABLE_H_ diff --git a/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx b/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx index 7f043626f09..5122a881f47 100644 --- a/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx +++ b/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx @@ -14,13 +14,14 @@ // // Author: Giorgio Alberto Lucia +#include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" #include "PWGLF/DataModel/LFClusterStudiesTable.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/Core/PID/PIDTOF.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -50,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -58,10 +60,11 @@ using namespace ::o2; using namespace o2::framework; using namespace o2::framework::expressions; -using Track = o2::track::TrackParCov; -using TracksFullIU = soa::Join; -using TracksFullIUMc = soa::Join; +using TracksFullIU = soa::Join; +using TracksFullIUMc = soa::Join; + using CollisionsCustom = soa::Join; +using CollisionsCustomMc = soa::Join; namespace BetheBloch { @@ -75,7 +78,7 @@ enum V0Type : uint8_t { K0s = 0, Lambda, AntiLambda, - Photon, + Photon, // deprecated, electrons are now selected from pi0 photons V0TypeAll }; @@ -113,20 +116,21 @@ enum CascSelections { kCascAll }; -enum DeSelections { - kDeNoCut = 0, - kDeNClsIts, - kDePIDtpc, - kDePIDtof, - kDeAll +enum NucleiSelections { + kNucleiNoCut = 0, + kNucleiNClsIts, + kNucleiPIDtpc, + kNucleiPIDtof, + kNucleiAll }; -enum He3Selections { - kHe3NoCut = 0, - kHe3NClsIts, - kHe3PIDtpc, - kHe3PIDtof, - kHe3All +enum ESelections { + kENoCut = 0, + kETrackQuality, + kEPrimary, + kEPid, + kEPi0, + kEAll }; enum PartID { @@ -136,9 +140,12 @@ enum PartID { ka, pr, de, - he + he, + all }; +static constexpr std::string_view cNames[] = {"none", "electron", "pion", "kaon", "proton", "deuteron", "He3"}; + struct Candidate { float p = -999.f; // momentum * charge float eta = -999.f; @@ -158,17 +165,15 @@ struct Candidate { struct LfTreeCreatorClusterStudies { Service m_ccdb; + SliceCache m_cache; int m_runNumber; int m_collisionCounter = 0; float m_d_bz; uint32_t m_randomSeed = 0.; Configurable setting_fillV0{"fillV0", true, "Fill the V0 tree"}; - Configurable setting_fillK{"fillK", true, "Fill the K tree"}; - Configurable setting_fillDe{"fillDe", true, "Fill the De tree"}; - Configurable setting_fillHe3{"fillHe3", true, "Fill the He3 tree"}; - Configurable setting_fillPKPi{"fillPKPPi", true, "Fill the p, K, pi tree"}; - Configurable setting_smallTable{"smallTable", true, "Use a small table for testing"}; + Configurable setting_fillExtraTable{"fillExtraTable", false, "Fill the extra table"}; + Configurable setting_fillCollTable{"fillCollTable", false, "Fill the collision table"}; Configurable setting_materialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; @@ -193,13 +198,10 @@ struct LfTreeCreatorClusterStudies { Configurable v0setting_nsigmatpc{"v0setting_nsigmaTPC", 4.f, "Number of sigmas for the TPC PID"}; Configurable v0setting_massWindowLambda{"v0setting_massWindowLambda", 0.02f, "Mass window for the Lambda"}; Configurable v0setting_massWindowK0s{"v0setting_massWindowK0s", 0.02f, "Mass window for the K0s"}; - Configurable v0setting_nsigmatpcEl{"v0setting_nsigmaTPCEl", 1.f, "Number of sigmas for the TPC PID for electrons"}; Configurable v0setting_nsigmatpcPi{"v0setting_nsigmaTPCPi", 2.f, "Number of sigmas for the TPC PID for pions"}; Configurable v0setting_nsigmatpcPr{"v0setting_nsigmaTPCPr", 2.f, "Number of sigmas for the TPC PID for protons"}; Configurable lambdasetting_qtAPcut{"lambdasetting_qtAPcut", 0.02f, "Cut on the qt for the Armenteros-Podolanski plot for photon rejection"}; Configurable lambdasetting_pmin{"lambdasetting_pmin", 0.0f, "Minimum momentum for the V0 daughters"}; - Configurable electronsetting_conversion_rmin{"electron_conversion_rmin", 1.76f, "Minimum radius for the photon conversion (cm)"}; - Configurable electronsetting_conversion_rmax{"electron_conversion_rmax", 19.77f, "Maximum radius for the photon conversion (cm)"}; Configurable cascsetting_dcaCascDaughters{"casc_setting_dcaV0daughters", 0.1f, "DCA between the V0 daughters"}; Configurable cascsetting_cosPA{"casc_setting_cosPA", 0.99f, "Cosine of the pointing angle of the V0"}; @@ -207,6 +209,17 @@ struct LfTreeCreatorClusterStudies { Configurable cascsetting_massWindowXi{"casc_setting_massWindowXi", 0.01f, "Mass window for the Xi"}; Configurable cascsetting_nsigmatpc{"casc_setting_nsigmaTPC", 3.f, "Number of sigmas for the TPC PID"}; + Configurable electronsetting_conversion_rmin{"electron_conversion_rmin", 1.76f, "Minimum radius for the photon conversion (cm)"}; + Configurable electronsetting_conversion_rmax{"electron_conversion_rmax", 19.77f, "Maximum radius for the photon conversion (cm)"}; + Configurable electronsetting_maxNsigmaDca3d{"electronsetting_maxNsigmaDca3d", 0.1f, "Maximum value for the number of sigmas for the DCA (3d)"}; + Configurable electronsetting_minNsigmatpcEl{"electronsetting_minNsigmaTPCEl", -2.5f, "Minimum value for the number of sigmas for the TPC PID for electrons"}; + Configurable electronsetting_maxNsigmatpcEl{"electronsetting_maxNsigmaTPCEl", 3.5f, "Maximum number for the number of sigmas for the TPC PID for electrons"}; + Configurable electronsetting_maxNsigmatpcPi{"electronsetting_maxNsigmaTPCPi", 2.f, "Maximum number for the number of sigmas for pi rejection for the TPC PID for electrons"}; + Configurable electronsetting_maxNsigmatpcKa{"electronsetting_maxNsigmaTPCKa", 2.f, "Maximum number for the number of sigmas for K rejection for the TPC PID for electrons"}; + Configurable electronsetting_maxNsigmatpcPr{"electronsetting_maxNsigmaTPCPr", 2.f, "Maximum number for the number of sigmas for p rejection for the TPC PID for electrons"}; + Configurable electronsetting_maxNsigmatofEl{"electronsetting_maxNsigmaTOFEl", 4.f, "Minimum value for the number of sigmas for the TPC PID for electrons"}; + Configurable electronsetting_minPt{"electronsetting_minPt", 0.f, "Minimum pT accepted for electrons"}; + Configurable desetting_nClsIts{"desetting_nClsIts", 6, "Minimum number of ITS clusters"}; Configurable desetting_nsigmatpc{"desetting_nsigmaCutTPC", 2.f, "Number of sigmas for the TPC PID"}; Configurable desetting_nsigmatof{"desetting_nsigmaCutTOF", 2.f, "Number of sigmas for the TOF PID"}; @@ -230,59 +243,40 @@ struct LfTreeCreatorClusterStudies { {{"collision_selections", "Collision selection; selection; counts", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, {"v0_selections", "V0 selection; selection; counts", {HistType::kTH1F, {{V0Selections::kV0All, -0.5, static_cast(V0Selections::kV0All) - 0.5}}}}, {"casc_selections", "Cascade selection; selection; counts", {HistType::kTH1F, {{CascSelections::kCascAll, -0.5, static_cast(CascSelections::kCascAll) - 0.5}}}}, - {"de_selections", "Deuteron track selection; selection; counts", {HistType::kTH1F, {{DeSelections::kDeAll, -0.5, static_cast(DeSelections::kDeAll) - 0.5}}}}, - {"he3_selections", "He3 track selection; selection; counts", {HistType::kTH1F, {{He3Selections::kHe3All, -0.5, static_cast(He3Selections::kHe3All) - 0.5}}}}, + {"e_selections", "e^{#pm} selection; selection; counts", {HistType::kTH1F, {{CascSelections::kCascAll, -0.5, static_cast(CascSelections::kCascAll) - 0.5}}}}, {"v0_type", "Selected V0; particle; counts", {HistType::kTH1F, {{V0Type::V0TypeAll, -0.5, static_cast(V0Type::V0TypeAll) - 0.5}}}}, {"radiusV0", "Decay radius (xy) V0; radius (cm); counts", {HistType::kTH1F, {{100, 0., 100.}}}}, - {"massLambda", "#Lambda invariant mass; signed #it{p} (GeV/#it{c}); m (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {200, 1.08f, 1.18f}}}}, - {"massLambdaMc", "#Lambda invariant mass (MC); signed #it{p} (GeV/#it{c}); m (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {200, 1.08f, 1.18f}}}}, - {"Lambda_vs_K0s", "Mass #Lambda vs K^{0}_s; m_{K^{0}_{s}} (GeV/#it{c}^{2}); m_{#Lambda} (GeV/#it{c}^{2})", {HistType::kTH2F, {{50, 0.f, 1.f}, {70, 0.6f, 2.f}}}}, - {"armenteros_plot_before_selections", "Armenteros-Podolanski plot; #alpha; q_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, - {"armenteros_plot", "Armenteros-Podolanski plot; #alpha; q_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, - {"armenteros_plot_lambda", "Armenteros-Podolanski plot (#Lambda only); #alpha; q_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, - {"armenteros_plot_gamma", "Armenteros-Podolanski plot (#gamma only); #alpha; q_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, - {"photon_radiusV0", "Photon conversion radius (xy) V0; radius (cm); counts", {HistType::kTH1F, {{100, 0., 100.}}}}, - {"photon_conversion_position", "Photon conversion position; x (cm); y (cm)", {HistType::kTH2F, {{250, -5.f, 5.f}, {250, -5.f, 5.f}}}}, - {"photon_conversion_position_layer", "Photon conversion position (ITS layers); x (cm); y (cm)", {HistType::kTH2F, {{100, -5.f, 5.f}, {100, -5.f, 5.f}}}}, - {"casc_dca_daughter_pairs", "DCA (xy) for cascade daughter pairs; DCAxy (cm); counts", {HistType::kTH1F, {{100, -0.1, 0.1}}}}, - {"Xi_vs_Omega", "Mass Xi vs Omega; mass Omega (GeV/#it{c}^{2}); mass Xi (GeV/#it{c}^{2})", {HistType::kTH2F, {{50, 1.f, 2.f}, {50, 1.f, 2.f}}}}, - {"massOmega", "Mass #Omega; signed #it{p}_{T} (GeV/#it{c}); mass (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {400, 1.62f, 1.72f}}}}, - {"massOmegaMc", "Mass #Omega (MC); signed #it{p}_{T} (GeV/#it{c}); mass (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {400, 1.62f, 1.72f}}}}, - {"massOmegaWithBkg", "Mass Omega with Background; mass Omega (GeV/#it{c}^{2}); counts", {HistType::kTH1F, {{100, 1.62f, 1.72f}}}}, - {"nSigmaTPCEl", "nSigma TPC Electron; signed #it{p} (GeV/#it{c}); n#sigma_{TPC} e", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {60, -2.0f, 2.0f}}}}, - {"nSigmaTPCPi", "nSigma TPC Pion; signed #it{p} (GeV/#it{c}); n#sigma_{TPC} #pi", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}}}, - {"nSigmaTPCKa", "nSigma TPC Kaon; signed #it{p} (GeV/#it{c}); n#sigma_{TPC} e", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {60, -4.0f, 4.0f}}}}, - {"nSigmaTPCPr", "nSigma TPC Proton; signed #it{p} (GeV/#it{c}); n#sigma_{TPC} p", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}}}, - {"nSigmaTPCDe", "nSigma TPC Deuteron; signed #it{p} (GeV/#it{c}); n#sigma_{TPC} d", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, - {"nSigmaTPCHe", "nSigma TPC He3; signed #it{p} (GeV/#it{c}); n#sigma_{TPC} ^{3}He", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, - {"nSigmaTOFDe", "nSigma TOF Deuteron; signed #it{p} (GeV/#it{c}); n#sigma_{TOF} d", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, - {"TOFmassDe", "TOF mass De; signed #it{p}_{T} (GeV/#it{c}); mass_{TOF} ^{3}He (GeV/#it{c}^2)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 1.0f, 5.0f}}}}, - {"TOFmassHe", "TOF mass He3; signed #it{p}_{T} (GeV/#it{c}); mass_{TOF} ^{3}He (GeV/#it{c}^2)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 1.0f, 5.0f}}}}, - {"nSigmaITSEl", "nSigma ITS Electron; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} e", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -2.0f, 2.0f}}}}, - {"nSigmaITSPi", "nSigma ITS Pion; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} #pi", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}}}, - {"nSigmaITSKa", "nSigma ITS Kaon; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} e", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -4.0f, 4.0f}}}}, - {"nSigmaITSPr", "nSigma ITS Proton; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} p", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}}}, - {"nSigmaITSDe", "nSigma ITS Deuteron; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} d", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, - {"nSigmaITSHe", "nSigma ITS He3; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} ^{3}He", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, - {"pmatchingEl", "#it{p} matching e; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, - {"pmatchingPi", "#it{p} matching #pi; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, - {"pmatchingKa", "#it{p} matching K; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, - {"pmatchingPr", "#it{p} matching p; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, - {"pmatchingDe", "#it{p} matching d; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, - {"pmatchingHe", "#it{p} matching ^{3}He; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, - {"zVtx", "Binning for the vertex z in cm", {HistType::kTH1F, {{100, -20.f, 20.f}}}}, + {"massLambda", "#Lambda invariant mass; signed #it{p} (GeV/#it{c}); #it{m}_{#Lambda} (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {200, 1.08f, 1.18f}}}}, + {"massLambdaMc", "#Lambda invariant mass (MC); signed #it{p} (GeV/#it{c}); #it{m}_{#Lambda} (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {200, 1.08f, 1.18f}}}}, + {"Lambda_vs_K0s", "Mass #Lambda vs K^{0}_s; #it{m}_{K^{0}_{s}} (GeV/#it{c}^{2}); #it{m}_{#Lambda} (GeV/#it{c}^{2})", {HistType::kTH2F, {{50, 0.f, 1.f}, {70, 0.6f, 2.f}}}}, + {"armenteros_plot_before_selections", "Armenteros-Podolanski plot; #alpha; #it{q}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, + {"armenteros_plot", "Armenteros-Podolanski plot; #alpha; #it{q}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, + {"armenteros_plot_lambda", "Armenteros-Podolanski plot (#Lambda only); #alpha; #it{q}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, + {"armenteros_plot_gamma", "Armenteros-Podolanski plot (#gamma only); #alpha; #it{q}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -1.f, 1.f}, {100, 0.f, 0.3f}}}}, + {"photon_radiusV0", "Photon conversion radius (xy) V0; #it{r} (cm); counts", {HistType::kTH1F, {{100, 0., 100.}}}}, + {"photon_conversion_position", "Photon conversion position; #it{x} (cm); #it{y} (cm)", {HistType::kTH2F, {{250, -5.f, 5.f}, {250, -5.f, 5.f}}}}, + {"photon_conversion_position_layer", "Photon conversion position (ITS layers); #it{x} (cm); #it{y} (cm)", {HistType::kTH2F, {{100, -5.f, 5.f}, {100, -5.f, 5.f}}}}, + {"casc_dca_daughter_pairs", "DCA (xy) for cascade daughter pairs; DCA_{#it{xy}} (cm); counts", {HistType::kTH1F, {{100, -0.1, 0.1}}}}, + {"Xi_vs_Omega", "Mass Xi vs Omega; mass Omega (GeV/#it{c}^{2}); #it{m}_#Xi (GeV/#it{c}^{2})", {HistType::kTH2F, {{50, 1.f, 2.f}, {50, 1.f, 2.f}}}}, + {"massOmega", "Mass #Omega; signed #it{p}_{T} (GeV/#it{c}); #it{m}_{#Omega} (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {400, 1.62f, 1.72f}}}}, + {"massOmegaMc", "Mass #Omega (MC); signed #it{p}_{T} (GeV/#it{c}); #it{m}_{#Omega} (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {400, 1.62f, 1.72f}}}}, + {"massOmegaWithBkg", "Mass #Omega with Background; #it{m}_{#Omega} (GeV/#it{c}^{2}); counts", {HistType::kTH1F, {{100, 1.62f, 1.72f}}}}, + {"massPi0", "Mass #pi^{0}; #it{m}_{#pi^{0}} (GeV/#it{c}^{2})", {HistType::kTH1F, {{100, 0.0f, 0.200f}}}}, + {"massPi0Mc", "Mass #pi^{0} (MC); #it{m}_{#pi^{0}} (GeV/#it{c}^{2})", {HistType::kTH1F, {{100, 0.0f, 0.200f}}}}, + {"massPi0WithBkg", "Mass #pi^{0} with Background; #it{m}_{#pi^{0}} (GeV/#it{c}^{2}); counts", {HistType::kTH1F, {{100, 0.0f, 0.200f}}}}, + {"zVtx", "Binning for the vertex z in cm; #it{z}_{vertex} (cm)", {HistType::kTH1F, {{100, -20.f, 20.f}}}}, {"isPositive", "is the candidate positive?; isPositive; counts", {HistType::kTH1F, {{2, -0.5f, 1.5f}}}}}, OutputObjHandlingPolicy::AnalysisObject, - false, - true}; // check histograms + false}; Produces m_ClusterStudiesTable; Produces m_ClusterStudiesTableExtra; + Produces m_ClusterStudiesTableCollision; Produces m_ClusterStudiesTableMc; struct V0TrackParCov { int64_t globalIndex; - Track trackParCov; + o2::track::TrackParCov trackParCov; }; std::vector m_v0TrackParCovs; @@ -306,24 +300,6 @@ struct LfTreeCreatorClusterStudies { return true; } - /** - * Compute the momentum of the track using the fitter - * @param itrack Index of the track in the fitter - * @param mom Array to store the momentum - */ - void computeTrackMomentum(const int itrack, std::array& mom) - { - auto fittedTrack = m_fitter.getTrack(itrack); - fittedTrack.getPxPyPzGlo(mom); - } - - void computeMotherMomentum(const std::array& momA, const std::array& momB, std::array& momMother) - { - momMother[0] = momA[0] + momB[0]; - momMother[1] = momA[1] + momB[1]; - momMother[2] = momA[2] + momB[2]; - } - /** * Compute the alpha for the Armenteros-Podolanski plot */ @@ -359,16 +335,8 @@ struct LfTreeCreatorClusterStudies { return std::hypot(dcaInfo[0], dcaInfo[1]); } - float computeMassMother(const float massA, const float massB, const std::array& momA, const std::array& momB, const std::array& momMother) const - { - float eA = std::hypot(massA, std::hypot(momA[0], momA[1], momA[2])); - float eB = std::hypot(massB, std::hypot(momB[0], momB[1], momB[2])); - float lmomMotherl = std::hypot(momMother[0], momMother[1], momMother[2]); - float eMother = eA + eB; - return std::sqrt(eMother * eMother - lmomMotherl * lmomMotherl); - } - - bool collisionSelection(const CollisionsCustom::iterator& collision) + template + bool collisionSelection(const Tcollision& collision) { m_hAnalysis.fill(HIST("collision_selections"), Selections::kNoCut); if (!collision.sel8()) { @@ -390,13 +358,11 @@ struct LfTreeCreatorClusterStudies { /** * Select the V0 daughters based on the quality cuts */ - template - bool qualityTrackSelection(const T& track) + template + bool qualityTrackSelection(const Track& track) { - if (std::abs(track.eta()) > track_etaMax) { - return false; - } - if (track.itsNCls() < track_nClsItsMin || + if (std::abs(track.eta()) > track_etaMax || + track.itsNCls() < track_nClsItsMin || track.tpcNClsFound() < track_nClsTpcMin || track.tpcNClsCrossedRows() < track_nClsTpcMin || track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || @@ -439,12 +405,9 @@ struct LfTreeCreatorClusterStudies { return true; } - uint8_t selectV0MotherHypothesis(float massK0sV0, float massLambdaV0, float massAntiLambdaV0, float alphaAP, const o2::aod::V0& v0) + uint8_t selectV0MotherHypothesis(float massK0sV0, float massLambdaV0, float massAntiLambdaV0, float alphaAP) { uint8_t v0Bitmask(0); - if (v0.isPhotonV0()) { - SETBIT(v0Bitmask, Photon); - } if (std::abs(massK0sV0 - o2::constants::physics::MassK0Short) < v0setting_massWindowK0s) { SETBIT(v0Bitmask, K0s); } @@ -457,10 +420,10 @@ struct LfTreeCreatorClusterStudies { return v0Bitmask; } - template - bool selectPidV0Daughters(Candidate& candidatePos, Candidate& candidateNeg, const T& posTrack, - const T& negTrack, const std::array& momMother, const std::array& decayVtx, - float qtAP, float radiusV0, uint8_t v0Bitmask) + template + bool selectPidV0Daughters(Candidate& candidatePos, Candidate& candidateNeg, const Track& posTrack, + const Track& negTrack, const std::array& momMother, const std::array& /*decayVtx*/, + float qtAP, float /*radiusV0*/, uint8_t v0Bitmask) { if (TESTBIT(v0Bitmask, Lambda)) { if (qtAP < lambdasetting_qtAPcut) @@ -488,25 +451,6 @@ struct LfTreeCreatorClusterStudies { candidateNeg.nsigmaTPC = negTrack.tpcNSigmaPr(); m_hAnalysis.fill(HIST("v0_type"), V0Type::AntiLambda); - } else if (TESTBIT(v0Bitmask, K0s)) { - m_hAnalysis.fill(HIST("v0_type"), V0Type::K0s); - return false; // K0s not implemented - - } else if (TESTBIT(v0Bitmask, Photon)) { - // require photon conversion to happen in one of the Inner Tracker layers (± 0.5 cm resolution) - m_hAnalysis.fill(HIST("photon_conversion_position"), decayVtx[0], decayVtx[1]); - m_hAnalysis.fill(HIST("photon_radiusV0"), radiusV0); - if (!(radiusV0 > electronsetting_conversion_rmin && radiusV0 < electronsetting_conversion_rmax)) - return false; - if (std::abs(posTrack.tpcNSigmaEl()) > v0setting_nsigmatpcEl || std::abs(negTrack.tpcNSigmaEl()) > v0setting_nsigmatpcEl) - return false; - m_hAnalysis.fill(HIST("photon_conversion_position_layer"), decayVtx[0], decayVtx[1]); - candidatePos.partID = PartID::el; - candidateNeg.partID = PartID::el; - candidatePos.nsigmaTPC = posTrack.tpcNSigmaEl(); - candidateNeg.nsigmaTPC = negTrack.tpcNSigmaEl(); - m_hAnalysis.fill(HIST("v0_type"), V0Type::Photon); - } else { return false; } @@ -517,58 +461,133 @@ struct LfTreeCreatorClusterStudies { /** * Fill the histograms for the V0 candidate and return the mass of the V0 */ - float fillHistogramsV0(float massLambdaV0, float massAntiLambdaV0, + template + float fillHistogramsV0(const float massLambdaV0, const float massAntiLambdaV0, const std::array& momMother, - const Candidate& candidatePos, const Candidate& candidateNeg, float alphaAP, float qtAP, float radiusV0, uint8_t v0Bitmask) + const Track& trackPos, const Track& trackNeg, + const float alphaAP, const float qtAP, const float radiusV0, const uint8_t v0Bitmask) { float massV0{0.f}; m_hAnalysis.fill(HIST("v0_selections"), V0Selections::kV0DaughterDCAtoPV); if (TESTBIT(v0Bitmask, Lambda)) { massV0 = massLambdaV0; m_hAnalysis.fill(HIST("massLambda"), std::hypot(momMother[0], momMother[1], momMother[2]), massLambdaV0); - m_hAnalysis.fill(HIST("armenteros_plot_lambda"), alphaAP, qtAP); - m_hAnalysis.fill(HIST("nSigmaTPCPr"), candidatePos.p, candidatePos.nsigmaTPC); - m_hAnalysis.fill(HIST("nSigmaITSPr"), candidatePos.p, m_responseITS.nSigmaITS(candidatePos.itsClusterSize, candidatePos.p, candidatePos.eta)); - m_hAnalysis.fill(HIST("nSigmaTPCPi"), candidateNeg.p, candidateNeg.nsigmaTPC); - m_hAnalysis.fill(HIST("nSigmaITSPi"), candidateNeg.p, m_responseITS.nSigmaITS(candidateNeg.itsClusterSize, candidateNeg.p, candidateNeg.eta)); - m_hAnalysis.fill(HIST("pmatchingPr"), candidatePos.pTPC, (candidatePos.pTPC - candidatePos.p) / candidatePos.pTPC); - m_hAnalysis.fill(HIST("pmatchingPi"), -candidateNeg.pTPC, (candidateNeg.pTPC - candidateNeg.p) / candidateNeg.pTPC); - + fillHistogramsParticle(trackPos); + fillHistogramsParticle(trackNeg); } else if (TESTBIT(v0Bitmask, AntiLambda)) { massV0 = massAntiLambdaV0; m_hAnalysis.fill(HIST("massLambda"), std::hypot(momMother[0], momMother[1], momMother[2]) * -1.f, massAntiLambdaV0); - // "signed" pt for antimatter - m_hAnalysis.fill(HIST("armenteros_plot_lambda"), alphaAP, qtAP); - m_hAnalysis.fill(HIST("nSigmaTPCPi"), candidatePos.p, candidatePos.nsigmaTPC); - m_hAnalysis.fill(HIST("nSigmaITSPi"), candidatePos.p, m_responseITS.nSigmaITS(candidatePos.itsClusterSize, candidatePos.p, candidatePos.eta)); - m_hAnalysis.fill(HIST("nSigmaTPCPr"), candidateNeg.p, candidateNeg.nsigmaTPC); - m_hAnalysis.fill(HIST("nSigmaITSPr"), candidateNeg.p, m_responseITS.nSigmaITS(candidateNeg.itsClusterSize, candidateNeg.p, candidateNeg.eta)); - m_hAnalysis.fill(HIST("pmatchingPi"), candidatePos.pTPC, (candidatePos.pTPC - candidatePos.p) / candidatePos.pTPC); - m_hAnalysis.fill(HIST("pmatchingPr"), -candidateNeg.pTPC, (candidateNeg.pTPC - candidateNeg.p) / candidateNeg.pTPC); - - } else if (TESTBIT(v0Bitmask, Photon)) { - massV0 = 0.f; - m_hAnalysis.fill(HIST("nSigmaTPCEl"), candidatePos.p, candidatePos.nsigmaTPC); - m_hAnalysis.fill(HIST("nSigmaTPCEl"), candidateNeg.p, candidateNeg.nsigmaTPC); - m_hAnalysis.fill(HIST("nSigmaITSEl"), candidatePos.p, m_responseITS.nSigmaITS(candidatePos.itsClusterSize, candidatePos.p, candidatePos.eta)); - m_hAnalysis.fill(HIST("nSigmaITSEl"), candidateNeg.p, m_responseITS.nSigmaITS(candidateNeg.itsClusterSize, candidateNeg.p, candidateNeg.eta)); - m_hAnalysis.fill(HIST("armenteros_plot_gamma"), alphaAP, qtAP); - m_hAnalysis.fill(HIST("pmatchingEl"), candidatePos.pTPC, (candidatePos.pTPC - candidatePos.p) / candidatePos.pTPC); - m_hAnalysis.fill(HIST("pmatchingEl"), -candidateNeg.pTPC, (candidateNeg.pTPC - candidateNeg.p) / candidateNeg.pTPC); + fillHistogramsParticle(trackPos); + fillHistogramsParticle(trackNeg); } + m_hAnalysis.fill(HIST("radiusV0"), radiusV0); + m_hAnalysis.fill(HIST("armenteros_plot_lambda"), alphaAP, qtAP); m_hAnalysis.fill(HIST("armenteros_plot"), alphaAP, qtAP); return massV0; } + template + void fillHistogramsParticle(const Track& track) + { + float nsigmaTpc = -999.f; + switch (partID) { + case PartID::el: + nsigmaTpc = track.tpcNSigmaEl(); + break; + case PartID::pi: + nsigmaTpc = track.tpcNSigmaPi(); + break; + case PartID::ka: + nsigmaTpc = track.tpcNSigmaKa(); + break; + case PartID::pr: + nsigmaTpc = track.tpcNSigmaPr(); + break; + case PartID::de: + nsigmaTpc = track.tpcNSigmaDe(); + break; + case PartID::he: + nsigmaTpc = computeNSigmaTPCHe3(track); + break; + default: + nsigmaTpc = -999.f; + break; + } + + float nsigmaTof = -999.f; + switch (partID) { + case PartID::el: + nsigmaTof = track.tofNSigmaEl(); + break; + case PartID::de: + nsigmaTof = track.tofNSigmaDe(); + break; + default: + nsigmaTof = -999.f; + break; + } + + float massTof = -999.f; + if (track.hasTOF()) { + switch (partID) { + case PartID::de: + massTof = computeTOFmassDe(track); + break; + case PartID::he: + massTof = computeTOFmassHe3(track); + break; + default: + massTof = -999.f; + break; + } + } + + float nsigmaIts = -999.f; + switch (partID) { + case PartID::el: + nsigmaIts = m_responseITS.nSigmaITS(track); + break; + case PartID::pi: + nsigmaIts = m_responseITS.nSigmaITS(track); + break; + case PartID::ka: + nsigmaIts = m_responseITS.nSigmaITS(track); + break; + case PartID::pr: + nsigmaIts = m_responseITS.nSigmaITS(track); + break; + case PartID::de: + nsigmaIts = m_responseITS.nSigmaITS(track); + break; + case PartID::he: + nsigmaIts = m_responseITS.nSigmaITS(track); + break; + default: + nsigmaIts = -999.f; + break; + } + + float correctedTpcInnerParam = track.tpcInnerParam(); + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + correctedTpcInnerParam = (partID == PartID::he && he3setting_compensatePIDinTracking && heliumPID) ? track.tpcInnerParam() / 2.f : track.tpcInnerParam(); + + m_hAnalysis.fill(HIST(cNames[partID]) + HIST("/nSigmaTPC"), track.p() * track.sign(), nsigmaTpc); + m_hAnalysis.fill(HIST(cNames[partID]) + HIST("/nSigmaITS"), track.p() * track.sign(), nsigmaIts); + m_hAnalysis.fill(HIST(cNames[partID]) + HIST("/nSigmaTOF"), track.p() * track.sign(), nsigmaTof); + if (partID == static_cast(PartID::de) || partID == static_cast(PartID::he)) + m_hAnalysis.fill(HIST(cNames[partID]) + HIST("/TOFmass"), track.p() * track.sign(), massTof); + m_hAnalysis.fill(HIST(cNames[partID]) + HIST("/pmatching"), correctedTpcInnerParam * track.sign(), (correctedTpcInnerParam - track.p()) / correctedTpcInnerParam); + } + template void fillMcHistogramsV0(const float massLambda, const float massAntiLambda, const std::array& momMother, const McPart& posDaughter, const McPart& negDaughter) { - if ((std::abs(posDaughter.pdgCode()) != 2212 && std::abs(posDaughter.pdgCode()) != 211) || - (std::abs(negDaughter.pdgCode()) != 2212 && std::abs(negDaughter.pdgCode()) != 211)) { + if ((std::abs(posDaughter.pdgCode()) != PDG_t::kProton && std::abs(posDaughter.pdgCode()) != PDG_t::kPiPlus) || + (std::abs(negDaughter.pdgCode()) != PDG_t::kProton && std::abs(negDaughter.pdgCode()) != PDG_t::kPiPlus)) { return; } @@ -581,9 +600,9 @@ struct LfTreeCreatorClusterStudies { } } - if (motherPdgCode == 3122) { + if (motherPdgCode == PDG_t::kLambda0) { m_hAnalysis.fill(HIST("massLambdaMc"), std::hypot(momMother[0], momMother[1], momMother[2]), massLambda); - } else if (motherPdgCode == -3122) { + } else if (motherPdgCode == PDG_t::kLambda0Bar) { m_hAnalysis.fill(HIST("massLambdaMc"), std::hypot(momMother[0], momMother[1], momMother[2]) * -1.f, massAntiLambda); } } @@ -595,12 +614,12 @@ struct LfTreeCreatorClusterStudies { { McPart v0Daughter; for (const auto& iterV0Daughter : posV0Daughter.template mothers_as()) { - if (std::abs(iterV0Daughter.pdgCode()) != 3122) { + if (std::abs(iterV0Daughter.pdgCode()) != PDG_t::kLambda0) { continue; } v0Daughter = iterV0Daughter; } - if (std::abs(bachelorDaughter.pdgCode()) != 321) { + if (std::abs(bachelorDaughter.pdgCode()) != PDG_t::kKPlus) { return; } @@ -613,9 +632,9 @@ struct LfTreeCreatorClusterStudies { } } - if (motherPdgCode == 3334) { + if (motherPdgCode == PDG_t::kOmegaMinus) { m_hAnalysis.fill(HIST("massOmegaMc"), std::hypot(momMother[0], momMother[1], momMother[2]), massOmega); - } else if (motherPdgCode == -3334) { + } else if (motherPdgCode == -PDG_t::kOmegaMinus) { m_hAnalysis.fill(HIST("massOmegaMc"), std::hypot(momMother[0], momMother[1], momMother[2]) * -1.f, massOmega); } } @@ -624,78 +643,38 @@ struct LfTreeCreatorClusterStudies { void fillTable(const Candidate& candidate) { m_ClusterStudiesTable( - candidate.p, // p - candidate.eta, // eta - candidate.phi, // phi - candidate.itsClusterSize, // itsClsize - static_cast(candidate.partID)); // partID - if (!setting_smallTable) { + candidate.p, candidate.eta, candidate.phi, + candidate.itsClusterSize, static_cast(candidate.partID)); + if (setting_fillExtraTable) { m_ClusterStudiesTableExtra( - candidate.pTPC, // pTPC - candidate.pidInTrk, // pidInTrk - candidate.nsigmaTPC, // TpcNSigma - candidate.nsigmaTOF, // TofNSigma - candidate.tofMass, // TofMass - candidate.cosPAMother, // cosPA - candidate.massMother); // massMother + candidate.pTPC, candidate.pidInTrk, + candidate.nsigmaTPC, candidate.nsigmaTOF, candidate.tofMass, + candidate.cosPAMother, candidate.massMother); + } + if (setting_fillCollTable) { + m_ClusterStudiesTableCollision( + m_runNumber); } if constexpr (isMC) { m_ClusterStudiesTableMc( - candidate.pdgCode); // pdgCod + candidate.pdgCode); } } // ========================================================================================================= - template - bool nucleiTrackSelection(const T& track) - { - if (std::abs(track.eta()) > track_etaMax) { - return false; - } - if (track.tpcNClsFound() < 90) { - return false; - } - if ((track.tpcChi2NCl() > 4.0f) || - (track.tpcChi2NCl() < track_tpcChi2Min)) { - return false; - } - return true; - } - - // ========================================================================================================= - - template - float computeNSigmaDe(const T& candidate) - { - float expTPCSignal = o2::tpc::BetheBlochAleph(static_cast(candidate.tpcInnerParam() / constants::physics::MassDeuteron), m_BBparamsDe[0], m_BBparamsDe[1], m_BBparamsDe[2], m_BBparamsDe[3], m_BBparamsDe[4]); - double resoTPC{expTPCSignal * m_BBparamsDe[5]}; - return static_cast((candidate.tpcSignal() - expTPCSignal) / resoTPC); - } - - template - bool selectionPIDtpcDe(const T& candidate) - { - auto nSigmaDe = computeNSigmaDe(candidate); - if (std::abs(nSigmaDe) < desetting_nsigmatpc) { - return true; - } - return false; - } - template float computeTOFmassDe(const T& candidate) { float beta = o2::pid::tof::Beta::GetBeta(candidate); - beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); /// sometimes beta > 1 or < 0, to be checked return candidate.tpcInnerParam() * std::sqrt(1.f / (beta * beta) - 1.f); } // ========================================================================================================= - template - float computeNSigmaHe3(const T& candidate) + template + float computeNSigmaTPCHe3(const Track& candidate) { bool heliumPID = candidate.pidForTracking() == o2::track::PID::Helium3 || candidate.pidForTracking() == o2::track::PID::Alpha; float correctedTPCinnerParam = (heliumPID && he3setting_compensatePIDinTracking) ? candidate.tpcInnerParam() / 2.f : candidate.tpcInnerParam(); @@ -704,21 +683,10 @@ struct LfTreeCreatorClusterStudies { return static_cast((candidate.tpcSignal() - expTPCSignal) / resoTPC); } - template - bool selectionPIDtpcHe3(const T& candidate) - { - auto nSigmaHe3 = computeNSigmaHe3(candidate); - if (std::abs(nSigmaHe3) < he3setting_nsigmatpc) { - return true; - } - return false; - } - - template - float computeTOFmassHe3(const T& candidate) + template + float computeTOFmassHe3(const Track& candidate) { float beta = o2::pid::tof::Beta::GetBeta(candidate); - beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); /// sometimes beta > 1 or < 0, to be checked bool heliumPID = candidate.pidForTracking() == o2::track::PID::Helium3 || candidate.pidForTracking() == o2::track::PID::Alpha; float correctedTPCinnerParamHe3 = (heliumPID && he3setting_compensatePIDinTracking) ? candidate.tpcInnerParam() / 2.f : candidate.tpcInnerParam(); return correctedTPCinnerParamHe3 * 2.f * std::sqrt(1.f / (beta * beta) - 1.f); @@ -726,6 +694,40 @@ struct LfTreeCreatorClusterStudies { // ========================================================================================================= + template + bool electronPrimarySelection(const Track& track) + { + float dca_3d = 999.f; + float det = track.cYY() * track.cZZ() - track.cZY() * track.cZY(); + if (det < 0) { + dca_3d = 999.f; + } else { + float chi2 = (track.dcaXY() * track.dcaXY() * track.cZZ() + track.dcaZ() * track.dcaZ() * track.cYY() - 2. * track.dcaXY() * track.dcaZ() * track.cZY()) / det; + dca_3d = std::sqrt(std::abs(chi2) / 2.); + } + if (dca_3d > electronsetting_maxNsigmaDca3d) { + return false; + } + return true; + } + + template + bool electronPidSelection(const Track& track) + { + if (track.tpcNSigmaEl() < electronsetting_minNsigmatpcEl || + electronsetting_maxNsigmatpcEl < track.tpcNSigmaEl() || + std::abs(track.tpcNSigmaPi()) < electronsetting_maxNsigmatpcPi || + std::abs(track.tpcNSigmaKa()) < electronsetting_maxNsigmatpcKa || + std::abs(track.tpcNSigmaPr()) < electronsetting_maxNsigmatpcPr) + return false; + + if (electronsetting_maxNsigmatofEl != 0 && + std::abs(track.tofNSigmaEl()) < electronsetting_maxNsigmatofEl) + return false; + + return true; + } + template void initCCDB(Bc const& bc) { @@ -733,7 +735,7 @@ struct LfTreeCreatorClusterStudies { return; } - auto timestamp = bc.timestamp(); + const auto& timestamp = bc.timestamp(); o2::parameters::GRPMagField* grpmag = 0x0; auto grpmagPath{"GLO/Config/GRPMagField"}; @@ -759,7 +761,6 @@ struct LfTreeCreatorClusterStudies { m_ccdb->setURL("http://alice-ccdb.cern.ch"); m_ccdb->setCaching(true); - m_ccdb->setLocalObjectValidityChecking(); m_ccdb->setFatalWhenNull(false); // lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); @@ -775,6 +776,26 @@ struct LfTreeCreatorClusterStudies { int mat{static_cast(setting_materialCorrection)}; m_fitter.setMatCorrType(static_cast(mat)); + for (int ipartid = 0; ipartid < static_cast(PartID::all); ipartid++) { + if (ipartid == 0) + continue; + + m_hAnalysis.add(fmt::format("{}/nSigmaITS", cNames[ipartid]).c_str(), (fmt::format("nSigma ITS {};", cNames[ipartid]) + std::string("signed #it{p} (GeV/#it{c}); n#sigma_{ITS}")).c_str(), HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -5.0f, 5.0f}}); + m_hAnalysis.add(fmt::format("{}/nSigmaTPC", cNames[ipartid]).c_str(), (fmt::format("nSigma TPC {};", cNames[ipartid]) + std::string("signed #it{p} (GeV/#it{c}); n#sigma_{TPC}")).c_str(), HistType::kTH2F, {{100, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}); + m_hAnalysis.add(fmt::format("{}/nSigmaTOF", cNames[ipartid]).c_str(), (fmt::format("nSigma TOF {};", cNames[ipartid]) + std::string("signed #it{p} (GeV/#it{c}); n#sigma_{TOF}")).c_str(), HistType::kTH2F, {{100, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}); + if (ipartid == static_cast(PartID::de) || ipartid == static_cast(PartID::he)) { + m_hAnalysis.add(fmt::format("{}/TOFmass", cNames[ipartid]).c_str(), (fmt::format("TOF mass {};", cNames[ipartid]) + std::string("signed #it{p} (GeV/#it{c}); #it{m}_{TOF} (GeV/#it{c}^{2})")).c_str(), HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 1.0f, 5.0f}}); + m_hAnalysis.add(fmt::format("{}/trackSelections", cNames[ipartid]).c_str(), (fmt::format("track selections {};", cNames[ipartid]) + std::string("Selections; Counts")).c_str(), HistType::kTH1F, {{NucleiSelections::kNucleiAll, -0.5, static_cast(NucleiSelections::kNucleiAll) - 0.5}}); + } + m_hAnalysis.add(fmt::format("{}/pmatching", cNames[ipartid]).c_str(), (fmt::format("p matching {};", cNames[ipartid]) + std::string("signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}")).c_str(), HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}); + } + + std::vector trackSelectionLabels = {"All", "n clusters ITS", "TPC", "TOF"}; + for (int i = 0; i < NucleiSelections::kNucleiAll; i++) { + m_hAnalysis.get(HIST(cNames[static_cast(PartID::de)]) + HIST("/trackSelections"))->GetXaxis()->SetBinLabel(i + 1, trackSelectionLabels[i].c_str()); + m_hAnalysis.get(HIST(cNames[static_cast(PartID::he)]) + HIST("/trackSelections"))->GetXaxis()->SetBinLabel(i + 1, trackSelectionLabels[i].c_str()); + } + LOG(info) << "Bethe-Bloch parameters for He3:"; for (int i = 0; i < 5; i++) { m_BBparamsHe[i] = setting_BetheBlochParams->get("He3", Form("p%i", i)); @@ -803,26 +824,23 @@ struct LfTreeCreatorClusterStudies { for (int i = 0; i < CascSelections::kCascAll; i++) m_hAnalysis.get(HIST("casc_selections"))->GetXaxis()->SetBinLabel(i + 1, Casc_selection_labels[i].c_str()); - std::vector De_selection_labels = {"All", "n clusters ITS", "n#sigma_{TPC} d", "n#sigma_{TOF} d"}; - for (int i = 0; i < DeSelections::kDeAll; i++) - m_hAnalysis.get(HIST("de_selections"))->GetXaxis()->SetBinLabel(i + 1, De_selection_labels[i].c_str()); - - std::vector He3_selection_labels = {"All", "n clusters ITS", "n#sigma_{TPC} ^{3}He", "TOF mass ^{3}He"}; - for (int i = 0; i < He3Selections::kHe3All; i++) - m_hAnalysis.get(HIST("he3_selections"))->GetXaxis()->SetBinLabel(i + 1, He3_selection_labels[i].c_str()); + std::vector E_selections_labels = {"All", "Track quality", "Primary", "Pid", "#pi^{0}"}; + for (int i = 0; i < ESelections::kEAll; i++) + m_hAnalysis.get(HIST("e_selections"))->GetXaxis()->SetBinLabel(i + 1, E_selections_labels[i].c_str()); std::vector V0Type_labels = {"K0s", "#Lambda", "#bar{#Lambda}", "Photon"}; for (int i = 0; i < V0Type::V0TypeAll; i++) m_hAnalysis.get(HIST("v0_type"))->GetXaxis()->SetBinLabel(i + 1, V0Type_labels[i].c_str()); } - template - void fillV0Cand(const std::array& PV, const aod::V0s::iterator& v0, const Track&) + template + void fillV0Cand(const std::array& PV, const aod::V0s::iterator& v0, const Tracks&) { m_hAnalysis.fill(HIST("v0_selections"), V0Selections::kV0NoCut); - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + const auto& posTrack = v0.posTrack_as(); + const auto& negTrack = v0.negTrack_as(); + if (!qualityTrackSelection(posTrack) || !qualityTrackSelection(negTrack)) { return; } @@ -834,34 +852,36 @@ struct LfTreeCreatorClusterStudies { return; } - std::array momPos, momNeg, momMother; - computeTrackMomentum(0, momPos); - computeTrackMomentum(1, momNeg); - computeMotherMomentum(momPos, momNeg, momMother); + std::array momPos, momNeg; + m_fitter.getTrack(0).getPxPyPzGlo(momPos); + m_fitter.getTrack(1).getPxPyPzGlo(momNeg); + const std::array momMother = RecoDecay::sumOfVec(momPos, momNeg); + ROOT::Math::SVector vec_decayVtx = m_fitter.getPCACandidate(); std::array decayVtx = {static_cast(vec_decayVtx[0]), static_cast(vec_decayVtx[1]), static_cast(vec_decayVtx[2])}; - float alphaAP = computeAlphaAP(momMother, momPos, momNeg); - float qtAP = computeQtAP(momMother, momPos); + const float alphaAP = computeAlphaAP(momMother, momPos, momNeg); + const float qtAP = computeQtAP(momMother, momPos); m_hAnalysis.fill(HIST("armenteros_plot_before_selections"), alphaAP, qtAP); std::array dcaInfo; V0TrackParCov v0TrackParCov{v0.globalIndex(), m_fitter.createParentTrackParCov()}; - float dcaV0daughters = std::sqrt(std::abs(m_fitter.getChi2AtPCACandidate())); - float radiusV0 = std::hypot(decayVtx[0], decayVtx[1]); - float dcaV0toPV = dcaToPV(PV, v0TrackParCov.trackParCov, dcaInfo); - float cosPA = RecoDecay::cpa(PV, decayVtx, momMother); + const float dcaV0daughters = std::sqrt(std::abs(m_fitter.getChi2AtPCACandidate())); + const float radiusV0 = std::hypot(decayVtx[0], decayVtx[1]); + const float dcaV0toPV = dcaToPV(PV, v0TrackParCov.trackParCov, dcaInfo); + const float cosPA = RecoDecay::cpa(PV, decayVtx, momMother); if (!qualitySelectionV0(dcaV0toPV, dcaV0daughters, radiusV0, cosPA)) { return; } - // mass hypothesis - float massLambdaV0 = computeMassMother(o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, momPos, momNeg, momMother); - float massAntiLambdaV0 = computeMassMother(o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, momPos, momNeg, momMother); - float massK0sV0 = computeMassMother(o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged, momPos, momNeg, momMother); + const float massLambdaV0 = std::sqrt(RecoDecay::m2(std::array, 2>{momPos, momNeg}, + std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); + const float massAntiLambdaV0 = std::sqrt(RecoDecay::m2(std::array, 2>{momPos, momNeg}, + std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton})); + const float massK0sV0 = std::sqrt(RecoDecay::m2(std::array, 2>{momPos, momNeg}, + std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged})); m_hAnalysis.fill(HIST("Lambda_vs_K0s"), massK0sV0, massLambdaV0); - // float massPhotonV0 = computeMassMother(o2::constants::physics::MassElectron, o2::constants::physics::MassElectron, momPos, momNeg, momMother); - uint8_t v0Bitmask = selectV0MotherHypothesis(massK0sV0, massLambdaV0, massAntiLambdaV0, alphaAP, v0); + uint8_t v0Bitmask = selectV0MotherHypothesis(massK0sV0, massLambdaV0, massAntiLambdaV0, alphaAP); if (v0Bitmask == 0 || (v0Bitmask & (v0Bitmask - 1)) != 0) { return; } @@ -890,7 +910,7 @@ struct LfTreeCreatorClusterStudies { } m_v0TrackParCovs.emplace_back(v0TrackParCov); - float massV0 = fillHistogramsV0(massLambdaV0, massAntiLambdaV0, momMother, candidatePos, candidateNeg, alphaAP, qtAP, radiusV0, v0Bitmask); + float massV0 = fillHistogramsV0(massLambdaV0, massAntiLambdaV0, momMother, posTrack, negTrack, alphaAP, qtAP, radiusV0, v0Bitmask); candidatePos.massMother = massV0; candidateNeg.massMother = massV0; @@ -903,8 +923,8 @@ struct LfTreeCreatorClusterStudies { return; } - auto posMcParticle = posTrack.mcParticle(); - auto negMcParticle = negTrack.mcParticle(); + const auto& posMcParticle = posTrack.mcParticle(); + const auto& negMcParticle = negTrack.mcParticle(); candidatePos.pdgCode = posMcParticle.pdgCode(); candidateNeg.pdgCode = negMcParticle.pdgCode(); @@ -924,10 +944,10 @@ struct LfTreeCreatorClusterStudies { { m_hAnalysis.fill(HIST("casc_selections"), CascSelections::kCascNoCut); - auto v0Track = cascade.template v0_as(); - auto bachelorTrack = cascade.template bachelor_as(); + const auto& v0Track = cascade.template v0_as(); + const auto& bachelorTrack = cascade.template bachelor_as(); - auto itv0 = std::find_if(m_v0TrackParCovs.begin(), m_v0TrackParCovs.end(), [&](const V0TrackParCov& v0) { return v0.globalIndex == v0Track.globalIndex(); }); + const auto& itv0 = std::find_if(m_v0TrackParCovs.begin(), m_v0TrackParCovs.end(), [&](const V0TrackParCov& v0) { return v0.globalIndex == v0Track.globalIndex(); }); if (itv0 == m_v0TrackParCovs.end()) { return; } @@ -938,10 +958,10 @@ struct LfTreeCreatorClusterStudies { return; } - std::array momV0, momBachelor, momMother; - computeTrackMomentum(0, momV0); - computeTrackMomentum(1, momBachelor); - computeMotherMomentum(momV0, momBachelor, momMother); + std::array momV0, momBachelor; + m_fitter.getTrack(0).getPxPyPzGlo(momV0); + m_fitter.getTrack(1).getPxPyPzGlo(momBachelor); + const std::array momMother = RecoDecay::sumOfVec(momV0, momBachelor); ROOT::Math::SVector vec_decayVtx = m_fitter.getPCACandidate(); std::array decayVtx = {static_cast(vec_decayVtx[0]), static_cast(vec_decayVtx[1]), static_cast(vec_decayVtx[2])}; @@ -952,11 +972,12 @@ struct LfTreeCreatorClusterStudies { if (!qualitySelectionCascade(dcaV0daughters, cosPA)) { return; } - // std::array dcaInfo; - // float dcaToPVbachelor = dcaToPV(PV, bachelorTrackCovariance, dcaInfo); - float massXi = computeMassMother(o2::constants::physics::MassLambda0, o2::constants::physics::MassPionCharged, momV0, momBachelor, momMother); - float massOmega = computeMassMother(o2::constants::physics::MassLambda0, o2::constants::physics::MassKaonCharged, momV0, momBachelor, momMother); + const float massXi = std::sqrt(RecoDecay::m2(std::array, 2>{momV0, momBachelor}, + std::array{o2::constants::physics::MassLambda0, o2::constants::physics::MassPionCharged})); + const float massOmega = std::sqrt(RecoDecay::m2(std::array, 2>{momV0, momBachelor}, + std::array{o2::constants::physics::MassLambda0, o2::constants::physics::MassKaonCharged})); + m_hAnalysis.fill(HIST("Xi_vs_Omega"), massOmega, massXi); if (std::abs(massOmega - o2::constants::physics::MassOmegaMinus) > cascsetting_massWindowOmega) { return; @@ -965,165 +986,111 @@ struct LfTreeCreatorClusterStudies { m_hAnalysis.fill(HIST("casc_selections"), CascSelections::kAcceptedOmega); if (std::abs(massXi - o2::constants::physics::MassXiMinus) < cascsetting_massWindowXi) { return; - } // enhance purity by rejecting Xi background + } m_hAnalysis.fill(HIST("casc_selections"), CascSelections::kRejectedXi); if (std::abs(bachelorTrack.tpcNSigmaKa()) > cascsetting_nsigmatpc) { return; } m_hAnalysis.fill(HIST("casc_selections"), CascSelections::kNSigmaTPC); m_hAnalysis.fill(HIST("massOmega"), std::hypot(momMother[0], momMother[1]) * bachelorTrack.sign(), massOmega); - m_hAnalysis.fill(HIST("pmatchingKa"), bachelorTrack.sign() * bachelorTrack.tpcInnerParam(), (bachelorTrack.tpcInnerParam() - bachelorTrack.p()) / bachelorTrack.tpcInnerParam()); - m_hAnalysis.fill(HIST("nSigmaTPCKa"), bachelorTrack.sign() * std::hypot(momBachelor[0], momBachelor[1], momBachelor[2]), bachelorTrack.tpcNSigmaKa()); - - uint8_t partID_bachelor = PartID::ka; + fillHistogramsParticle(bachelorTrack); m_ClusterStudiesTable( - std::hypot(momBachelor[0], momBachelor[1], momBachelor[2]) * bachelorTrack.sign(), // p_K - RecoDecay::eta(momBachelor), // eta_K - RecoDecay::phi(momBachelor), // phi_K - bachelorTrack.itsClusterSizes(), // itsClSize_K - partID_bachelor); // partID_K - if (!setting_smallTable) { + std::hypot(momBachelor[0], momBachelor[1], momBachelor[2]) * bachelorTrack.sign(), + RecoDecay::eta(momBachelor), RecoDecay::phi(momBachelor), + bachelorTrack.itsClusterSizes(), PartID::ka); + if (setting_fillExtraTable) { m_ClusterStudiesTableExtra( - bachelorTrack.tpcInnerParam() * bachelorTrack.sign(), // pTPC_K - bachelorTrack.pidForTracking(), // PIDinTrk_K - -999.f, // TpcNSigma_K - -999.f, // TofNSigma_K - -999.f, // TofMass_K - cosPA, // cosPA - massOmega); + bachelorTrack.tpcInnerParam() * bachelorTrack.sign(), + bachelorTrack.pidForTracking(), + bachelorTrack.tpcNSigmaKa(), /*TOF nsigma*/ -999.f, /*TOF mass*/ -999.f, + cosPA, massOmega); + } + if (setting_fillCollTable) { + m_ClusterStudiesTableCollision( + m_runNumber); } if constexpr (isMC) { if (!bachelorTrack.has_mcParticle()) { return; } - auto mcParticle = bachelorTrack.mcParticle(); + const auto& mcParticle = bachelorTrack.mcParticle(); m_ClusterStudiesTableMc( - mcParticle.pdgCode()); // pdgCode_K + mcParticle.pdgCode()); - auto posV0Daughter = v0Track.posTrack_as(); + const auto& posV0Daughter = v0Track.posTrack_as(); if (!posV0Daughter.has_mcParticle()) { return; } - auto mcPosParticleV0 = posV0Daughter.mcParticle(); + const auto& mcPosParticleV0 = posV0Daughter.mcParticle(); fillMcHistogramsCascade(massOmega, momMother, mcParticle, mcPosParticleV0); } m_hAnalysis.fill(HIST("isPositive"), bachelorTrack.p() > 0); } - template - void fillDeTable(const Track& track) + template + void fillNucleusTable(const Track& track) { - if (track.sign() > 0) { - return; - } - m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDeNoCut); - if (track.itsNCls() < desetting_nClsIts) { - return; - } - m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDeNClsIts); - if (std::abs(track.tpcNSigmaDe()) > desetting_nsigmatpc) { + constexpr int kPartID = partID; + + if (kPartID == static_cast(PartID::de) && track.sign() > 0) return; - } - m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDePIDtpc); - if (!track.hasTOF() || std::abs(track.tofNSigmaDe()) > desetting_nsigmatof) { + m_hAnalysis.fill(HIST(cNames[kPartID]) + HIST("/trackSelections"), NucleiSelections::kNucleiNoCut); + + if (track.itsNCls() < desetting_nClsIts) return; - } - m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDePIDtof); - m_hAnalysis.fill(HIST("nSigmaTPCDe"), track.p() * track.sign(), track.tpcNSigmaDe()); - m_hAnalysis.fill(HIST("nSigmaITSDe"), track.p() * track.sign(), m_responseITS.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta())); - m_hAnalysis.fill(HIST("nSigmaTOFDe"), track.p() * track.sign(), track.tofNSigmaDe()); - m_hAnalysis.fill(HIST("TOFmassDe"), track.p() * track.sign(), computeTOFmassDe(track)); - m_hAnalysis.fill(HIST("pmatchingDe"), track.sign() * track.tpcInnerParam(), (track.tpcInnerParam() - track.p()) / track.tpcInnerParam()); + m_hAnalysis.fill(HIST(cNames[kPartID]) + HIST("/trackSelections"), NucleiSelections::kNucleiNClsIts); - uint8_t partID = PartID::de; + const float tpcNsigma = kPartID == static_cast(PartID::de) ? track.tpcNSigmaDe() : computeNSigmaTPCHe3(track); + const float tpcNsigmaMax = kPartID == static_cast(PartID::de) ? desetting_nsigmatpc : he3setting_nsigmatpc; + if (std::abs(tpcNsigma) > tpcNsigmaMax) + return; + m_hAnalysis.fill(HIST(cNames[kPartID]) + HIST("/trackSelections"), NucleiSelections::kNucleiPIDtpc); - m_ClusterStudiesTable( - track.p() * track.sign(), // p_De, - track.eta(), // eta_De, - track.phi(), // phi_De, - track.itsClusterSizes(), // itsClSize_De, - partID); // partID_De - if (!setting_smallTable) { - m_ClusterStudiesTableExtra( - track.tpcInnerParam() * track.sign(), // pTPC_De, - track.pidForTracking(), // PIDinTrk_De, - track.tpcNSigmaDe(), // TpcNSigma_De, - track.tofNSigmaDe(), // TofNSigma_De, - computeTOFmassDe(track), // TofMass_De, - -999.f, // cosPA, - -999.f); // massMother - } + const float tofMass = track.hasTOF() ? (kPartID == static_cast(PartID::de) ? computeTOFmassDe(track) : computeTOFmassHe3(track)) : -999.f; + const float tofNsigma = kPartID == static_cast(PartID::de) ? track.tofNSigmaDe() : -999.f; + float correctedTPCinnerParam = track.tpcInnerParam(); - if constexpr (isMC) { - if (!track.has_mcParticle() || track.sign() > 0) { + if (kPartID == static_cast(PartID::de)) { + if (!track.hasTOF() || std::abs(tofNsigma) > desetting_nsigmatof) + return; + } else { + if (track.hasTOF() && (tofMass < he3setting_tofmasslow || tofMass > he3setting_tofmasshigh)) return; - } - - auto mcParticle = track.mcParticle(); - - m_ClusterStudiesTableMc( - mcParticle.pdgCode()); // pdgCode_De - } - - m_hAnalysis.fill(HIST("isPositive"), track.sign() > 0); - } - - template - void fillHe3Table(const Track& track) - { - m_hAnalysis.fill(HIST("he3_selections"), He3Selections::kHe3NoCut); - if (track.itsNCls() < he3setting_nClsIts) { - return; - } - m_hAnalysis.fill(HIST("he3_selections"), He3Selections::kHe3NClsIts); - if (!selectionPIDtpcHe3(track)) { - return; - } - m_hAnalysis.fill(HIST("he3_selections"), He3Selections::kHe3PIDtpc); - float tofMass = track.hasTOF() ? computeTOFmassHe3(track) : -999.f; - if (track.hasTOF() && (tofMass < he3setting_tofmasslow || tofMass > he3setting_tofmasshigh)) { - return; + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + correctedTPCinnerParam = (heliumPID && he3setting_compensatePIDinTracking) ? track.tpcInnerParam() / 2.f : track.tpcInnerParam(); } - uint8_t partID = PartID::he; - bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; - float correctedTPCinnerParam = (heliumPID && he3setting_compensatePIDinTracking) ? track.tpcInnerParam() / 2.f : track.tpcInnerParam(); + m_hAnalysis.fill(HIST(cNames[kPartID]) + HIST("/trackSelections"), NucleiSelections::kNucleiPIDtof); - m_hAnalysis.fill(HIST("he3_selections"), He3Selections::kHe3PIDtof); - m_hAnalysis.fill(HIST("nSigmaTPCHe"), track.p() * track.sign(), computeNSigmaHe3(track)); - m_hAnalysis.fill(HIST("nSigmaITSHe"), track.p() * track.sign(), m_responseITS.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta())); - m_hAnalysis.fill(HIST("TOFmassHe"), track.p() * track.sign(), tofMass); - m_hAnalysis.fill(HIST("pmatchingHe"), track.sign() * correctedTPCinnerParam, (correctedTPCinnerParam - track.p()) / correctedTPCinnerParam); + fillHistogramsParticle(track); m_ClusterStudiesTable( - track.p() * track.sign(), // p_He3, - track.eta(), // eta_He3, - track.phi(), // phi_He3, - track.itsClusterSizes(), // itsClSize_He3, - partID); // partID_He3 - if (!setting_smallTable) { + track.p() * track.sign(), track.eta(), track.phi(), + track.itsClusterSizes(), kPartID); + if (setting_fillExtraTable) { m_ClusterStudiesTableExtra( - correctedTPCinnerParam * track.sign(), // pTPC_He3, - track.pidForTracking(), // PIDinTrk_He3, - computeNSigmaHe3(track), // TpcNSigma_He3, - -999.f, // TofNSigma_He3, - tofMass, // TofMass_He3, - -999.f, // cosPA, - -999.f); // massMother + correctedTPCinnerParam * track.sign(), track.pidForTracking(), + tpcNsigma, tofNsigma, tofMass, + /*cosPA*/ -999.f, /*mass mother*/ -999.f); + } + if (setting_fillCollTable) { + m_ClusterStudiesTableCollision( + m_runNumber); } if constexpr (isMC) { if (!track.has_mcParticle()) { return; } - auto mcParticle = track.mcParticle(); + + const auto& mcParticle = track.mcParticle(); m_ClusterStudiesTableMc( - mcParticle.pdgCode()); // pdgCodeMc_He3 + mcParticle.pdgCode()); } m_hAnalysis.fill(HIST("isPositive"), track.sign() > 0); @@ -1150,20 +1117,105 @@ struct LfTreeCreatorClusterStudies { } m_ClusterStudiesTable( - track.p() * track.sign(), - track.eta(), - track.phi(), - track.itsClusterSizes(), - partID); - if (!setting_smallTable) { + track.p() * track.sign(), track.eta(), track.phi(), + track.itsClusterSizes(), partID); + if (setting_fillExtraTable) { m_ClusterStudiesTableExtra( - track.tpcInnerParam() * track.sign(), // pTPC, - track.pidForTracking(), // PIDinTrk, - tpcNSigma, // TpcNSigma, - -999.f, // TofNSigma, - -999.f, // TofMass, - -999.f, // cosPA, - -999.f); // massMother + track.tpcInnerParam() * track.sign(), track.pidForTracking(), + tpcNSigma, /*TOF nsigma*/ -999.f, /*TOF mass*/ -999.f, + /*cosPA*/ -999.f, /*mass mother*/ -999.f); + } + if (setting_fillCollTable) { + m_ClusterStudiesTableCollision( + m_runNumber); + } + } + + template + void fillElectronTable(const Track& posTrack, const Track& negTrack) + { + m_hAnalysis.fill(HIST("e_selections"), ESelections::kENoCut); + if (!qualityTrackSelection(posTrack) || !qualityTrackSelection(negTrack)) { + return; + } + m_hAnalysis.fill(HIST("e_selections"), ESelections::kETrackQuality); + + if (!electronPrimarySelection(posTrack) || !electronPrimarySelection(negTrack)) { + return; + } + m_hAnalysis.fill(HIST("e_selections"), ESelections::kEPrimary); + + if (!electronPidSelection(posTrack) || !electronPidSelection(negTrack)) { + return; + } + m_hAnalysis.fill(HIST("e_selections"), ESelections::kEPid); + + const float invariantMass = std::sqrt(RecoDecay::m2<2>(std::array, 2>{ + std::array{posTrack.px(), posTrack.py(), posTrack.pz()}, + std::array{negTrack.px(), negTrack.py(), negTrack.pz()}}, + std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron})); + + m_hAnalysis.fill(HIST("massPi0WithBkg"), invariantMass); + if (invariantMass > o2::constants::physics::MassPi0) { + return; + } + m_hAnalysis.fill(HIST("e_selections"), ESelections::kEPi0); + m_hAnalysis.fill(HIST("massPi0"), invariantMass); + fillHistogramsParticle(posTrack); + fillHistogramsParticle(negTrack); + + // float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), m_d_bz); + // float opangle = o2::aod::pwgem::dilepton::utils::pairutil::getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); + + m_ClusterStudiesTable( + posTrack.p(), posTrack.eta(), posTrack.phi(), + posTrack.itsClusterSizes(), PartID::el); + if (setting_fillExtraTable) { + m_ClusterStudiesTableExtra( + posTrack.tpcInnerParam(), posTrack.pidForTracking(), + posTrack.tpcNSigmaEl(), posTrack.tofNSigmaEl(), -999.f /* TofMass */, + -999.f /* cosPA */, invariantMass); + } + if (setting_fillCollTable) { + m_ClusterStudiesTableCollision( + m_runNumber); + } + + m_ClusterStudiesTable( + negTrack.p(), negTrack.eta(), negTrack.phi(), + negTrack.itsClusterSizes(), PartID::el); + if (setting_fillExtraTable) { + m_ClusterStudiesTableExtra( + negTrack.tpcInnerParam(), negTrack.pidForTracking(), + negTrack.tpcNSigmaEl(), negTrack.tofNSigmaEl(), -999.f /* TofMass */, + -999.f /* cosPA */, invariantMass); + } + if (setting_fillCollTable) { + m_ClusterStudiesTableCollision( + m_runNumber); + } + + if constexpr (isMC) { + const auto& posMcParticle = posTrack.mcParticle(); + const auto& negMcParticle = negTrack.mcParticle(); + + m_ClusterStudiesTableMc( + posMcParticle.pdgCode()); + m_ClusterStudiesTableMc( + negMcParticle.pdgCode()); + + if (!posMcParticle.has_mothers() || !negMcParticle.has_mothers()) + return; + + for (const auto& posMother : posMcParticle.template mothers_as()) { + for (const auto& negMother : negMcParticle.template mothers_as()) { + if (posMother.globalIndex() != negMother.globalIndex() || std::abs(posMother.pdgCode()) != PDG_t::kPi0) + return; + m_hAnalysis.fill(HIST("massPi0Mc"), std::sqrt((posMcParticle.e() + negMcParticle.e()) * (posMcParticle.e() + negMcParticle.e()) - + (posMcParticle.p() + negMcParticle.p()) * (posMcParticle.p() + posMcParticle.p()))); + break; + } + } } } @@ -1172,13 +1224,13 @@ struct LfTreeCreatorClusterStudies { void processDataV0Casc(CollisionsCustom const& collisions, TracksFullIU const& tracks, aod::V0s const& v0s, aod::Cascades const& cascades, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - if (!collisionSelection(collision)) { - continue; + return; } + const auto& bc = collision.bc_as(); + initCCDB(bc); + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); std::array PV = {collision.posX(), collision.posY(), collision.posZ()}; @@ -1189,44 +1241,58 @@ struct LfTreeCreatorClusterStudies { cascTable_thisCollision.bindExternalIndices(&tracks); cascTable_thisCollision.bindExternalIndices(&v0s); - if (setting_fillV0 || setting_fillK) { - m_v0TrackParCovs.clear(); - for (auto& v0 : v0Table_thisCollision) { - fillV0Cand(PV, v0, tracks); - } + m_v0TrackParCovs.clear(); + for (const auto& v0 : v0Table_thisCollision) { + fillV0Cand(PV, v0, tracks); } - if (setting_fillK) { // the v0 loops are needed for the Ks - for (auto& cascade : cascTable_thisCollision) { - fillKCand(PV, cascade, tracks); - } + + for (const auto& cascade : cascTable_thisCollision) { + fillKCand(PV, cascade, tracks); } } } PROCESS_SWITCH(LfTreeCreatorClusterStudies, processDataV0Casc, "process Data V0 and cascade", false); - void processDataNuclei(CollisionsCustom const& collisions, TracksFullIU const& tracks) + Partition posTracks = o2::aod::track::signed1Pt > 0.f; + Partition negTracks = o2::aod::track::signed1Pt < 0.f; + void processDataElectrons(CollisionsCustom::iterator const& collision, TracksFullIU const& /*tracks*/, aod::BCsWithTimestamps const&) { - for (const auto& collision : collisions) { - if (!collisionSelection(collision)) { - continue; - } + if (!collisionSelection(collision)) { + return; + } - m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); + const auto& bc = collision.bc_as(); + initCCDB(bc); - const uint64_t collIdx = collision.globalIndex(); - auto TrackTable_thisCollision = tracks.sliceBy(m_perCol, collIdx); - TrackTable_thisCollision.bindExternalIndices(&tracks); + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); - for (auto track : TrackTable_thisCollision) { - if (!nucleiTrackSelection(track)) { - continue; - } + const auto& posTracks_thisCollision = posTracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), m_cache); + const auto& negTracks_thisCollision = negTracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), m_cache); + + for (const auto& [posTrack, negTrack] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_thisCollision, negTracks_thisCollision))) { + fillElectronTable(posTrack, negTrack); + } + } + PROCESS_SWITCH(LfTreeCreatorClusterStudies, processDataElectrons, "process Data Electrons", false); + + void processDataNuclei(CollisionsCustom::iterator const& collision, TracksFullIU const& tracks, aod::BCsWithTimestamps const&) + { + if (!collisionSelection(collision)) { + return; + } + + const auto& bc = collision.bc_as(); + initCCDB(bc); - if (setting_fillDe) - fillDeTable(track); - if (setting_fillHe3) - fillHe3Table(track); + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); + + for (const auto& track : tracks) { + if (!qualityTrackSelection(track)) { + return; } + + fillNucleusTable(track); + fillNucleusTable(track); } } PROCESS_SWITCH(LfTreeCreatorClusterStudies, processDataNuclei, "process Data Nuclei", false); @@ -1234,92 +1300,106 @@ struct LfTreeCreatorClusterStudies { /** * @brief Produce a dataset with high purity p, K, #pi */ - void processDataPKPi(CollisionsCustom const& collisions, TracksFullIU const& tracks) + void processDataPKPi(CollisionsCustom::iterator const& collision, TracksFullIU const& tracks) { - for (const auto& collision : collisions) { - if (!collisionSelection(collision)) { - continue; - } - - m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); + if (!collisionSelection(collision)) { + return; + } - const uint64_t collIdx = collision.globalIndex(); - auto TrackTable_thisCollision = tracks.sliceBy(m_perCol, collIdx); - TrackTable_thisCollision.bindExternalIndices(&tracks); + const auto& bc = collision.bc_as(); + initCCDB(bc); - for (auto track : TrackTable_thisCollision) { - if (!qualityTrackSelection(track)) { - continue; - } + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); - if (setting_fillPKPi) - fillPKPiTable(track); + for (const auto& track : tracks) { + if (!qualityTrackSelection(track)) { + return; } + + fillPKPiTable(track); } } PROCESS_SWITCH(LfTreeCreatorClusterStudies, processDataPKPi, "process Data p, K, pi", false); - void processMcV0Casc(CollisionsCustom const& collisions, TracksFullIUMc const& tracks, aod::V0s const& v0s, aod::Cascades const& cascades, aod::BCsWithTimestamps const&, aod::McParticles const&) + void processMcV0Casc(CollisionsCustomMc const& collisions, TracksFullIUMc const& tracks, aod::V0s const& v0s, aod::Cascades const& cascades, aod::BCsWithTimestamps const&, aod::McParticles const&, aod::McCollisions const&) { for (const auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - if (!collisionSelection(collision)) { - continue; + return; } + const auto& bc = collision.template bc_as(); + initCCDB(bc); + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); std::array PV = {collision.posX(), collision.posY(), collision.posZ()}; const uint64_t collIdx = collision.globalIndex(); auto v0Table_thisCollision = v0s.sliceBy(m_perCollisionV0, collIdx); auto cascTable_thisCollision = cascades.sliceBy(m_perCollisionCascade, collIdx); + v0Table_thisCollision.bindExternalIndices(&tracks); cascTable_thisCollision.bindExternalIndices(&tracks); cascTable_thisCollision.bindExternalIndices(&v0s); m_v0TrackParCovs.clear(); - if (setting_fillV0 || setting_fillK) { - for (auto& v0 : v0Table_thisCollision) { - fillV0Cand(PV, v0, tracks); - } + for (const auto& v0 : v0Table_thisCollision) { + fillV0Cand(PV, v0, tracks); } - if (setting_fillK) { // the v0 loops are needed for the Ks - for (auto& cascade : cascTable_thisCollision) { - fillKCand(PV, cascade, tracks); - } + for (const auto& cascade : cascTable_thisCollision) { + fillKCand(PV, cascade, tracks); } } } PROCESS_SWITCH(LfTreeCreatorClusterStudies, processMcV0Casc, "process Mc V0 and cascade", false); - void processMcNuclei(CollisionsCustom const& collisions, TracksFullIUMc const& tracks, aod::BCs const&, aod::McParticles const&) + Partition posTracksMc = o2::aod::track::signed1Pt > 0.f; + Partition negTracksMc = o2::aod::track::signed1Pt < 0.f; + void processMcElectrons(CollisionsCustomMc::iterator const& collision, TracksFullIUMc const& /*tracks*/, aod::BCsWithTimestamps const&, aod::McParticles const&, aod::McCollisions const&) { - for (const auto& collision : collisions) { - if (!collisionSelection(collision)) { - continue; - } + if (!collision.has_mcCollision()) { + return; + } + if (!collisionSelection(collision)) { + return; + } - m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); + const auto& bc = collision.template bc_as(); + initCCDB(bc); + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); - const uint64_t collIdx = collision.globalIndex(); - auto TrackTable_thisCollision = tracks.sliceBy(m_perColMC, collIdx); - TrackTable_thisCollision.bindExternalIndices(&tracks); + const auto& posTracks_thisCollision = posTracksMc.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), m_cache); + const auto& negTracks_thisCollision = negTracksMc.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), m_cache); - for (auto track : TrackTable_thisCollision) { - if (!nucleiTrackSelection(track)) { - continue; - } + for (const auto& [posTrack, negTrack] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_thisCollision, negTracks_thisCollision))) { + if (!posTrack.has_mcParticle() || !negTrack.has_mcParticle()) + continue; - if (setting_fillDe) { - fillDeTable(track); - } - if (setting_fillHe3) { - fillHe3Table(track); - } + fillElectronTable(posTrack, negTrack); + } + } + PROCESS_SWITCH(LfTreeCreatorClusterStudies, processMcElectrons, "process Mc Electrons", false); + + void processMcNuclei(CollisionsCustomMc::iterator const& collision, TracksFullIUMc const& tracks, aod::BCsWithTimestamps const&, aod::McParticles const&, aod::McCollisions const&) + { + if (!collision.has_mcCollision()) { + return; + } + if (!collisionSelection(collision)) { + return; + } + const auto& bc = collision.template bc_as(); + initCCDB(bc); + m_hAnalysis.fill(HIST("zVtx"), collision.posZ()); + + for (const auto& track : tracks) { + if (!qualityTrackSelection(track)) { + return; } + + fillNucleusTable(track); + fillNucleusTable(track); } } PROCESS_SWITCH(LfTreeCreatorClusterStudies, processMcNuclei, "process Mc Nuclei", false);