From 749f9807e5f4411d48a749c3eab8e9374631793b Mon Sep 17 00:00:00 2001 From: Andrea Sofia Triolo Date: Mon, 8 Jan 2024 15:13:52 +0100 Subject: [PATCH 01/48] [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 02/48] 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 03/48] 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 04/48] 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 05/48] 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 06/48] 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 07/48] 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 08/48] 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 09/48] 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 10/48] 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 11/48] 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 12/48] 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 13/48] 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 14/48] 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 15/48] 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 16/48] 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 17/48] 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 18/48] 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 19/48] 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 20/48] 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 21/48] 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 22/48] 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 23/48] 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 24/48] 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 25/48] [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 26/48] 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 27/48] 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 28/48] 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()); } } From d4ccc753a50b8a7657607738ccf2bd169b8a388e Mon Sep 17 00:00:00 2001 From: ariedel-cern <85537041+ariedel-cern@users.noreply.github.com> Date: Thu, 11 Jan 2024 20:23:08 +0100 Subject: [PATCH 29/48] PWGCF: trigger update (#4279) * Feat: use recalculated DCA to PV for V0 daughters * Feat: use track variables from v0 table * Fix: fix linter issues --- EventFiltering/PWGCF/CFFilterAll.cxx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/EventFiltering/PWGCF/CFFilterAll.cxx b/EventFiltering/PWGCF/CFFilterAll.cxx index 6e0147621f1..fb719a02bcf 100644 --- a/EventFiltering/PWGCF/CFFilterAll.cxx +++ b/EventFiltering/PWGCF/CFFilterAll.cxx @@ -929,12 +929,19 @@ struct CFFilter { return true; } - template - bool isSelectedV0Daughter(T const& track, float charge, CFTrigger::V0Daughters species, double nSigmaTPCDaug[2]) + template + bool isSelectedV0Daughter(T const& track, V const& v0, float charge, CFTrigger::V0Daughters species, double nSigmaTPCDaug[2]) { - const auto eta = track.eta(); const auto tpcNClsF = track.tpcNClsFound(); - const auto dcaXY = track.dcaXY(); + float eta = -1; + float dca = -1; + if (charge > 0) { + eta = v0.positiveeta(); + dca = v0.dcapostopv(); + } else if (charge < 0) { + eta = v0.negativeeta(); + dca = v0.dcanegtopv(); + } const auto sign = track.sign(); double nSigmaTPC = -999.f; @@ -950,7 +957,7 @@ struct CFFilter { if (tpcNClsF < ConfDaughTPCnclsMin) { return false; } - if (std::abs(dcaXY) < ConfDaughDCAMin) { + if (std::abs(dca) < ConfDaughDCAMin) { return false; } @@ -1143,18 +1150,18 @@ struct CFFilter { } } if (charge > 0) { - if (!isSelectedV0Daughter(posTrack, 1, CFTrigger::kDaughProton, nSigmaTPCPos)) { + if (!isSelectedV0Daughter(posTrack, v0, 1, CFTrigger::kDaughProton, nSigmaTPCPos)) { return false; } - if (!isSelectedV0Daughter(negTrack, -1, CFTrigger::kDaughPion, nSigmaTPCNeg)) { + if (!isSelectedV0Daughter(negTrack, v0, -1, CFTrigger::kDaughPion, nSigmaTPCNeg)) { return false; } } if (charge < 0) { - if (!isSelectedV0Daughter(posTrack, 1, CFTrigger::kDaughPion, nSigmaTPCPos)) { + if (!isSelectedV0Daughter(posTrack, v0, 1, CFTrigger::kDaughPion, nSigmaTPCPos)) { return false; } - if (!isSelectedV0Daughter(negTrack, -1, CFTrigger::kDaughProton, nSigmaTPCNeg)) { + if (!isSelectedV0Daughter(negTrack, v0, -1, CFTrigger::kDaughProton, nSigmaTPCNeg)) { return false; } } From cc8aad44bba46b1a32b6265c642bff70c8f7946c Mon Sep 17 00:00:00 2001 From: Zuzanna Chochulska <87480906+zchochul@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:39:03 +0100 Subject: [PATCH 30/48] Producer's configurable change (#4284) --- 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 86b7ce16430..f07d1eba235 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -163,7 +163,7 @@ struct femtoUniverseProducerTask { 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 ConfTOFnSigmaCut{"ConfTOFnSigmaCut", 5., "TOF NSigma cut"}; - Configurable ConfTOFpTmin{"ConfTOFpTmin", 0.5, "TOF pT min"}; + Configurable ConfTOFpTmin{"ConfTOFpTmin", 500, "TOF pT min"}; // TrackSelection *o2PhysicsTrackSelection; /// \todo Labeled array (see Track-Track task) From 596fa6b8273fc68c2ccc9b1f2c46499cc720072c Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 12 Jan 2024 08:47:25 +0100 Subject: [PATCH 31/48] DPG/AOT-Track: Add more info in final histograms and fix minor bugs (#4286) * DPG/AOT-Track: Add more info in final histograms and fix minor bugs * Fix label * Fix range of D* mass * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot --- DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx | 71 ++++++++++++----------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx b/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx index 47d6cb9f2ab..8e048bce237 100644 --- a/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx +++ b/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx @@ -187,9 +187,9 @@ struct TagTwoProngDisplacedVertices { 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}; + const AxisSpec axisMassPiPi{250, 0.f, 2.5f}; + const AxisSpec axisMassKaKa{200, constants::physics::MassPhi - 0.05f, constants::physics::MassPhi + 0.05f}; + const AxisSpec axisMassKaPi{400, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}; 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}); @@ -366,7 +366,7 @@ struct TagTwoProngDisplacedVertices { LOG(error) << "Exception caught in DCA fitter process call!"; continue; } - if (nVertices == 0) { + if (nVertices != 1) { continue; } @@ -421,7 +421,7 @@ struct TagTwoProngDisplacedVertices { LOG(error) << "Exception caught in DCA fitter process call!"; continue; } - if (nVertices == 0) { + if (nVertices != 1) { continue; } @@ -526,7 +526,7 @@ struct TagTwoProngDisplacedVertices { /// Probe third track reconstruction efficiency with different selections struct ProbeThirdTrack { - using TracksWithSelAndDca = soa::Join; + using TracksWithDca = soa::Join; Preslice tagsPiPiPerCollision = aod::tagandprobe::collisionId; Preslice tagsKaKaPerCollision = aod::tagandprobe::collisionId; @@ -541,7 +541,7 @@ struct ProbeThirdTrack { std::array trackSelector{}; // define the track selectors - std::array, aod::tagandprobe::TrackTypes::NTrackTypes>, aod::tagandprobe::TagChannels::NTagChannels> histos{}; + std::array, aod::tagandprobe::TrackTypes::NTrackTypes>, aod::tagandprobe::TagChannels::NTagChannels> histos{}; HistogramRegistry registry{"registry"}; void init(InitContext&) @@ -579,35 +579,39 @@ struct ProbeThirdTrack { 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}}; + const AxisSpec axisPtProbe{250, 0.f, 25.f}; + const AxisSpec axisPtTag{250, 0.f, 50.f}; + const AxisSpec axisPtD{50, 0.f, 50.f}; + std::array axisMass = {AxisSpec{450, 1.65f, 2.10f}, AxisSpec{450, 1.65f, 2.10f}, AxisSpec{350, 0.135f, 0.17f}, AxisSpec{350, 0.135f, 0.17f}}; + std::array axisMassTag = {AxisSpec{250, 0.f, 2.5f}, AxisSpec{200, constants::physics::MassPhi - 0.05f, constants::physics::MassPhi + 0.05f}, AxisSpec{400, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}, AxisSpec{400, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}}; 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]}); + histos[iChannel][iTrackType] = registry.add(Form("h%sVsPtProbeTag_%s", tagChannels[iChannel].data(), trackTypes[iTrackType].data()), "; #it{p}_{T}(D) (GeV/#it{c}); #it{p}_{T}(tag) (GeV/#it{c}); #it{p}_{T}(probe track) (GeV/#it{c}); #it{M}(D) (GeV/#it{c}^{2}); #it{M}(tag) (GeV/#it{c}^{2});", HistType::kTHnSparseF, {axisPtD, axisPtTag, axisPtProbe, axisMass[iChannel], axisMassTag[iChannel]}); } } } template - float computeInvariantMass(TTrack const& trackFirst, TTrack const& trackSecond, TTrack const& trackThird, const uint8_t channel) + void computeInvariantMass(TTrack const& trackFirst, TTrack const& trackSecond, TTrack const& trackThird, const uint8_t channel, float& ptTag, float& invMassTag, float& ptD, float& invMass) { 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]); + auto arrMomentumTag = std::array{pVecTrackFirst, pVecTrackSecond}; + ptTag = RecoDecay::pt(RecoDecay::pVec(pVecTrackFirst, pVecTrackSecond)); + ptD = RecoDecay::pt(RecoDecay::pVec(pVecTrackFirst, pVecTrackSecond, pVecTrackThird)); + invMass = RecoDecay::m(arrMomentum, masses[channel]); + auto massesTagDau = std::array{masses[channel][0], masses[channel][1]}; + invMassTag = RecoDecay::m(arrMomentumTag, massesTagDau); + 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; + invMass -= invMassTag; } - - return invMass; } template @@ -628,15 +632,16 @@ struct ProbeThirdTrack { 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) { + float invMass{-1.f}, invMassTag{-1.f}, ptTag{-1.f}, ptD{-1.f}; + computeInvariantMass(trackFirst, trackSecond, trackThird, channel, ptTag, invMassTag, ptD, invMass); + if ((channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi || channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi) && invMass > 0.17f) { continue; - } else if (invMass < 1.65f || invMass > 2.10f) { + } else if ((channel == aod::tagandprobe::TagChannels::DplusToKPiPi || channel == aod::tagandprobe::TagChannels::DsOrDplusToKKPi) && (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); + histos[channel][iTrackType]->Fill(ptD, ptTag, ptTrackThird, invMass, invMassTag); } } } @@ -645,7 +650,7 @@ struct ProbeThirdTrack { void processCombinatorialDplusToKaPiPi(aod::Collisions const& collisions, aod::PiPiFromDpTags const& tagsPiPi, aod::TrackAssoc const& trackIndices, - TracksWithSelAndDca const& tracks) + TracksWithDca const& tracks) { for (const auto& collision : collisions) { auto thisCollId = collision.globalIndex(); @@ -653,8 +658,8 @@ struct ProbeThirdTrack { // 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(); + auto trackFirst = tagPiPi.track0_as(); + auto trackSecond = tagPiPi.track1_as(); loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DplusToKPiPi); } } @@ -664,7 +669,7 @@ struct ProbeThirdTrack { void processCombinatorialDsToPhiPi(aod::Collisions const& collisions, aod::KaKaFromDspTags const& tagsKaKa, aod::TrackAssoc const& trackIndices, - TracksWithSelAndDca const& tracks) + TracksWithDca const& tracks) { for (const auto& collision : collisions) { // Ds+/D+ -> phi(->K+K-)pi+ and c.c. @@ -672,8 +677,8 @@ struct ProbeThirdTrack { 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(); + auto trackFirst = tagKaKa.track0_as(); + auto trackSecond = tagKaKa.track1_as(); loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DsOrDplusToKKPi); } } @@ -684,7 +689,7 @@ struct ProbeThirdTrack { aod::PiKaFromDzTags const& tagsPiKa, aod::KaPiFromDzTags const& tagsKaPi, aod::TrackAssoc const& trackIndices, - TracksWithSelAndDca const& tracks) + TracksWithDca const& tracks) { for (const auto& collision : collisions) { auto thisCollId = collision.globalIndex(); @@ -692,15 +697,15 @@ struct ProbeThirdTrack { // 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(); + auto trackFirst = tagPiKa.track0_as(); // positive --> pion + auto trackSecond = tagPiKa.track1_as(); // negative --> kaon 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(); + auto trackFirst = tagKaPi.track0_as(); // positive --> kaon + auto trackSecond = tagKaPi.track1_as(); // negative --> pion loopOverThirdTrack(groupedTrackIndices, tracks, trackFirst, trackSecond, aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi); } } From 70e1391c3c8d96f1441dd40c558fe3486ec92336 Mon Sep 17 00:00:00 2001 From: Swati <69241911+SwatiSaha-1997@users.noreply.github.com> Date: Fri, 12 Jan 2024 14:10:25 +0530 Subject: [PATCH 32/48] MeanpT fluctuations of charged particles (#4277) * MeanptFluctuation-Task-O2 * MeanptFluctuation-Task-O2 * MeanptFluctuation-Task-O2 * MeanptFluctuation-Task-O2-modified * MeanptFluctuation-Task-O2-CopyrightError * EbyE-Fluctuations commit * previous files deleted * Meanpt Fluctuations * Meanpt Fluctuations * Meanpt Fluctuations * update comments for table definition * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot --- PWGCF/CMakeLists.txt | 3 +- PWGCF/EbyEFluctuations/CMakeLists.txt | 14 + PWGCF/EbyEFluctuations/Core/CMakeLists.txt | 10 + .../TableProducer/CMakeLists.txt | 10 + PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt | 15 ++ .../Tasks/MeanptFluctuations.cxx | 254 ++++++++++++++++++ 6 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 PWGCF/EbyEFluctuations/CMakeLists.txt create mode 100644 PWGCF/EbyEFluctuations/Core/CMakeLists.txt create mode 100644 PWGCF/EbyEFluctuations/TableProducer/CMakeLists.txt create mode 100644 PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt create mode 100644 PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx diff --git a/PWGCF/CMakeLists.txt b/PWGCF/CMakeLists.txt index 966c6c7a4dc..7432d5c21b1 100644 --- a/PWGCF/CMakeLists.txt +++ b/PWGCF/CMakeLists.txt @@ -22,4 +22,5 @@ add_subdirectory(TableProducer) add_subdirectory(Tutorial) add_subdirectory(TwoParticleCorrelations) add_subdirectory(JCorran) -add_subdirectory(Femto3D) \ No newline at end of file +add_subdirectory(Femto3D) +add_subdirectory(EbyEFluctuations) diff --git a/PWGCF/EbyEFluctuations/CMakeLists.txt b/PWGCF/EbyEFluctuations/CMakeLists.txt new file mode 100644 index 00000000000..0d3bb13ae7b --- /dev/null +++ b/PWGCF/EbyEFluctuations/CMakeLists.txt @@ -0,0 +1,14 @@ +# 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. + +add_subdirectory(Core) +add_subdirectory(Tasks) +add_subdirectory(TableProducer) diff --git a/PWGCF/EbyEFluctuations/Core/CMakeLists.txt b/PWGCF/EbyEFluctuations/Core/CMakeLists.txt new file mode 100644 index 00000000000..bbfd7adac2b --- /dev/null +++ b/PWGCF/EbyEFluctuations/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. diff --git a/PWGCF/EbyEFluctuations/TableProducer/CMakeLists.txt b/PWGCF/EbyEFluctuations/TableProducer/CMakeLists.txt new file mode 100644 index 00000000000..bbfd7adac2b --- /dev/null +++ b/PWGCF/EbyEFluctuations/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/EbyEFluctuations/Tasks/CMakeLists.txt b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt new file mode 100644 index 00000000000..ee6933efe5f --- /dev/null +++ b/PWGCF/EbyEFluctuations/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(meanpt-fluctuations + SOURCES MeanptFluctuations.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx new file mode 100644 index 00000000000..36cdf1c911a --- /dev/null +++ b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx @@ -0,0 +1,254 @@ +// 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/AnalysisTask.h" +#include "Framework/runDataProcessing.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 "TList.h" +#include "TProfile.h" +#include "TProfile2D.h" +#include "TRandom3.h" +#include "TMath.h" + +namespace o2::aod +{ +namespace ptQn +{ +DECLARE_SOA_COLUMN(Q1, q1, float); //! sum of pT of tracks in an event +DECLARE_SOA_COLUMN(Q2, q2, float); //! sum of (pT)^2 of tracks in an event +DECLARE_SOA_COLUMN(Q3, q3, float); //! sum of (pT)^3 of tracks in an event +DECLARE_SOA_COLUMN(Q4, q4, float); //! sum of (pT)^4 of tracks in an event +DECLARE_SOA_COLUMN(N_ch, n_ch, float); //! no of charged particles/multiplicity in an event +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Centrality of event +} // namespace ptQn +DECLARE_SOA_TABLE(MultPtQn, "AOD", "PTQN", ptQn::Q1, ptQn::Q2, ptQn::Q3, ptQn::Q4, ptQn::N_ch, ptQn::Centrality); //! table to store e-by-e sum of pT, (pT)^2, (pT)^3, (pT)^4 of tracks, multiplicity and centrality +} // namespace o2::aod + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct MeanptFluctuations_QA_QnTable { + + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutPtLower{"cfgCutPtLower", 0.2f, "Lower pT cut"}; + Configurable cfgCutPtUpper{"cfgCutPtUpper", 3.0f, "Higher pT cut"}; + Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPCchi2NCl"}; + + // Filter command*********** + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter trackFilter = (nabs(aod::track::eta) < 0.8f) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl); + + // 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"}; + + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // filtering collisions and tracks*********** + using aodCollisions = soa::Filtered>; + // using aodCollisions = soa::Filtered>; + using aodTracks = soa::Filtered>; + + // Equivalent of the AliRoot task UserCreateOutputObjects + void init(o2::framework::InitContext&) + { + // Define your axes + // Constant bin width axis + AxisSpec vtxZAxis = {100, -20, 20}; + // Variable bin width axis + std::vector ptBinning = {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.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4.}; + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + std::vector centBining = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}; + AxisSpec centAxis = {centBining, "centrality (%)"}; + + // Add histograms to histogram manager (as in the output object of in AliPhysics) + histos.add("hZvtx_after_sel", ";Z (cm)", kTH1F, {vtxZAxis}); + histos.add("hP", ";#it{p} (GeV/#it{c})", kTH1F, {{35, 0.2, 4.}}); + histos.add("hPt", ";#it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); + histos.add("hPhi", ";#phi", kTH1F, {{100, 0., 2. * M_PI}}); + histos.add("hEta", ";#eta", kTH1F, {{100, -2.01, 2.01}}); + histos.add("hCentrality", ";centrality (%)", kTH1F, {{90, 0, 90}}); + histos.add("hMeanPt", "", kTProfile, {centAxis}); + } + + Produces mult_ptQn; + + // void process(aod::Collision const& coll, aod::Tracks const& inputTracks) + void process(aodCollisions::iterator const& coll, aod::BCsWithTimestamps const&, aodTracks const& inputTracks) + { + histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); + histos.fill(HIST("hCentrality"), coll.centFT0C()); + + // variables + double cent = coll.centFT0C(); + double pT_sum = 0.0; + double N = 0.0; + + float q1 = 0.0; + float q2 = 0.0; + float q3 = 0.0; + float q4 = 0.0; + float n_ch = 0.0; + + for (auto track : inputTracks) { // Loop over tracks + + histos.fill(HIST("hP"), track.p()); + histos.fill(HIST("hPt"), track.pt()); + histos.fill(HIST("hEta"), track.eta()); + histos.fill(HIST("hPhi"), track.phi()); + + pT_sum += track.pt(); + N += 1.0; + + float pT = track.pt(); + // calculating Q1, Q2, Q3, Q4. N_ch + if (track.pt() > cfgCutPtLower && track.pt() < cfgCutPtUpper && track.sign() != 0) { + q1 = q1 + pow(pT, 1.0); + q2 = q2 + pow(pT, 2.0); + q3 = q3 + pow(pT, 3.0); + q4 = q4 + pow(pT, 4.0); + n_ch = n_ch + 1; + } + } + mult_ptQn(q1, q2, q3, q4, n_ch, cent); + // MeanPt + if (N > 0.0f) + histos.fill(HIST("hMeanPt"), cent, pT_sum / N); + } +}; + +struct MeanptFluctuations_analysis { + + Configurable cfgNSubsample{"cfgNSubsample", 10, "Number of subsamples"}; + + expressions::Filter Nch_filter = aod::ptQn::n_ch > 3.0f; + using FilteredMultPtQn = soa::Filtered; + + // Define output + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::vector>> Subsample; + TRandom3* fRndm = new TRandom3(0); + + void init(o2::framework::InitContext&) + { + AxisSpec centAxis = {90, 0, 90, "centrality (%)"}; + AxisSpec multAxis = {5000, 0.5, 5000.5, "#it{N}_{ch,acc}"}; + + registry.add("Prof_mean_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_var_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_var_t2", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_skew_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_skew_t2", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_skew_t3", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_kurt_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_kurt_t2", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_kurt_t3", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Prof_kurt_t4", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + + // initial array + Subsample.resize(cfgNSubsample); + for (int i = 0; i < cfgNSubsample; i++) { + Subsample[i].resize(10); + } + for (int i = 0; i < cfgNSubsample; i++) { + Subsample[i][0] = std::get>(registry.add(Form("Subsample_%d/Prof_mean_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][1] = std::get>(registry.add(Form("Subsample_%d/Prof_var_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][2] = std::get>(registry.add(Form("Subsample_%d/Prof_var_t2", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][3] = std::get>(registry.add(Form("Subsample_%d/Prof_skew_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][4] = std::get>(registry.add(Form("Subsample_%d/Prof_skew_t2", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][5] = std::get>(registry.add(Form("Subsample_%d/Prof_skew_t3", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][6] = std::get>(registry.add(Form("Subsample_%d/Prof_kurt_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][7] = std::get>(registry.add(Form("Subsample_%d/Prof_kurt_t2", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][8] = std::get>(registry.add(Form("Subsample_%d/Prof_kurt_t3", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + Subsample[i][9] = std::get>(registry.add(Form("Subsample_%d/Prof_kurt_t4", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + } + } + + float mean_term1; + float variance_term1; + float variance_term2; + float skewness_term1; + float skewness_term2; + float skewness_term3; + float kurtosis_term1; + float kurtosis_term2; + float kurtosis_term3; + float kurtosis_term4; + + // void process(aod::MultPtQn::iterator const& event_ptqn) + void process(FilteredMultPtQn::iterator const& event_ptqn) + { + // LOGF(info, "Centrality= %f Nch= %f Q1= %f Q2= %f", event_ptqn.centrality(), event_ptqn.n_ch(), event_ptqn.q1(), event_ptqn.q2()); + + // calculating observables + mean_term1 = event_ptqn.q1() / event_ptqn.n_ch(); + + variance_term1 = (TMath::Power(event_ptqn.q1(), 2.0f) - event_ptqn.q2()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f)); + variance_term2 = event_ptqn.q1() / event_ptqn.n_ch(); + + skewness_term1 = (TMath::Power(event_ptqn.q1(), 3.0f) - 3.0f * event_ptqn.q2() * event_ptqn.q1() + 2.0f * event_ptqn.q3()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f) * (event_ptqn.n_ch() - 2.0f)); + skewness_term2 = (TMath::Power(event_ptqn.q1(), 2.0f) - event_ptqn.q2()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f)); + skewness_term3 = (event_ptqn.q1() / event_ptqn.n_ch()); + + kurtosis_term1 = (TMath::Power(event_ptqn.q1(), 4.0f) - (6.0f * event_ptqn.q4()) + (8.0f * event_ptqn.q1() * event_ptqn.q3()) - (6.0f * TMath::Power(event_ptqn.q1(), 2.0f) * event_ptqn.q2()) + (3.0f * TMath::Power(event_ptqn.q2(), 2.0f))) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f) * (event_ptqn.n_ch() - 2.0f) * (event_ptqn.n_ch() - 3.0f)); + kurtosis_term2 = (TMath::Power(event_ptqn.q1(), 3.0f) - 3.0f * event_ptqn.q2() * event_ptqn.q1() + 2.0f * event_ptqn.q3()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f) * (event_ptqn.n_ch() - 2.0f)); + kurtosis_term3 = (TMath::Power(event_ptqn.q1(), 2.0f) - event_ptqn.q2()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f)); + kurtosis_term4 = (event_ptqn.q1() / event_ptqn.n_ch()); + + // filling profiles for central values + registry.get(HIST("Prof_mean_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), mean_term1); + registry.get(HIST("Prof_var_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), variance_term1); + registry.get(HIST("Prof_var_t2"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), variance_term2); + registry.get(HIST("Prof_skew_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term1); + registry.get(HIST("Prof_skew_t2"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term2); + registry.get(HIST("Prof_skew_t3"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term3); + registry.get(HIST("Prof_kurt_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term1); + registry.get(HIST("Prof_kurt_t2"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term2); + registry.get(HIST("Prof_kurt_t3"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term3); + registry.get(HIST("Prof_kurt_t4"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term4); + + // selecting subsample and filling profiles + float l_Random = fRndm->Rndm(); + int SampleIndex = static_cast(cfgNSubsample * l_Random); + Subsample[SampleIndex][0]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), mean_term1); + Subsample[SampleIndex][1]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), variance_term1); + Subsample[SampleIndex][2]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), variance_term2); + Subsample[SampleIndex][3]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term1); + Subsample[SampleIndex][4]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term2); + Subsample[SampleIndex][5]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term3); + Subsample[SampleIndex][6]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term1); + Subsample[SampleIndex][7]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term2); + Subsample[SampleIndex][8]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term3); + Subsample[SampleIndex][9]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term4); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + // Equivalent to the AddTask in AliPhysics + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; +} From b1584ffd496dbea887a5df384974bd379f3ddf60 Mon Sep 17 00:00:00 2001 From: ldellost <47105254+DelloStritto@users.noreply.github.com> Date: Fri, 12 Jan 2024 15:26:57 +0100 Subject: [PATCH 33/48] PWGHF: fixing chi2PCA histogram in the Lc->pKpi task (#4288) * PWGHF: Fix chi2PCA histo binning in the Lc task * fix --------- Co-authored-by: Luigi Dello Stritto --- PWGHF/D2H/Tasks/taskLc.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskLc.cxx b/PWGHF/D2H/Tasks/taskLc.cxx index 1040f7fca96..854ac445c73 100644 --- a/PWGHF/D2H/Tasks/taskLc.cxx +++ b/PWGHF/D2H/Tasks/taskLc.cxx @@ -110,10 +110,10 @@ struct HfTaskLc { {"MC/reconstructed/prompt/hCPAxyRecSigPrompt", "3-prong candidates;cosine of pointing angle xy;entries", {HistType::kTH1F, {{110, -1.1, 1.1}}}}, {"MC/reconstructed/nonprompt/hCPAxyRecSigNonPrompt", "3-prong candidates;cosine of pointing angle xy;entries", {HistType::kTH1F, {{110, -1.1, 1.1}}}}, /// Chi 2 PCA to sec. vertex - {"Data/hDca2", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{100, 0, 0.5}}}}, - {"MC/reconstructed/signal/hDca2RecSig", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{100, 0, 0.5}}}}, - {"MC/reconstructed/prompt/hDca2RecSigPrompt", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{100, 0, 0.5}}}}, - {"MC/reconstructed/nonprompt/hDca2RecSigNonPrompt", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{100, 0, 0.5}}}}, + {"Data/hDca2", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{400, 0., 20.}}}}, + {"MC/reconstructed/signal/hDca2RecSig", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{400, 0., 20.}}}}, + {"MC/reconstructed/prompt/hDca2RecSigPrompt", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{400, 0., 20.}}}}, + {"MC/reconstructed/nonprompt/hDca2RecSigNonPrompt", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{400, 0., 20.}}}}, /// eta {"Data/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1F, {{100, -2., 2.}}}}, {"MC/reconstructed/signal/hEtaRecSig", "3-prong candidates (matched);#it{#eta};entries", {HistType::kTH1F, {{100, -2., 2.}}}}, @@ -188,10 +188,10 @@ struct HfTaskLc { registry.add("MC/reconstructed/nonprompt/hCPAxyVsPtRecSigNonPrompt", "3-prong candidates (matched, non-prompt);cosine of pointing angle xy;entries", {HistType::kTH2F, {{110, -1.1, 1.1}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); /// Chi 2 PCA to sec. vertex - registry.add("Data/hDca2VsPt", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("MC/reconstructed/signal/hDca2VsPtRecSig", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("MC/reconstructed/prompt/hDca2VsPtRecSigPrompt", "3-prong candidates (matched, prompt);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("MC/reconstructed/nonprompt/hDca2VsPtRecSigNonPrompt", "3-prong candidates (matched, non-prompt);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{100, 0., 0.5}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("Data/hDca2VsPt", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{400, 0., 20.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("MC/reconstructed/signal/hDca2VsPtRecSig", "3-prong candidates (matched);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{400, 0., 20.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("MC/reconstructed/prompt/hDca2VsPtRecSigPrompt", "3-prong candidates (matched, prompt);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{400, 0., 20.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("MC/reconstructed/nonprompt/hDca2VsPtRecSigNonPrompt", "3-prong candidates (matched, non-prompt);prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{400, 0., 20.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); /// eta registry.add("Data/hEtaVsPt", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("MC/reconstructed/signal/hEtaVsPtRecSig", "3-prong candidates (matched);candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); From d96c836dd29a24f5a45940018847f8e983b8cf6f Mon Sep 17 00:00:00 2001 From: Tanu Gahlaut <154991749+TGahlaut1@users.noreply.github.com> Date: Fri, 12 Jan 2024 20:41:24 +0530 Subject: [PATCH 34/48] PWGCF: Mean pt fluc identified (#4290) * Update CMakeLists.txt * Create EbyEmeanPtFlucIdentified.cxx * Update CMakeLists.txt * Create CMakeLists.txt --- PWGCF/EbyEFluctuations/CMakeLists.txt | 1 + .../EbyEFluctuations/DataModel/CMakeLists.txt | 10 + PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt | 6 + .../Tasks/EbyEmeanPtFlucIdentified.cxx | 777 ++++++++++++++++++ 4 files changed, 794 insertions(+) create mode 100644 PWGCF/EbyEFluctuations/DataModel/CMakeLists.txt create mode 100644 PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx diff --git a/PWGCF/EbyEFluctuations/CMakeLists.txt b/PWGCF/EbyEFluctuations/CMakeLists.txt index 0d3bb13ae7b..10cac339f90 100644 --- a/PWGCF/EbyEFluctuations/CMakeLists.txt +++ b/PWGCF/EbyEFluctuations/CMakeLists.txt @@ -10,5 +10,6 @@ # or submit itself to any jurisdiction. add_subdirectory(Core) +add_subdirectory(DataModel) add_subdirectory(Tasks) add_subdirectory(TableProducer) diff --git a/PWGCF/EbyEFluctuations/DataModel/CMakeLists.txt b/PWGCF/EbyEFluctuations/DataModel/CMakeLists.txt new file mode 100644 index 00000000000..bbfd7adac2b --- /dev/null +++ b/PWGCF/EbyEFluctuations/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/EbyEFluctuations/Tasks/CMakeLists.txt b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt index ee6933efe5f..53fdf85a489 100644 --- a/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt +++ b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt @@ -13,3 +13,9 @@ o2physics_add_dpl_workflow(meanpt-fluctuations SOURCES MeanptFluctuations.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(mean-pt-fluc-id + SOURCES EbyEmeanPtFlucIdentified.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) + diff --git a/PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx b/PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx new file mode 100644 index 00000000000..8721b374e9d --- /dev/null +++ b/PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx @@ -0,0 +1,777 @@ +// 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 EbyEmeanPtFluc.cxx +/// \brief Calculate EbyE fluctuations with cummulant method. +/// For charged particles and identified particles. +/// +/// \author Tanu Gahlaut + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/HistogramSpec.h" +#include "TDatabasePDG.h" +#include "TLorentzVector.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +double massPi = TDatabasePDG::Instance()->GetParticle(211)->Mass(); +double massKa = TDatabasePDG::Instance()->GetParticle(321)->Mass(); +double massPr = TDatabasePDG::Instance()->GetParticle(2212)->Mass(); + +struct meanPtFlucId { + Configurable ptMax{"ptMax", 2.0, "maximum pT"}; + Configurable ptMin{"ptMin", 0.15, "minimum pT"}; + Configurable etaCut{"etaCut", 0.8, "Eta cut"}; + Configurable rapCut{"rapCut", 0.5, "Rapidity Cut"}; + Configurable dcaXYCut{"dcaXYCut", 0.12, "DCAxy cut"}; + Configurable dcaZCut{"dcaZCut", 1.0, "DCAz cut"}; + Configurable posZCut{"posZCut", 7.0, "cut for vertex Z"}; + Configurable nSigCut1{"nSigCut1", 1.0, "nSigma cut (1)"}; + Configurable nSigCut2{"nSigCut2", 2.0, "nSigma cut (2)"}; + Configurable nSigCut3{"nSigCut3", 3.0, "nSigma cut (3)"}; + Configurable nSigCut4{"nSigCut4", 4.0, "nSigma cut (4)"}; + Configurable nSigCut5{"nSigCut5", 5.0, "nSigma cut (5)"}; + Configurable nSigCut15{"nSigCut15", 1.5, "nSigma cut (1.5)"}; + Configurable nSigCut25{"nSigCut25", 2.5, "nSigma cut (2.5)"}; + Configurable piP1{"piP1", 0.65, "pion p (1)"}; + Configurable piP2{"piP2", 0.70, "pion p (2)"}; + Configurable piP3{"piP3", 1.40, "pion p (3)"}; + Configurable piP4{"piP4", 1.70, "pion p (4)"}; + Configurable kaP1{"kaP1", 0.20, "min kaon p (1)"}; + Configurable kaP2{"kaP2", 0.5, "kaon p (2)"}; + Configurable kaP3{"kaP3", 0.55, "kaon p (3)"}; + Configurable kaP4{"kaP4", 0.60, "kaon p (4)"}; + Configurable kaP5{"kaP5", 0.65, "kaon p (5)"}; + Configurable kaP6{"kaP6", 1.10, "kaon p (6)"}; + Configurable kaP7{"kaP7", 1.28, "kaon p (7)"}; + Configurable kaP8{"kaP8", 1.50, "kaon p (8)"}; + Configurable prP1{"prP1", 0.40, "min proton p (1)"}; + Configurable prP2{"prP2", 0.95, "proton p (2)"}; + Configurable prP3{"prP3", 1.00, "proton p (3)"}; + Configurable prP4{"prP4", 1.05, "proton p (4)"}; + Configurable prP5{"prP5", 1.13, "proton p (5)"}; + Configurable prP6{"prP6", 1.18, "proton p (6)"}; + + using MyAllTracks = soa::Join; + using MyAllCollisions = soa::Join; + + Filter collisionZFilter = nabs(aod::collision::posZ) < posZCut; + Filter collisionTrigger = o2::aod::evsel::sel8 == true; + Filter trackDCA = nabs(aod::track::dcaXY) < dcaXYCut && nabs(aod::track::dcaZ) < dcaZCut; + Filter trackEta = nabs(aod::track::eta) < etaCut; + Filter trackPt = aod::track::pt > ptMin&& aod::track::pt < ptMax; + Filter trackGobal = requireGlobalTrackInFilter(); + // Filter trackGobal = requirePrimaryTracksInFilter(); + using MyFilteredTracks = soa::Filtered; + using MyFilteredCollisions = soa::Filtered; + + HistogramRegistry hist{"hist", {}, OutputObjHandlingPolicy::AnalysisObject}; + void init(InitContext const&) + { + const AxisSpec axisEvents{5, 0, 5, "Counts"}; + const AxisSpec axisEta{100, -1., +1., "#eta"}; + const AxisSpec axisY{100, -1., +1., "Rapidity"}; + const AxisSpec axisPt{300, 0., 3., "p_{T} (GeV/c)"}; + const AxisSpec axisP{300, 0., 3., "p (GeV/c)"}; + const AxisSpec axisPart{500, 0., 5., " "}; + const AxisSpec axisMeanPt{100, 0., 3., "M(p_{T}) (GeV/c)"}; + const AxisSpec axisMult{100, 0, 100, "N_{ch}"}; + const AxisSpec axisMultTPC{200, 0, 800, "N_{TPC} "}; + const AxisSpec axisMultFT0M{150, 0, 15000, "N_{FT0M}"}; + const AxisSpec axisCentFT0M{50, 0, 101, "FT0M (%)"}; + const AxisSpec axisVtxZ{80, -20., 20., "V_{Z} (cm)"}; + const AxisSpec axisDCAz{100, -1.2, 1.2, "DCA_{Z} (cm)"}; + const AxisSpec axisDCAxy{100, -0.15, 0.15, "DCA_{XY} (cm)"}; + const AxisSpec axisTPCNsigma{500, -5., 5., "n #sigma_{TPC}"}; + const AxisSpec axisTOFNsigma{500, -5., 5., "n #sigma_{TOF}"}; + const AxisSpec axisTPCSignal{180, 20., 200., "#frac{dE}{dx}"}; + const AxisSpec axisTOFSignal{100, 0.2, 1.2, "TOF #beta"}; + const AxisSpec axisChi2{50, 0., 50., "Chi2"}; + const AxisSpec axisCrossedTPC{500, 0, 500, "Crossed TPC"}; + + // QA checks: + hist.add("QA/before/h_Counts", "Counts before cuts", kTH1D, {axisEvents}); + hist.add("QA/before/h_VtxZ", "V_{Z}", kTH1D, {axisVtxZ}); + + hist.add("QA/before/h_TPCChi2perCluster", "TPC #Chi^{2}/Cluster", kTH1D, {axisChi2}); + hist.add("QA/before/h_ITSChi2perCluster", "ITS #Chi^{2}/Cluster", kTH1D, {axisChi2}); + hist.add("QA/before/h_crossedTPC", "Crossed TPC", kTH1D, {axisCrossedTPC}); + + hist.add("QA/before/Charged/h_Eta_ch", "#eta Charged Particles", kTH1D, {axisEta}); + hist.add("QA/before/Charged/h_Pt_ch", "p_{T} Charged Particles", kTH1D, {axisPt}); + hist.add("QA/before/Charged/h2_DcaZ_ch", "DCA_{Z}", kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/before/Charged/h2_DcaXY_ch", "DCA_{XY}", kTH2D, {{axisPt}, {axisDCAxy}}); + + hist.add("QA/before/h2_TPCSignal_b", "TPC Signal (before)", kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/before/h2_TOFSignal_b", "TOF Signal (before)", kTH2D, {{axisP}, {axisTOFSignal}}); + + hist.add("QA/before/Pion/h2_TPCNsigma_pi", "n #sigma_{TPC} (Pions)", + kTH2D, {{axisP}, {axisTPCNsigma}}); + hist.add("QA/before/Pion/h2_TOFNsigma_pi", "n #sigma_{TOF} (Pions)", + kTH2D, {{axisP}, {axisTOFNsigma}}); + hist.add("QA/before/Pion/h2_TpcTofNsigma_pi", "n #sigma_{TPC} vs n #sigma_{TOF} (Pions)", + kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); + hist.add("QA/before/Kaon/h2_TPCNsigma_ka", "n #sigma_{TPC} Kaons", + kTH2D, {{axisP}, {axisTPCNsigma}}); + hist.add("QA/before/Kaon/h2_TOFNsigma_ka", "n #sigma_{TOF} Kaons", + kTH2D, {{axisP}, {axisTOFNsigma}}); + hist.add("QA/before/Kaon/h2_TpcTofNsigma_ka", "N_{TPC} igma vs n #sigma_{TOF} Kaons", + kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); + hist.add("QA/before/Proton/h2_TPCNsigma_pr", "n #sigma_{TPC} Protons", + kTH2D, {{axisP}, {axisTPCNsigma}}); + hist.add("QA/before/Proton/h2_TOFNsigma_pr", "n #sigma_{TOF} Protons", + kTH2D, {{axisP}, {axisTOFNsigma}}); + hist.add("QA/before/Proton/h2_TpcTofNsigma_pr", "n #sigma_{TPC} vs n #sigma_{TOF} Protons", + kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); + + // after + hist.add("QA/after/h_Counts", "Counts after cuts", kTH1D, {axisEvents}); + hist.add("QA/after/h_VtxZ", "V_{Z} (after)", kTH1D, {axisVtxZ}); + + hist.add("QA/after/h_NTPC", "N_{TPC}", kTH1D, {axisMultTPC}); + hist.add("QA/after/h_NFT0M", "FT0M Multiplicity", kTH1D, {axisMultFT0M}); + hist.add("QA/after/h_Cent", "FT0M (%)", kTH1D, {axisCentFT0M}); + hist.add("QA/after/h2_NTPC_NFT0M", "N_{TPC} vs N_{FT0M}", kTH2D, {{axisMultFT0M}, {axisMultTPC}}); + hist.add("QA/after/p_NTPC_NFT0M", "N_{TPC} vs N_{FT0M} (Profile)", kTProfile, {{axisMultFT0M}}); + hist.add("QA/after/p_NFT0M_NTPC", "N_{FT0M} vs N_{TPC} (Profile)", kTProfile, {{axisMultTPC}}); + hist.add("QA/after/h2_NTPC_Cent", "N_{TPC} vs FT0M(%)", kTH2D, {{axisCentFT0M}, {axisMultTPC}}); + hist.add("QA/after/p_NTPC_Cent", "N_{TPC} vs FT0M(%) (Profile)", kTProfile, {{axisCentFT0M}}); + hist.add("QA/after/h2_NTPC_Nch", "N_{ch} vs N_{TPC}", kTH2D, {{axisMultTPC}, {axisMult}}); + + hist.add("QA/after/h_TPCChi2perCluster", "TPC #Chi^{2}/Cluster (after)", kTH1D, {axisChi2}); + hist.add("QA/after/h_ITSChi2perCluster", "ITS #Chi^{2}/Cluster (after)", kTH1D, {axisChi2}); + hist.add("QA/after/h_crossedTPC", "Crossed TPC", kTH1D, {axisCrossedTPC}); + + hist.add("QA/after/Charged/h_Mult_ch", "Multiplicity Charged Prticles", kTH1D, {axisMult}); + hist.add("QA/after/Charged/h_Eta_ch", "#eta Charged Particles (after)", kTH1D, {axisEta}); + hist.add("QA/after/Charged/h_Pt_ch", "p_{T} Charged Particles (after)", kTH1D, {axisPt}); + hist.add("QA/after/Charged/h2_DcaZ_ch", "DCA_{Z} Charged Particles (after)", + kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/after/Charged/h2_DcaXY_ch", "DCA_{XY} Charged Particles (after)", + kTH2D, {{axisPt}, {axisDCAxy}}); + hist.add("QA/after/Charged/h2_Pt_Eta_ch", "p_{T} vs #eta (Charged Particles)", + kTH2D, {{axisEta}, {axisPt}}); + + hist.add("QA/after/h2_TPCSignal_a", "TPC Signal (after)", kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/h2_TOFSignal_a", "TOF Signal (after)", kTH2D, {{axisP}, {axisTOFSignal}}); + + hist.add("QA/after/TPC/Pion/h_Pt_pi_TPC", "p_{T} (Pions) TPC", kTH1D, {axisPt}); + hist.add("QA/after/TPC/Kaon/h_Pt_ka_TPC", "p_{T} (Kaons) TPC", kTH1D, {axisPt}); + hist.add("QA/after/TPC/Proton/h_Pt_pr_TPC", "p_{T} (Protons) TPC ", kTH1D, {axisPt}); + hist.add("QA/after/TPC/Pion/h_rap_pi_TPC", "y (Pions) TPC ", kTH1D, {axisY}); + hist.add("QA/after/TPC/Kaon/h_rap_ka_TPC", "y (Kaons) TPC", kTH1D, {axisY}); + hist.add("QA/after/TPC/Proton/h_rap_pr_TPC", "y (Protons) TPC", kTH1D, {axisY}); + hist.add("QA/after/TPC/Pion/h2_TPCSignal_pi_b", "TPC Signal Pions", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/TPC/Pion/h2_ExpTPCSignal_pi_b", "Expected TPC Signal Pions", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/TPC/Kaon/h2_TPCSignal_ka_b", "TPC Signal Kaons", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/TPC/Kaon/h2_ExpTPCSignal_ka_b", "Expected TPC Signal Kaons", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/TPC/Proton/h2_TPCSignal_pr_b", "TPC Signal Protons", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/TPC/Proton/h2_ExpTPCSignal_pr_b", "Expected TPC Signal Protons", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/TOF/Pion/h_Pt_pi_TOF", "p_{T} (Pions) TPC+TOF", kTH1D, {axisPt}); + hist.add("QA/after/TOF/Kaon/h_Pt_ka_TOF", "p_{T} (Kaons) TPC+TOF", kTH1D, {axisPt}); + hist.add("QA/after/TOF/Proton/h_Pt_pr_TOF", "p_{T} (Protons) TPC+TOF", kTH1D, {axisPt}); + hist.add("QA/after/TOF/Pion/h_rap_pi_TOF", "y (Pions) TPC+TOF ", kTH1D, {axisY}); + hist.add("QA/after/TOF/Kaon/h_rap_ka_TOF", "y (Kaons) TPC+TOF", kTH1D, {axisY}); + hist.add("QA/after/TOF/Proton/h_rap_pr_TOF", "y (Protons) TPC+TOF", kTH1D, {axisY}); + hist.add("QA/after/TOF/Pion/h2_TOFSignal_pi_b", "TOF Signal Pions", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/TOF/Pion/h2_ExpTOFSignal_pi_b", "Expected TOF Signal Pions", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/TOF/Kaon/h2_TOFSignal_ka_b", "TOF Signal Kaons", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/TOF/Kaon/h2_ExpTOFSignal_ka_b", "Expected TOF Signal Kaons", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/TOF/Proton/h2_TOFSignal_pr_b", "TOF Signal Protons", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/TOF/Proton/h2_ExpTOFSignal_pr_b", "Expected TOF Signal Protons", + kTH2D, {{axisP}, {axisTOFSignal}}); + + hist.add("QA/after/Pion/h_Mult_pi", "Multiplicity Pion", kTH1D, {axisMult}); + hist.add("QA/after/Pion/h_Pt_pi", "p_{T} (Pions) TPC and TPC+TOF", kTH1D, {axisPt}); + hist.add("QA/after/Pion/h_rap_pi", "y (Pions) TPC and TPC+TOF", kTH1D, {axisY}); + hist.add("QA/after/Pion/h2_Pt_rap_pi", "p_{T} vs y (Pions)", kTH2D, {{axisY}, {axisPt}}); + hist.add("QA/after/Pion/h2_DcaZ_pi", "DCA_{z} (Pions)", kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/after/Pion/h2_DcaXY_pi", "DCA_{xy} (Pions)", kTH2D, {{axisPt}, {axisDCAxy}}); + hist.add("QA/after/Pion/h2_TPCNsigma_pi", "n #sigma_{TPC} (Pions)", + kTH2D, {{axisP}, {axisTPCNsigma}}); + hist.add("QA/after/Pion/h2_TOFNsigma_pi", "n #sigma_{TOF} (Pions)", + kTH2D, {{axisP}, {axisTOFNsigma}}); + hist.add("QA/after/Pion/h2_TpcTofNsigma_pi", "n #sigma_{TPC} vs n #sigma_{TOF} (Pions)", + kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); + hist.add("QA/after/Pion/h2_TPCSignal_pi_a", "TPC Signal Pions (after)", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/Pion/h2_TOFSignal_pi_a", "TOF Signal Pions (after)", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/Pion/h2_ExpTPCSignal_pi_a", "Expected TPC Signal Pions (after)", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/Pion/h2_ExpTOFSignal_pi_a", "Expected TOF Signal Pions (after)", + kTH2D, {{axisP}, {axisTOFSignal}}); + + hist.add("QA/after/Kaon/h_Mult_ka", "Multiplicity Kaon", kTH1D, {axisMult}); + hist.add("QA/after/Kaon/h_Pt_ka", "p_{T} (Kaons) TPC and TPC+TOF", kTH1D, {axisPt}); + hist.add("QA/after/Kaon/h_rap_ka", "y (Kaons) TPC and TPC+TOF", kTH1D, {axisY}); + hist.add("QA/after/Kaon/h2_Pt_rap_ka", "p_{T} vs y (Kaons)", kTH2D, {{axisY}, {axisPt}}); + hist.add("QA/after/Kaon/h2_DcaZ_ka", "DCA_{z} Kaons", kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/after/Kaon/h2_DcaXY_ka", "DCA_{xy} Kaons", kTH2D, {{axisPt}, {axisDCAxy}}); + hist.add("QA/after/Kaon/h2_TPCNsigma_ka", "n #sigma_{TPC} Kaons", + kTH2D, {{axisP}, {axisTPCNsigma}}); + hist.add("QA/after/Kaon/h2_TOFNsigma_ka", "n #sigma_{TOF} Kaons", + kTH2D, {{axisP}, {axisTOFNsigma}}); + hist.add("QA/after/Kaon/h2_TpcTofNsigma_ka", "n #sigma_{TPC} vs n #sigma_{TOF} Kaons", + kTH2D, {{axisTPCNsigma}, {axisTOFNsigma}}); + hist.add("QA/after/Kaon/h2_TPCSignal_ka_a", "TPC Signal Kaons (after)", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/Kaon/h2_TOFSignal_ka_a", "TOF Signal Kaons (after)", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/Kaon/h2_ExpTPCSignal_ka_a", "Expected TPC Signal Kaons (after)", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/Kaon/h2_ExpTOFSignal_ka_a", "Expected TOF Signal Kaons (after)", + kTH2D, {{axisP}, {axisTOFSignal}}); + + hist.add("QA/after/Proton/h_Mult_pr", "Multiplicity Proton", kTH1D, {axisMult}); + hist.add("QA/after/Proton/h_Pt_pr", "p_{T} (Protons) TPC and TPC+TOF", kTH1D, {axisPt}); + hist.add("QA/after/Proton/h_rap_pr", "y(Protons) TPC and TPC+TOF", kTH1D, {axisY}); + hist.add("QA/after/Proton/h2_Pt_rap_pr", "p_{T} vs y (Protons)", kTH2D, {{axisY}, {axisPt}}); + hist.add("QA/after/Proton/h2_DcaZ_pr", "DCA_{z} (Protons)", kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/after/Proton/h2_DcaXY_pr", "DCA_{xy} (Protons)", kTH2D, {{axisPt}, {axisDCAxy}}); + hist.add("QA/after/Proton/h2_TPCNsigma_pr", "n #sigma_{TPC} (Protons)", + kTH2D, {{axisP}, {axisTPCNsigma}}); + hist.add("QA/after/Proton/h2_TOFNsigma_pr", "n #sigma_{TOF} (Protons)", + kTH2D, {{axisP}, {axisTOFNsigma}}); + hist.add("QA/after/Proton/h2_TpcTofNsigma_pr", "n #sigma_{TPC} vs n #sigma_{TOF} (Protons)", + kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); + hist.add("QA/after/Proton/h2_TPCSignal_pr_a", "TPC Signal Protons (after)", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/Proton/h2_TOFSignal_pr_a", "TOF Signal Protons (after)", + kTH2D, {{axisP}, {axisTOFSignal}}); + hist.add("QA/after/Proton/h2_ExpTPCSignal_pr_a", "Expected TPC Signal Protons (after)", + kTH2D, {{axisP}, {axisTPCSignal}}); + hist.add("QA/after/Proton/h2_ExpTOFSignal_pr_a", "Expected TOF Signal Protons (after)", + kTH2D, {{axisP}, {axisTOFSignal}}); + + // Analysis: + // Charged Particles + hist.add("Analysis/Charged/h_Mult_ch", "Multiplicity of Charged Prticles", kTH1D, {axisMult}); + hist.add("Analysis/Charged/h_mean_Q1_ch", "mean p_{T} (Charged particles)", kTH1D, {axisMeanPt}); + hist.add("Analysis/Charged/p_mean_Q1_ch", "mean p_{T} (Charged particles)", kTProfile, {axisMult}); + hist.add("Analysis/Charged/h_mean_Q1_Mult_ch", "Mean p_{T} vs N_{ch} (Charged Particles)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Charged/h_twopart_Mult_ch", "Twopart vs N_{ch} (Charged Particles)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Charged/h_threepart_Mult_ch", "Threepart vs N_{ch} (Charged Particles)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Charged/h_fourpart_Mult_ch", "Fourpart vs N_{ch} (Charged Particles)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + + // Pions + hist.add("Analysis/Pion/h_Mult_pi", "Multiplicity Pion", kTH1D, {axisMult}); + hist.add("Analysis/Pion/h_mean_Q1_pi", "mean p_{T} Pion", kTH1D, {axisMeanPt}); + hist.add("Analysis/Pion/p_mean_Q1_pi", "mean p_{T} Pion", kTProfile, {axisMult}); + hist.add("Analysis/Pion/h_mean_Q1_Mult_pi", "mean_Q1_Mult Pion", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_twopart_Mult_pi", "twopart_Mult Pion", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_threepart_Mult_pi", "threepart_Mult Pion", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_fourpart_Mult_pi", "fourpart_Mult Pion", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + + // Kaons + hist.add("Analysis/Kaon/h_Mult_ka", "Multiplicity Kaon", kTH1D, {axisMult}); + hist.add("Analysis/Kaon/h_mean_Q1_ka", "mean p_{T} Kaon", kTH1D, {axisMeanPt}); + hist.add("Analysis/Kaon/p_mean_Q1_ka", "mean p_{T} Kaon", kTProfile, {axisMult}); + hist.add("Analysis/Kaon/h_mean_Q1_Mult_ka", "mean_Q1_Mult Kaon", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_twopart_Mult_ka", "twopart_Mult Kaon", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_threepart_Mult_ka", "threepart_Mult Kaon", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_fourpart_Mult_ka", "fourpart_Mult Kaon", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + + // Protons + hist.add("Analysis/Proton/h_Mult_pr", "Multiplicity Proton", kTH1D, {axisMult}); + hist.add("Analysis/Proton/h_mean_Q1_pr", "mean p_{T} Proton", kTH1D, {axisMeanPt}); + hist.add("Analysis/Proton/p_mean_Q1_pr", "mean p_{T} Proton", kTProfile, {axisMult}); + hist.add("Analysis/Proton/h_mean_Q1_Mult_pr", "mean_Q1_Mult Proton", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_twopart_Mult_pr", "twopart_Mult Proton", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_threepart_Mult_pr", "threepart_Mult Proton", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_fourpart_Mult_pr", "fourpart_Mult Proton", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + + // Additional QA + hist.add("Analysis/Charged/h_mean_Q1_Mult_ch_tof", "mean_Q1_Mult (Charged Particles) (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Charged/h_twopart_Mult_ch_tof", "twopart_Mult (Charged Particles) (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_mean_Q1_Mult_pi_tof", "mean_Q1_Mult Pion (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_mean_Q1_Mult_pi_tpc", "mean_Q1_Mult Pion (TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_twopart_Mult_pi_tof", "twopart_Mult Pion (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Pion/h_twopart_Mult_pi_tpc", "twopart_Mult Pion (TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_mean_Q1_Mult_pr_tof", "mean_Q1_Mult Proton (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_mean_Q1_Mult_pr_tpc", "mean_Q1_Mult Proton (TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_twopart_Mult_pr_tof", "twopart_Mult Proton (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Proton/h_twopart_Mult_pr_tpc", "twopart_Mult Proton (TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_mean_Q1_Mult_ka_tof", "mean_Q1_Mult Kaon (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_mean_Q1_Mult_ka_tpc", "mean_Q1_Mult Kaon (TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_twopart_Mult_ka_tof", "twopart_Mult Kaon (TOF+TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + hist.add("Analysis/Kaon/h_twopart_Mult_ka_tpc", "twopart_Mult Kaon (TPC)", + kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); + } + + void process_QA(MyAllCollisions::iterator const& myCol, MyAllTracks const& myTracks) + { + for (auto& myTrack : myTracks) { + hist.fill(HIST("QA/before/Charged/h_Eta_ch"), myTrack.eta()); + hist.fill(HIST("QA/before/Charged/h_Pt_ch"), myTrack.pt()); + hist.fill(HIST("QA/before/h_TPCChi2perCluster"), myTrack.tpcChi2NCl()); + hist.fill(HIST("QA/before/h_ITSChi2perCluster"), myTrack.itsChi2NCl()); + hist.fill(HIST("QA/before/h_crossedTPC"), myTrack.tpcNClsCrossedRows()); + hist.fill(HIST("QA/before/Charged/h2_DcaXY_ch"), myTrack.pt(), myTrack.dcaXY()); + hist.fill(HIST("QA/before/Charged/h2_DcaZ_ch"), myTrack.pt(), myTrack.dcaZ()); + } + hist.fill(HIST("QA/before/h_VtxZ"), myCol.posZ()); + hist.fill(HIST("QA/before/h_Counts"), 2); + } + PROCESS_SWITCH(meanPtFlucId, process_QA, "process QA", true); + + void process(MyFilteredCollisions::iterator const& col, MyFilteredTracks const& tracks) + { + double Cent_FT0M = 0; + int N_Pi = 0, N_Ka = 0, N_Pr = 0; + int Nch = 0, NTPC = 0, N_FT0M = 0; + int N_Ka_tpc = 0, N_Pr_tpc = 0, N_Pi_tpc = 0; + int Nch_tof = 0, N_Ka_tof = 0, N_Pr_tof = 0, N_Pi_tof = 0; + double pt_ch = 0, Q1_ch = 0, Q2_ch = 0, Q3_ch = 0, Q4_ch = 0; + double pt_Pi = 0, Q1_Pi = 0, Q2_Pi = 0, Q3_Pi = 0, Q4_Pi = 0; + double pt_Pr = 0, Q1_Pr = 0, Q2_Pr = 0, Q3_Pr = 0, Q4_Pr = 0; + double pt_Ka = 0, Q1_Ka = 0, Q2_Ka = 0, Q3_Ka = 0, Q4_Ka = 0; + double Q1_tof = 0, Q1_Pi_tof = 0, Q1_Pr_tof = 0, Q1_Ka_tof = 0; + double Q1_Pi_tpc = 0, Q1_Pr_tpc = 0, Q1_Ka_tpc = 0; + double Q2_tof = 0, Q2_Pi_tof = 0, Q2_Pr_tof = 0, Q2_Ka_tof = 0; + double Q2_Pi_tpc = 0, Q2_Pr_tpc = 0, Q2_Ka_tpc = 0; + + for (auto& track : tracks) { + Nch++; + pt_ch = track.pt(); + Q1_ch += pt_ch; + Q2_ch += pt_ch * pt_ch; + Q3_ch += pt_ch * pt_ch * pt_ch; + Q4_ch += pt_ch * pt_ch * pt_ch * pt_ch; + + hist.fill(HIST("QA/after/Charged/h_Eta_ch"), track.eta()); + hist.fill(HIST("QA/after/Charged/h_Pt_ch"), track.pt()); + hist.fill(HIST("QA/after/Charged/h2_Pt_Eta_ch"), track.eta(), track.pt()); + hist.fill(HIST("QA/after/Charged/h2_DcaXY_ch"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/after/Charged/h2_DcaZ_ch"), track.pt(), track.dcaZ()); + + hist.fill(HIST("QA/after/h_TPCChi2perCluster"), track.tpcChi2NCl()); + hist.fill(HIST("QA/after/h_ITSChi2perCluster"), track.itsChi2NCl()); + hist.fill(HIST("QA/after/h_crossedTPC"), track.tpcNClsCrossedRows()); + + hist.fill(HIST("QA/before/h2_TOFSignal_b"), track.p(), track.beta()); + hist.fill(HIST("QA/before/h2_TPCSignal_b"), track.p(), track.tpcSignal()); + + hist.fill(HIST("QA/before/Pion/h2_TPCNsigma_pi"), track.p(), track.tpcNSigmaPi()); + hist.fill(HIST("QA/before/Pion/h2_TOFNsigma_pi"), track.p(), track.tofNSigmaPi()); + hist.fill(HIST("QA/before/Pion/h2_TpcTofNsigma_pi"), track.tpcNSigmaPi(), track.tofNSigmaPi()); + hist.fill(HIST("QA/before/Proton/h2_TPCNsigma_pr"), track.p(), track.tpcNSigmaPr()); + hist.fill(HIST("QA/before/Proton/h2_TOFNsigma_pr"), track.p(), track.tofNSigmaPr()); + hist.fill(HIST("QA/before/Proton/h2_TpcTofNsigma_pr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + hist.fill(HIST("QA/before/Kaon/h2_TPCNsigma_ka"), track.p(), track.tpcNSigmaKa()); + hist.fill(HIST("QA/before/Kaon/h2_TOFNsigma_ka"), track.p(), track.tofNSigmaKa()); + hist.fill(HIST("QA/before/Kaon/h2_TpcTofNsigma_ka"), track.tpcNSigmaKa(), track.tofNSigmaKa()); + + // ###################################################// + // TPC (Without p cuts) // + // ###################################################// + if (abs(track.tpcNSigmaPi()) < nSigCut3) { + if (abs(track.rapidity(massPi)) >= 0.5) + continue; + N_Pi_tpc++; + Q1_Pi_tpc += track.pt(); + Q2_Pi_tpc += track.pt() * track.pt(); + hist.fill(HIST("QA/after/TPC/Pion/h_Pt_pi_TPC"), track.pt()); + hist.fill(HIST("QA/after/TPC/Pion/h_rap_pi_TPC"), track.rapidity(massPi)); + hist.fill(HIST("QA/after/TPC/Pion/h2_TPCSignal_pi_b"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/TPC/Pion/h2_ExpTPCSignal_pi_b"), track.p(), track.tpcExpSignalPi(track.tpcSignal())); + } + if (abs(track.tpcNSigmaKa()) < nSigCut3) { + if (abs(track.rapidity(massKa)) >= 0.5) + continue; + N_Ka_tpc++; + Q1_Ka_tpc += track.pt(); + Q2_Ka_tpc += track.pt() * track.pt(); + hist.fill(HIST("QA/after/TPC/Kaon/h_Pt_ka_TPC"), track.pt()); + hist.fill(HIST("QA/after/TPC/Kaon/h_rap_ka_TPC"), track.rapidity(massKa)); + hist.fill(HIST("QA/after/TPC/Kaon/h2_TPCSignal_ka_b"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/TPC/Kaon/h2_ExpTPCSignal_ka_b"), track.p(), track.tpcExpSignalKa(track.tpcSignal())); + } + if (abs(track.tpcNSigmaPr()) < nSigCut3) { + if (abs(track.rapidity(massPr)) >= 0.5) + continue; + N_Pr_tpc++; + Q1_Pr_tpc += track.pt(); + Q2_Pr_tpc += track.pt() * track.pt(); + hist.fill(HIST("QA/after/TPC/Proton/h_Pt_pr_TPC"), track.pt()); + hist.fill(HIST("QA/after/TPC/Proton/h_rap_pr_TPC"), track.rapidity(massPr)); + hist.fill(HIST("QA/after/TPC/Proton/h2_TPCSignal_pr_b"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/TPC/Proton/h2_ExpTPCSignal_pr_b"), track.p(), track.tpcExpSignalPr(track.tpcSignal())); + } + + // ###################################################// + // TPC + TOF (Without p cuts) // + // ###################################################// + if (track.hasTOF()) { + Nch_tof++; + Q1_tof += track.pt(); + Q2_tof += track.pt() * track.pt(); + + if ((std::pow(track.tpcNSigmaPi(), 2) + std::pow(track.tofNSigmaPi(), 2)) < 6.0) { + if (abs(track.rapidity(massPi)) >= 0.5) + continue; + N_Pi_tof++; + Q1_Pi_tof += track.pt(); + Q2_Pi_tof += track.pt() * track.pt(); + hist.fill(HIST("QA/after/TOF/Pion/h_Pt_pi_TOF"), track.pt()); + hist.fill(HIST("QA/after/TOF/Pion/h_rap_pi_TOF"), track.rapidity(massPi)); + hist.fill(HIST("QA/after/TOF/Pion/h2_TOFSignal_pi_b"), track.p(), track.beta()); + hist.fill(HIST("QA/after/TOF/Pion/h2_ExpTOFSignal_pi_b"), track.p(), track.tofExpSignalPi(track.beta())); + } + if ((std::pow(track.tpcNSigmaKa(), 2) + std::pow(track.tofNSigmaKa(), 2)) < 6.0) { + if (abs(track.rapidity(massKa)) >= 0.5) + continue; + N_Ka_tof++; + Q1_Ka_tof += track.pt(); + Q2_Ka_tof += track.pt() * track.pt(); + hist.fill(HIST("QA/after/TOF/Kaon/h_Pt_ka_TOF"), track.pt()); + hist.fill(HIST("QA/after/TOF/Kaon/h_rap_ka_TOF"), track.rapidity(massKa)); + hist.fill(HIST("QA/after/TOF/Kaon/h2_TOFSignal_ka_b"), track.p(), track.beta()); + hist.fill(HIST("QA/after/TOF/Kaon/h2_ExpTOFSignal_ka_b"), track.p(), track.tofExpSignalKa(track.beta())); + } + if ((std::pow(track.tpcNSigmaPr(), 2) + std::pow(track.tofNSigmaPr(), 2)) < 6.0) { + if (abs(track.rapidity(massPr)) >= 0.5) + continue; + N_Pr_tof++; + Q1_Pr_tof += track.pt(); + Q2_Pr_tof += track.pt() * track.pt(); + hist.fill(HIST("QA/after/TOF/Proton/h_Pt_pr_TOF"), track.pt()); + hist.fill(HIST("QA/after/TOF/Proton/h_rap_pr_TOF"), track.rapidity(massPr)); + hist.fill(HIST("QA/after/TOF/Proton/h2_TOFSignal_pr_b"), track.p(), track.beta()); + hist.fill(HIST("QA/after/TOF/Proton/h2_ExpTOFSignal_pr_b"), track.p(), track.tofExpSignalPr(track.beta())); + } + } + + // ####################################################// + // TPC and TPC+TOF nSigma Cuts (with p cuts) // + // ####################################################// + // For Pions: + if ((track.hasTOF() == false && + ((abs(track.tpcNSigmaPi()) < nSigCut3 && track.p() <= piP1) || (abs(track.tpcNSigmaPi()) < nSigCut2 && track.p() > piP1 && track.p() <= piP2))) || + (track.hasTOF() && abs(track.tpcNSigmaPi()) < nSigCut4 && abs(track.tofNSigmaEl()) > nSigCut1 && + ((abs(track.tofNSigmaPi()) < nSigCut3 && track.p() <= piP3) || (abs(track.tofNSigmaPi()) < nSigCut25 && track.p() > piP3 && track.p() <= piP4) || (abs(track.tofNSigmaPi()) < nSigCut2 && track.p() > piP4)))) { + if (abs(track.rapidity(massPi)) >= 0.5) + continue; + N_Pi++; + pt_Pi = track.pt(); + Q1_Pi += pt_Pi; + Q2_Pi += pt_Pi * pt_Pi; + Q3_Pi += pt_Pi * pt_Pi * pt_Pi; + Q4_Pi += pt_Pi * pt_Pi * pt_Pi * pt_Pi; + hist.fill(HIST("QA/after/Pion/h_Pt_pi"), track.pt()); + hist.fill(HIST("QA/after/Pion/h_rap_pi"), track.rapidity(massPi)); + hist.fill(HIST("QA/after/Pion/h2_Pt_rap_pi"), track.rapidity(massPi), track.pt()); + hist.fill(HIST("QA/after/Pion/h2_DcaXY_pi"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/after/Pion/h2_DcaZ_pi"), track.pt(), track.dcaZ()); + hist.fill(HIST("QA/after/Pion/h2_TPCNsigma_pi"), track.p(), track.tpcNSigmaPi()); + hist.fill(HIST("QA/after/Pion/h2_TOFNsigma_pi"), track.p(), track.tofNSigmaPi()); + hist.fill(HIST("QA/after/Pion/h2_TpcTofNsigma_pi"), track.tpcNSigmaPi(), track.tofNSigmaPi()); + hist.fill(HIST("QA/after/h2_TOFSignal_a"), track.p(), track.beta()); + hist.fill(HIST("QA/after/Pion/h2_TOFSignal_pi_a"), track.p(), track.beta()); + hist.fill(HIST("QA/after/h2_TPCSignal_a"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/Pion/h2_TPCSignal_pi_a"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/Pion/h2_ExpTOFSignal_pi_a"), track.p(), track.tofExpSignalPi(track.beta())); + hist.fill(HIST("QA/after/Pion/h2_ExpTPCSignal_pi_a"), track.p(), track.tpcExpSignalPi(track.tpcSignal())); + } + + // For Kaons: + if ((track.hasTOF() == false && + ((abs(track.tpcNSigmaKa()) < nSigCut3 && track.pt() > kaP1 && track.p() <= kaP2) || (abs(track.tpcNSigmaKa()) < nSigCut25 && track.p() > kaP2 && track.p() <= kaP3) || (abs(track.tpcNSigmaKa()) < nSigCut2 && track.p() > kaP3 && track.p() <= kaP4) || (abs(track.tpcNSigmaKa()) < nSigCut15 && track.p() > kaP4 && track.p() <= kaP5))) || + (track.hasTOF() && abs(track.tpcNSigmaKa()) < nSigCut4 && abs(track.tofNSigmaEl()) > nSigCut1 && + ((abs(track.tofNSigmaKa()) < nSigCut3 && track.pt() > kaP1 && track.p() <= kaP6) || (abs(track.tofNSigmaKa()) < nSigCut2 && track.p() > kaP6 && track.p() <= kaP7) || (abs(track.tofNSigmaKa()) < nSigCut15 && track.p() > kaP7 && track.p() <= kaP8) || (abs(track.tofNSigmaKa()) < nSigCut1 && track.p() > kaP8)))) { + if (abs(track.rapidity(massKa)) >= 0.5) + continue; + pt_Ka = track.pt(); + Q1_Ka += pt_Ka; + Q2_Ka += pt_Ka * pt_Ka; + Q3_Ka += pt_Ka * pt_Ka * pt_Ka; + Q4_Ka += pt_Ka * pt_Ka * pt_Ka * pt_Ka; + N_Ka++; + hist.fill(HIST("QA/after/Kaon/h_Pt_ka"), track.pt()); + hist.fill(HIST("QA/after/Kaon/h_rap_ka"), track.rapidity(massKa)); + hist.fill(HIST("QA/after/Kaon/h2_Pt_rap_ka"), track.rapidity(massKa), track.pt()); + hist.fill(HIST("QA/after/Kaon/h2_DcaXY_ka"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/after/Kaon/h2_DcaZ_ka"), track.pt(), track.dcaZ()); + hist.fill(HIST("QA/after/Kaon/h2_TPCNsigma_ka"), track.p(), track.tpcNSigmaKa()); + hist.fill(HIST("QA/after/Kaon/h2_TOFNsigma_ka"), track.p(), track.tofNSigmaKa()); + hist.fill(HIST("QA/after/Kaon/h2_TpcTofNsigma_ka"), track.tpcNSigmaKa(), track.tofNSigmaKa()); + hist.fill(HIST("QA/after/h2_TOFSignal_a"), track.p(), track.beta()); + hist.fill(HIST("QA/after/Kaon/h2_TOFSignal_ka_a"), track.p(), track.beta()); + hist.fill(HIST("QA/after/h2_TPCSignal_a"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/Kaon/h2_TPCSignal_ka_a"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/Kaon/h2_ExpTOFSignal_ka_a"), track.p(), track.tofExpSignalKa(track.beta())); + hist.fill(HIST("QA/after/Kaon/h2_ExpTPCSignal_ka_a"), track.p(), track.tpcExpSignalKa(track.tpcSignal())); + } + + // For Protons: + if ((track.hasTOF() == false && + ((abs(track.tpcNSigmaPr()) < nSigCut3 && track.pt() > prP1 && track.p() <= prP2) || (abs(track.tpcNSigmaPr()) < nSigCut25 && track.p() > prP2 && track.p() <= prP3) || (abs(track.tpcNSigmaPr()) < nSigCut2 && track.p() > prP3 && track.p() <= prP4) || (abs(track.tpcNSigmaPr()) < nSigCut15 && track.p() > prP4 && track.p() <= prP5) || (abs(track.tpcNSigmaPr()) < nSigCut1 && track.p() > prP5 && track.p() <= prP6))) || + (track.hasTOF() && abs(track.tpcNSigmaPr()) < nSigCut4 && abs(track.tofNSigmaEl()) > nSigCut1 && abs(track.tofNSigmaPr()) < nSigCut3 && track.pt() > prP1)) { + if (abs(track.rapidity(massPr)) >= 0.5) + continue; + pt_Pr = track.pt(); + Q1_Pr += pt_Pr; + Q2_Pr += pt_Pr * pt_Pr; + Q3_Pr += pt_Pr * pt_Pr * pt_Pr; + Q4_Pr += pt_Pr * pt_Pr * pt_Pr * pt_Pr; + N_Pr++; + hist.fill(HIST("QA/after/Proton/h_Pt_pr"), track.pt()); + hist.fill(HIST("QA/after/Proton/h_rap_pr"), track.rapidity(massPr)); + hist.fill(HIST("QA/after/Proton/h2_DcaZ_pr"), track.pt(), track.dcaZ()); + hist.fill(HIST("QA/after/Proton/h2_DcaXY_pr"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/after/Proton/h2_Pt_rap_pr"), track.rapidity(massPr), track.pt()); + hist.fill(HIST("QA/after/Proton/h2_TPCNsigma_pr"), track.p(), track.tpcNSigmaPr()); + hist.fill(HIST("QA/after/Proton/h2_TOFNsigma_pr"), track.p(), track.tofNSigmaPr()); + hist.fill(HIST("QA/after/Proton/h2_TpcTofNsigma_pr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + hist.fill(HIST("QA/after/Proton/h2_TPCSignal_pr_a"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/h2_TPCSignal_a"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/h2_TOFSignal_a"), track.p(), track.beta()); + hist.fill(HIST("QA/after/Proton/h2_TOFSignal_pr_a"), track.p(), track.beta()); + hist.fill(HIST("QA/after/Proton/h2_ExpTOFSignal_pr_a"), track.p(), track.tofExpSignalPr(track.beta())); + hist.fill(HIST("QA/after/Proton/h2_ExpTPCSignal_pr_a"), track.p(), track.tpcExpSignalPr(track.tpcSignal())); + } + } + + NTPC = col.multTPC(); + N_FT0M = col.multFT0M(); + Cent_FT0M = col.centFT0M(); + hist.fill(HIST("QA/after/h_VtxZ"), col.posZ()); + hist.fill(HIST("QA/after/h_Counts"), 2); + hist.fill(HIST("QA/after/h_NTPC"), NTPC); + hist.fill(HIST("QA/after/h_Cent"), Cent_FT0M); + hist.fill(HIST("QA/after/h_NFT0M"), N_FT0M); + hist.fill(HIST("QA/after/h2_NTPC_NFT0M"), N_FT0M, NTPC); + hist.fill(HIST("QA/after/h2_NTPC_Cent"), Cent_FT0M, NTPC); + hist.fill(HIST("QA/after/p_NTPC_Cent"), Cent_FT0M, NTPC); + hist.fill(HIST("QA/after/p_NTPC_NFT0M"), N_FT0M, NTPC); + hist.fill(HIST("QA/after/p_NFT0M_NTPC"), NTPC, N_FT0M); + hist.fill(HIST("QA/after/h2_NTPC_Nch"), NTPC, Nch); + + hist.fill(HIST("Analysis/Charged/h_Mult_ch"), Nch); + hist.fill(HIST("Analysis/Pion/h_Mult_pi"), N_Pi); + hist.fill(HIST("Analysis/Kaon/h_Mult_ka"), N_Ka); + hist.fill(HIST("Analysis/Proton/h_Mult_pr"), N_Pr); + + hist.fill(HIST("QA/after/Charged/h_Mult_ch"), Nch); + hist.fill(HIST("QA/after/Pion/h_Mult_pi"), N_Pi); + hist.fill(HIST("QA/after/Kaon/h_Mult_ka"), N_Ka); + hist.fill(HIST("QA/after/Proton/h_Mult_pr"), N_Pr); + + // Charged Particles: + if (Nch > 1) { + auto Nch2 = static_cast(Nch) * (static_cast(Nch) - 1); + auto mean_Q1 = Q1_ch / static_cast(Nch); + auto twopart = ((Q1_ch * Q1_ch) - Q2_ch); + auto twopart1 = (twopart) / (Nch2); + hist.fill(HIST("Analysis/Charged/h_mean_Q1_ch"), mean_Q1); + hist.fill(HIST("Analysis/Charged/p_mean_Q1_ch"), NTPC, mean_Q1); + hist.fill(HIST("Analysis/Charged/h_mean_Q1_Mult_ch"), NTPC, mean_Q1, N_FT0M); + hist.fill(HIST("Analysis/Charged/h_twopart_Mult_ch"), NTPC, twopart1, N_FT0M); + } + + if (Nch > 2) { + auto Nch3 = static_cast(Nch) * (static_cast(Nch) - 1) * (static_cast(Nch) - 2); + auto threepart = ((Q1_ch * Q1_ch * Q1_ch) - (3 * Q2_ch * Q1_ch) + 2 * Q3_ch); + auto threepart1 = threepart / Nch3; + hist.fill(HIST("Analysis/Charged/h_threepart_Mult_ch"), NTPC, threepart1, N_FT0M); + } + + if (Nch > 3) { + auto Nch4 = static_cast(Nch) * (static_cast(Nch) - 1) * (static_cast(Nch) - 2) * (static_cast(Nch) - 3); + auto fourpart = ((Q1_ch * Q1_ch * Q1_ch * Q1_ch) - (6 * Q2_ch * Q1_ch * Q1_ch) + (3 * Q2_ch * Q2_ch) + (8 * Q3_ch * Q1_ch) - 6 * Q4_ch); + auto fourpart1 = fourpart / Nch4; + hist.fill(HIST("Analysis/Charged/h_fourpart_Mult_ch"), NTPC, fourpart1, N_FT0M); + } + + // Pions: + if (N_Pi > 1) { + auto Nch2_Pi = static_cast(N_Pi) * (static_cast(N_Pi) - 1); + auto mean_Q1_Pi = Q1_Pi / static_cast(N_Pi); + auto twopart_Pi = ((Q1_Pi * Q1_Pi) - Q2_Pi); + auto twopart1_Pi = (twopart_Pi) / (Nch2_Pi); + hist.fill(HIST("Analysis/Pion/h_mean_Q1_pi"), mean_Q1_Pi); + hist.fill(HIST("Analysis/Pion/p_mean_Q1_pi"), NTPC, mean_Q1_Pi); + hist.fill(HIST("Analysis/Pion/h_mean_Q1_Mult_pi"), NTPC, mean_Q1_Pi, N_FT0M); + hist.fill(HIST("Analysis/Pion/h_twopart_Mult_pi"), NTPC, twopart1_Pi, N_FT0M); + } + + if (N_Pi > 2) { + auto Nch3_Pi = static_cast(N_Pi) * (static_cast(N_Pi) - 1) * (static_cast(N_Pi) - 2); + auto threepart_Pi = ((Q1_Pi * Q1_Pi * Q1_Pi) - (3 * Q2_Pi * Q1_Pi) + 2 * Q3_Pi); + auto threepart1_Pi = threepart_Pi / Nch3_Pi; + hist.fill(HIST("Analysis/Pion/h_threepart_Mult_pi"), NTPC, threepart1_Pi, N_FT0M); + } + + if (N_Pi > 3) { + auto Nch4_Pi = static_cast(N_Pi) * (static_cast(N_Pi) - 1) * (static_cast(N_Pi) - 2) * (static_cast(N_Pi) - 3); + auto fourpart_Pi = ((Q1_Pi * Q1_Pi * Q1_Pi * Q1_Pi) - (6 * Q2_Pi * Q1_Pi * Q1_Pi) + (3 * Q2_Pi * Q2_Pi) + (8 * Q3_Pi * Q1_Pi) - 6 * Q4_Pi); + auto fourpart1_Pi = fourpart_Pi / Nch4_Pi; + hist.fill(HIST("Analysis/Pion/h_fourpart_Mult_pi"), NTPC, fourpart1_Pi, N_FT0M); + } + + // Kaons: + if (N_Ka > 1) { + auto Nch2_Ka = static_cast(N_Ka) * (static_cast(N_Ka) - 1); + auto mean_Q1_Ka = Q1_Ka / static_cast(N_Ka); + auto twopart_Ka = ((Q1_Ka * Q1_Ka) - Q2_Ka); + auto twopart1_Ka = (twopart_Ka) / (Nch2_Ka); + hist.fill(HIST("Analysis/Kaon/h_mean_Q1_ka"), mean_Q1_Ka); + hist.fill(HIST("Analysis/Kaon/p_mean_Q1_ka"), NTPC, mean_Q1_Ka); + hist.fill(HIST("Analysis/Kaon/h_mean_Q1_Mult_ka"), NTPC, mean_Q1_Ka, N_FT0M); + hist.fill(HIST("Analysis/Kaon/h_twopart_Mult_ka"), NTPC, twopart1_Ka, N_FT0M); + } + + if (N_Ka > 2) { + auto Nch3_Ka = static_cast(N_Ka) * (static_cast(N_Ka) - 1) * (static_cast(N_Ka) - 2); + auto threepart_Ka = ((Q1_Ka * Q1_Ka * Q1_Ka) - (3 * Q2_Ka * Q1_Ka) + 2 * Q3_Ka); + auto threepart1_Ka = threepart_Ka / Nch3_Ka; + hist.fill(HIST("Analysis/Kaon/h_threepart_Mult_ka"), NTPC, threepart1_Ka, N_FT0M); + } + + if (N_Ka > 3) { + auto Nch4_Ka = static_cast(N_Ka) * (static_cast(N_Ka) - 1) * (static_cast(N_Ka) - 2) * (static_cast(N_Ka) - 3); + auto fourpart_Ka = ((Q1_Ka * Q1_Ka * Q1_Ka * Q1_Ka) - (6 * Q2_Ka * Q1_Ka * Q1_Ka) + (3 * Q2_Ka * Q2_Ka) + (8 * Q3_Ka * Q1_Ka) - 6 * Q4_Ka); + auto fourpart1_Ka = fourpart_Ka / Nch4_Ka; + hist.fill(HIST("Analysis/Kaon/h_fourpart_Mult_ka"), NTPC, fourpart1_Ka, N_FT0M); + } + + // Protons: + if (N_Pr > 1) { + auto Nch2_Pr = static_cast(N_Pr) * (static_cast(N_Pr) - 1); + auto mean_Q1_Pr = Q1_Pr / static_cast(N_Pr); + auto twopart_Pr = ((Q1_Pr * Q1_Pr) - Q2_Pr); + auto twopart1_Pr = (twopart_Pr) / (Nch2_Pr); + hist.fill(HIST("Analysis/Proton/h_mean_Q1_pr"), mean_Q1_Pr); + hist.fill(HIST("Analysis/Proton/p_mean_Q1_pr"), NTPC, mean_Q1_Pr); + hist.fill(HIST("Analysis/Proton/h_mean_Q1_Mult_pr"), NTPC, mean_Q1_Pr, N_FT0M); + hist.fill(HIST("Analysis/Proton/h_twopart_Mult_pr"), NTPC, twopart1_Pr, N_FT0M); + } + + if (N_Pr > 2) { + auto Nch3_Pr = static_cast(N_Pr) * (static_cast(N_Pr) - 1) * (static_cast(N_Pr) - 2); + auto threepart_Pr = ((Q1_Pr * Q1_Pr * Q1_Pr) - (3 * Q2_Pr * Q1_Pr) + 2 * Q3_Pr); + auto threepart1_Pr = threepart_Pr / Nch3_Pr; + hist.fill(HIST("Analysis/Proton/h_threepart_Mult_pr"), NTPC, threepart1_Pr, N_FT0M); + } + + if (N_Pr > 3) { + auto Nch4_Pr = static_cast(N_Pr) * (static_cast(N_Pr) - 1) * (static_cast(N_Pr) - 2) * (static_cast(N_Pr) - 3); + auto fourpart_Pr = ((Q1_Pr * Q1_Pr * Q1_Pr * Q1_Pr) - (6 * Q2_Pr * Q1_Pr * Q1_Pr) + (3 * Q2_Pr * Q2_Pr) + (8 * Q3_Pr * Q1_Pr) - 6 * Q4_Pr); + auto fourpart1_Pr = fourpart_Pr / Nch4_Pr; + hist.fill(HIST("Analysis/Proton/h_fourpart_Mult_pr"), NTPC, fourpart1_Pr, Cent_FT0M); + } + + //----------------------------- TPC (No p cuts)---------------------------// + if (N_Pi_tpc > 1) { + double mean_Q1_Pi_tpc = Q1_Pi_tpc / static_cast(N_Pi_tpc); + double twopart_Pi_tpc = ((Q1_Pi_tpc * Q1_Pi_tpc) - Q2_Pi_tpc) / (static_cast(N_Pi_tpc) * (static_cast(N_Pi_tpc) - 1)); + hist.fill(HIST("Analysis/Pion/h_mean_Q1_Mult_pi_tpc"), NTPC, mean_Q1_Pi_tpc, N_FT0M); + hist.fill(HIST("Analysis/Pion/h_twopart_Mult_pi_tpc"), NTPC, twopart_Pi_tpc, N_FT0M); + } + if (N_Ka_tpc > 1) { + double mean_Q1_Ka_tpc = Q1_Ka_tpc / static_cast(N_Ka_tpc); + double twopart_Ka_tpc = ((Q1_Ka_tpc * Q1_Ka_tpc) - Q2_Ka_tpc) / (static_cast(N_Ka_tpc) * (static_cast(N_Ka_tpc) - 1)); + hist.fill(HIST("Analysis/Kaon/h_mean_Q1_Mult_ka_tpc"), NTPC, mean_Q1_Ka_tpc, N_FT0M); + hist.fill(HIST("Analysis/Kaon/h_twopart_Mult_ka_tpc"), NTPC, twopart_Ka_tpc, N_FT0M); + } + if (N_Pr_tpc > 1) { + double mean_Q1_Pr_tpc = Q1_Pr_tpc / static_cast(N_Pr_tpc); + double twopart_Pr_tpc = ((Q1_Pr_tpc * Q1_Pr_tpc) - Q2_Pr_tpc) / (static_cast(N_Pr_tpc) * (static_cast(N_Pr_tpc) - 1)); + hist.fill(HIST("Analysis/Proton/h_mean_Q1_Mult_pr_tpc"), NTPC, mean_Q1_Pr_tpc, N_FT0M); + hist.fill(HIST("Analysis/Proton/h_twopart_Mult_pr_tpc"), NTPC, twopart_Pr_tpc, N_FT0M); + } + + //-----------------------TPC + TOF (No p cuts)--------------------------// + if (Nch_tof > 1) { + double mean_Q1_tof = Q1_tof / static_cast(Nch_tof); + double twopart_tof = ((Q1_tof * Q1_tof) - Q2_tof) / (static_cast(Nch_tof) * (static_cast(Nch_tof) - 1)); + hist.fill(HIST("Analysis/Charged/h_mean_Q1_Mult_ch_tof"), NTPC, mean_Q1_tof, N_FT0M); + hist.fill(HIST("Analysis/Charged/h_twopart_Mult_ch_tof"), NTPC, twopart_tof, N_FT0M); + } + if (N_Pi_tof > 1) { + double mean_Q1_Pi_tof = Q1_Pi_tof / static_cast(N_Pi_tof); + double twopart_Pi_tof = ((Q1_Pi_tof * Q1_Pi_tof) - Q2_Pi_tof) / (static_cast(N_Pi_tof) * (static_cast(N_Pi_tof) - 1)); + hist.fill(HIST("Analysis/Pion/h_mean_Q1_Mult_pi_tof"), NTPC, mean_Q1_Pi_tof, N_FT0M); + hist.fill(HIST("Analysis/Pion/h_twopart_Mult_pi_tof"), NTPC, twopart_Pi_tof, N_FT0M); + } + if (N_Ka_tof > 1) { + double mean_Q1_Ka_tof = Q1_Ka_tof / static_cast(N_Ka_tof); + double twopart_Ka_tof = ((Q1_Ka_tof * Q1_Ka_tof) - Q2_Ka_tof) / (static_cast(N_Ka_tof) * (static_cast(N_Ka_tof) - 1)); + hist.fill(HIST("Analysis/Kaon/h_mean_Q1_Mult_ka_tof"), NTPC, mean_Q1_Ka_tof, N_FT0M); + hist.fill(HIST("Analysis/Kaon/h_twopart_Mult_ka_tof"), NTPC, twopart_Ka_tof, N_FT0M); + } + if (N_Pr_tof > 1) { + double mean_Q1_Pr_tof = Q1_Pr_tof / static_cast(N_Pr_tof); + double twopart_Pr_tof = ((Q1_Pr_tof * Q1_Pr_tof) - Q2_Pr_tof) / (static_cast(N_Pr_tof) * (static_cast(N_Pr_tof) - 1)); + hist.fill(HIST("Analysis/Proton/h_mean_Q1_Mult_pr_tof"), NTPC, mean_Q1_Pr_tof, N_FT0M); + hist.fill(HIST("Analysis/Proton/h_twopart_Mult_pr_tof"), NTPC, twopart_Pr_tof, N_FT0M); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 111d5301effa8792d904a75e5bb37b94ce0c3dbe Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Fri, 12 Jan 2024 17:34:58 +0100 Subject: [PATCH 35/48] PWGLF: Changes to strangeness derived data builder for MC (#4281) * Changes to strangeness derived data builder for MC * Please consider the following formatting changes (#215) * Remove unnecessary subscription * Update strangederivedbuilder.cxx --------- Co-authored-by: ALICE Builder --- PWGLF/TableProducer/strangederivedbuilder.cxx | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index 833676bce8a..2617150e8ea 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 TracksCompleteIUMC = soa::Join; using FullTracksExtIUTOF = soa::Join; // simple checkers @@ -117,6 +118,8 @@ struct strangederivedbuilder { "Fill generated particle histograms for each species. 0: no, 1: yes"}; 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 axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, "Centrality"}; + ConfigurableAxis axisNVertices{"axisNVertices", {10, -0.5f, 9.5f}, "N(vertices)"}; Configurable fillEmptyCollisions{"fillEmptyCollisions", false, "fill collision entries without candidates"}; @@ -141,8 +144,12 @@ struct strangederivedbuilder { }); // Creation of histograms: MC generated - for (Int_t i = 0; i < nSpecies; i++) + for (Int_t i = 0; i < nSpecies; i++) { histos.add(Form("hGen%s", particleNames[i].data()), Form("hGen%s", particleNames[i].data()), kTH1D, {axisPt}); + histos.add(Form("h2dGen%s", particleNames[i].data()), Form("h2dGen%s", particleNames[i].data()), kTH2D, {axisCentrality, axisPt}); + } + + histos.add("h2dNVerticesVsCentrality", "h2dNVerticesVsCentrality", kTH2D, {axisCentrality, axisNVertices}); } void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) @@ -409,9 +416,8 @@ struct strangederivedbuilder { } } - void processSimulation(aod::McParticles const& mcParticles) + void processPureSimulation(aod::McParticles const& mcParticles) { - // check if collision successfully reconstructed for (auto& mcp : mcParticles) { if (TMath::Abs(mcp.y()) < 0.5) { static_for<0, nSpecies - 1>([&](auto i) { @@ -424,6 +430,33 @@ struct strangederivedbuilder { } } + void processReconstructedSimulation(aod::McCollision const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) + { + // this process function also checks if a given collision was reconstructed and checks explicitly for splitting, etc + + // identify best-of collision + int biggestNContribs = -1; + float bestCentrality = 100.5; + for (auto& collision : collisions) { + if (biggestNContribs < collision.numContrib()) { + biggestNContribs = collision.numContrib(); + bestCentrality = collision.centFT0C(); + } + } + histos.fill(HIST("h2dNVerticesVsCentrality"), bestCentrality, collisions.size()); + + for (auto& mcp : mcParticles) { + if (TMath::Abs(mcp.y()) < 0.5) { + static_for<0, nSpecies - 1>([&](auto i) { + constexpr int index = i.value; + if (mcp.pdgCode() == particlePDGCodes[index] && bitcheck(enabledBits, index)) { + histos.fill(HIST("h2dGen") + HIST(particleNamesConstExpr[index]), bestCentrality, mcp.pt()); + } + }); + } + } + } + void processProduceV0TOFs(aod::Collision const& collision, aod::V0Datas const& V0s, FullTracksExtIUTOF const&) { for (auto const& v0 : V0s) { @@ -453,7 +486,8 @@ struct strangederivedbuilder { PROCESS_SWITCH(strangederivedbuilder, processStrangeMothers, "Produce tables with mother info for V0s + casc", true); 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, processPureSimulation, "Produce pure simulated information", true); + PROCESS_SWITCH(strangederivedbuilder, processReconstructedSimulation, "Produce reco-ed simulated information", true); PROCESS_SWITCH(strangederivedbuilder, processProduceV0TOFs, "Produce V0TOFs table", true); PROCESS_SWITCH(strangederivedbuilder, processProduceCascTOFs, "Produce CascTOFs table", true); }; From f38897cceba7d0b8817f06f9b5c1d8bb3b21ce7f Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Sat, 13 Jan 2024 02:28:31 +0900 Subject: [PATCH 36/48] PWGEM/PhotonMeson: fix DCA_3D (#4293) --- PWGEM/PhotonMeson/Core/CutsLibrary.cxx | 54 +++++ PWGEM/PhotonMeson/Core/DalitzEECut.h | 11 +- PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx | 6 +- PWGEM/PhotonMeson/DataModel/gammaTables.h | 4 +- .../TableProducer/skimmerDalitzMuMu.cxx | 2 + .../TableProducer/skimmerPrimaryElectron.cxx | 11 +- .../TableProducer/skimmerPrimaryMuon.cxx | 11 +- PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx | 194 ++++++++++-------- PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx | 28 ++- PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx | 127 ++++++------ 10 files changed, 282 insertions(+), 166 deletions(-) diff --git a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx index dbdae5bc015..6946f3788dc 100644 --- a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx @@ -341,6 +341,34 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMuonExclusionTPC(true); return cut; } + if (!nameStr.compare("mee_all_tpchadrejortofreq_nonprompt_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(2.0, 1e+10); + + // 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) { @@ -935,6 +963,32 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetTOFNsigmaElRange(-3, +3); return cut; } + if (!nameStr.compare("mee_all_tpchadrejortofreq_nonprompt")) { + // 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(2.0, 1e+10); // 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.h b/PWGEM/PhotonMeson/Core/DalitzEECut.h index 763687533d6..c7a543287c6 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.h +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.h @@ -350,8 +350,15 @@ class DalitzEECut : public TNamed 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 + 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.); + } + return mMinDca3D <= dca_3d && dca_3d <= mMaxDca3D; // in sigma for single leg } case DalitzEECuts::kDCAxy: return abs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx index b022f25e3a3..c58fd0c3ea6 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx @@ -162,19 +162,19 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* const double xmin[ndim] = {0.0, 0.0, 0.0, 0.0}; 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 = new THnSparseF("hs_dilepton_uls_same", "hs_dilepton_uls;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_uls_same->SetBinEdges(0, mee); hs_dilepton_uls_same->SetBinEdges(1, pt); hs_dilepton_uls_same->Sumw2(); list->Add(hs_dilepton_uls_same); - hs_dilepton_lspp_same = new THnSparseF("hs_dilepton_lspp_same", "hs_dilepton_lspp;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{xy,ee} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); + hs_dilepton_lspp_same = new THnSparseF("hs_dilepton_lspp_same", "hs_dilepton_lspp;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_lspp_same->SetBinEdges(0, mee); hs_dilepton_lspp_same->SetBinEdges(1, pt); hs_dilepton_lspp_same->Sumw2(); list->Add(hs_dilepton_lspp_same); - hs_dilepton_lsmm_same = new THnSparseF("hs_dilepton_lsmm_same", "hs_dilepton_lsmm;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{xy,ee} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); + hs_dilepton_lsmm_same = new THnSparseF("hs_dilepton_lsmm_same", "hs_dilepton_lsmm;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_lsmm_same->SetBinEdges(0, mee); hs_dilepton_lsmm_same->SetBinEdges(1, pt); hs_dilepton_lsmm_same->Sumw2(); diff --git a/PWGEM/PhotonMeson/DataModel/gammaTables.h b/PWGEM/PhotonMeson/DataModel/gammaTables.h index 3209ca952e2..7bf03140ace 100644 --- a/PWGEM/PhotonMeson/DataModel/gammaTables.h +++ b/PWGEM/PhotonMeson/DataModel/gammaTables.h @@ -329,7 +329,7 @@ DECLARE_SOA_TABLE(EMPrimaryElectrons, "AOD", "EMPRIMARYEL", //! track::TPCChi2NCl, track::TPCInnerParam, track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaMu, pidtpc::TPCNSigmaPi, pidtpc::TPCNSigmaKa, pidtpc::TPCNSigmaPr, pidtofbeta::Beta, pidtof::TOFNSigmaEl, pidtof::TOFNSigmaMu, pidtof::TOFNSigmaPi, pidtof::TOFNSigmaKa, pidtof::TOFNSigmaPr, - track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, track::Signed1Pt, track::CYY, track::CZZ, + track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, track::Signed1Pt, track::CYY, track::CZZ, track::CZY, // dynamic column track::TPCNClsFound, @@ -400,7 +400,7 @@ DECLARE_SOA_TABLE(EMPrimaryMuons, "AOD", "EMPRIMARYMU", //! track::TPCChi2NCl, track::TPCInnerParam, track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaMu, pidtpc::TPCNSigmaPi, pidtpc::TPCNSigmaKa, pidtpc::TPCNSigmaPr, pidtofbeta::Beta, pidtof::TOFNSigmaEl, pidtof::TOFNSigmaMu, pidtof::TOFNSigmaPi, pidtof::TOFNSigmaKa, pidtof::TOFNSigmaPr, - track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, track::Signed1Pt, track::CYY, track::CZZ, + track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, track::Signed1Pt, track::CYY, track::CZZ, track::CZY, // dynamic column track::TPCNClsFound, diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx index 2d8c8093510..5f725831bf7 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx @@ -78,6 +78,7 @@ struct skimmerDalitzMuMu { 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, opangle, dcamumuxy, dcamumuz, static_cast(pairtype)); dalitz_mumu_eventid(collision.globalIndex()); fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); @@ -99,6 +100,7 @@ struct skimmerDalitzMuMu { 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, opangle, dcamumuxy, dcamumuz, static_cast(pairtype)); dalitz_mumu_eventid(collision.globalIndex()); fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx index 678a97b9212..5d47c7c7476 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx @@ -186,7 +186,14 @@ 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)); + 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 > dca_3d_sigma_max) { return false; } @@ -242,7 +249,7 @@ struct skimmerPrimaryElectron { track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaMu(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.beta(), track.tofNSigmaEl(), track.tofNSigmaMu(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), track.signed1Pt(), track.cYY(), track.cZZ()); + track.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), track.signed1Pt(), track.cYY(), track.cZZ(), track.cZY()); fRegistry.fill(HIST("Track/hTPCdEdx_Pin_after"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("Track/hTOFbeta_Pin_after"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("Track/hTPCNsigmaEl_after"), track.tpcInnerParam(), track.tpcNSigmaEl()); diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx index 4ef6297ae7c..06f55d6d422 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx @@ -166,7 +166,14 @@ 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)); + 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 > dca_3d_sigma_max) { return false; } @@ -276,7 +283,7 @@ struct skimmerPrimaryMuon { track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaMu(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.beta(), track.tofNSigmaEl(), track.tofNSigmaMu(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), track.signed1Pt(), track.cYY(), track.cZZ()); + track.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), track.signed1Pt(), track.cYY(), track.cZZ(), track.cZY()); fRegistry.fill(HIST("Track/hTPCdEdx_Pin_after"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("Track/hTOFbeta_Pin_after"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("Track/hTPCNsigmaMu_after"), track.tpcInnerParam(), track.tpcNSigmaMu()); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx index 300d0811f91..dc7417f80f0 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx @@ -141,6 +141,8 @@ struct DalitzEEQC { THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; double values_single[4] = {0, 0, 0, 0}; + float dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + float det_pos = 999.f, det_ele = 999.f; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -176,17 +178,30 @@ struct DalitzEEQC { auto pos = uls_pair.template posTrack_as(); auto ele = uls_pair.template negTrack_as(); if (cut.IsSelected(uls_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values_single[0] = uls_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + values[0] = uls_pair.mass(); values[1] = uls_pair.pt(); - values[2] = uls_pair.dcaXY(); + values[2] = dca_ee_3d; 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)); - 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}) { if (std::find(used_trackIds.begin(), used_trackIds.end(), track.globalIndex()) == used_trackIds.end()) { @@ -202,17 +217,30 @@ struct DalitzEEQC { auto pos = lspp_pair.template posTrack_as(); auto ele = lspp_pair.template negTrack_as(); if (cut.IsSelected(lspp_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values_single[0] = lspp_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_dca_same"))->Fill(values_single); + values[0] = lspp_pair.mass(); values[1] = lspp_pair.pt(); - values[2] = lspp_pair.dcaXY(); + values[2] = dca_ee_3d; 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)); - 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 reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_lspp"))->Fill(nlspp); @@ -221,17 +249,30 @@ struct DalitzEEQC { auto pos = lsmm_pair.template posTrack_as(); auto ele = lsmm_pair.template negTrack_as(); if (cut.IsSelected(lsmm_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values_single[0] = lsmm_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_dca_same"))->Fill(values_single); + values[0] = lsmm_pair.mass(); values[1] = lsmm_pair.pt(); - values[2] = lsmm_pair.dcaXY(); + values[2] = dca_ee_3d; 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)); - 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 reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_lsmm"))->Fill(nlsmm); @@ -260,6 +301,8 @@ struct DalitzEEQC { ROOT::Math::PtEtaPhiMVector v1, v2, v12; float phiv = 0; double values_single[4] = {0, 0, 0, 0}; + float dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + float det_pos = 999.f, det_ele = 999.f; 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()); @@ -278,77 +321,50 @@ struct DalitzEEQC { auto pos2 = dl2.template posTrack_as(); auto ele2 = dl2.template negTrack_as(); - 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; - phiv = getPhivPair(pos1.px(), pos1.py(), pos1.pz(), ele2.px(), ele2.py(), ele2.pz(), pos1.sign(), ele2.sign(), collision1.bz()); - values[0] = v12.M(); - 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 - v1 = ROOT::Math::PtEtaPhiMVector(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassElectron); - v2 = ROOT::Math::PtEtaPhiMVector(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassElectron); - v12 = v1 + v2; - phiv = getPhivPair(pos2.px(), pos2.py(), pos2.pz(), ele1.px(), ele1.py(), ele1.pz(), pos2.sign(), ele1.sign(), collision1.bz()); - values[0] = v12.M(); - 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 - v1 = ROOT::Math::PtEtaPhiMVector(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassElectron); - v2 = ROOT::Math::PtEtaPhiMVector(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassElectron); - v12 = v1 + v2; - phiv = getPhivPair(pos1.px(), pos1.py(), pos1.pz(), pos2.px(), pos2.py(), pos2.pz(), pos1.sign(), pos2.sign(), collision1.bz()); - values[0] = v12.M(); - 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 - v1 = ROOT::Math::PtEtaPhiMVector(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassElectron); - v2 = ROOT::Math::PtEtaPhiMVector(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassElectron); - v12 = v1 + v2; - phiv = getPhivPair(ele1.px(), ele1.py(), ele1.pz(), ele2.px(), ele2.py(), ele2.pz(), ele1.sign(), ele2.sign(), collision1.bz()); - values[0] = v12.M(); - 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); + for (auto& t1 : {pos1, ele1}) { + for (auto& t2 : {pos2, ele2}) { + v1 = ROOT::Math::PtEtaPhiMVector(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); + v2 = ROOT::Math::PtEtaPhiMVector(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); + v12 = v1 + v2; + phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision1.bz()); + + det_pos = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); + det_ele = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (t1.dcaXY() * t1.dcaXY() * t1.cZZ() + t1.dcaZ() * t1.dcaZ() * t1.cYY() - 2. * t1.dcaXY() * t1.dcaZ() * t1.cZY()) / det_pos; + float chi2ele = (t2.dcaXY() * t2.dcaXY() * t2.cZZ() + t2.dcaZ() * t2.dcaZ() * t2.cYY() - 2. * t2.dcaXY() * t2.dcaZ() * t2.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values_single[0] = v12.M(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + + values[0] = v12.M(); + values[1] = v12.Pt(); + values[2] = dca_ee_3d; + values[3] = phiv; + + if (cut.IsSelectedTrack(t1) && cut.IsSelectedTrack(t2) && cut.IsSelectedPair(v12.M(), phiv)) { + if (t1.sign() * t2.sign() < 0) { + 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); + } else if (t1.sign() > 0 && t2.sign() > 0) { + 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); + } else if (t1.sign() < 0 && t2.sign() < 0) { + 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); + } else { + LOGF(info, "This should not happen."); + } + } + } } } // end of different dileptn combinations diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx index 24de1d22dcc..8f711631939 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx @@ -146,6 +146,8 @@ struct DalitzEEQCMC { THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; double values_single[4] = {0, 0, 0, 0}; + float dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + float det_pos = 999.f, det_ele = 999.f; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -193,18 +195,30 @@ struct DalitzEEQCMC { if (mother_id > 0) { auto mcmother = mcparticles.iteratorAt(mother_id); if (IsPhysicalPrimary(mcmother.emreducedmcevent(), mcmother, mcparticles)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values_single[0] = uls_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + values[0] = uls_pair.mass(); values[1] = uls_pair.pt(); - values[2] = uls_pair.dcaXY(); + values[2] = dca_ee_3d; 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)); - 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) { 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()); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx index 30ba51e986d..0a09f0ccff1 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx @@ -140,6 +140,8 @@ struct DalitzMuMuQC { THashList* list_dalitzmumu = static_cast(fMainList->FindObject("DalitzMuMu")); THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; + float dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + float det_pos = 999.f, det_ele = 999.f; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -174,10 +176,24 @@ struct DalitzMuMuQC { for (auto& uls_pair : uls_pairs_per_coll) { auto pos = uls_pair.template posTrack_as(); auto ele = uls_pair.template negTrack_as(); + if (cut.IsSelected(uls_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values[0] = uls_pair.mass(); values[1] = uls_pair.pt(); - values[2] = uls_pair.dcaXY(); + values[2] = dca_ee_3d; values[3] = uls_pair.phiv(); reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_same"))->Fill(values); nuls++; @@ -192,10 +208,24 @@ struct DalitzMuMuQC { reinterpret_cast(list_dalitzmumu_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)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } values[0] = lspp_pair.mass(); values[1] = lspp_pair.pt(); - values[2] = lspp_pair.dcaXY(); + values[2] = dca_ee_3d; values[3] = lspp_pair.phiv(); reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lspp_same"))->Fill(values); nlspp++; @@ -204,10 +234,24 @@ struct DalitzMuMuQC { reinterpret_cast(list_dalitzmumu_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)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + LOGF(info, "determinant is negative."); + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } values[0] = lsmm_pair.mass(); values[1] = lsmm_pair.pt(); - values[2] = lsmm_pair.dcaXY(); + values[2] = dca_ee_3d; values[3] = lsmm_pair.phiv(); reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lsmm_same"))->Fill(values); nlsmm++; @@ -255,62 +299,27 @@ struct DalitzMuMuQC { 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::MassMuon); - // ROOT::Math::PtEtaPhiMVector v2(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassMuon); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - v1 = ROOT::Math::PtEtaPhiMVector(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassMuon); - v2 = ROOT::Math::PtEtaPhiMVector(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassMuon); - v12 = v1 + v2; - values[0] = v12.M(); - 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] = 0.f; - if (cut.IsSelectedTrack(pos1) && cut.IsSelectedTrack(ele2) && cut.IsSelectedPair(v12.M(), 0.f)) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); - } - - // mix uls2 - v1 = ROOT::Math::PtEtaPhiMVector(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassMuon); - v2 = ROOT::Math::PtEtaPhiMVector(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassMuon); - v12 = v1 + v2; - values[0] = v12.M(); - 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] = 0.f; - if (cut.IsSelectedTrack(pos2) && cut.IsSelectedTrack(ele1) && cut.IsSelectedPair(v12.M(), 0.f)) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); - } - - // mix lspp - v1 = ROOT::Math::PtEtaPhiMVector(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassMuon); - v2 = ROOT::Math::PtEtaPhiMVector(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassMuon); - v12 = v1 + v2; - values[0] = v12.M(); - 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] = 0.f; - if (cut.IsSelectedTrack(pos1) && cut.IsSelectedTrack(pos2) && cut.IsSelectedPair(v12.M(), 0.f)) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); - } - - // mix lsmm - v1 = ROOT::Math::PtEtaPhiMVector(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassMuon); - v2 = ROOT::Math::PtEtaPhiMVector(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassMuon); - v12 = v1 + v2; - values[0] = v12.M(); - 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] = 0.f; - if (cut.IsSelectedTrack(ele1) && cut.IsSelectedTrack(ele2) && cut.IsSelectedPair(v12.M(), 0.f)) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); + for (auto& t1 : {pos1, ele1}) { + for (auto& t2 : {pos2, ele2}) { + v1 = ROOT::Math::PtEtaPhiMVector(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon); + v2 = ROOT::Math::PtEtaPhiMVector(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon); + v12 = v1 + v2; + values[0] = v12.M(); + values[1] = v12.Pt(); + values[2] = sqrt((pow(t1.dcaXY() / sqrt(t1.cYY()), 2) + pow(t2.dcaXY() / sqrt(t2.cYY()), 2)) / 2.); // pair DCAxy + values[3] = 0.f; + if (cut.IsSelectedTrack(t1) && cut.IsSelectedTrack(t2) && cut.IsSelectedPair(v12.M(), 0.f)) { + if (t1.sign() * t2.sign() < 0) { + reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); + } else if (t1.sign() > 0 && t2.sign() > 0) { + reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); + } else if (t1.sign() < 0 && t2.sign() < 0) { + reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); + } else { + LOGF(info, "This should not happen."); + } + } + } } } // end of different dileptn combinations From 5a41f24bec8a19e4566135abfa716d5363eb5afa Mon Sep 17 00:00:00 2001 From: Deependra Sharma <38365215+deependra170598@users.noreply.github.com> Date: Sat, 13 Jan 2024 01:20:21 +0530 Subject: [PATCH 37/48] Correction to D0 Selection cut in Dstar Selector Task (#4299) --- PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index 49f6c097898..a919affba3c 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -128,7 +128,7 @@ struct HfCandidateSelectorDstarToD0Pi { return false; } // normalised decay length in XY plane - if (candidate.decayLengthXYNormalisedD0() < cutsD0->get(binPt, "normalized decay length XY")) { + if (candidate.decayLengthXYNormalisedD0() < cutsD0->get(binPt, "min norm decay length XY")) { return false; } @@ -148,14 +148,14 @@ struct HfCandidateSelectorDstarToD0Pi { // 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")); + double decayLengthCut = std::min((candidate.pD0() * 0.0066) + 0.01, cutsD0->get(binPt, "min decay length")); if (candidate.decayLengthD0() * candidate.decayLengthD0() < decayLengthCut * decayLengthCut) { return false; } - if (candidate.decayLengthD0() > cutsD0->get(binPt, "decay length")) { + if (candidate.decayLengthD0() > cutsD0->get(binPt, "max decay length")) { return false; } - if (candidate.decayLengthXYD0() > cutsD0->get(binPt, "decay length XY")) { + if (candidate.decayLengthXYD0() > cutsD0->get(binPt, "max decay length XY")) { return false; } From 421fb2ab2d66c56f68089eb8dc7e9e7ea1ce1812 Mon Sep 17 00:00:00 2001 From: cterrevo Date: Fri, 12 Jan 2024 21:13:26 +0100 Subject: [PATCH 38/48] [PWG-HF]: adding fillOnlySignal option (#4291) * adding fillOnlySignal option * Please consider the following formatting changes * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano * Update PWGHF/TableProducer/treeCreatorXicToPKPi.cxx Co-authored-by: Fabio Catalano --------- Co-authored-by: ALICE Action Bot Co-authored-by: Fabio Catalano --- PWGHF/TableProducer/treeCreatorXicToPKPi.cxx | 596 +++++++++---------- 1 file changed, 275 insertions(+), 321 deletions(-) diff --git a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx index a0af9dc888d..43d8a30fbd9 100644 --- a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx @@ -26,11 +26,13 @@ using namespace o2; using namespace o2::framework; +using namespace o2::framework::expressions; namespace o2::aod { namespace full { + DECLARE_SOA_INDEX_COLUMN(Collision, collision); DECLARE_SOA_COLUMN(RSecondaryVertex, rSecondaryVertex, float); DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); @@ -230,372 +232,324 @@ struct HfTreeCreatorXicToPKPi { Produces rowCandidateFullParticles; Produces rowCandidateLite; + Configurable selectionFlagXic{"selectionFlagXic", 1, "Selection flag for Xic"}; 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 fillOnlySignal{"fillOnlySignal", false, "Flag to fill derived tables with signal for ML trainings"}; + Configurable fillOnlyBackground{"fillOnlyBackground", false, "Flag to fill derived tables with background for ML trainings"}; + 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; + using CandXicData = soa::Filtered>; + using CandXicMcReco = soa::Filtered>; + using CandXicMcGen = soa::Filtered>; using TracksWPid = soa::Join; + Filter filterSelectCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic; + Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); + + Partition selectedXicToPKPiCand = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic; + Partition selectedXicToPiKPCand = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic; + + Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); + Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); + void init(InitContext const&) { } - void processMc(aod::Collisions const& collisions, - aod::McCollisions const& mcCollisions, - soa::Join const& candidates, - soa::Join const& particles, - TracksWPid const& tracks) + template + void fillEvent(const T& collision, int isEventReject, int runNumber) + { + rowCandidateFullEvents( + collision.globalIndex(), + collision.bcId(), + collision.numContrib(), + collision.posX(), + collision.posY(), + collision.posZ(), + isEventReject, + runNumber); + } + + /// Fill table accounting for MC information and mass hypothesis + /// \param doMc true to fill MC information + /// \param massHypo mass hypothesis considered: 0 = PKPi, 1 = PiKP + /// \param candidate is candidate + template + void fillCandidateTable(const T& candidate) + { + int8_t flagMc = 0; + int8_t originMc = 0; + if constexpr (doMc) { + flagMc = candidate.flagMcMatchRec(); + originMc = candidate.originMcRec(); + } + + float invMassXic = 0; + if constexpr (massHypo == 0) { + invMassXic = hfHelper.invMassXicToPKPi(candidate); + } else if constexpr (massHypo == 1) { + invMassXic = hfHelper.invMassXicToPiKP(candidate); + } + + auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) + auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) + auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) + + if (fillCandidateLiteTable) { + rowCandidateLite( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaKa(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaKa(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaPi(), + trackNeg.tpcNSigmaKa(), + trackNeg.tpcNSigmaPr(), + trackNeg.tofNSigmaPi(), + trackNeg.tofNSigmaKa(), + trackNeg.tofNSigmaPr(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaKa(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaKa(), + trackPos2.tofNSigmaPr(), + candidate.isSelXicToPKPi(), + candidate.isSelXicToPiKP(), + invMassXic, + candidate.pt(), + candidate.cpa(), + candidate.cpaXY(), + candidate.eta(), + candidate.phi(), + flagMc, + originMc); + } else { + rowCandidateFull( + candidate.collisionId(), + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.rSecondaryVertex(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.impactParameterNormalised0(), + candidate.ptProng0(), + RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), + candidate.impactParameterNormalised1(), + candidate.ptProng1(), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.impactParameterNormalised2(), + candidate.ptProng2(), + RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaKa(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaKa(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaPi(), + trackNeg.tpcNSigmaKa(), + trackNeg.tpcNSigmaPr(), + trackNeg.tofNSigmaPi(), + trackNeg.tofNSigmaKa(), + trackNeg.tofNSigmaPr(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaKa(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaKa(), + trackPos2.tofNSigmaPr(), + candidate.isSelXicToPKPi(), + candidate.isSelXicToPiKP(), + invMassXic, + candidate.pt(), + candidate.p(), + candidate.cpa(), + candidate.cpaXY(), + hfHelper.ctXic(candidate), + candidate.eta(), + candidate.phi(), + hfHelper.yXic(candidate), + hfHelper.eXic(candidate), + flagMc, + originMc, + candidate.globalIndex()); + } + } + + void processData(aod::Collisions const& collisions, + CandXicData const& candidates, + TracksWPid const&) { // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); for (const auto& collision : collisions) { - rowCandidateFullEvents( - collision.globalIndex(), - collision.bcId(), - collision.numContrib(), - collision.posX(), - collision.posY(), - collision.posZ(), - 0, - 1); + fillEvent(collision, 0, 1); } - // Filling candidate properties if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); + rowCandidateLite.reserve(selectedXicToPKPiCand.size() + selectedXicToPiKPCand.size()); } else { - rowCandidateFull.reserve(candidates.size()); + rowCandidateFull.reserve(selectedXicToPKPiCand.size() + selectedXicToPiKPCand.size()); } - for (const auto& candidate : candidates) { - 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); + + for (const auto& candidate : selectedXicToPKPiCand) { + if (downSampleBkgFactor < 1.) { + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { continue; } } - auto fillTable = [&](int CandFlag, - int FunctionSelection, - float FunctionInvMass, - float FunctionCt, - float FunctionY, - float FunctionE) { - if (FunctionSelection >= 1) { - if (fillCandidateLiteTable) { - - rowCandidateLite( - candidate.chi2PCA(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.ptProng0(), - candidate.ptProng1(), - candidate.ptProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.cpa(), - candidate.cpaXY(), - candidate.eta(), - candidate.phi(), - candidate.flagMcMatchRec(), - candidate.originMcRec(), - candidate.isCandidateSwapped()); - } else { - rowCandidateFull( - candidate.collisionId(), - candidate.posX(), - candidate.posY(), - candidate.posZ(), - candidate.xSecondaryVertex(), - candidate.ySecondaryVertex(), - candidate.zSecondaryVertex(), - candidate.errorDecayLength(), - candidate.errorDecayLengthXY(), - candidate.chi2PCA(), - candidate.rSecondaryVertex(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.impactParameterNormalised0(), - candidate.ptProng0(), - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - candidate.impactParameterNormalised1(), - candidate.ptProng1(), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), - candidate.impactParameterNormalised2(), - candidate.ptProng2(), - RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), - candidate.pxProng0(), - candidate.pyProng0(), - candidate.pzProng0(), - candidate.pxProng1(), - candidate.pyProng1(), - candidate.pzProng1(), - candidate.pxProng2(), - candidate.pyProng2(), - candidate.pzProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - candidate.errorImpactParameter0(), - candidate.errorImpactParameter1(), - candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.p(), - candidate.cpa(), - candidate.cpaXY(), - FunctionCt, - candidate.eta(), - candidate.phi(), - FunctionY, - FunctionE, - candidate.flagMcMatchRec(), - candidate.originMcRec(), - candidate.isCandidateSwapped(), - candidate.globalIndex()); - } - } - }; - - 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)); + fillCandidateTable(candidate); } - // Filling particle properties - rowCandidateFullParticles.reserve(particles.size()); - for (const auto& particle : particles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::XicToPKPi) { - rowCandidateFullParticles( - particle.mcCollision().globalIndex(), - particle.mcCollision().bcId(), - particle.pt(), - particle.eta(), - particle.phi(), - RecoDecay::y(std::array{particle.px(), particle.py(), particle.pz()}, o2::constants::physics::MassXiCPlus), - particle.flagMcMatchGen(), - particle.originMcGen(), - particle.globalIndex()); + for (const auto& candidate : selectedXicToPiKPCand) { + if (downSampleBkgFactor < 1.) { + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; + } } + fillCandidateTable(candidate); } } - PROCESS_SWITCH(HfTreeCreatorXicToPKPi, processMc, "Process MC tree writer", true); - void processData(aod::Collisions const& collisions, - soa::Join const& candidates, - TracksWPid const& tracks) - { + PROCESS_SWITCH(HfTreeCreatorXicToPKPi, processData, "Process data tree writer", true); + void processMc(aod::Collisions const& collisions, + aod::McCollisions const&, + CandXicMcReco const& candidates, + CandXicMcGen const& mcParticles, + TracksWPid const&) + { // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); for (const auto& collision : collisions) { - rowCandidateFullEvents( - collision.globalIndex(), - collision.bcId(), - collision.numContrib(), - collision.posX(), - collision.posY(), - collision.posZ(), - 0, - 1); + fillEvent(collision, 0, 1); } // Filling candidate properties - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); - } else { - rowCandidateFull.reserve(candidates.size()); - } - for (const auto& candidate : candidates) { - 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; + if (fillOnlySignal) { + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(reconstructedCandSig.size()); + } else { + rowCandidateFull.reserve(reconstructedCandSig.size()); + } + + for (const auto& candidate : reconstructedCandSig) { + if (candidate.isCandidateSwapped() == 0) { + fillCandidateTable(candidate); } + if (candidate.isCandidateSwapped() == 1) { + fillCandidateTable(candidate); + } + } + } else if (fillOnlyBackground) { + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(reconstructedCandBkg.size()); + } else { + rowCandidateFull.reserve(reconstructedCandBkg.size()); } - auto fillTable = [&](int CandFlag, - int FunctionSelection, - float FunctionInvMass, - float FunctionCt, - float FunctionY, - float FunctionE) { - if (FunctionSelection >= 1) { - if (fillCandidateLiteTable) { - rowCandidateLite( - candidate.chi2PCA(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.ptProng0(), - candidate.ptProng1(), - candidate.ptProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.cpa(), - candidate.cpaXY(), - candidate.eta(), - candidate.phi(), - 0., - 0., - 0.); - } else { - rowCandidateFull( - candidate.collisionId(), - candidate.posX(), - candidate.posY(), - candidate.posZ(), - candidate.xSecondaryVertex(), - candidate.ySecondaryVertex(), - candidate.zSecondaryVertex(), - candidate.errorDecayLength(), - candidate.errorDecayLengthXY(), - candidate.chi2PCA(), - candidate.rSecondaryVertex(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.impactParameterNormalised0(), - candidate.ptProng0(), - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - candidate.impactParameterNormalised1(), - candidate.ptProng1(), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), - candidate.impactParameterNormalised2(), - candidate.ptProng2(), - RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), - candidate.pxProng0(), - candidate.pyProng0(), - candidate.pzProng0(), - candidate.pxProng1(), - candidate.pyProng1(), - candidate.pzProng1(), - candidate.pxProng2(), - candidate.pyProng2(), - candidate.pzProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - candidate.errorImpactParameter0(), - candidate.errorImpactParameter1(), - candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.p(), - candidate.cpa(), - candidate.cpaXY(), - FunctionCt, - candidate.eta(), - candidate.phi(), - FunctionY, - FunctionE, - 0., - 0., - 0., - candidate.globalIndex()); + + for (const auto& candidate : reconstructedCandBkg) { + if (downSampleBkgFactor < 1.) { + float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; } } - }; + // Bkg candidates are not matched to MC so rely on selections only + if (candidate.isSelXicToPKPi() >= selectionFlagXic) { + fillCandidateTable(candidate); + } + if (candidate.isSelXicToPiKP() >= selectionFlagXic) { + fillCandidateTable(candidate); + } + } + } else { + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(reconstructedCandSig.size() + reconstructedCandBkg.size()); + } else { + rowCandidateFull.reserve(reconstructedCandSig.size() + reconstructedCandBkg.size()); + } + + for (const auto& candidate : reconstructedCandSig) { + if (candidate.isCandidateSwapped() == 0) { + fillCandidateTable(candidate); + } + if (candidate.isCandidateSwapped() == 1) { + fillCandidateTable(candidate); + } + } - 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)); + for (const auto& candidate : reconstructedCandBkg) { + // Bkg candidates are not matched to MC so rely on selections only + if (candidate.isSelXicToPKPi() >= selectionFlagXic) { + fillCandidateTable(candidate); + } + if (candidate.isSelXicToPiKP() >= selectionFlagXic) { + fillCandidateTable(candidate); + } + } + } + + // Filling particle properties + rowCandidateFullParticles.reserve(mcParticles.size()); + for (const auto& particle : mcParticles) { + rowCandidateFullParticles( + particle.mcCollision().globalIndex(), + particle.mcCollision().bcId(), + particle.pt(), + particle.eta(), + particle.phi(), + RecoDecay::y(std::array{particle.px(), particle.py(), particle.pz()}, o2::constants::physics::MassXiCPlus), + particle.flagMcMatchGen(), + particle.originMcGen(), + particle.globalIndex()); } } - PROCESS_SWITCH(HfTreeCreatorXicToPKPi, processData, "Process data tree writer", false); + + PROCESS_SWITCH(HfTreeCreatorXicToPKPi, processMc, "Process MC tree writer", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From a23ec43ee2fd97f4a8b38751ae72292e5c86e904 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sat, 13 Jan 2024 10:48:22 +0100 Subject: [PATCH 39/48] PWGLF / V0 builders: add momentum window selection for testing (#4295) * Add momentum window selection for testing * Please consider the following formatting changes (#216) --------- Co-authored-by: ALICE Builder --- PWGLF/TableProducer/lambdakzerobuilder.cxx | 26 +++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/PWGLF/TableProducer/lambdakzerobuilder.cxx b/PWGLF/TableProducer/lambdakzerobuilder.cxx index 07d239f0c0b..a695d7c212a 100644 --- a/PWGLF/TableProducer/lambdakzerobuilder.cxx +++ b/PWGLF/TableProducer/lambdakzerobuilder.cxx @@ -122,6 +122,10 @@ struct lambdakzeroBuilder { Configurable tpcrefit{"tpcrefit", 0, "demand TPC refit"}; + // select momentum slice if desired + Configurable minimumPt{"minimumPt", 0.0f, "Minimum pT to store candidate"}; + Configurable maximumPt{"maximumPt", 1000.0f, "Maximum pT to store candidate"}; + // Operation and minimisation criteria Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; Configurable d_UseAbsDCA{"d_UseAbsDCA", true, "Use Abs DCAs"}; @@ -191,6 +195,7 @@ struct lambdakzeroBuilder { kV0DCADau, kV0CosPA, kV0Radius, + kWithinMomentumRange, kCountStandardV0, kCountV0forCascade, kNV0Steps }; @@ -273,8 +278,9 @@ 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"); + h->GetXaxis()->SetBinLabel(7, "Within momentum range"); + h->GetXaxis()->SetBinLabel(8, "Count: Standard V0"); + h->GetXaxis()->SetBinLabel(9, "Count: V0 exc. for casc"); randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); @@ -646,6 +652,18 @@ struct lambdakzeroBuilder { statisticsRegistry.v0stats[kV0Radius]++; // Return OK: passed all v0 candidate selecton criteria + auto px = v0candidate.posP[0] + v0candidate.negP[0]; + auto py = v0candidate.posP[1] + v0candidate.negP[1]; + auto pz = v0candidate.posP[2] + v0candidate.negP[2]; + auto lPt = RecoDecay::sqrtSumOfSquares(v0candidate.posP[0] + v0candidate.negP[0], v0candidate.posP[1] + v0candidate.negP[1]); + + if (lPt < minimumPt || lPt > maximumPt) { + return false; // reject if not within desired window + } + + // Passes momentum window check + statisticsRegistry.v0stats[kWithinMomentumRange]++; + if (d_doTrackQA) { if (posTrack.itsNCls() < 10) statisticsRegistry.posITSclu[posTrack.itsNCls()]++; @@ -665,10 +683,6 @@ struct lambdakzeroBuilder { auto lHypertritonMass = RecoDecay::m(array{array{2.0f * v0candidate.posP[0], 2.0f * v0candidate.posP[1], 2.0f * v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassHelium3, o2::constants::physics::MassPionCharged}); auto lAntiHypertritonMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{2.0f * v0candidate.negP[0], 2.0f * v0candidate.negP[1], 2.0f * v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassHelium3}); - auto px = v0candidate.posP[0] + v0candidate.negP[0]; - auto py = v0candidate.posP[1] + v0candidate.negP[1]; - auto pz = v0candidate.posP[2] + v0candidate.negP[2]; - auto lPt = RecoDecay::sqrtSumOfSquares(v0candidate.posP[0] + v0candidate.negP[0], v0candidate.posP[1] + v0candidate.negP[1]); auto lPtHy = RecoDecay::sqrtSumOfSquares(2.0f * v0candidate.posP[0] + v0candidate.negP[0], 2.0f * v0candidate.posP[1] + v0candidate.negP[1]); auto lPtAnHy = RecoDecay::sqrtSumOfSquares(v0candidate.posP[0] + 2.0f * v0candidate.negP[0], v0candidate.posP[1] + 2.0f * v0candidate.negP[1]); From 8b16cd60e614573ce51beab91a5e8843d3c44624 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sat, 13 Jan 2024 10:49:16 +0100 Subject: [PATCH 40/48] PWGLF: Move V0 analysis to derived data format, add etas for cascs (#4278) * Move V0 analysis to derived data format, add etas for cascs * Please consider the following formatting changes (#214) * Add sel8 criteria --------- Co-authored-by: ALICE Builder --- PWGLF/DataModel/LFStrangenessTables.h | 58 ++++- PWGLF/TableProducer/strangederivedbuilder.cxx | 7 +- PWGLF/Tasks/lambdakzeroanalysis.cxx | 222 +++--------------- 3 files changed, 90 insertions(+), 197 deletions(-) diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 2be338700ad..fdd0e6e993c 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -15,6 +15,7 @@ #include "Framework/AnalysisDataModel.h" #include "Common/Core/RecoDecay.h" #include "CommonConstants/PhysicsConstants.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Qvectors.h" @@ -29,6 +30,8 @@ DECLARE_SOA_TABLE(StraCollisions, "AOD", "STRACOLLISION", //! basic collision pr DECLARE_SOA_TABLE(StraCents, "AOD", "STRACENTS", //! centrality percentiles cent::CentFT0M, cent::CentFT0A, cent::CentFT0C, cent::CentFV0A); +DECLARE_SOA_TABLE(StraEvSels, "AOD", "STRAEVSELS", //! event selection: sel8 + evsel::Sel8); DECLARE_SOA_TABLE(StraEPs, "AOD", "STRAEPS", //! centrality percentiles qvec::QvecFT0ARe, qvec::QvecFT0AIm, qvec::SumAmplFT0A, qvec::QvecFT0CRe, qvec::QvecFT0CIm, qvec::SumAmplFT0C, @@ -698,6 +701,25 @@ DECLARE_SOA_DYNAMIC_COLUMN(Rapidity, rapidity, //! rapidity (0, 1: Xi; 2, 3: Ome return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassOmegaMinus); return 0.0f; }); + +DECLARE_SOA_DYNAMIC_COLUMN(NegativePt, negativept, //! negative daughter pT + [](float pxneg, float pyneg) -> float { return RecoDecay::sqrtSumOfSquares(pxneg, pyneg); }); +DECLARE_SOA_DYNAMIC_COLUMN(PositivePt, positivept, //! positive daughter pT + [](float pxpos, float pypos) -> float { return RecoDecay::sqrtSumOfSquares(pxpos, pypos); }); +DECLARE_SOA_DYNAMIC_COLUMN(BachelorPt, bachelorpt, //! bachelor daughter pT + [](float pxpos, float pypos) -> float { return RecoDecay::sqrtSumOfSquares(pxpos, pypos); }); +DECLARE_SOA_DYNAMIC_COLUMN(NegativeEta, negativeeta, //! negative daughter eta + [](float PxNeg, float PyNeg, float PzNeg) -> float { return RecoDecay::eta(std::array{PxNeg, PyNeg, PzNeg}); }); +DECLARE_SOA_DYNAMIC_COLUMN(NegativePhi, negativephi, //! negative daughter phi + [](float PxNeg, float PyNeg) -> float { return RecoDecay::phi(PxNeg, PyNeg); }); +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(BachelorEta, bacheloreta, //! bachelor daughter eta + [](float PxPos, float PyPos, float PzPos) -> float { return RecoDecay::eta(std::array{PxPos, PyPos, PzPos}); }); +DECLARE_SOA_DYNAMIC_COLUMN(BachelorPhi, bachelorphi, //! bachelor daughter phi + [](float PxPos, float PyPos) -> float { return RecoDecay::phi(PxPos, PyPos); }); } // namespace cascdata //______________________________________________________ @@ -792,7 +814,17 @@ DECLARE_SOA_TABLE(StoredCascCores, "AOD", "CASCCORE", //! core information about // Longitudinal cascdata::YXi, cascdata::YOmega, - cascdata::Rapidity); + cascdata::Rapidity, + + cascdata::NegativePt, + cascdata::PositivePt, + cascdata::BachelorPt, + cascdata::NegativeEta, + cascdata::NegativePhi, + cascdata::PositiveEta, + cascdata::PositivePhi, + cascdata::BachelorEta, + cascdata::BachelorPhi); DECLARE_SOA_TABLE(StoredKFCascCores, "AOD", "KFCASCCORE", //! cascdata::Sign, cascdata::MXi, cascdata::MOmega, @@ -820,7 +852,17 @@ DECLARE_SOA_TABLE(StoredKFCascCores, "AOD", "KFCASCCORE", //! // Longitudinal cascdata::YXi, - cascdata::YOmega); + cascdata::YOmega, + + cascdata::NegativePt, + cascdata::PositivePt, + cascdata::BachelorPt, + cascdata::NegativeEta, + cascdata::NegativePhi, + cascdata::PositiveEta, + cascdata::PositivePhi, + cascdata::BachelorEta, + cascdata::BachelorPhi); DECLARE_SOA_TABLE(StoredTraCascCores, "AOD", "TRACASCCORE", //! cascdata::Sign, cascdata::MXi, cascdata::MOmega, @@ -848,7 +890,17 @@ DECLARE_SOA_TABLE(StoredTraCascCores, "AOD", "TRACASCCORE", //! // Longitudinal cascdata::YXi, - cascdata::YOmega); + cascdata::YOmega, + + cascdata::NegativePt, + cascdata::PositivePt, + cascdata::BachelorPt, + cascdata::NegativeEta, + cascdata::NegativePhi, + cascdata::PositiveEta, + cascdata::PositivePhi, + cascdata::BachelorEta, + cascdata::BachelorPhi); DECLARE_SOA_TABLE(CascMCCores, "AOD", "CASCMCCORE", //! bachelor-baryon correlation variables cascdata::PDGCode, cascdata::PDGCodeMother, cascdata::PDGCodeV0, cascdata::IsPhysicalPrimary, diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index 2617150e8ea..b6445933c7f 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -64,6 +64,7 @@ struct strangederivedbuilder { // fundamental building blocks of derived data Produces strangeColl; // characterises collisions Produces strangeCents; // characterises collisions / centrality + Produces strangeEvSels; // characterises collisions / sel8 selection Produces strangeStamps; // provides timestamps, run numbers Produces v0collref; // references collisions from V0s Produces casccollref; // references collisions from cascades @@ -152,7 +153,7 @@ struct strangederivedbuilder { histos.add("h2dNVerticesVsCentrality", "h2dNVerticesVsCentrality", kTH2D, {axisCentrality, axisNVertices}); } - void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); @@ -163,6 +164,7 @@ struct strangederivedbuilder { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centFV0A()); + strangeEvSels(collision.sel8()); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); } @@ -171,7 +173,7 @@ struct strangederivedbuilder { } } - 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&) + 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&) { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); @@ -188,6 +190,7 @@ struct strangederivedbuilder { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centFV0A()); + strangeEvSels(collision.sel8()); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); } diff --git a/PWGLF/Tasks/lambdakzeroanalysis.cxx b/PWGLF/Tasks/lambdakzeroanalysis.cxx index c009dab1235..c427b051579 100644 --- a/PWGLF/Tasks/lambdakzeroanalysis.cxx +++ b/PWGLF/Tasks/lambdakzeroanalysis.cxx @@ -13,9 +13,8 @@ // ======================== // // This code loops over a V0Data table and produces some -// standard analysis output. It requires either -// the lambdakzerofinder or the lambdakzeroproducer tasks -// to have been executed in the workflow (before). +// standard analysis output. It is meant to be run over +// derived data. // // Comments, questions, complaints, suggestions? // Please write to: @@ -29,6 +28,7 @@ #include "CommonConstants/PhysicsConstants.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" @@ -52,95 +52,31 @@ using namespace o2::framework; using namespace o2::framework::expressions; using std::array; -using MyTracks = soa::Join; - -struct lambdakzeroQa { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hV0Radius", "hV0Radius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hV0CosPA", "hV0CosPA", {HistType::kTH1F, {{1000, 0.95f, 1.0f}}}}, - {"hDCAPosToPV", "hDCAPosToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCANegToPV", "hDCANegToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hArmenterosPreAnalyserCuts", "hArmenterosPreAnalyserCuts", {HistType::kTH2F, {{1000, -1.0f, 1.0f, "#alpha"}, {1000, 0.0f, 0.30f, "#it{Q}_{T}"}}}}, - }, - }; - void init(InitContext const&) - { - AxisSpec massAxisK0Short = {600, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}; - - registry.add("hMassK0Short", "hMassK0Short", {HistType::kTH1F, {massAxisK0Short}}); - registry.add("hMassLambda", "hMassLambda", {HistType::kTH1F, {massAxisLambda}}); - registry.add("hMassAntiLambda", "hMassAntiLambda", {HistType::kTH1F, {massAxisLambda}}); - } - void process(aod::Collision const& collision, aod::V0Datas const& fullV0s) - { - - for (auto& v0 : fullV0s) { - registry.fill(HIST("hMassK0Short"), v0.mK0Short()); - registry.fill(HIST("hMassLambda"), v0.mLambda()); - registry.fill(HIST("hMassAntiLambda"), v0.mAntiLambda()); - - registry.fill(HIST("hV0Radius"), v0.v0radius()); - registry.fill(HIST("hV0CosPA"), v0.v0cosPA()); - registry.fill(HIST("hDCAPosToPV"), v0.dcapostopv()); - registry.fill(HIST("hDCANegToPV"), v0.dcanegtopv()); - registry.fill(HIST("hDCAV0Dau"), v0.dcaV0daughters()); - registry.fill(HIST("hArmenterosPreAnalyserCuts"), v0.alpha(), v0.qtarm()); - } - } -}; +using dauTracks = soa::Join; struct lambdakzeroAnalysis { - HistogramRegistry registry{ - "registry", - { - {"h3dMassK0Short", "h3dMassK0Short", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {400, 0.400f, 0.600f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dMassLambda", "h3dMassLambda", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {200, 1.015f, 1.215f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dMassAntiLambda", "h3dMassAntiLambda", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {200, 1.015f, 1.215f, "Inv. Mass (GeV/c^{2})"}}}}, - {"hArmenterosPostAnalyserCuts", "hArmenterosPostAnalyserCuts", {HistType::kTH2F, {{1000, -1.0f, 1.0f, "#alpha"}, {1000, 0.0f, 0.30f, "#it{Q}_{T}"}}}}, - {"hEventSelection", "hEventSelection", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"V0loopFiltersCounts", "V0loopFiltersCounts", {HistType::kTH1F, {{11, 0.0f, 11.0f}}}}, - }, - }; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - ConfigurableAxis dcaBinning{"dca-binning", {200, 0.0f, 1.0f}, ""}; - ConfigurableAxis ptBinning{"pt-binning", {200, 0.0f, 10.0f}, ""}; + 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}, "pt axis for QA histograms"}; + ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; + ConfigurableAxis axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, ""}; void init(InitContext const&) { - AxisSpec dcaAxis = {dcaBinning, "DCA (cm)"}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/c)"}; - AxisSpec massAxisK0Short = {400, 0.400f, 0.60f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec massAxisLambda = {200, 1.015f, 1.215f, "Inv. Mass (GeV/c^{2})"}; - - registry.add("h3dMassK0ShortDca", "h3dMassK0ShortDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisK0Short}}); - registry.add("h3dMassLambdaDca", "h3dMassLambdaDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisLambda}}); - registry.add("h3dMassAntiLambdaDca", "h3dMassAntiLambdaDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisLambda}}); + // Event Counters + histos.add("hEventSelection", "hEventSelection", kTH1F, {{2, -0.5f, +1.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "posZ cut"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(1, "V0 Candidates"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(2, "V0Radius and CosPA"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(4, "Lambda Rapidity"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(5, "Lambda lifetime cut"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(6, "Lambda TPC PID cut"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(8, "K0S Rapidity"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(9, "K0S lifetime cut"); - registry.get(HIST("V0loopFiltersCounts"))->GetXaxis()->SetBinLabel(10, "K0S Armenteros cut"); + histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); - registry.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); - registry.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "Sel8 cut"); - registry.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - if (doprocessRun3 && doprocessRun2) { - LOGF(fatal, "processRun3 and processRun2 are both set to true; try again with only one of them set to true"); - } - if (!doprocessRun3 && !doprocessRun2) { - LOGF(fatal, "processRun3 nor processRun2 are both set to false; try again with only one of them set to false"); - } + // Extra QA histograms to be added } // Selection criteria @@ -154,150 +90,52 @@ struct lambdakzeroAnalysis { Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; Configurable boolArmenterosCut{"boolArmenterosCut", true, "cut on Armenteros-Podolanski graph"}; Configurable paramArmenterosCut{"paramArmenterosCut", 0.2, "parameter Armenteros Cut"}; - Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; - Configurable event_posZ_selection{"event_posZ_selection", true, "event selection count post poZ cut"}; static constexpr float defaultLifetimeCuts[1][2] = {{25., 20.}}; Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; Filter preFilterV0 = nabs(aod::v0data::dcapostopv) > dcapostopv&& nabs(aod::v0data::dcanegtopv) > dcanegtopv&& aod::v0data::dcaV0daughters < dcav0dau; - // void process(soa::Join::iterator const& collision, soa::Filtered const& fullV0s) //for now CentV0M info is not available for run 3 pp - void processRun3(soa::Join::iterator const& collision, soa::Filtered const& fullV0s, MyTracks const& tracks) + void process(soa::Join::iterator const& collision, soa::Filtered> const& fullV0s, dauTracks const&) { - registry.fill(HIST("hEventSelection"), 0.5); - if (event_sel8_selection && !collision.sel8()) { - return; - } - registry.fill(HIST("hEventSelection"), 1.5); - if (event_posZ_selection && abs(collision.posZ()) > 10.f) { // 10cm + histos.fill(HIST("hEventSelection"), 0.5); + if (abs(collision.posZ()) > 10.f) { // 10cm return; } - registry.fill(HIST("hEventSelection"), 2.5); + histos.fill(HIST("hEventSelection"), 1.5); + histos.fill(HIST("hEventCentrality"), collision.centFT0C()); for (auto& v0 : fullV0s) { // FIXME: could not find out how to filter cosPA and radius variables (dynamic columns) - registry.fill(HIST("V0loopFiltersCounts"), 0.5); if (v0.v0radius() > v0radius && v0.v0cosPA() > v0cospa) { - registry.fill(HIST("V0loopFiltersCounts"), 1.5); if (TMath::Abs(v0.yLambda()) < rapidity) { - registry.fill(HIST("V0loopFiltersCounts"), 3.5); if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) { - registry.fill(HIST("V0loopFiltersCounts"), 4.5); - // Lambda - if (TMath::Abs(v0.posTrack_as().tpcNSigmaPr()) < TpcPidNsigmaCut) { // previous 900Gev pp analysis had nSigma< 5 for pt<0.7Gev and tpcNSigmaStorePi<3 for pt>0.7GeV; and no cut on K0S - registry.fill(HIST("V0loopFiltersCounts"), 5.5); - registry.fill(HIST("h3dMassLambda"), 0., v0.pt(), v0.mLambda()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("hArmenterosPostAnalyserCuts"), v0.alpha(), v0.qtarm()); - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassLambdaDca"), v0.dcaV0daughters(), v0.pt(), v0.mLambda()); - } + if (TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { + histos.fill(HIST("h3dMassLambda"), collision.centFT0C(), v0.pt(), v0.mLambda()); } - - // AntiLambda - if (TMath::Abs(v0.negTrack_as().tpcNSigmaPr()) < TpcPidNsigmaCut) { // previous 900Gev pp analysis had nSigma< 5 for pt<0.7Gev and tpcNSigmaStorePi<3 for pt>0.7GeV; and no cut on K0S - registry.fill(HIST("V0loopFiltersCounts"), 5.5); - registry.fill(HIST("h3dMassAntiLambda"), 0., v0.pt(), v0.mAntiLambda()); - registry.fill(HIST("hArmenterosPostAnalyserCuts"), v0.alpha(), v0.qtarm()); - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassAntiLambdaDca"), v0.dcaV0daughters(), v0.pt(), v0.mAntiLambda()); - } - } - } - } - - // K0Short - if (TMath::Abs(v0.yK0Short()) < rapidity) { - registry.fill(HIST("V0loopFiltersCounts"), 7.5); - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) { - registry.fill(HIST("V0loopFiltersCounts"), 8.5); - if ((v0.qtarm() > paramArmenterosCut * TMath::Abs(v0.alpha())) || !boolArmenterosCut) { - registry.fill(HIST("V0loopFiltersCounts"), 9.5); - registry.fill(HIST("h3dMassK0Short"), 0., v0.pt(), v0.mK0Short()); - registry.fill(HIST("hArmenterosPostAnalyserCuts"), v0.alpha(), v0.qtarm()); - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassK0ShortDca"), v0.dcaV0daughters(), v0.pt(), v0.mK0Short()); - } - } - } - } - } - } - } - PROCESS_SWITCH(lambdakzeroAnalysis, processRun3, "Process Run 3 data", true); - - void processRun2(soa::Join::iterator const& collision, soa::Filtered const& fullV0s, MyTracks const& tracks) - { - registry.fill(HIST("hEventSelection"), 0.5); - if (!collision.alias_bit(kINT7)) { - return; - } - if (event_sel8_selection && !collision.sel7()) { - return; - } - registry.fill(HIST("hEventSelection"), 1.5); - if (event_posZ_selection && abs(collision.posZ()) > 10.f) { // 10cm - return; - } - registry.fill(HIST("hEventSelection"), 2.5); - - for (auto& v0 : fullV0s) { - // FIXME: could not find out how to filter cosPA and radius variables (dynamic columns) - registry.fill(HIST("V0loopFiltersCounts"), 0.5); - if (v0.v0radius() > v0radius && v0.v0cosPA() > v0cospa) { - registry.fill(HIST("V0loopFiltersCounts"), 1.5); - if (TMath::Abs(v0.yLambda()) < rapidity) { - registry.fill(HIST("V0loopFiltersCounts"), 3.5); - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) { - registry.fill(HIST("V0loopFiltersCounts"), 4.5); - - // Lambda - if (TMath::Abs(v0.posTrack_as().tpcNSigmaPr()) < TpcPidNsigmaCut) { // previous 900Gev pp analysis had nSigma< 5 for pt<0.7Gev and tpcNSigmaStorePi<3 for pt>0.7GeV; and no cut on K0S - registry.fill(HIST("V0loopFiltersCounts"), 5.5); - registry.fill(HIST("h3dMassLambda"), collision.centRun2V0M(), v0.pt(), v0.mLambda()); - registry.fill(HIST("hArmenterosPostAnalyserCuts"), v0.alpha(), v0.qtarm()); - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassLambdaDca"), v0.dcaV0daughters(), v0.pt(), v0.mLambda()); - } - } - // AntiLambda - if (TMath::Abs(v0.negTrack_as().tpcNSigmaPr()) < TpcPidNsigmaCut) { // previous 900Gev pp analysis had nSigma< 5 for pt<0.7Gev and tpcNSigmaStorePi<3 for pt>0.7GeV; and no cut on K0S - registry.fill(HIST("V0loopFiltersCounts"), 5.5); - registry.fill(HIST("h3dMassAntiLambda"), collision.centRun2V0M(), v0.pt(), v0.mAntiLambda()); - registry.fill(HIST("hArmenterosPostAnalyserCuts"), v0.alpha(), v0.qtarm()); - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassAntiLambdaDca"), v0.dcaV0daughters(), v0.pt(), v0.mAntiLambda()); - } + if (TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { + histos.fill(HIST("h3dMassAntiLambda"), collision.centFT0C(), v0.pt(), v0.mAntiLambda()); } } } // K0Short if (TMath::Abs(v0.yK0Short()) < rapidity) { - registry.fill(HIST("V0loopFiltersCounts"), 7.5); if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) { - registry.fill(HIST("V0loopFiltersCounts"), 8.5); - if ((v0.qtarm() > paramArmenterosCut * v0.alpha()) || !boolArmenterosCut) { - registry.fill(HIST("V0loopFiltersCounts"), 9.5); - registry.fill(HIST("h3dMassK0Short"), collision.centRun2V0M(), v0.pt(), v0.mK0Short()); - registry.fill(HIST("hArmenterosPostAnalyserCuts"), v0.alpha(), v0.qtarm()); - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassK0ShortDca"), v0.dcaV0daughters(), v0.pt(), v0.mK0Short()); - } + if (TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { + histos.fill(HIST("h3dMassK0Short"), collision.centFT0C(), v0.pt(), v0.mK0Short()); } } } } } } - PROCESS_SWITCH(lambdakzeroAnalysis, processRun2, "Process Run 2 data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } From b9dcf330c4bf2eb7312d398ab1d8fa43573b560a Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sat, 13 Jan 2024 10:50:26 +0100 Subject: [PATCH 41/48] PWGLF: Additional TOF work (#4274) * Additional TOF work * Please consider the following formatting changes (#213) * Update LFStrangenessTables.h --------- Co-authored-by: ALICE Builder --- PWGLF/DataModel/LFStrangenessPIDTables.h | 34 ++- PWGLF/DataModel/LFStrangenessTables.h | 2 +- PWGLF/TableProducer/lambdakzeropid.cxx | 99 ++++++-- PWGLF/Tasks/QC/strangepidqa.cxx | 295 ++++++++++++++++++++++- 4 files changed, 401 insertions(+), 29 deletions(-) diff --git a/PWGLF/DataModel/LFStrangenessPIDTables.h b/PWGLF/DataModel/LFStrangenessPIDTables.h index ab8e0ccd37b..fdef30d1d1f 100644 --- a/PWGLF/DataModel/LFStrangenessPIDTables.h +++ b/PWGLF/DataModel/LFStrangenessPIDTables.h @@ -62,13 +62,31 @@ DECLARE_SOA_COLUMN(NegTOFDeltaTLaPr, negTOFDeltaTLaPr, float); //! negative trac DECLARE_SOA_COLUMN(PosTOFDeltaTK0Pi, posTOFDeltaTK0Pi, float); //! positive track TOFDeltaT from pion <- k0short expectation DECLARE_SOA_COLUMN(NegTOFDeltaTK0Pi, negTOFDeltaTK0Pi, float); //! positive track TOFDeltaT from pion <- k0short expectation -// n-sigmas +// delta-decay-times (event-time-independent) +DECLARE_SOA_COLUMN(DeltaDecayTimeLambda, deltaDecayTimeLambda, float); //! delta-decay time estimate from proton/pion from Lambda +DECLARE_SOA_COLUMN(DeltaDecayTimeAntiLambda, deltaDecayTimeAntiLambda, float); //! delta-decay time estimate from pion/proton from AntiLambda +DECLARE_SOA_COLUMN(DeltaDecayTimeK0Short, deltaDecayTimeK0Short, float); //! delta-decay time estimate from pion/pion from K0Short + +// n-sigmas - unused as of now DECLARE_SOA_COLUMN(PosNSigmaLaPi, posNSigmaLaPi, float); //! positive track NSigma from pion <- lambda expectation DECLARE_SOA_COLUMN(PosNSigmaLaPr, posNSigmaLaPr, float); //! positive track NSigma from proton <- lambda expectation DECLARE_SOA_COLUMN(NegNSigmaLaPi, negNSigmaLaPi, float); //! negative track NSigma from pion <- lambda expectation DECLARE_SOA_COLUMN(NegNSigmaLaPr, negNSigmaLaPr, float); //! negative track NSigma from proton <- lambda expectation DECLARE_SOA_COLUMN(PosNSigmaK0Pi, posNSigmaK0Pi, float); //! positive track NSigma from pion <- k0short expectation DECLARE_SOA_COLUMN(NegNSigmaK0Pi, negNSigmaK0Pi, float); //! positive track NSigma from pion <- k0short expectation + +// beta values +DECLARE_SOA_COLUMN(TofBetaLambda, tofBetaLambda, float); //! beta value with Lambda hypothesis +DECLARE_SOA_COLUMN(TofBetaAntiLambda, tofBetaAntiLambda, float); //! beta value with AntiLambda hypothesis +DECLARE_SOA_COLUMN(TofBetaK0Short, tofBetaK0Short, float); //! beta value with K0Short hypothesis + +// debug quantities +DECLARE_SOA_COLUMN(V0LifetimeLambda, v0LifetimeLambda, float); //! lifetime of V0 assuming lambda mass (ps) +DECLARE_SOA_COLUMN(V0LifetimeK0Short, v0LifetimeK0Short, float); //! lifetime of V0 assuming K0 mass (ps) +DECLARE_SOA_COLUMN(PosLifetimePr, posLifetimePr, float); //! lifetime (to TOF) of pos prong assuming proton mass (ps) +DECLARE_SOA_COLUMN(PosLifetimePi, posLifetimePi, float); //! lifetime (to TOF) of pos prong assuming pion mass (ps) +DECLARE_SOA_COLUMN(NegLifetimePr, negLifetimePr, float); //! lifetime (to TOF) of neg prong assuming proton mass (ps) +DECLARE_SOA_COLUMN(NegLifetimePi, negLifetimePi, float); //! lifetime (to TOF) of neg prong assuming pion mass (ps) } // namespace v0data DECLARE_SOA_TABLE(V0TOFs, "AOD", "V0TOF", // raw information table (for debug, etc) @@ -80,9 +98,17 @@ DECLARE_SOA_TABLE(V0TOFPIDs, "AOD", "V0TOFPID", // processed info table (for ana v0data::PosTOFDeltaTLaPi, v0data::PosTOFDeltaTLaPr, v0data::NegTOFDeltaTLaPi, v0data::NegTOFDeltaTLaPr, v0data::PosTOFDeltaTK0Pi, v0data::NegTOFDeltaTK0Pi, - v0data::PosNSigmaLaPi, v0data::PosNSigmaLaPr, - v0data::NegNSigmaLaPi, v0data::NegNSigmaLaPr, - v0data::PosNSigmaK0Pi, v0data::NegNSigmaK0Pi); + v0data::DeltaDecayTimeLambda, + v0data::DeltaDecayTimeAntiLambda, + v0data::DeltaDecayTimeK0Short); + +DECLARE_SOA_TABLE(V0TOFDebugs, "AOD", "V0TOFDEBUG", // table with intermediate information solely for debugging + v0data::V0LifetimeLambda, v0data::V0LifetimeK0Short, + v0data::PosLifetimePr, v0data::PosLifetimePi, + v0data::NegLifetimePr, v0data::NegLifetimePi); + +DECLARE_SOA_TABLE(V0TOFBetas, "AOD", "V0TOFBETA", // processed info table (for analysis) + v0data::TofBetaLambda, v0data::TofBetaAntiLambda, v0data::TofBetaK0Short); namespace cascdata { diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index fdd0e6e993c..9d962372322 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -108,7 +108,7 @@ DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); //! pdg code DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, bool); //! primary criterion } // namespace motherParticle -DECLARE_SOA_TABLE(MotherMCParts, "AOD", "MOTHERMCPARTS", //! mother MC information, abbreviated name due to size limit +DECLARE_SOA_TABLE(MotherMCParts, "AOD", "MOTHERMCPART", //! mother MC information, abbreviated name due to size limit motherParticle::Px, motherParticle::Py, motherParticle::Pz, motherParticle::PDGCode, motherParticle::IsPhysicalPrimary); diff --git a/PWGLF/TableProducer/lambdakzeropid.cxx b/PWGLF/TableProducer/lambdakzeropid.cxx index 2dd4ecb79c7..bdda2efffab 100644 --- a/PWGLF/TableProducer/lambdakzeropid.cxx +++ b/PWGLF/TableProducer/lambdakzeropid.cxx @@ -81,6 +81,8 @@ using V0FullCores = soa::Join; struct lambdakzeropid { // TOF pid for strangeness (recalculated with topology) Produces v0tofpid; // table with Nsigmas + Produces v0tofbeta; // table with betas + Produces v0tofdebugs; // table with extra debug information Service ccdb; @@ -92,7 +94,7 @@ struct lambdakzeropid { // Operation and minimisation criteria Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; - Configurable checkTPCCompatibility{"checkTPCCompatibility", true, "check compatibility with dE/dx in QA plots"}; + Configurable doQA{"doQA", true, "create QA histos"}; // CCDB options Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -101,10 +103,9 @@ struct lambdakzeropid { Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - ConfigurableAxis axisPtQA{"axisPtQA", {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}, "pt axis for QA histograms"}; ConfigurableAxis axisDeltaTime{"axisDeltaTime", {2000, -1000.0f, +1000.0f}, "delta-time (ps)"}; - ConfigurableAxis axisK0ShortMass{"axisK0ShortMass", {200, 0.400f, 0.600f}, "Inv. Mass (GeV/c^{2})"}; - ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.01f, 1.21f}, "Inv. Mass (GeV/c^{2})"}; + ConfigurableAxis axisTime{"axisTime", {200, 0.0f, +20000.0f}, "T (ps)"}; + 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)"}; int mRunNumber; float d_bz; @@ -132,8 +133,9 @@ struct lambdakzeropid { std::array startPoint; track.getXYZGlo(startPoint); - if (((x1 + x2) * mom[0] + (y1 + y2) * mom[1]) < 0.0f) - return -101; + // better replaced with scalar momentum check later + // if (((x1 + x2) * mom[0] + (y1 + y2) * mom[1]) < 0.0f) + // return -101; // get circle X, Y please o2::math_utils::CircleXYf_t trcCircle; @@ -203,13 +205,11 @@ struct lambdakzeropid { 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) { + if (scalarCheck1 > 0.0f && scalarCheck1 < segmentModulus && scalarMomentumCheck1 > 0.0f) { length = length1; // X = interceptX1; Y = interceptY1; } - if (scalarCheck2 > 0.0f && scalarCheck2 < segmentModulus && length2 < halfPerimeter && scalarMomentumCheck2 > 0.0f) { + if (scalarCheck2 > 0.0f && scalarCheck2 < segmentModulus && scalarMomentumCheck2 > 0.0f) { length = length2; // X = interceptX2; Y = interceptY2; } @@ -221,6 +221,7 @@ struct lambdakzeropid { /// \param magneticField the magnetic field to use when propagating float findInterceptLength(o2::track::TrackPar track, float magneticField) { + float length = 1e+6; for (int iSeg = 0; iSeg < 18; iSeg++) { // Detector segmentation loop float segmentAngle = 20.0f / 180.0f * TMath::Pi(); @@ -230,11 +231,13 @@ struct lambdakzeropid { 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; + float thisLength = trackLengthToSegment(track, x1, y1, x2, y2, magneticField); + if (thisLength < length && thisLength > 0) + length = thisLength; } - return -100; // not reached / not found + if (length > 1e+5) + length = -100; // force negative to avoid misunderstandings + return length; } void init(InitContext& context) @@ -251,6 +254,15 @@ struct lambdakzeropid { // per event histos.add("hCandidateCounter", "hCandidateCounter", kTH1F, {{500, -0.5f, 499.5f}}); + + // measured vs expected total time QA + if (doQA) { + histos.add("h2dProtonMeasuredVsExpected", "h2dProtonMeasuredVsExpected", {HistType::kTH2F, {axisTime, axisTime}}); + histos.add("h2dPionMeasuredVsExpected", "h2dPionMeasuredVsExpected", {HistType::kTH2F, {axisTime, axisTime}}); + + // delta lambda decay time + histos.add("h2dLambdaDeltaDecayTime", "h2dLambdaDeltaDecayTime", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + } } void initCCDB(soa::Join::iterator const& collision) @@ -341,18 +353,63 @@ struct lambdakzeropid { float timeNegativePr = lengthNegative / velocityNegativePr; float timeNegativePi = lengthNegative / velocityNegativePi; - 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); + if (v0.posTOFSignal() > 0 && v0.posTOFEventTime() > 0 && lengthPositive > 0) { + deltaTimePositiveLambdaPr = (v0.posTOFSignal() - v0.posTOFEventTime()) - (timeLambda + timePositivePr); + deltaTimePositiveLambdaPi = (v0.posTOFSignal() - v0.posTOFEventTime()) - (timeLambda + timePositivePi); + deltaTimePositiveK0ShortPi = (v0.posTOFSignal() - v0.posTOFEventTime()) - (timeK0Short + timeNegativePi); + } + if (v0.negTOFSignal() > 0 && v0.negTOFEventTime() > 0 && lengthNegative > 0) { + deltaTimeNegativeLambdaPr = (v0.negTOFSignal() - v0.negTOFEventTime()) - (timeLambda + timeNegativePr); + deltaTimeNegativeLambdaPi = (v0.negTOFSignal() - v0.negTOFEventTime()) - (timeLambda + timeNegativePi); + deltaTimeNegativeK0ShortPi = (v0.negTOFSignal() - v0.negTOFEventTime()) - (timeK0Short + timeNegativePi); + } + float deltaDecayTimeLambda = -10e+4; + float deltaDecayTimeAntiLambda = -10e+4; + float deltaDecayTimeK0Short = -10e+4; + if (v0.posTOFSignal() > 0 && v0.negTOFSignal() > 0 && lengthPositive > 0 && lengthNegative > 0) { // does not depend on event time + deltaDecayTimeLambda = (v0.posTOFSignal() - timePositivePr) - (v0.negTOFSignal() - timeNegativePi); + deltaDecayTimeAntiLambda = (v0.posTOFSignal() - timePositivePi) - (v0.negTOFSignal() - timeNegativePr); + deltaDecayTimeK0Short = (v0.posTOFSignal() - timePositivePi) - (v0.negTOFSignal() - timeNegativePi); + } + + // calculate betas + + float evTimeMean = 0.5f * (v0.posTOFEventTime() + v0.negTOFEventTime()); + float decayTimeLambda = 0.5f * ((v0.posTOFSignal() - timePositivePr) + (v0.negTOFSignal() - timeNegativePi)) - evTimeMean; + float decayTimeAntiLambda = 0.5f * ((v0.posTOFSignal() - timePositivePi) + (v0.negTOFSignal() - timeNegativePr)) - evTimeMean; + float decayTimeK0Short = 0.5f * ((v0.posTOFSignal() - timePositivePi) + (v0.negTOFSignal() - timeNegativePi)) - evTimeMean; + + float betaLambda = -1e+6; + float betaAntiLambda = -1e+6; + float betaK0Short = -1e+6; + + if (v0.posTOFSignal() > 0 && v0.negTOFSignal() > 0 && v0.posTOFEventTime() > 0 && v0.negTOFEventTime() > 0) { + betaLambda = (lengthV0 / decayTimeLambda) / 0.0299792458; + betaAntiLambda = (lengthV0 / decayTimeAntiLambda) / 0.0299792458; + betaK0Short = (lengthV0 / decayTimeK0Short) / 0.0299792458; + } v0tofpid(lengthPositive, lengthNegative, deltaTimePositiveLambdaPi, deltaTimePositiveLambdaPr, deltaTimeNegativeLambdaPi, deltaTimeNegativeLambdaPr, deltaTimePositiveK0ShortPi, deltaTimeNegativeK0ShortPi, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); // FIXME + deltaDecayTimeLambda, deltaDecayTimeAntiLambda, deltaDecayTimeK0Short); + v0tofbeta(betaLambda, betaAntiLambda, betaK0Short); + v0tofdebugs(timeLambda, timeK0Short, timePositivePr, timePositivePi, timeNegativePr, timeNegativePi); + + if (doQA) { + if (v0.posTOFSignal() > 0 && v0.posTOFEventTime() > 0) + histos.fill(HIST("h2dProtonMeasuredVsExpected"), + (timeLambda + timePositivePr), + (v0.posTOFSignal() - v0.posTOFEventTime())); + if (v0.negTOFSignal() > 0 && v0.negTOFEventTime() > 0) + histos.fill(HIST("h2dPionMeasuredVsExpected"), + (timeLambda + timeNegativePi), + (v0.negTOFSignal() - v0.negTOFEventTime())); + + // delta lambda decay time + histos.fill(HIST("h2dLambdaDeltaDecayTime"), v0.pt(), deltaDecayTimeLambda); + } } } } diff --git a/PWGLF/Tasks/QC/strangepidqa.cxx b/PWGLF/Tasks/QC/strangepidqa.cxx index a27aa7df1d3..5dc7173b1a3 100644 --- a/PWGLF/Tasks/QC/strangepidqa.cxx +++ b/PWGLF/Tasks/QC/strangepidqa.cxx @@ -57,23 +57,100 @@ struct strangepidqa { // Invariant Mass ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.08f, 1.16f}, "M_{#Lambda} (GeV/c^{2})"}; - // Delta time + // time axes ConfigurableAxis axisDeltaTime{"axisDeltaTime", {200, -1000.0f, +1000.0f}, "#Delta time (ps)"}; + ConfigurableAxis axisTime{"axisTime", {200, 0.0f, +20000.0f}, "T (ps)"}; + ConfigurableAxis axisBeta{"axisBeta", {1200, 0.0f, +1.2f}, "#Beta"}; // Length axis ConfigurableAxis axisLength{"axisLength", {600, 0.0f, +600.0f}, "track Length (cm)"}; + // TOF cut axis + ConfigurableAxis axisTOFCut{"axisTOFCut", {100, 0.0f, +10000.0f}, "TOF compat. cut (ps)"}; + + // TOF selection matters + Configurable requireTOFsignalPion{"requireTOFsignalPion", true, "require that pion prongs have TOF"}; + Configurable requireTOFsignalProton{"requireTOFsignalProton", true, "require that proton prongs have TOF"}; + Configurable requireTOFEventTimePion{"requireTOFEventTimePion", true, "require that pion prongs have TOF event time"}; + Configurable requireTOFEventTimeProton{"requireTOFEventTimeProton", true, "require that proton prongs have TOF event time"}; + + Configurable maxDeltaTimeProton{"maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimePion{"maxDeltaTimePion", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimeDecay{"maxDeltaTimeDecay", 1e+9, "check maximum allowed delta-time-decay"}; + + Configurable minCentrality{"minCentrality", 60, "max value of centrality allowed"}; + Configurable maxCentrality{"maxCentrality", 100, "max value of centrality allowed"}; + + Configurable minV0Radius{"minV0Radius", 1.5, "min radius"}; + Configurable minCosPA{"minCosPA", .98, "min cosPA"}; + + Configurable minPtV0{"minPtV0", 1.0, "min pT for integrated mass histograms"}; + Configurable maxPtV0{"maxPtV0", 3.0, "max pT for integrated mass histograms"}; + void init(InitContext const&) { // Event counter histos.add("hEventVertexZ", "hEventVertexZ", kTH1F, {vertexZ}); + // Presence of negative and positive signals and event time + auto hPositiveStatus = histos.add("hPositiveStatus", "hPositiveStatus", kTH1F, {{4, -0.5f, 3.5f}}); + auto hNegativeStatus = histos.add("hNegativeStatus", "hNegativeStatus", kTH1F, {{4, -0.5f, 3.5f}}); + auto hPositiveStatusReachedTOF = histos.add("hPositiveStatusReachedTOF", "hPositiveStatusReachedTOF", kTH1F, {{4, -0.5f, 3.5f}}); + auto hNegativeStatusReachedTOF = histos.add("hNegativeStatusReachedTOF", "hNegativeStatusReachedTOF", kTH1F, {{4, -0.5f, 3.5f}}); + hPositiveStatus->GetXaxis()->SetBinLabel(1, "All positive"); + hPositiveStatus->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); + hPositiveStatus->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); + hPositiveStatus->GetXaxis()->SetBinLabel(4, "Has full time info"); + hNegativeStatus->GetXaxis()->SetBinLabel(1, "All negative"); + hNegativeStatus->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); + hNegativeStatus->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); + hNegativeStatus->GetXaxis()->SetBinLabel(4, "Has full time info"); + + hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(1, "All positive"); + hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); + hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); + hPositiveStatusReachedTOF->GetXaxis()->SetBinLabel(4, "Has full time info"); + hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(1, "All negative"); + hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(2, "Has only TOF sig"); + hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(3, "Has only TOF ev time"); + hNegativeStatusReachedTOF->GetXaxis()->SetBinLabel(4, "Has full time info"); + + // V0 Radius + histos.add("hLambdaMass", "hLambdaMass", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hAssocLambdaMass", "hAssocLambdaMass", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hAssocLambdaMassGoodTime", "hAssocLambdaMassGoodTime", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hAssocLambdaMassBadTime", "hAssocLambdaMassBadTime", {HistType::kTH1F, {axisLambdaMass}}); + // V0 Radius histos.add("h2dLambdaRadiusVsPt", "hLambdaRadiusVsPt", {HistType::kTH2F, {axisPt, axisRadius}}); // Invariant Mass histos.add("h2dLambdaMassVsPt", "hLambdaMassVsPt", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + // Invariant Mass + histos.add("h2dLambdaMassVsTOFCut", "h2dLambdaMassVsTOFCut", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); + histos.add("h2dLambdaMassVsTOFCutWithSignals", "h2dLambdaMassVsTOFCutWithSignals", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); + histos.add("h2dLambdaMassVsTOFCutMeson", "h2dLambdaMassVsTOFCutMeson", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); + histos.add("h2dLambdaMassVsTOFCutMesonWithSignals", "h2dLambdaMassVsTOFCutMesonWithSignals", {HistType::kTH2F, {axisLambdaMass, axisTOFCut}}); + + // Invariant Mass with TOF selections + histos.add("hLambdaMass_ProtonTOF", "hLambdaMass_ProtonTOF", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hLambdaMass_PionTOF", "hLambdaMass_PionTOF", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hLambdaMass_AllTOF", "hLambdaMass_AllTOF", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hLambdaMass_DeltaDecayTime", "hLambdaMass_DeltaDecayTime", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_ProtonTOF", "hLambdaMassVsPtProtonTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_PionTOF", "hLambdaMassVsPtPionTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_AllTOF", "hLambdaMassVsPtAllTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_DeltaDecayTime", "hLambdaMassVsPtDeltaDecayTime", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + + // Invariant Mass with TOF selections + histos.add("hLambdaMass_InvertProtonTOF", "hLambdaMass_InvertProtonTOF", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hLambdaMass_InvertPionTOF", "hLambdaMass_InvertPionTOF", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("hLambdaMass_InvertAllTOF", "hLambdaMass_InvertAllTOF", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_InvertProtonTOF", "hLambdaMassVsPtInvertProtonTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_InvertPionTOF", "hLambdaMassVsPtInvertPionTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + histos.add("h2dLambdaMassVsPt_InvertAllTOF", "hLambdaMassVsPtInvertAllTOF", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + // radius vs prong length histos.add("h2dProtonLengthVsRadius", "h2dProtonLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); histos.add("h2dPionLengthVsRadius", "h2dPionLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); @@ -87,15 +164,132 @@ struct strangepidqa { histos.add("h2dProtonDeltaTimeVsRadius", "h2dProtonDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); histos.add("h2dPionDeltaTimeVsPt", "h2dPionDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); histos.add("h2dPionDeltaTimeVsRadius", "h2dPionDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + + // TOF PID testing for prongs + histos.add("h2dProtonDeltaTimeVsPt_MassSelected", "h2dProtonDeltaTimeVsPt_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dProtonDeltaTimeVsRadius_MassSelected", "h2dProtonDeltaTimeVsRadius_MassSelected", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + histos.add("h2dPionDeltaTimeVsPt_MassSelected", "h2dPionDeltaTimeVsPt_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dPionDeltaTimeVsRadius_MassSelected", "h2dPionDeltaTimeVsRadius_MassSelected", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + + // delta lambda decay time + histos.add("h2dLambdaDeltaDecayTime", "h2dLambdaDeltaDecayTime", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dLambdaDeltaDecayTime_MassSelected", "h2dLambdaDeltaDecayTime_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + + // beta plots + histos.add("h2dLambdaBeta", "h2dLambdaBeta", {HistType::kTH2F, {axisPt, axisBeta}}); + histos.add("h2dLambdaBeta_MassSelected", "h2dLambdaBeta_MassSelected", {HistType::kTH2F, {axisPt, axisBeta}}); + + // length vs time for prongs / debug + histos.add("h2dTimeVsLengthProtonProng", "h2dTimeVsLengthProtonProng", {HistType::kTH2F, {axisLength, axisTime}}); + histos.add("h2dTimeVsLengthPionProng", "h2dTimeVsLengthPionProng", {HistType::kTH2F, {axisLength, axisTime}}); + + // --- ASSOCIATED --- + // V0 Radius + if (doprocessSim) { + histos.add("h2dAssocLambdaRadiusVsPt", "hLambdaRadiusVsPt", {HistType::kTH2F, {axisPt, axisRadius}}); + + // Invariant Mass + histos.add("h2dAssocLambdaMassVsPt", "hLambdaMassVsPt", {HistType::kTH2F, {axisPt, axisLambdaMass}}); + + // radius vs prong length + histos.add("h2dAssocProtonLengthVsRadius", "h2dAssocProtonLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); + histos.add("h2dAssocPionLengthVsRadius", "h2dAssocPionLengthVsRadius", {HistType::kTH2F, {axisRadius, axisLength}}); + + // recalculated vs topv lengths + histos.add("h2dAssocProtonLengthVsLengthToPV", "h2dAssocProtonLengthVsRadiusToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); + histos.add("h2dAssocPionLengthVsLengthToPV", "h2dAssocPionLengthVsLengthToPV", {HistType::kTH2F, {axisRadius, axisRadius}}); + + // TOF PID testing for prongs + histos.add("h2dAssocProtonDeltaTimeVsPt", "h2dAssocProtonDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dAssocProtonDeltaTimeVsRadius", "h2dAssocProtonDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + histos.add("h2dAssocPionDeltaTimeVsPt", "h2dAssocPionDeltaTimeVsPt", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dAssocPionDeltaTimeVsRadius", "h2dAssocPionDeltaTimeVsRadius", {HistType::kTH2F, {axisRadius, axisDeltaTime}}); + + // delta lambda decay time + histos.add("h2dAssocLambdaDeltaDecayTime", "h2dAssocLambdaDeltaDecayTime", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + histos.add("h2dAssocLambdaDeltaDecayTime_MassSelected", "h2dAssocLambdaDeltaDecayTime_MassSelected", {HistType::kTH2F, {axisPt, axisDeltaTime}}); + } } - void process(aod::StraCollision const& coll, soa::Join const& v0s) + void processReal(soa::Join::iterator const& coll, soa::Join const& v0s) { histos.fill(HIST("hEventVertexZ"), coll.posZ()); + if (coll.centFT0C() > maxCentrality || coll.centFT0C() < minCentrality) + return; + for (auto& lambda : v0s) { // selecting photons from Sigma0 - if (lambda.pdgCode() != 3122) + + if (TMath::Abs(lambda.eta()) > 0.5) + continue; + + if (TMath::Abs(lambda.mLambda() - 1.115683) < 0.01 && lambda.v0cosPA() > minCosPA) { + histos.fill(HIST("hPositiveStatus"), 0.0f); + if (lambda.posTOFSignal() > 1e-5 && lambda.posTOFEventTime() < 0.0f) + histos.fill(HIST("hPositiveStatus"), 1.0f); + if (lambda.posTOFSignal() < 0.0f && lambda.posTOFEventTime() > 1e-5) + histos.fill(HIST("hPositiveStatus"), 2.0f); + if (lambda.posTOFSignal() > 1e-5 && lambda.posTOFEventTime() > 1e-5) + histos.fill(HIST("hPositiveStatus"), 3.0f); + + histos.fill(HIST("hNegativeStatus"), 0.0f); + if (lambda.negTOFSignal() > 1e-5 && lambda.negTOFEventTime() < 0.0f) + histos.fill(HIST("hNegativeStatus"), 1.0f); + if (lambda.negTOFSignal() < 0.0f && lambda.negTOFEventTime() > 1e-5) + histos.fill(HIST("hNegativeStatus"), 2.0f); + if (lambda.negTOFSignal() > 1e-5 && lambda.negTOFEventTime() > 1e-5) + histos.fill(HIST("hNegativeStatus"), 3.0f); + + if (lambda.posTOFLength() > 0.0f) { + histos.fill(HIST("hPositiveStatusReachedTOF"), 0.0f); + if (lambda.posTOFSignal() > 1e-5 && lambda.posTOFEventTime() < 0.0f) + histos.fill(HIST("hPositiveStatusReachedTOF"), 1.0f); + if (lambda.posTOFSignal() < 0.0f && lambda.posTOFEventTime() > 1e-5) + histos.fill(HIST("hPositiveStatusReachedTOF"), 2.0f); + if (lambda.posTOFSignal() > 1e-5 && lambda.posTOFEventTime() > 1e-5) + histos.fill(HIST("hPositiveStatusReachedTOF"), 3.0f); + } + + if (lambda.negTOFLength() > 0.0f) { + histos.fill(HIST("hNegativeStatusReachedTOF"), 0.0f); + if (lambda.negTOFSignal() > 1e-5 && lambda.negTOFEventTime() < 0.0f) + histos.fill(HIST("hNegativeStatusReachedTOF"), 1.0f); + if (lambda.negTOFSignal() < 0.0f && lambda.negTOFEventTime() > 1e-5) + histos.fill(HIST("hNegativeStatusReachedTOF"), 2.0f); + if (lambda.negTOFSignal() > 1e-5 && lambda.negTOFEventTime() > 1e-5) + histos.fill(HIST("hNegativeStatusReachedTOF"), 3.0f); + } + + // properties of the positive and negative prongs / debug + histos.fill(HIST("h2dTimeVsLengthProtonProng"), lambda.posTOFLength(), lambda.posLifetimePr()); + histos.fill(HIST("h2dTimeVsLengthPionProng"), lambda.negTOFLength(), lambda.negLifetimePr()); + } + + histos.fill(HIST("h2dLambdaMassVsTOFCut"), lambda.mLambda(), TMath::Abs(lambda.posTOFDeltaTLaPr())); + histos.fill(HIST("h2dLambdaMassVsTOFCutMeson"), lambda.mLambda(), TMath::Abs(lambda.negTOFDeltaTLaPi())); + + if (lambda.v0radius() < minV0Radius) + continue; + if (lambda.posTOFSignal() < 0 && requireTOFsignalProton) continue; + if (lambda.negTOFSignal() < 0 && requireTOFsignalPion) + continue; + + histos.fill(HIST("h2dLambdaDeltaDecayTime"), lambda.pt(), lambda.deltaDecayTimeLambda()); + if (TMath::Abs(lambda.mLambda() - 1.115683) < 0.01 && lambda.v0cosPA() > minCosPA) { + histos.fill(HIST("h2dLambdaDeltaDecayTime_MassSelected"), lambda.pt(), lambda.deltaDecayTimeLambda()); + } + + if (lambda.posTOFEventTime() < 0 && requireTOFEventTimeProton) + continue; + if (lambda.negTOFEventTime() < 0 && requireTOFEventTimePion) + continue; + + histos.fill(HIST("h2dLambdaMassVsTOFCutWithSignals"), lambda.mLambda(), TMath::Abs(lambda.posTOFDeltaTLaPr())); + histos.fill(HIST("h2dLambdaMassVsTOFCutMesonWithSignals"), lambda.mLambda(), TMath::Abs(lambda.negTOFDeltaTLaPi())); + + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass"), lambda.mLambda()); histos.fill(HIST("h2dLambdaRadiusVsPt"), lambda.pt(), lambda.v0radius()); histos.fill(HIST("h2dLambdaMassVsPt"), lambda.pt(), lambda.mLambda()); @@ -104,14 +298,109 @@ struct strangepidqa { 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("h2dLambdaBeta"), lambda.p(), lambda.tofBetaLambda()); + + if (TMath::Abs(lambda.mLambda() - 1.115683) < 0.01 && lambda.v0cosPA() > minCosPA) { + histos.fill(HIST("h2dProtonDeltaTimeVsPt_MassSelected"), lambda.pt(), lambda.posTOFDeltaTLaPr()); + histos.fill(HIST("h2dProtonDeltaTimeVsRadius_MassSelected"), lambda.v0radius(), lambda.posTOFDeltaTLaPr()); + histos.fill(HIST("h2dPionDeltaTimeVsPt_MassSelected"), lambda.pt(), lambda.negTOFDeltaTLaPi()); + histos.fill(HIST("h2dPionDeltaTimeVsRadius_MassSelected"), lambda.v0radius(), lambda.negTOFDeltaTLaPi()); + histos.fill(HIST("h2dLambdaBeta_MassSelected"), lambda.p(), lambda.tofBetaLambda()); + } 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()); + + // Standard selection of time + if (TMath::Abs(lambda.deltaDecayTimeLambda()) < maxDeltaTimeDecay) { + histos.fill(HIST("h2dLambdaMassVsPt_DeltaDecayTime"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_DeltaDecayTime"), lambda.mLambda()); + } + + if (TMath::Abs(lambda.posTOFDeltaTLaPr()) < maxDeltaTimeProton) { + histos.fill(HIST("h2dLambdaMassVsPt_ProtonTOF"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_ProtonTOF"), lambda.mLambda()); + } + if (TMath::Abs(lambda.negTOFDeltaTLaPi()) < maxDeltaTimeProton) { + histos.fill(HIST("h2dLambdaMassVsPt_PionTOF"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_PionTOF"), lambda.mLambda()); + if (TMath::Abs(lambda.posTOFDeltaTLaPr()) < maxDeltaTimeProton) { + histos.fill(HIST("h2dLambdaMassVsPt_AllTOF"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_AllTOF"), lambda.mLambda()); + } + } + // Inversion of time selection for debug + // if(TMath::Abs(lambda.deltaDecayTimeLambda())>maxDeltaTimeDecay && TMath::Abs(lambda.deltaDecayTimeLambda()) < 5e+4){ + // histos.fill(HIST("h2dLambdaMassVsPt_DeltaDecayTime"), lambda.pt(), lambda.mLambda()); + // if(lambda.pt()>minPtV0 && lambda.pt() < maxPtV0) histos.fill(HIST("hLambdaMass_DeltaDecayTime"), lambda.mLambda()); + // } + + if (TMath::Abs(lambda.posTOFDeltaTLaPr()) > maxDeltaTimeProton && TMath::Abs(lambda.posTOFDeltaTLaPr()) < 5e+4) { + histos.fill(HIST("h2dLambdaMassVsPt_InvertProtonTOF"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_InvertProtonTOF"), lambda.mLambda()); + } + if (TMath::Abs(lambda.negTOFDeltaTLaPi()) > maxDeltaTimeProton && TMath::Abs(lambda.negTOFDeltaTLaPi()) < 5e+4) { + histos.fill(HIST("h2dLambdaMassVsPt_InvertPionTOF"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_InvertPionTOF"), lambda.mLambda()); + if (TMath::Abs(lambda.posTOFDeltaTLaPr()) > maxDeltaTimeProton && TMath::Abs(lambda.posTOFDeltaTLaPr()) < 5e+4) { + histos.fill(HIST("h2dLambdaMassVsPt_InvertAllTOF"), lambda.pt(), lambda.mLambda()); + if (lambda.pt() > minPtV0 && lambda.pt() < maxPtV0) + histos.fill(HIST("hLambdaMass_InvertAllTOF"), lambda.mLambda()); + } + } + } + } + + void processSim(aod::StraCollision const& coll, soa::Join const& v0s) + { + for (auto& lambda : v0s) { // selecting photons from Sigma0 + if (lambda.pdgCode() != 3122) + continue; + if (!lambda.isPhysicalPrimary()) + continue; + if (lambda.pdgCodePositive() != 2212) + continue; + if (lambda.pdgCodeNegative() != -211) + continue; + + histos.fill(HIST("hAssocLambdaMass"), lambda.mLambda()); + + if (TMath::Abs(lambda.negTOFDeltaTLaPi()) > 800) { + histos.fill(HIST("hAssocLambdaMassGoodTime"), lambda.mLambda()); + } else { + histos.fill(HIST("hAssocLambdaMassBadTime"), lambda.mLambda()); + } + + histos.fill(HIST("h2dAssocLambdaRadiusVsPt"), lambda.pt(), lambda.v0radius()); + histos.fill(HIST("h2dAssocLambdaMassVsPt"), lambda.pt(), lambda.mLambda()); + + histos.fill(HIST("h2dAssocProtonDeltaTimeVsPt"), lambda.pt(), lambda.posTOFDeltaTLaPr()); + histos.fill(HIST("h2dAssocProtonDeltaTimeVsRadius"), lambda.v0radius(), lambda.posTOFDeltaTLaPr()); + histos.fill(HIST("h2dAssocPionDeltaTimeVsPt"), lambda.pt(), lambda.negTOFDeltaTLaPi()); + histos.fill(HIST("h2dAssocPionDeltaTimeVsRadius"), lambda.v0radius(), lambda.negTOFDeltaTLaPi()); + + histos.fill(HIST("h2dAssocProtonLengthVsRadius"), lambda.v0radius(), lambda.posTOFLength()); + histos.fill(HIST("h2dAssocPionLengthVsRadius"), lambda.v0radius(), lambda.negTOFLength()); + + histos.fill(HIST("h2dAssocProtonLengthVsLengthToPV"), lambda.posTOFLengthToPV(), lambda.posTOFLength()); + histos.fill(HIST("h2dAssocPionLengthVsLengthToPV"), lambda.negTOFLengthToPV(), lambda.negTOFLength()); + + // delta lambda decay time + histos.fill(HIST("h2dAssocLambdaDeltaDecayTime"), lambda.pt(), lambda.deltaDecayTimeLambda()); } } + + PROCESS_SWITCH(strangepidqa, processReal, "Produce real information", true); + PROCESS_SWITCH(strangepidqa, processSim, "Produce simulated information", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 0694de0e123efd29058e83158d32dadae479ade6 Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Sat, 13 Jan 2024 20:49:50 +0100 Subject: [PATCH 42/48] Phi mc crun3 (#4302) * Modification of mixing and ITS only study * clang * Fix histogram binning * Fixes for Efficiency calculation --- PWGLF/Tasks/phianalysisrun3.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PWGLF/Tasks/phianalysisrun3.cxx b/PWGLF/Tasks/phianalysisrun3.cxx index 25259a611fb..10a03a80f38 100644 --- a/PWGLF/Tasks/phianalysisrun3.cxx +++ b/PWGLF/Tasks/phianalysisrun3.cxx @@ -203,7 +203,8 @@ struct phianalysisrun3 { using TrackCandidates = soa::Filtered>; - using EventCandidatesMC = soa::Join; + // using EventCandidatesMC = soa::Join; + using EventCandidatesMC = soa::Join; using TrackCandidatesMC = soa::Filtered>; From 39f1a7ce88724c2e7d807054726616257f45fd51 Mon Sep 17 00:00:00 2001 From: skundu692 <86804743+skundu692@users.noreply.github.com> Date: Sun, 14 Jan 2024 10:41:14 +0100 Subject: [PATCH 43/48] Phieffyfix (#4304) * Modification of mixing and ITS only study * clang * Fix histogram binning * Fixes for Efficiency calculation * Fix Efficiency calculation --- PWGLF/Tasks/phianalysisrun3.cxx | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/PWGLF/Tasks/phianalysisrun3.cxx b/PWGLF/Tasks/phianalysisrun3.cxx index 10a03a80f38..1dedfabd679 100644 --- a/PWGLF/Tasks/phianalysisrun3.cxx +++ b/PWGLF/Tasks/phianalysisrun3.cxx @@ -402,26 +402,24 @@ struct phianalysisrun3 { if (std::abs(mothertrack1.y()) > 0.5) { continue; } - if (isITSOnlycut) { - if (std::abs(mothertrack1.pdgCode()) != 333) { + if (std::abs(mothertrack1.pdgCode()) != 333) { + continue; + } + if (!isITSOnlycut) { + if (!selectionPID(track1) || !selectionPID(track2)) { 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}; + } + pvec0 = array{track1.px(), track1.py(), track1.pz()}; + pvec1 = array{track2.px(), track2.py(), track2.pz()}; + auto arrMomrec = array{pvec0, pvec1}; - auto motherP = mothertrack1.p(); - auto motherE = mothertrack1.e(); - genMass = std::sqrt(motherE * motherE - motherP * motherP); + auto motherP = mothertrack1.p(); + auto motherE = mothertrack1.e(); + genMass = std::sqrt(motherE * motherE - motherP * motherP); - recMass = RecoDecay::m(arrMomrec, array{massKa, massKa}); - histos.fill(HIST("h2PhiRec"), mothertrack1.pt(), recMass - genMass); - } + recMass = RecoDecay::m(arrMomrec, array{massKa, massKa}); + histos.fill(HIST("h2PhiRec"), mothertrack1.pt(), recMass - genMass); } } } From 53d3b3a8086f515cae8d16fc09e0c8bdb40f052c Mon Sep 17 00:00:00 2001 From: basiach <74355517+basiach@users.noreply.github.com> Date: Sun, 14 Jan 2024 12:03:22 +0100 Subject: [PATCH 44/48] PWGCF: FemtoUniverse - Deleting TOF nSigma cut from Producer (#4303) * 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 * Revoking TOF nSigma cut --------- Co-authored-by: Barbara Chytla --- .../TableProducer/femtoUniverseProducerTask.cxx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index f07d1eba235..0c14ee52a13 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -162,7 +162,6 @@ 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 ConfTOFnSigmaCut{"ConfTOFnSigmaCut", 5., "TOF NSigma cut"}; Configurable ConfTOFpTmin{"ConfTOFpTmin", 500, "TOF pT min"}; // TrackSelection *o2PhysicsTrackSelection; @@ -627,12 +626,6 @@ struct femtoUniverseProducerTask { if (!track.hasTOF()) { continue; } - std::vector tmpPids = ConfChildPIDspecies; - for (o2::track::PID pid : tmpPids) { - if (!trackCuts.getNsigmaTOF(track, pid) < ConfTOFnSigmaCut) { - continue; - } - } } } From e70e1f6fb0b0e74d57594bfa7d19d476038ad367 Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Sun, 14 Jan 2024 20:01:47 +0100 Subject: [PATCH 45/48] PWGLF / strange derived data: rounding some vars for better disk use (#4306) * Rounding some vars for better disk use * Please consider the following formatting changes (#217) --------- Co-authored-by: ALICE Builder --- PWGLF/TableProducer/cascadebuilder.cxx | 38 +++++++++++++++++++ PWGLF/TableProducer/lambdakzerobuilder.cxx | 30 ++++++++++++++- PWGLF/TableProducer/strangederivedbuilder.cxx | 32 ++++++++++++++-- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/PWGLF/TableProducer/cascadebuilder.cxx b/PWGLF/TableProducer/cascadebuilder.cxx index b36b445d497..4521d9680ad 100644 --- a/PWGLF/TableProducer/cascadebuilder.cxx +++ b/PWGLF/TableProducer/cascadebuilder.cxx @@ -188,6 +188,12 @@ struct cascadeBuilder { ConfigurableAxis axisTopoVarDCAToPV{"axisTopoVarDCAToPV", {200, -1, 1.0}, "single track DCA to PV (cm)"}; ConfigurableAxis axisTopoVarDCAV0ToPV{"axisTopoVarDCAV0ToPV", {200, 0, 5.0}, "V0 DCA to PV (cm)"}; + // round some V0 core variables up to a certain level of precision if requested + // useful to keep derived data sizes under control + // variables that are rounded include the DCAs but not the CosPA (precision needed) + Configurable roundDCAVariables{"roundDCAVariables", false, "round topological variables"}; + Configurable precisionDCAs{"precisionDCAs", 0.01f, "precision to keep the DCAs with"}; + int mRunNumber; float d_bz; float maxSnp; // max sine phi for propagation @@ -273,6 +279,25 @@ struct cascadeBuilder { {"hNegativeITSClusters", "hNegativeITSClusters", {HistType::kTH1D, {{10, -0.5f, 9.5f}}}}, {"hBachelorITSClusters", "hBachelorITSClusters", {HistType::kTH1D, {{10, -0.5f, 9.5f}}}}}}; + float roundToPrecision(float number, float step = 0.01) + { + // this function rounds a certain number in an axis that is quantized by + // the variable 'step'; the rounded number is placed halfway between + // n*step and (n+1)*step such that analysis can be done with absolutely + // no issue with precision 'step'. + return step * static_cast(static_cast((number) / step)) + TMath::Sign(1.0f, number) * (0.5f) * step; + } + + void roundCascadeCandidateVariables() + { + // Do not round actual cascade (pseudo-)track DCAs -> consider they may be tracked, high precision + cascadecandidate.dcacascdau = roundToPrecision(cascadecandidate.dcacascdau, precisionDCAs); + cascadecandidate.v0dcadau = roundToPrecision(cascadecandidate.v0dcadau, precisionDCAs); + cascadecandidate.v0dcanegtopv = roundToPrecision(cascadecandidate.v0dcanegtopv, precisionDCAs); + cascadecandidate.v0dcapostopv = roundToPrecision(cascadecandidate.v0dcapostopv, precisionDCAs); + cascadecandidate.bachDCAxy = roundToPrecision(cascadecandidate.bachDCAxy, precisionDCAs); + } + void resetHistos() { statisticsRegistry.exceptions = 0; @@ -1287,6 +1312,10 @@ struct cascadeBuilder { if (!validCascadeCandidate) continue; // doesn't pass cascade selections + // round the DCA variables to a certain precision if asked + if (roundDCAVariables) + roundCascadeCandidateVariables(); + cascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), cascadecandidate.positiveId, cascadecandidate.negativeId, cascadecandidate.bachelorId, cascade.collisionId()); @@ -1345,6 +1374,11 @@ struct cascadeBuilder { bool validCascadeCandidateKF = buildCascadeCandidateWithKF(cascade); if (!validCascadeCandidateKF) continue; // doesn't pass cascade selections + + // round the DCA variables to a certain precision if asked + if (roundDCAVariables) + roundCascadeCandidateVariables(); + registry.fill(HIST("hKFParticleStatistics"), 2.0f); kfcascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), @@ -1408,6 +1442,10 @@ struct cascadeBuilder { if (!validCascadeCandidate) continue; // doesn't pass cascade selections + // round the DCA variables to a certain precision if asked + if (roundDCAVariables) + roundCascadeCandidateVariables(); + // fill regular tables (no strangeness tracking) cascidx(/*cascadecandidate.v0Id, */ cascade.globalIndex(), cascadecandidate.positiveId, cascadecandidate.negativeId, diff --git a/PWGLF/TableProducer/lambdakzerobuilder.cxx b/PWGLF/TableProducer/lambdakzerobuilder.cxx index a695d7c212a..0cee635b5bd 100644 --- a/PWGLF/TableProducer/lambdakzerobuilder.cxx +++ b/PWGLF/TableProducer/lambdakzerobuilder.cxx @@ -147,7 +147,13 @@ struct lambdakzeroBuilder { Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - // generate and fill extra QA histograms is requested + // round some V0 core variables up to a certain level of precision if requested + // useful to keep derived data sizes under control + // variables that are rounded include the DCAs but not the CosPA (precision needed) + Configurable roundDCAVariables{"roundDCAVariables", false, "round topological variables"}; + Configurable precisionDCAs{"precisionDCAs", 0.01f, "precision to keep the DCAs with"}; + + // generate and fill extra QA histograms if requested Configurable d_doQA{"d_doQA", false, "Do basic QA"}; Configurable dQANBinsRadius{"dQANBinsRadius", 500, "Number of radius bins in QA histo"}; Configurable dQANBinsPtCoarse{"dQANBinsPtCoarse", 10, "Number of pT bins in QA histo"}; @@ -238,6 +244,23 @@ struct lambdakzeroBuilder { return std::sqrt((std::pow((pvY - Y) * Pz - (pvZ - Z) * Py, 2) + std::pow((pvX - X) * Pz - (pvZ - Z) * Px, 2) + std::pow((pvX - X) * Py - (pvY - Y) * Px, 2)) / (Px * Px + Py * Py + Pz * Pz)); } + float roundToPrecision(float number, float step = 0.01) + { + // this function rounds a certain number in an axis that is quantized by + // the variable 'step'; the rounded number is placed halfway between + // n*step and (n+1)*step such that analysis can be done with absolutely + // no issue with precision 'step'. + return step * static_cast(static_cast((number) / step)) + TMath::Sign(1.0f, number) * (0.5f) * step; + } + + void roundV0CandidateVariables() + { + v0candidate.dcaV0dau = roundToPrecision(v0candidate.dcaV0dau, precisionDCAs); + v0candidate.posDCAxy = roundToPrecision(v0candidate.posDCAxy, precisionDCAs); + v0candidate.negDCAxy = roundToPrecision(v0candidate.negDCAxy, precisionDCAs); + v0candidate.dcav0topv = roundToPrecision(v0candidate.dcav0topv, precisionDCAs); + } + void resetHistos() { statisticsRegistry.exceptions = 0; @@ -795,9 +818,12 @@ struct lambdakzeroBuilder { continue; // doesn't pass selections } + // round the DCA variables to a certain precision if asked + if (roundDCAVariables) + roundV0CandidateVariables(); + // 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; diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index b6445933c7f..6c4a6c3b9df 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -124,6 +124,12 @@ struct strangederivedbuilder { Configurable fillEmptyCollisions{"fillEmptyCollisions", false, "fill collision entries without candidates"}; + // round Nsigma variables up to a certain level of precision if requested + // useful to keep derived data sizes under control + // variables that are rounded include the DCAs but not the CosPA (precision needed) + Configurable roundNSigmaVariables{"roundNSigmaVariables", false, "round NSigma variables"}; + Configurable precisionNSigmas{"precisionNSigmas", 0.1f, "precision to keep NSigmas"}; + // For manual sliceBy Preslice V0perCollision = o2::aod::v0data::collisionId; Preslice CascperCollision = o2::aod::cascdata::collisionId; @@ -132,6 +138,15 @@ struct strangederivedbuilder { int64_t currentCollIdx; + float roundToPrecision(float number, float step = 0.01) + { + // this function rounds a certain number in an axis that is quantized by + // the variable 'step'; the rounded number is placed halfway between + // n*step and (n+1)*step such that analysis can be done with absolutely + // no issue with precision 'step'. + return step * static_cast(static_cast((number) / step)) + TMath::Sign(1.0f, number) * (0.5f) * step; + } + void init(InitContext& context) { currentCollIdx = -1; @@ -329,9 +344,20 @@ struct strangederivedbuilder { if (trackMap[tr.globalIndex()] >= 0) { dauTrackExtras(tr.detectorMap(), tr.itsClusterSizes(), tr.tpcNClsFound(), tr.tpcNClsCrossedRows()); - dauTrackTPCPIDs(tr.tpcSignal(), tr.tpcNSigmaEl(), - tr.tpcNSigmaPi(), tr.tpcNSigmaKa(), - tr.tpcNSigmaPr(), tr.tpcNSigmaHe()); + + // round if requested + if (roundNSigmaVariables) { + dauTrackTPCPIDs(tr.tpcSignal(), + roundToPrecision(tr.tpcNSigmaEl(), precisionNSigmas), + roundToPrecision(tr.tpcNSigmaPi(), precisionNSigmas), + roundToPrecision(tr.tpcNSigmaKa(), precisionNSigmas), + roundToPrecision(tr.tpcNSigmaPr(), precisionNSigmas), + roundToPrecision(tr.tpcNSigmaHe(), precisionNSigmas)); + } else { + dauTrackTPCPIDs(tr.tpcSignal(), tr.tpcNSigmaEl(), + tr.tpcNSigmaPi(), tr.tpcNSigmaKa(), + tr.tpcNSigmaPr(), tr.tpcNSigmaHe()); + } } } // done! From 05678ed4cee9f12b0f20f14b840d1daaa46bebcb Mon Sep 17 00:00:00 2001 From: prottayCMT <61418725+prottayCMT@users.noreply.github.com> Date: Mon, 15 Jan 2024 00:45:14 +0530 Subject: [PATCH 46/48] added formatted code for CKS QA (#4307) * added formatted code for CKS QA * tried correcting clang issue --------- Co-authored-by: prottayHEP --- PWGLF/Tasks/CMakeLists.txt | 7 + PWGLF/Tasks/chargedkstaranalysis.cxx | 554 +++++++++++++++++++++++++++ 2 files changed, 561 insertions(+) create mode 100644 PWGLF/Tasks/chargedkstaranalysis.cxx diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 0e4ae82b2c4..88931ba6097 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -181,6 +181,7 @@ o2physics_add_dpl_workflow(k892pmanalysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(lambda1520analysis SOURCES lambda1520analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -240,3 +241,9 @@ o2physics_add_dpl_workflow(f1protoncorrelation SOURCES f1protoncorrelation.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + + +o2physics_add_dpl_workflow(chargedkstaranalysis + SOURCES chargedkstaranalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/chargedkstaranalysis.cxx b/PWGLF/Tasks/chargedkstaranalysis.cxx new file mode 100644 index 00000000000..497b607698c --- /dev/null +++ b/PWGLF/Tasks/chargedkstaranalysis.cxx @@ -0,0 +1,554 @@ +// 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 this is a code for the CKS resonance +/// \author prottay das +/// \since 13/01/2024 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +struct chargedkstaranalysis { + + // 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"}; + + SliceCache cache; + + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", + {}, + OutputObjHandlingPolicy::AnalysisObject, + true, + true}; + HistogramRegistry histos{ + "histos", + {}, + OutputObjHandlingPolicy::AnalysisObject, + true, + true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Confugrable for QA histograms + Configurable QAbefore{"QAbefore", false, "QAbefore"}; + Configurable QAafter{"QAafter", false, "QAafter"}; + Configurable QAv0{"QAv0", false, "QAv0"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, + "Accepted z-vertex range (cm)"}; + + // Configurable parameters for V0 selection + Configurable ConfV0PtMin{"ConfV0PtMin", 0.f, + "Minimum transverse momentum of V0"}; + Configurable ConfV0DCADaughMax{"ConfV0DCADaughMax", 1.0f, + "Maximum DCA between the V0 daughters"}; + Configurable ConfV0CPAMin{"ConfV0CPAMin", 0.985f, "Minimum CPA of V0"}; + Configurable ConfV0TranRadV0Min{"ConfV0TranRadV0Min", 0.5f, + "Minimum transverse radius"}; + Configurable ConfV0TranRadV0Max{"ConfV0TranRadV0Max", 200.f, + "Maximum transverse radius"}; + Configurable cMaxV0LifeTime{"cMaxV0LifeTime", 15, + "Maximum V0 life time"}; + Configurable cMaxV0DCA{"cMaxV0DCA", 0.3, "DCA V0 to PV"}; + Configurable cSigmaMassKs0{"cSigmaMassKs0", 4, + "n Sigma cut on KS0 mass"}; + Configurable cWidthKs0{"cWidthKs0", 0.005, "Width of KS0"}; + + Configurable ConfDaughEta{"ConfDaughEta", 0.8f, + "V0 Daugh sel: max eta"}; + Configurable ConfDaughTPCnclsMin{"ConfDaughTPCnclsMin", 70.f, + "V0 Daugh sel: Min. nCls TPC"}; + Configurable ConfDaughDCAMin{ + "ConfDaughDCAMin", 0.06f, "V0 Daugh sel: Max. DCA Daugh to PV (cm)"}; + Configurable ConfDaughPIDCuts{"ConfDaughPIDCuts", 4, + "PID selections for KS0 daughters"}; + + // Configurables for track selections + Configurable cfgCutPT{"cfgCutPT", 0.2f, "PT cut on daughter track"}; + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta cut on daughter track"}; + Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, + "DCAxy range for tracks"}; + Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; + Configurable nsigmaCutTPC{"nsigmacutTPC", 3.0, + "Value of the TPC Nsigma cut"}; + Configurable nsigmaCutCombined{"nsigmaCutCombined", 3.0, + "Value of the Combined Nsigma cut"}; + Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, + "Number of mixed events per event"}; + Configurable cfgMultFT0{"cfgMultFT0", false, "cfgMultFT0"}; + Configurable cfgCentFT0C{"cfgCentFT0C", true, "cfgCentFT0C"}; + Configurable iscustomDCAcut{"iscustomDCAcut", false, "iscustomDCAcut"}; + Configurable ismanualDCAcut{"ismanualDCAcut", true, "ismanualDCAcut"}; + Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; + + void init(InitContext const&) + { + // Axes + AxisSpec K0ShortMassAxis = {200, 0.45f, 0.55f, + "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec vertexZAxis = {nBins, -10., 10., "vrtx_{Z} [cm]"}; + AxisSpec ptAxis = {200, 0.0f, 20.0f, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec multAxis = {100, 0.0f, 100.0f, "Multiplicity"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", + {HistType::kTH1F, {vertexZAxis}}); + rEventSelection.add("hmult", "Centrality distribution", kTH1F, + {{200, 0.0f, 200.0f}}); + + // for primary tracks + if (QAbefore && QAafter) { + histos.add("hNsigmaPionTPC_before", "NsigmaPion TPC distribution before", + kTH1F, {{200, -10.0f, 10.0f}}); + histos.add("hNsigmaPionTOF_before", "NsigmaPion TOF distribution before", + kTH1F, {{200, -10.0f, 10.0f}}); + + histos.add("hEta_after", "Eta distribution", kTH1F, {{200, -1.0f, 1.0f}}); + histos.add("hDcaxy_after", "Dcaxy distribution", kTH1F, + {{200, -10.0f, 10.0f}}); + histos.add("hDcaz_after", "Dcaz distribution", kTH1F, + {{200, -10.0f, 10.0f}}); + histos.add("hNsigmaPionTPC_after", "NsigmaPion TPC distribution", kTH1F, + {{200, -10.0f, 10.0f}}); + histos.add("hNsigmaPionTOF_after", "NsigmaPion TOF distribution", kTH1F, + {{200, -10.0f, 10.0f}}); + } + + if (QAv0) { + // K0s reconstruction + histos.add( + "hMassvsptvsmult", "hMassvsptvsmult", + {HistType::kTHnSparseF, {{K0ShortMassAxis}, {ptAxis}, {multAxis}}}, + true); + // K0s topological/PID cuts + histos.add("hDCAV0Daughters", "hDCAV0Daughters", + {HistType::kTH1F, {{50, 0.0f, 5.0f}}}); + histos.add("hLT", "hLT", {HistType::kTH1F, {{100, 0.0f, 50.0f}}}); + histos.add("hV0CosPA", "hV0CosPA", + {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + } + + // CKStar histograms + histos.add("h3CKSInvMassUnlikeSign", + "Invariant mass of CKS meson Unlike Sign", kTHnSparseF, + {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {90, 0.6, 1.5}}, true); + histos.add("h3CKSInvMassMixed", "Invariant mass of CKS meson Mixed", + kTHnSparseF, + {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {90, 0.6, 1.5}}, true); + } + + double massPi = TDatabasePDG::Instance() + ->GetParticle(kPiPlus) + ->Mass(); // FIXME: Get from the common header + double massK0s = TDatabasePDG::Instance() + ->GetParticle(kK0Short) + ->Mass(); // FIXME: Get from the common header + ROOT::Math::PtEtaPhiMVector CKSVector; + + template + bool selectionTrack(const T& candidate) + { + 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; + } + return true; + } + + template + bool selectionPID(const T& candidate) + { + if (candidate.hasTOF() && + (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < + (nsigmaCutCombined * nsigmaCutCombined)) { + return true; + } + if (!candidate.hasTOF() && + std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { + return true; + } + return false; + } + + template + bool SelectionV0(Collision const& collision, V0 const& candidate, + float multiplicity) + { + if (fabs(candidate.dcav0topv()) > cMaxV0DCA) { + return false; + } + + if (TMath::Abs(candidate.yK0Short()) > 0.5) { + return false; + } + + const float qtarm = candidate.qtarm(); + const float alph = candidate.alpha(); + float arm = qtarm / alph; + const float pT = candidate.pt(); + const float tranRad = candidate.v0radius(); + const float dcaDaughv0 = candidate.dcaV0daughters(); + const float cpav0 = candidate.v0cosPA(); + float CtauK0s = candidate.distovertotmom(collision.posX(), collision.posY(), + collision.posZ()) * + TDatabasePDG::Instance() + ->GetParticle(kK0Short) + ->Mass(); // FIXME: Get from the common header + float lowmasscutks0 = 0.497 - cWidthKs0 * cSigmaMassKs0; + float highmasscutks0 = 0.497 + cWidthKs0 * cSigmaMassKs0; + // float decayLength = candidate.distovertotmom(collision.posX(), + // collision.posY(), collision.posZ()) * + // RecoDecay::sqrtSumOfSquares(candidate.px(), candidate.py(), + // candidate.pz()); + + if (pT < ConfV0PtMin) { + return false; + } + if (dcaDaughv0 > ConfV0DCADaughMax) { + return false; + } + if (cpav0 < ConfV0CPAMin) { + return false; + } + if (tranRad < ConfV0TranRadV0Min) { + return false; + } + if (tranRad > ConfV0TranRadV0Max) { + return false; + } + if (fabs(CtauK0s) > cMaxV0LifeTime || + candidate.mK0Short() < lowmasscutks0 || + candidate.mK0Short() > highmasscutks0) { + return false; + } + if (arm < 0.2) { + return false; + } + + if (QAv0) { + histos.fill(HIST("hLT"), CtauK0s); + histos.fill(HIST("hMassvsptvsmult"), candidate.mK0Short(), candidate.pt(), + multiplicity); + histos.fill(HIST("hDCAV0Daughters"), candidate.dcaV0daughters()); + histos.fill(HIST("hV0CosPA"), candidate.v0cosPA()); + } + return true; + } + + template + bool isSelectedV0Daughter(T const& track, float charge, + double nsigmaV0Daughter) + { + const auto eta = track.eta(); + const auto tpcNClsF = track.tpcNClsFound(); + const auto dcaXY = track.dcaXY(); + const auto sign = track.sign(); + + if (!track.hasTPC()) + return false; + if (track.tpcNClsCrossedRows() < 70) + return false; + if (track.tpcCrossedRowsOverFindableCls() < 0.8) + return false; + + if (charge < 0 && sign > 0) { + return false; + } + if (charge > 0 && sign < 0) { + return false; + } + if (std::abs(eta) > ConfDaughEta) { + return false; + } + if (tpcNClsF < ConfDaughTPCnclsMin) { + return false; + } + if (std::abs(dcaXY) < ConfDaughDCAMin) { + return false; + } + if (std::abs(nsigmaV0Daughter) > ConfDaughPIDCuts) { + return false; + } + + return true; + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection + // requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + Filter acceptanceFilter = + (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); + Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && + (nabs(aod::track::dcaZ) < cfgCutDCAz); + + using EventCandidates = soa::Filtered< + soa::Join>; + using TrackCandidates = soa::Filtered< + soa::Join>; + using V0TrackCandidate = aod::V0Datas; + + ConfigurableAxis axisVertex{ + "axisVertex", + {20, -10, 10}, + "vertex axis for bin"}; + ConfigurableAxis axisMultiplicityClass{ + "axisMultiplicityClass", + {20, 0, 100}, + "multiplicity percentile for bin"}; + ConfigurableAxis axisMultiplicity{ + "axisMultiplicity", + {2000, 0, 10000}, + "TPC multiplicity for bin"}; + + using BinningTypeTPCMultiplicity = + ColumnBinningPolicy; + using BinningTypeVertexContributor = + ColumnBinningPolicy; + using BinningTypeCentralityM = + ColumnBinningPolicy; + using BinningTypeCentralityC = + ColumnBinningPolicy; + + BinningTypeVertexContributor binningOnPositions{ + {axisVertex, axisMultiplicity}, + true}; + Pair + pair{binningOnPositions, cfgNoMixedEvents, -1, &cache}; + + void processSE(EventCandidates::iterator const& collision, + TrackCandidates const& tracks, aod::V0Datas const& V0s, + aod::BCs const&) + { + + if (!collision.sel8()) { + return; + } + + std::vector pions, kshorts; + std::vector PionIndex = {}; + std::vector KshortPosDaughIndex = {}; + std::vector KshortNegDaughIndex = {}; + + float multiplicity = 0.0f; + if (cfgMultFT0) + multiplicity = collision.multZeqFT0A() + collision.multZeqFT0C(); + if (cfgMultFT0 == 0 && cfgCentFT0C == 1) + multiplicity = collision.centFT0C(); + if (cfgMultFT0 == 0 && cfgCentFT0C == 0) + multiplicity = collision.centFT0M(); + + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + rEventSelection.fill(HIST("hmult"), multiplicity); + + for (auto track1 : tracks) { + + if (QAbefore) { + histos.fill(HIST("hNsigmaPionTPC_before"), track1.tpcNSigmaPi()); + histos.fill(HIST("hNsigmaPionTOF_before"), track1.tofNSigmaPi()); + } + + if (!selectionPID(track1)) + continue; // for primary particle PID + + if (!selectionTrack(track1)) { + continue; + } + + if (QAafter) { + histos.fill(HIST("hEta_after"), track1.eta()); + histos.fill(HIST("hDcaxy_after"), track1.dcaXY()); + histos.fill(HIST("hDcaz_after"), track1.dcaZ()); + histos.fill(HIST("hNsigmaPionTPC_after"), track1.tpcNSigmaPi()); + histos.fill(HIST("hNsigmaPionTOF_after"), track1.tofNSigmaPi()); + } + + ROOT::Math::PtEtaPhiMVector temp1(track1.pt(), track1.eta(), track1.phi(), + massPi); + pions.push_back(temp1); + PionIndex.push_back(track1.globalIndex()); + + } // track loop ends + + for (auto& v0 : V0s) { + + auto postrack = v0.template posTrack_as(); + auto negtrack = v0.template negTrack_as(); + double nTPCSigmaPos[1]{postrack.tpcNSigmaPi()}; + double nTPCSigmaNeg[1]{negtrack.tpcNSigmaPi()}; + + if (!isSelectedV0Daughter(postrack, 1, nTPCSigmaPos[0])) { + continue; + } + if (!isSelectedV0Daughter(negtrack, -1, nTPCSigmaNeg[0])) { + continue; + } + + if (!SelectionV0(collision, v0, multiplicity)) { + continue; + } + + ROOT::Math::PtEtaPhiMVector temp2(v0.pt(), v0.eta(), v0.phi(), massK0s); + kshorts.push_back(temp2); + KshortPosDaughIndex.push_back(postrack.globalIndex()); + KshortNegDaughIndex.push_back(negtrack.globalIndex()); + } + + if (pions.size() != 0 && kshorts.size() != 0) { + for (auto ipion = pions.begin(); ipion != pions.end(); ++ipion) { + auto i1 = std::distance(pions.begin(), ipion); + for (auto ikshort = kshorts.begin(); ikshort != kshorts.end(); + ++ikshort) { + auto i3 = std::distance(kshorts.begin(), ikshort); + if (PionIndex.at(i1) == KshortPosDaughIndex.at(i3)) + continue; + if (PionIndex.at(i1) == KshortNegDaughIndex.at(i3)) + continue; + CKSVector = pions.at(i1) + kshorts.at(i3); + + if (TMath::Abs(CKSVector.Rapidity()) < 0.5) { + histos.fill(HIST("h3CKSInvMassUnlikeSign"), multiplicity, + CKSVector.Pt(), CKSVector.M()); + } + } + } + } + } + + PROCESS_SWITCH(chargedkstaranalysis, processSE, "Process Same event", true); + + void processME(EventCandidates const& collisions, + TrackCandidates const& tracks, V0TrackCandidate const& V0s) + + { + + for (auto& [c1, tracks1, c2, tracks2] : pair) { + + if (!c1.sel8()) { + continue; + } + if (!c2.sel8()) { + continue; + } + + float multiplicity = 0.0f; + if (cfgMultFT0) + multiplicity = c1.multZeqFT0A() + c1.multZeqFT0C(); + if (cfgMultFT0 == 0 && cfgCentFT0C == 1) + multiplicity = c1.centFT0C(); + if (cfgMultFT0 == 0 && cfgCentFT0C == 0) + multiplicity = c1.centFT0M(); + + for (auto& [t1, t2] : o2::soa::combinations( + o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + + if (!(selectionTrack(t1) || selectionPID(t1))) + continue; + if (!SelectionV0(c2, t2, multiplicity)) + continue; + + auto postrack = t2.template posTrack_as(); + auto negtrack = t2.template negTrack_as(); + double nTPCSigmaPos[1]{postrack.tpcNSigmaPi()}; + double nTPCSigmaNeg[1]{negtrack.tpcNSigmaPi()}; + + if (!isSelectedV0Daughter(postrack, 1, nTPCSigmaPos[0])) { + continue; + } + if (!isSelectedV0Daughter(negtrack, -1, nTPCSigmaNeg[0])) { + continue; + } + + TLorentzVector pi; + pi.SetPtEtaPhiM(t1.pt(), t1.eta(), t1.phi(), massPi); + TLorentzVector KSh; + KSh.SetPtEtaPhiM(t2.pt(), t2.eta(), t2.phi(), massK0s); + + TLorentzVector CKSmix = pi + KSh; + + if (TMath::Abs(CKSmix.Rapidity()) < 0.5) { + histos.fill(HIST("h3CKSInvMassMixed"), multiplicity, CKSmix.Pt(), + CKSmix.M()); + } + } + } + } + + PROCESS_SWITCH(chargedkstaranalysis, processME, "Process Mixed event", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 425098120878d557596cd0a43165fd2f453061e3 Mon Sep 17 00:00:00 2001 From: fkrizek Date: Mon, 15 Jan 2024 10:12:00 +0100 Subject: [PATCH 47/48] Histos for MB inclsive jet pT added (#4297) * Histos for MB inclsive jet pT added * MegaLinter fixes --------- Co-authored-by: ALICE Action Bot --- EventFiltering/PWGJE/jetFilter.cxx | 81 +++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/EventFiltering/PWGJE/jetFilter.cxx b/EventFiltering/PWGJE/jetFilter.cxx index acb47bdf1f1..8a1e9c04a84 100644 --- a/EventFiltering/PWGJE/jetFilter.cxx +++ b/EventFiltering/PWGJE/jetFilter.cxx @@ -40,7 +40,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -static const std::vector highPtObjectsNames{"JetChHighPt"}; +static const std::vector highPtObjectsNames = {"JetChLowPt", "JetChHighPt"}; struct jetFilter { enum { kJetChLowPt = 0, @@ -50,11 +50,24 @@ struct jetFilter { Produces tags; Configurable cfgJetR{"cfgJetR", 0.6, - "jet resolution parameter"}; // jet cone radius + "trigger jet resolution parameter"}; // jet cone radius Configurable jetPtLowThreshold{"jetPtLowThreshold", 30.0, "threshold for low pT jet trigger"}; Configurable jetPtHighThreshold{"jetPtHighThreshold", 50.0, "threshold for high pT jet trigger"}; + Configurable cfgZvtx{"cfgZvtx", 10., + "z vertex cut"}; // z vertex cut for full stat. inclusing jet spectra + + Configurable cfgEtaTPC{"cfgEtaTPC", 0.9, + "pseudorapidity coverage of TPC"}; // for full stat. inclusive jet spectra + + // jet resolution parameters for inclusive jets in fiducial volume + ConfigurableAxis cfgJetRadii{"cfgJetRadii", {VARIABLE_WIDTH, 0.2, 0.4, 0.6, 1.}, "jet resolution parameters (KEEP THE LAST PARAMETER AT 1.)"}; + + std::vector jetRFidVolume; // pseudorapidity limit for given a jet with given R + std::vector jetIntR; // jet radius * 100 + int triggerJetR; + HistogramRegistry spectra{ "spectra", {}, @@ -64,25 +77,46 @@ struct jetFilter { void init(o2::framework::InitContext&) { + triggerJetR = TMath::Nint(cfgJetR * 100.0f); spectra.add("fCollZpos", "collision z position", HistType::kTH1F, {{200, -20., +20., "#it{z}_{vtx} position (cm)"}}); - spectra.add("ptphiJetChSelected_lowptjettrigger", "pT of selected low pT charged jet trigger vs phi", HistType::kTH2F, + spectra.add("ptphiJetChSelected_lowptjettrigger", "#it{p}_{T} of selected low pT charged jet trigger vs #varphi", HistType::kTH2F, {{150, 0., +150., "charged jet #it{p}_{T} (GeV/#it{c})"}, - {60, 0, TMath::TwoPi()}}); + {60, 0, TMath::TwoPi(), "#varphi"}}); - spectra.add("ptphiJetChSelected_highptjettrigger", "pT of selected high pT charged jet trigger vs phi", HistType::kTH2F, + spectra.add("ptphiJetChSelected_highptjettrigger", "#it{p}_{T} of selected high pT charged jet trigger vs #varphi", HistType::kTH2F, {{150, 0., +150., "charged jet #it{p}_{T} (GeV/#it{c})"}, - {60, 0, TMath::TwoPi()}}); + {60, 0, TMath::TwoPi(), "#varphi"}}); - spectra.add("ptetaJetChSelected_lowptjettrigger", "pT of selected low pT charged jet trigger vs eta", HistType::kTH2F, + spectra.add("ptetaJetChSelected_lowptjettrigger", "#it{p}_{T} of selected low pT charged jet trigger vs #eta", HistType::kTH2F, {{150, 0., +150., "charged jet #it{p}_{T} (GeV/#it{c})"}, - {40, -1.0, 1.0}}); + {40, -1.0, 1.0, "#eta"}}); - spectra.add("ptetaJetChSelected_highptjettrigger", "pT of selected high pT charged jet trigger vs eta", HistType::kTH2F, + spectra.add("ptetaJetChSelected_highptjettrigger", "#it{p}_{T} of selected high pT charged jet trigger vs #eta", HistType::kTH2F, {{150, 0., +150., "charged jet #it{p}_{T} (GeV/#it{c})"}, - {40, -1.0, 1.0}}); + {40, -1.0, 1.0, "#eta"}}); + + AxisSpec jetRadiiAxis = {cfgJetRadii, "AKT jet resolution parameters"}; + const AxisSpec axisPt{1000, 0., +1000., "#it{p}_{T,jet} (GeV/#it{c})"}; + const AxisSpec axisEta{100, -1., +1., "#eta"}; + const AxisSpec axisPhi{100, 0., TMath::TwoPi(), "#varphi"}; + + // inclusive jet spectra in TPC fiducial volume for events with zvtx < 10 cm + for (unsigned int ir = 0; ir < jetRadiiAxis.binEdges.size() - 1; ir++) { + jetRFidVolume.push_back(cfgEtaTPC - jetRadiiAxis.binEdges[ir]); + jetIntR.push_back(TMath::Nint(100 * jetRadiiAxis.binEdges[ir])); + } + + spectra.add("hPtAKTJetsInclusive", "#it{p}_{T} of AKT charged jets in |#eta| < 0.9 - #it{R};", + {HistType::kTH2F, {jetRadiiAxis, axisPt}}); + + spectra.add("hEtaAKTJetsInclusive", "#eta of AKT charged jets with #it{p}_{T} > 10 GeV in |#eta| < 0.9 - #it{R};", + {HistType::kTH2F, {jetRadiiAxis, axisEta}}); + + spectra.add("hPhiAKTJetsInclusive", "#varphi of AKT charged jets with #it{p}_{T} > 10 GeV in |#eta| < 0.9 - #it{R};", + {HistType::kTH2F, {jetRadiiAxis, axisPhi}}); auto scalers{std::get>(spectra.add( "fProcessedEvents", ";;Number of filtered events", HistType::kTH1F, @@ -95,16 +129,37 @@ struct jetFilter { // declare filters on tracks // Filter collisionFilter = nabs(aod::jcollision::posZ) < cfgVertexCut; - Filter jetRadiusSelection = o2::aod::jet::r == nround(cfgJetR.node() * 100.0f); - using filteredJets = o2::soa::Filtered; + // Filter jetRadiusSelection = o2::aod::jet::r == nround(cfgJetR.node() * 100.0f); + // FK//using filteredJets = o2::soa::Filtered; - void process(aod::JCollision const& collision, filteredJets const& jets) + // FK//void process(aod::JCollision const& collision, filteredJets const& jets) + void process(aod::JCollision const& collision, o2::aod::ChargedJets const& jets) // FK// { // collision process loop bool keepEvent[kHighPtObjects]{false}; spectra.fill(HIST("fCollZpos"), collision.posZ()); + // FILL SPECTRA OF INCLUSIVE JETS IN FIDUCIAL VOLUME + if (TMath::Abs(collision.posZ()) < cfgZvtx) { + for (const auto& jet : jets) { // jets are ordered by pT + for (unsigned int ir = 0; ir < jetIntR.size(); ir++) { + if (jet.r() == jetIntR[ir]) { + if (TMath::Abs(jet.eta()) < jetRFidVolume[ir]) { + float jetr = (jet.r() / 100. + 1e-5); + spectra.fill(HIST("hPtAKTJetsInclusive"), jetr, jet.pt()); + if (jet.pt() > 10.) { + spectra.fill(HIST("hEtaAKTJetsInclusive"), jetr, jet.eta()); + spectra.fill(HIST("hPhiAKTJetsInclusive"), jetr, jet.phi()); + } + } + } + } + } + } + for (const auto& jet : jets) { // jets are ordered by pT + if (jet.r() != triggerJetR) + continue; if (jet.pt() >= jetPtLowThreshold) { spectra.fill(HIST("ptphiJetChSelected_lowptjettrigger"), jet.pt(), jet.phi()); // charged jet pT vs phi From caf08ed3d20f610d65d661df5fce03cae9d3c8ac Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Mon, 15 Jan 2024 09:44:05 +0000 Subject: [PATCH 48/48] MegaLinter fixes --- PWGJE/TableProducer/jettrackderived.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGJE/TableProducer/jettrackderived.cxx b/PWGJE/TableProducer/jettrackderived.cxx index f526e16e149..e8c369fd07e 100644 --- a/PWGJE/TableProducer/jettrackderived.cxx +++ b/PWGJE/TableProducer/jettrackderived.cxx @@ -48,7 +48,7 @@ struct jetspectraDerivedMaker { // Custom track cuts for the cut variation study TrackSelection customTrackCuts; - Configurable itsPattern{"itsPattern", 2, "0 = Run3ITSibAny, 1 = Run3ITSibTwo, 2 = Run3ITSallAny, 3 = Run3ITSall7Layers"}; + Configurable itsPattern{"itsPattern", 2, "0 = Run3ITSibAny, 1 = Run3ITSibTwo, 2 = Run3ITSallAny, 3 = Run3ITSall7Layers"}; Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; Configurable requireGoldenChi2{"requireGoldenChi2", true, "Additional cut on the GoldenChi2"};