From bc250659416634f73169ea3940ee805dff513842 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Sat, 16 Jul 2022 11:18:27 +0200 Subject: [PATCH 01/22] Update version of Resonance Package --- PWGLF/DataModel/LFResonanceTables.h | 359 ++++++++++++++++++ PWGLF/TableProducer/CMakeLists.txt | 10 + .../LFResonanceCandidateProducer.cxx | 186 +++++++++ ...LFResonanceCandidateProducerTrackTrack.cxx | 120 ++++++ PWGLF/Tasks/CMakeLists.txt | 5 + PWGLF/Tasks/k892sample.cxx | 173 +++++++++ PWGLF/Utils/collisionCuts.h | 135 +++++++ 7 files changed, 988 insertions(+) create mode 100644 PWGLF/DataModel/LFResonanceTables.h create mode 100644 PWGLF/TableProducer/LFResonanceCandidateProducer.cxx create mode 100644 PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx create mode 100644 PWGLF/Tasks/k892sample.cxx create mode 100644 PWGLF/Utils/collisionCuts.h diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h new file mode 100644 index 00000000000..625796b7ab4 --- /dev/null +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -0,0 +1,359 @@ +// 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 LFResonanceTables.h +/// \brief Definitions of tables of resonance decay candidates +/// +/// Inspired by StrangenessTables.h, FemtoDerived.h +/// +/// \author Bong-Hwi Lim + +#ifndef O2_ANALYSIS_LFRESONANCETABLES_H_ +#define O2_ANALYSIS_LFRESONANCETABLES_H_ + +#include + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +/// Resonance Collisions +namespace resocollision +{ +DECLARE_SOA_COLUMN(MultV0M, multV0M, float); //! V0M multiplicity +DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event +} // namespace resocollision +DECLARE_SOA_TABLE(ResoCollisions, "AOD", "RESOCOL", + o2::soa::Index<>, + o2::aod::collision::PosX, + o2::aod::collision::PosY, + o2::aod::collision::PosZ, + resocollision::MultV0M, + resocollision::Sphericity, + timestamp::Timestamp); +using ResoCollision = ResoCollisions::iterator; + +// Resonance Daughters +// inspired from PWGCF/DataModel/FemtoDerived.h +namespace resodaughter +{ +/// Distinuishes the different daughter types +enum DaughterType { + kTrack, //! Track + kV0, //! V0 + kCascade, //! Cascade + kNDaughterTypes //! Number of Daughter types +}; +static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", "V0", "Cascade"}; //! Naming of the different particle types + +enum PDGtype { + kPion = BIT(0), + kKaon = BIT(1), + kProton = BIT(2) +}; + +DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); +DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi +DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType +DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) +DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge +DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy +DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z +DECLARE_SOA_COLUMN(X, x, float); //! x position of the track +DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track +DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma +DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters +DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda +DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda +DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex + +DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, //! Compute the theta of the track + [](float eta) -> float { + return 2.f * std::atan(std::exp(-eta)); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Compute the momentum in x in GeV/c + [](float pt, float phi) -> float { + return pt * std::sin(phi); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Compute the momentum in y in GeV/c + [](float pt, float phi) -> float { + return pt * std::cos(phi); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Compute the momentum in z in GeV/c + [](float pt, float eta) -> float { + return pt * std::sinh(eta); + }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Compute the overall momentum in GeV/c + [](float pt, float eta) -> float { + return pt * std::cosh(eta); + }); +} // namespace resodaughter +DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", + o2::soa::Index<>, + resodaughter::ResoCollisionId, + resodaughter::Pt, + resodaughter::Eta, + resodaughter::Phi, + resodaughter::PartType, + resodaughter::TempFitVar, + resodaughter::Indices, + resodaughter::Sign, + resodaughter::TPCNClsCrossedRows, + resodaughter::DcaXY, + resodaughter::DcaZ, + resodaughter::X, + resodaughter::Alpha, + resodaughter::TPCnSigmaPi, + resodaughter::TPCnSigmaKa, + resodaughter::TPCnSigmaPr, + resodaughter::TOFnSigmaPi, + resodaughter::TOFnSigmaKa, + resodaughter::TOFnSigmaPr, + resodaughter::DaughDCA, + resodaughter::MLambda, + resodaughter::MAntiLambda, + resodaughter::TransRadius, + resodaughter::DecayVtxX, + resodaughter::DecayVtxY, + resodaughter::DecayVtxZ, + resodaughter::Theta, + resodaughter::Px, + resodaughter::Py, + resodaughter::Pz, + resodaughter::P); +using ResoDaughter = ResoDaughters::iterator; + +/// Reconstruction of track-track decay resonance candidates +/// +namespace reso2trktrkdata +{ +// Needed to have shorter table that does not rely on existing one (filtering!) +DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, Tracks, "_1"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, Tracks, "_2"); //! +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! + +// General two track properties: position, momentum +DECLARE_SOA_COLUMN(Trk1Sign, trk1Sign, int); //! track1 sign +DECLARE_SOA_COLUMN(Trk2Sign, trk2Sign, int); //! track2 sign +DECLARE_SOA_COLUMN(PxTrk1, pxTrk1, float); //! track1 px at min +DECLARE_SOA_COLUMN(PyTrk1, pyTrk1, float); //! track1 py at min +DECLARE_SOA_COLUMN(PzTrk1, pzTrk1, float); //! track1 pz at min +DECLARE_SOA_COLUMN(PxTrk2, pxTrk2, float); //! track2 px at min +DECLARE_SOA_COLUMN(PyTrk2, pyTrk2, float); //! track2 py at min +DECLARE_SOA_COLUMN(PzTrk2, pzTrk2, float); //! track2 pz at min + +// Saved from finding: DCAs +DECLARE_SOA_COLUMN(DCArTrk1ToPV, dcarTrk1toPV, float); //! DCA track1 to PVr +DECLARE_SOA_COLUMN(DCArTrk2ToPV, dcarTrk2toPV, float); //! DCA track2 to PVr +DECLARE_SOA_COLUMN(DCAzTrk1ToPV, dcazTrk1toPV, float); //! DCA track1 to PVz +DECLARE_SOA_COLUMN(DCAzTrk2ToPV, dcazTrk2toPV, float); //! DCA track2 to PVz + +// Derived expressions +// Momenta +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! resonance pT + [](float pxTrk1, float pyTrk1, float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1 + pxTrk2, pyTrk1 + pyTrk2); }); + +// Psi pair angle: angle between the plane defined by the electron and positron momenta and the xy plane +DECLARE_SOA_DYNAMIC_COLUMN(PsiPair, psiPair, //! psi pair angle + [](float pxTrk1, float pyTrk1, float pzTrk1, float pxTrk2, float pyTrk2, float pzTrk2) { + auto clipToPM1 = [](float x) { return x < -1.f ? -1.f : (x > 1.f ? 1.f : x); }; + float ptot2 = RecoDecay::p2(pxTrk1, pyTrk1, pzTrk1) * RecoDecay::p2(pxTrk2, pyTrk2, pzTrk2); + float argcos = RecoDecay::dotProd(array{pxTrk1, pyTrk1, pzTrk1}, array{pxTrk2, pyTrk2, pzTrk2}) / std::sqrt(ptot2); + float thetaPos = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1), pzTrk1); + float thetaNeg = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2), pzTrk2); + float argsin = (thetaNeg - thetaPos) / std::acos(clipToPM1(argcos)); + return std::asin(clipToPM1(argsin)); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Resonance eta + [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Resonance phi + [](float Px, float Py) -> float { return RecoDecay::phi(Px, Py); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Track2Pt, track2Pt, //! Track2 daughter pT + [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track1Pt, track1Pt, //! Track1 daughter pT + [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track2Eta, track2Eta, //! Track2 daughter eta + [](float pxTrk2, float pyTrk2, float pzTrk2) -> float { return RecoDecay::eta(array{pxTrk2, pyTrk2, pzTrk2}); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track2Phi, track2Phi, //! Track2 daughter phi + [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::phi(pxTrk2, pyTrk2); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track1Eta, track1Eta, //! Track1 daughter eta + [](float pxTrk1, float pyTrk1, float pzTrk1) -> float { return RecoDecay::eta(array{pxTrk1, pyTrk1, pzTrk1}); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track1Phi, track1Phi, //! Track1 daughter phi + [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::phi(pxTrk1, pyTrk1); }); + +DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! Resonance px + float, 1.f * aod::reso2trktrkdata::pxTrk1 + 1.f * aod::reso2trktrkdata::pxTrk2); +DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! Resonance py + float, 1.f * aod::reso2trktrkdata::pyTrk1 + 1.f * aod::reso2trktrkdata::pyTrk2); +DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! Resonance pz + float, 1.f * aod::reso2trktrkdata::pzTrk1 + 1.f * aod::reso2trktrkdata::pzTrk2); +} // namespace reso2trktrkdata + +DECLARE_SOA_TABLE_FULL(StoredReso2TrackTrackDatas, "Reso2TrackTrackDatas", "AOD", "Reso2TTDATA", //! + o2::soa::Index<>, reso2trktrkdata::Track1Id, reso2trktrkdata::Track2Id, reso2trktrkdata::CollisionId, + reso2trktrkdata::Trk1Sign, reso2trktrkdata::Trk2Sign, + reso2trktrkdata::PxTrk1, reso2trktrkdata::PyTrk1, reso2trktrkdata::PzTrk1, + reso2trktrkdata::PxTrk2, reso2trktrkdata::PyTrk2, reso2trktrkdata::PzTrk2, + + // Topological selections + reso2trktrkdata::DCArTrk1ToPV, reso2trktrkdata::DCArTrk2ToPV, + reso2trktrkdata::DCAzTrk1ToPV, reso2trktrkdata::DCAzTrk2ToPV, + + // Dynamic columns + reso2trktrkdata::Pt, + reso2trktrkdata::PsiPair, + + // Longitudinal + reso2trktrkdata::Eta, + reso2trktrkdata::Phi, + reso2trktrkdata::Track2Pt, + reso2trktrkdata::Track1Pt, + reso2trktrkdata::Track2Eta, + reso2trktrkdata::Track2Phi, + reso2trktrkdata::Track1Eta, + reso2trktrkdata::Track1Phi); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackTrackDatas, StoredReso2TrackTrackDatas, "Reso2TTDATAEXT", //! + reso2trktrkdata::Px, reso2trktrkdata::Py, reso2trktrkdata::Pz); // the table name has here to be the one with EXT which is not nice and under study + +using Reso2TrackTrackData = Reso2TrackTrackDatas::iterator; + +using Reso2TracksExt = soa::Join; +using Reso2TracksMC = soa::Join; +using Reso2TracksPID = soa::Join; +using Reso2TracksPIDExt = soa::Join; + +/// Reconstruction of track-v0 decay resonance candidates +/// +namespace reso2trkv0data +{ +// Needed to have shorter table that does not rely on existing one (filtering!) +DECLARE_SOA_INDEX_COLUMN_FULL(Track, track, int, Tracks, "_track"); //! +DECLARE_SOA_INDEX_COLUMN(V0, v0); //! +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! + +// General V0, track properties: position, momentum +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(PxPos, pxpos, float); //! +DECLARE_SOA_COLUMN(PyPos, pypos, float); //! +DECLARE_SOA_COLUMN(PzPos, pzpos, float); //! +DECLARE_SOA_COLUMN(PxNeg, pxneg, float); //! +DECLARE_SOA_COLUMN(PyNeg, pyneg, float); //! +DECLARE_SOA_COLUMN(PzNeg, pzneg, float); //! +DECLARE_SOA_COLUMN(PxTrack, pxtrack, float); //! +DECLARE_SOA_COLUMN(PyTrack, pytrack, float); //! +DECLARE_SOA_COLUMN(PzTrack, pztrack, float); //! +DECLARE_SOA_COLUMN(XV0, xV0, float); //! +DECLARE_SOA_COLUMN(YV0, yV0, float); //! +DECLARE_SOA_COLUMN(ZV0, zV0, float); //! + +// Saved from finding: DCAs +DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! +DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! +DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! +DECLARE_SOA_COLUMN(DCATrackToPV, dcatracktopv, float); //! + +// Derived expressions +// Momenta +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! + [](float Px, float Py) -> float { return RecoDecay::sqrtSumOfSquares(Px, Py); }); + +// Length quantities +DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, //! + [](float xV0, float yV0) -> float { return RecoDecay::sqrtSumOfSquares(xV0, yV0); }); + +// CosPAs +DECLARE_SOA_DYNAMIC_COLUMN(V0CosPA, v0cosPA, //! + [](float XV0, float YV0, float ZV0, float PxV0, float PyV0, float PzV0, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(array{pvX, pvY, pvZ}, array{XV0, YV0, ZV0}, array{PxV0, PyV0, PzV0}); }); +DECLARE_SOA_DYNAMIC_COLUMN(DCAV0ToPV, dcav0topv, //! + [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { 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)); }); + +// Calculated on the fly with mass assumption + dynamic tables +DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! mass under lambda hypothesis + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kProton), RecoDecay::getMassPDG(kPiPlus)}); }); +DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda, mAntiLambda, //! mass under antilambda hypothesis + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kProton)}); }); +DECLARE_SOA_DYNAMIC_COLUMN(MK0Short, mK0Short, //! mass under K0short hypothesis + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kPiPlus)}); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! + [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); + +DECLARE_SOA_EXPRESSION_COLUMN(PxV0, pxV0, //! + float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg); +DECLARE_SOA_EXPRESSION_COLUMN(PyV0, pyV0, //! + float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg); +DECLARE_SOA_EXPRESSION_COLUMN(PzV0, pzV0, //! + float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg); +DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! + float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg + 1.f * aod::reso2trkv0data::pxtrack); +DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! + float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg + 1.f * aod::reso2trkv0data::pytrack); +DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! + float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg + 1.f * aod::reso2trkv0data::pztrack); +} // namespace reso2trkv0data + +DECLARE_SOA_TABLE(Reso2TrackV0Data, "AOD", "Reso2TVDATA", //! + o2::soa::Index<>, reso2trkv0data::TrackId, reso2trkv0data::V0Id, reso2trkv0data::CollisionId, + + // General V0, track properties: position, momentum + reso2trkv0data::Sign, + reso2trkv0data::PxPos, reso2trkv0data::PyPos, reso2trkv0data::PzPos, + reso2trkv0data::PxNeg, reso2trkv0data::PyNeg, reso2trkv0data::PzNeg, + reso2trkv0data::PxTrack, reso2trkv0data::PyTrack, reso2trkv0data::PzTrack, + reso2trkv0data::XV0, reso2trkv0data::YV0, reso2trkv0data::ZV0, + + // Saved from finding: DCAs + reso2trkv0data::DCAV0Daughters, + reso2trkv0data::DCAPosToPV, reso2trkv0data::DCANegToPV, reso2trkv0data::DCATrackToPV, + + // Dynamic columns + reso2trkv0data::Pt, + reso2trkv0data::V0Radius, + reso2trkv0data::V0CosPA, + reso2trkv0data::DCAV0ToPV, + + // V0 Invariant masses + reso2trkv0data::MLambda, + reso2trkv0data::MAntiLambda, + reso2trkv0data::MK0Short, + + reso2trkv0data::Eta); + +using Reso2TrackV0DataOrigin = Reso2TrackV0Data; + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackV0DataExt, Reso2TrackV0DataOrigin, "Reso2TVDATAEXT", //! + reso2trkv0data::PxV0, reso2trkv0data::PyV0, reso2trkv0data::PzV0, + reso2trkv0data::Px, reso2trkv0data::Py, reso2trkv0data::Pz); // the table name has here to be the one with EXT which is not nice and under study + +using Reso2TrackV0DataFull = Reso2TrackV0DataExt; + +} // namespace o2::aod +#endif // O2_ANALYSIS_LFRESONANCETABLES_H_ \ No newline at end of file diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index 02b921804ef..e38a61a70ae 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -32,4 +32,14 @@ o2physics_add_dpl_workflow(cascadefinder o2physics_add_dpl_workflow(nucleustreecreator SOURCES LFTreeCreatorNuclei.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(reso2initializer + SOURCES LFResonanceCandidateProducer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(reso2trktrkbuilder + SOURCES LFResonanceCandidateProducer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx new file mode 100644 index 00000000000..5d4e6b3f115 --- /dev/null +++ b/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx @@ -0,0 +1,186 @@ +// 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 LFResonanceCandidateProducer.cxx +/// \brief Initializes variables for the resonance candidate producers +/// +/// +/// \author Bong-Hwi Lim + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/StrangenessTables.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "PWGLF/Utils/collisionCuts.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +/// Initializer for the resonance candidate producers +struct reso2initializer { + + Produces resoCollisions; + Produces reso2tracks; + + // Configurables + Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam + Configurable ConfStoreV0{"ConfStoreV0", true, "True: store V0s"}; + + /// Event cuts + o2::analysis::CollisonCuts colCuts; + Configurable ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable ConfEvtTriggerCheck{"ConfEvtTriggerCheck", true, "Evt sel: check for trigger"}; + Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; + Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; + + // Pre-selection cuts + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 5.0f, "TPC and TOF PID cut (loose, improve performance)"}; + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + Configurable isRun2{"isRun2", 0, "if Run2: demand TPC refit"}; + + /// DCA Selections for V0 + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.05, "Track DCAr cut to PV Maximum"}; + Configurable cMinV0PosDCArToPVcut{"cMinV0PosDCArToPVcut", 0.05f, "V0 Positive Track DCAr cut to PV Minimum"}; // Pre-selection + Configurable cMinV0NegDCArToPVcut{"cMinV0NegDCArToPVcut", 0.05f, "V0 Negative Track DCAr cut to PV Minimum"}; // Pre-selection + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + Configurable cMinV0Radius{"cMinV0Radius", 5.0, "Minimum V0 radius from PV"}; + Configurable cMaxV0Radius{"cMaxV0Radius", 200.0, "Maximum V0 radius from PV"}; + Configurable cMinV0CosPA{"cMinV0CosPA", 0.995, "Minimum V0 CosPA to PV"}; + + HistogramRegistry qaRegistry{"QAHistos", { + {"hGoodTrackIndices", "hGoodTrackIndices", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, + {"hGoodV0Indices", "hGoodV0Indices", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, + }, + OutputObjHandlingPolicy::QAObject}; + + // Pre-filters for efficient process + Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF + Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC + Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut + Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts + + void init(InitContext&) + { + colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3); + colCuts.init(&qaRegistry); + } + + void process(const soa::Join::iterator& collision, + soa::Filtered const& tracks, o2::aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); /// adding timestamp to access magnetic field later + // Default event selection + if (!colCuts.isSelected(collision)) + return; + colCuts.fillQA(collision); + + if (ConfIsRun3) { + resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFT0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); + } else { + resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.centRun2V0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); + } + + int childIDs[2] = {0, 0}; // these IDs are necessary to keep track of the children + // Loop over tracks + for (auto& track : tracks) { + // Tracks are already filtered by the pre-filters + reso2tracks(resoCollisions.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::resodaughter::DaughterType::kTrack, + track.dcaXY(), + childIDs, + track.sign(), + (uint8_t)track.tpcNClsCrossedRows(), + track.dcaXY(), + track.dcaZ(), + track.x(), + track.alpha(), + track.tpcNSigmaPi(), + track.tpcNSigmaKa(), + track.tpcNSigmaPr(), + track.tofNSigmaPi(), + track.tofNSigmaKa(), + track.tofNSigmaPr(), + 0, 0, 0, + 0, 0, 0, 0); + } + /// V0s + if (ConfStoreV0) { + for (auto& v0 : V0s) { + qaRegistry.fill(HIST("hGoodV0Indices"), 0.5); + auto postrack = v0.posTrack_as(); + auto negtrack = v0.negTrack_as(); + + if (postrack.tpcNClsCrossedRows() < mincrossedrows) + continue; + if (negtrack.tpcNClsCrossedRows() < mincrossedrows) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 1.5); + + if (fabs(postrack.dcaXY()) < cMinV0PosDCArToPVcut) + continue; + if (fabs(negtrack.dcaXY()) < cMinV0NegDCArToPVcut) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 2.5); + + if ((v0.v0radius() > cMaxV0Radius) || (v0.v0radius() < cMinV0Radius)) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 3.5); + if (v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cMinV0CosPA) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 4.5); + childIDs[0] = v0.posTrackId(); + childIDs[1] = v0.negTrackId(); + reso2tracks(resoCollisions.lastIndex(), + v0.pt(), + v0.eta(), + v0.phi(), + aod::resodaughter::DaughterType::kV0, + v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), + childIDs, + 0, + 0, + v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), + 0, + v0.x(), 0, 0, 0, 0, 0, 0, 0, + v0.dcaV0daughters(), v0.mLambda(), v0.mAntiLambda(), + v0.v0radius(), v0.x(), v0.y(), v0.z()); + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"lf-reso2initializer"}), + }; +} \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx new file mode 100644 index 00000000000..72c16e261a3 --- /dev/null +++ b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx @@ -0,0 +1,120 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file LFResonanceCandidateProducerTrackTrack.cxx +/// \brief Reconstruction of track-track decay resonance candidates +/// +/// Inspired by lambdakzerofinder.cxx, +/// +/// \author Bong-Hwi Lim + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/StrangenessTables.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "PWGLF/Utils/collisionCuts.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +/// Reconstruction of track-track decay resonance candidates +struct reso2trktrkbuilder { + Produces reso2trktrkdata; + + HistogramRegistry registry{ + "registry", + { + {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, + {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, + }, + OutputObjHandlingPolicy::QAObject + }; + + // Configurables + Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam + /// Selection criteria + Configurable selectUnLikeSignOnly{"selectUnLikeSignOnly", 1, "Select only unlike sign pair for resonance"}; + + // Pre-selection cuts + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + + /// DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 5.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + /// Partition for firstTrack + Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + + void process(aod::ResoCollision& collision, + aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) + { + // LOGF(info, "event id: %d", collision.bcId()); + auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { + registry.fill(HIST("hReso2trktrckCandidate"), 0.5); + // Un-like sign pair only + if (selectUnLikeSignOnly && (trk1.sign() * trk2.sign() > 0)) + continue; + registry.fill(HIST("hReso2trktrckCandidate"), 1.5); + reso2trktrkdata( + trk1.globalIndex(), + trk2.globalIndex(), + trk1.resoCollisionId(), + trk1.sign(), trk2.sign(), + trk1.px(), trk1.py(), trk1.pz(), + trk2.px(), trk2.py(), trk2.pz(), + trk1.dcaXY(), trk2.dcaXY(), + trk1.dcaZ(), trk2.dcaZ()); + } + } +}; + +/// Extends the v0data table with expression columns +struct reso2trktrkinitializer { + Spawns reso2tracktrackdatas; + void init(InitContext const&) {} +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkbuilder"}), + adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkinitializer"})}; +} \ No newline at end of file diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 19856979a23..204a2ef8ef8 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -97,4 +97,9 @@ o2physics_add_dpl_workflow(track-checks o2physics_add_dpl_workflow(rsnanalysis SOURCES rsnanalysis.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(k892sample + SOURCES k892sample.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/Tasks/k892sample.cxx b/PWGLF/Tasks/k892sample.cxx new file mode 100644 index 00000000000..2d742bd825d --- /dev/null +++ b/PWGLF/Tasks/k892sample.cxx @@ -0,0 +1,173 @@ +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include +#include "DataFormatsParameters/GRPObject.h" +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct k892sample { + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; + framework::Service ccdb; /// Accessing the CCDB + + + void init(o2::framework::InitContext&) + { + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + AxisSpec vtxZAxis = {100, -20, 20}; + + std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; + AxisSpec centAxis = {centBinning, "V0M (%)"}; + std::vector ptBinning = {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., 5., 10., 20.}; + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + + histos.add("EventQA/Centrality", "Centrality distribution (V0M)", kTH1F, {centAxis}); + histos.add("EventQA/VtxZBeforeSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); + histos.add("EventQA/VtxZAfterSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); + // Mass QA (quick check) + histos.add("k892invmass", "Invariant mass of K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("antik892invmass", "Invariant mass of Anti-K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("k892invmassME", "Invariant mass of K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("antik892invmassME", "Invariant mass of Anti-K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + + // 3d histogram + histos.add("h3k892invmass", "Invariant mass of K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); + histos.add("h3antik892invmass", "Invariant mass of Anti-K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); + } + + double massPi = TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(); + double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); + + void process(o2::aod::ResoCollision& inputCollision, + aod::Reso2TrackTrackDatas const& reso2trktrk, aod::Reso2TracksPIDExt const& track) + { + + histos.fill(HIST("EventQA/VtxZAfterSel"), inputCollision.posZ()); + + // fill centrality histos + histos.fill(HIST("EventQA/Centrality"), inputCollision.multV0M()); + + for (auto reso2 : reso2trktrk) { + auto trackPos = (reso2.trk1Sign() > 0) ? reso2.track1_as() : reso2.track2_as(); // positive daughter + auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter + bool isK892 = false; + bool isAntiK892 = false; + + // PID cuts + if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ + isK892 = true; + if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) + isAntiK892 = true; + if (!isK892 && !isAntiK892) + continue; + + // TOF PID cut (if available) + if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) + continue; + if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) + continue; + + auto arrMom = array{ + array{reso2.pxTrk1(), reso2.pyTrk1(), reso2.pzTrk1()}, + array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; + auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + if (isK892) { + histos.fill(HIST("k892invmass"), mass); + histos.fill(HIST("h3k892invmass"), inputCollision.multV0M(), reso2.pt(), mass); + } + if (isAntiK892) { // Anti-matter + histos.fill(HIST("antik892invmass"), mass); + histos.fill(HIST("h3antik892invmass"), inputCollision.multV0M(), reso2.pt(), mass); + } + } + } + // Processing Event Mixing + void processME(o2::aod::ResoCollisions& inputCollision, + o2::aod::BCsWithTimestamps const&, aod::Reso2TrackTrackDatas & reso2trktrk, aod::Reso2TracksPIDExt const& track) + { + BinningPolicy colBinning{{CfgVtxBins, CfgMultBins}, true}; + + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, inputCollision, inputCollision)) { + + auto magFieldTesla1 = 0.0; + static o2::parameters::GRPObject* grpo1 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision1.timestamp()); + if (!grpo1) { + magFieldTesla1 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision1.timestamp(), grpo1->getNominalL3Field()); + magFieldTesla1 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto magFieldTesla2 = 0.0; + static o2::parameters::GRPObject* grpo2 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision2.timestamp()); + if (!grpo2) { + magFieldTesla2 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision2.timestamp(), grpo2->getNominalL3Field()); + magFieldTesla2 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto reso2trktrkPartOne = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision1.globalIndex()); + auto reso2trktrkPartTwo = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision2.globalIndex()); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + for (auto& [reso1, reso2] : combinations(CombinationsStrictlyUpperIndexPolicy(reso2trktrkPartOne, reso2trktrkPartTwo))) { + auto trackPos = (reso1.trk1Sign() > 0) ? reso1.track1_as() : reso1.track2_as(); // positive daughter + auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter + bool isK892 = false; + bool isAntiK892 = false; + + // PID cuts + if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ + isK892 = true; + if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) + isAntiK892 = true; + if (!isK892 && !isAntiK892) + continue; + + // TOF PID cut (if available) + if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) + continue; + if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) + continue; + + auto arrMom = array{ + array{reso1.pxTrk1(), reso1.pyTrk1(), reso1.pzTrk1()}, + array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; + auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + if (isK892) { + histos.fill(HIST("k892invmassME"), mass); + } + if (isAntiK892) { // Anti-matter + histos.fill(HIST("antik892invmassME"), mass); + } + } + } + }; + PROCESS_SWITCH(k892sample, processME, "Process EventMixing", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} \ No newline at end of file diff --git a/PWGLF/Utils/collisionCuts.h b/PWGLF/Utils/collisionCuts.h new file mode 100644 index 00000000000..8f8f2f6cde1 --- /dev/null +++ b/PWGLF/Utils/collisionCuts.h @@ -0,0 +1,135 @@ +// 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 collisionCuts.h +/// \brief Traditional event selection cuts for O2 analysis +/// +/// Simply copied from FemtoDreamCollisionSelection.h +/// original author: Laura Serksnyte, TU München +/// +/// \author Bong-Hwi Lim + +#ifndef ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ +#define ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ + +#include "Common/CCDB/TriggerAliases.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/Logger.h" + +using namespace o2::framework; + +namespace o2::analysis +{ + +class CollisonCuts +{ + public: + virtual ~CollisonCuts() = default; + + /// Pass the selection criteria to the class + /// \param zvtxMax Maximal value of the z-vertex + /// \param checkTrigger whether or not to check for the trigger alias + /// \param trig Requested trigger alias + /// \param checkOffline whether or not to check for offline selection criteria + void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool checkRun3) + { + mCutsSet = true; + mZvtxMax = zvtxMax; + mCheckTrigger = checkTrigger; + mTrigger = static_cast(trig); + mCheckOffline = checkOffline; + mCheckIsRun3 = checkRun3; + } + + /// Initializes histograms for the task + /// \param registry Histogram registry to be passed + void init(HistogramRegistry* registry) + { + if (!mCutsSet) { + LOGF(error, "Event selection not set - quitting!"); + } + mHistogramRegistry = registry; + mHistogramRegistry->add("Event/posZ", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultFV0M", "; vMultV0M; Entries", kTH1F, {{600, 0, 600}}); + mHistogramRegistry->add("Event/MultFT0M", "; vMultT0M; Entries", kTH1F, {{600, 0, 600}}); + } + + /// Print some debug information + void printCuts() + { + std::cout << "Debug information for CollisonCuts \n Max. z-vertex: " << mZvtxMax << "\n Check trigger: " << mCheckTrigger << "\n Trigger: " << mTrigger << "\n Check offline: " << mCheckOffline << "\n"; + } + + /// Check whether the collisions fulfills the specified selections + /// \tparam T type of the collision + /// \param col Collision + /// \return whether or not the collisions fulfills the specified selections + template + bool isSelected(T const& col) + { + if (std::abs(col.posZ()) > mZvtxMax) { + return false; + } + if (mCheckIsRun3) { + if (mCheckOffline && !col.sel8()) { + return false; + } + } else { + if (mCheckTrigger && !col.alias()[mTrigger]) { + return false; + } + if (mCheckOffline && !col.sel7()) { + return false; + } + } + return true; + } + + /// Some basic QA of the event + /// \tparam T type of the collision + /// \param col Collision + template + void fillQA(T const& col) + { + if (mHistogramRegistry) { + mHistogramRegistry->fill(HIST("Event/posZ"), col.posZ()); + mHistogramRegistry->fill(HIST("Event/MultFV0M"), col.multFV0M()); + mHistogramRegistry->fill(HIST("Event/MultFT0M"), col.multFT0M()); + } + } + + /// \todo to be implemented! + /// Compute the sphericity of an event + /// Important here is that the filter on tracks does not interfere here! + /// In Run 2 we used here global tracks within |eta| < 0.8 + /// \tparam T1 type of the collision + /// \tparam T2 type of the tracks + /// \param col Collision + /// \param tracks All tracks + /// \return value of the sphericity of the event + template + float computeSphericity(T1 const& col, T2 const& tracks) + { + return 2.f; + } + + private: + HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + bool mCutsSet = false; ///< Protection against running without cuts + bool mCheckTrigger = false; ///< Check for trigger + bool mCheckOffline = false; ///< Check for offline criteria (might change) + bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam + triggerAliases mTrigger = kINT7; ///< Trigger to check for + float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) +}; +} // namespace o2::analysis::femtoDream + +#endif /* ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ */ \ No newline at end of file From 2b591be9de37ecd317147925c35071db46b2eefc Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 01:07:10 +0200 Subject: [PATCH 02/22] Change the name of task and add TPC/TOF selectors --- PWGLF/DataModel/LFResonanceTables.h | 10 ++++-- ...roducer.cxx => LFResonanceInitializer.cxx} | 32 ++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) rename PWGLF/TableProducer/{LFResonanceCandidateProducer.cxx => LFResonanceInitializer.cxx} (88%) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 625796b7ab4..ad370d767ad 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -76,6 +76,8 @@ DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z DECLARE_SOA_COLUMN(X, x, float); //! x position of the track DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track +DECLARE_SOA_COLUMN(TPCPIDselection, tpcPIDselection, uint8_t); //! TPC PID selection +DECLARE_SOA_COLUMN(TOFPIDselection, tofPIDselection, uint8_t); //! TOF PID selection DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma @@ -126,6 +128,8 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::DcaZ, resodaughter::X, resodaughter::Alpha, + resodaughter::TPCPIDselection, + resodaughter::TOFPIDselection, resodaughter::TPCnSigmaPi, resodaughter::TPCnSigmaKa, resodaughter::TPCnSigmaPr, @@ -244,9 +248,9 @@ DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackTrackDatas, StoredReso2TrackTrackDatas using Reso2TrackTrackData = Reso2TrackTrackDatas::iterator; -using Reso2TracksExt = soa::Join; -using Reso2TracksMC = soa::Join; -using Reso2TracksPID = soa::Join; +using Reso2TracksExt = soa::Join; +using Reso2TracksMC = soa::Join; +using Reso2TracksPID = soa::Join; using Reso2TracksPIDExt = soa::Join; /// Reconstruction of track-v0 decay resonance candidates diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx similarity index 88% rename from PWGLF/TableProducer/LFResonanceCandidateProducer.cxx rename to PWGLF/TableProducer/LFResonanceInitializer.cxx index 5d4e6b3f115..3249449335d 100644 --- a/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file LFResonanceCandidateProducer.cxx +/// \file LFResonanceInitializer.cxx /// \brief Initializes variables for the resonance candidate producers /// /// @@ -91,7 +91,7 @@ struct reso2initializer { colCuts.init(&qaRegistry); } - void process(const soa::Join::iterator& collision, + void process(const soa::Join::iterator& collision, soa::Filtered const& tracks, o2::aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { auto bc = collision.bc_as(); /// adding timestamp to access magnetic field later @@ -103,13 +103,35 @@ struct reso2initializer { if (ConfIsRun3) { resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFT0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); } else { - resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.centRun2V0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); + resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFV0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); } int childIDs[2] = {0, 0}; // these IDs are necessary to keep track of the children // Loop over tracks for (auto& track : tracks) { // Tracks are already filtered by the pre-filters + qaRegistry.fill(HIST("hGoodTrackIndices"), 0.5); + + // Add PID selection criteria here + uint8_t tpcPIDselections = 0; + uint8_t tofPIDselections = 0; + // TPC PID + if (std::abs(track.tpcNSigmaPi()) < pidnSigmaPreSelectionCut) + tpcPIDselections &= BIT(0); + if (std::abs(track.tpcNSigmaKa()) < pidnSigmaPreSelectionCut) + tpcPIDselections &= BIT(1); + if (std::abs(track.tpcNSigmaPr()) < pidnSigmaPreSelectionCut) + tpcPIDselections &= BIT(2); + // TOF PID + if (track.hasTOF()) { + if (std::abs(track.tofNSigmaPi()) < pidnSigmaPreSelectionCut) + tofPIDselections &= BIT(0); + if (std::abs(track.tofNSigmaKa()) < pidnSigmaPreSelectionCut) + tofPIDselections &= BIT(1); + if (std::abs(track.tofNSigmaPr()) < pidnSigmaPreSelectionCut) + tofPIDselections &= BIT(2); + } + reso2tracks(resoCollisions.lastIndex(), track.pt(), track.eta(), @@ -123,6 +145,8 @@ struct reso2initializer { track.dcaZ(), track.x(), track.alpha(), + tpcPIDselections, + tofPIDselections, track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), @@ -170,7 +194,7 @@ struct reso2initializer { 0, v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), 0, - v0.x(), 0, 0, 0, 0, 0, 0, 0, + v0.x(), 0, 0, 0, 0, 0, 0, 0, 0, 0, v0.dcaV0daughters(), v0.mLambda(), v0.mAntiLambda(), v0.v0radius(), v0.x(), v0.y(), v0.z()); } From ebd42a5840055d2a88ce7978349b2664c171a603 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 01:07:39 +0200 Subject: [PATCH 03/22] add cmake list --- PWGLF/TableProducer/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index e38a61a70ae..dbc232e0f27 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -35,11 +35,11 @@ o2physics_add_dpl_workflow(nucleustreecreator COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(reso2initializer - SOURCES LFResonanceCandidateProducer.cxx + SOURCES LFResonanceInitializer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(reso2trktrkbuilder - SOURCES LFResonanceCandidateProducer.cxx + SOURCES LFResonanceCandidateProducerTrackTrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file From 8c7825c560dd7ac1384866dfd1fc368f251b2d05 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 01:08:07 +0200 Subject: [PATCH 04/22] remove unused QA histos --- ...LFResonanceCandidateProducerTrackTrack.cxx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx index 72c16e261a3..d3daae324a6 100644 --- a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx +++ b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx @@ -40,18 +40,14 @@ using namespace o2::soa; /// Reconstruction of track-track decay resonance candidates struct reso2trktrkbuilder { Produces reso2trktrkdata; - - HistogramRegistry registry{ - "registry", - { - {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, - {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, - }, - OutputObjHandlingPolicy::QAObject - }; - + HistogramRegistry qaRegistry{"QAHistos", { + {"hReso2trktrckEvents", "hReso2trktrckEvents", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, + {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, + }, + OutputObjHandlingPolicy::QAObject}; // Configurables Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam /// Selection criteria @@ -77,8 +73,6 @@ struct reso2trktrkbuilder { && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; void process(aod::ResoCollision& collision, aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) @@ -86,13 +80,14 @@ struct reso2trktrkbuilder { // LOGF(info, "event id: %d", collision.bcId()); auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - + qaRegistry.fill(HIST("hReso2trktrckEvents"), 0.5); + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { - registry.fill(HIST("hReso2trktrckCandidate"), 0.5); + qaRegistry.fill(HIST("hReso2trktrckCandidate"), 0.5); // Un-like sign pair only if (selectUnLikeSignOnly && (trk1.sign() * trk2.sign() > 0)) continue; - registry.fill(HIST("hReso2trktrckCandidate"), 1.5); + qaRegistry.fill(HIST("hReso2trktrckCandidate"), 1.5); reso2trktrkdata( trk1.globalIndex(), trk2.globalIndex(), From c6ee9decf084201a7e6a064a8d860c6d50ff2d31 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 14:02:19 +0200 Subject: [PATCH 05/22] drop the old producers and add phi sample --- PWGLF/DataModel/LFResonanceTables.h | 228 ++---------------- PWGLF/TableProducer/CMakeLists.txt | 5 - ...LFResonanceCandidateProducerTrackTrack.cxx | 115 --------- .../TableProducer/LFResonanceInitializer.cxx | 15 +- PWGLF/Tasks/CMakeLists.txt | 4 +- PWGLF/Tasks/phisample.cxx | 168 +++++++++++++ 6 files changed, 195 insertions(+), 340 deletions(-) delete mode 100644 PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx create mode 100644 PWGLF/Tasks/phisample.cxx diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index ad370d767ad..0b98da0954f 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -60,9 +60,19 @@ static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", enum PDGtype { kPion = BIT(0), kKaon = BIT(1), - kProton = BIT(2) + kProton = BIT(2), + kHasTOF = BIT(6) // Save hasTOF info for TOF selection }; +#define requireTPCPIDCutInFilter(mask) ((aod::resodaughter::tpcPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) +#define requireTOFPIDCutInFilter(mask) (((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::kHasTOF) != (uint8_t)aod::resodaughter::kHasTOF) || (((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) && ((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::kHasTOF) == (uint8_t)aod::resodaughter::kHasTOF))) +#define requireTPCPIDPionCutInFilter() requireTPCPIDCutInFilter(PDGtype::kPion) +#define requireTPCPIDKaonCutInFilter() requireTPCPIDCutInFilter(PDGtype::kKaon) +#define requireTPCPIDProtonCutInFilter() requireTPCPIDCutInFilter(PDGtype::kProton) +#define requireTOFPIDPionCutInFilter() requireTOFPIDCutInFilter(PDGtype::kPion) +#define requireTOFPIDKaonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kKaon) +#define requireTOFPIDProtonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kProton) + DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta @@ -76,8 +86,8 @@ DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z DECLARE_SOA_COLUMN(X, x, float); //! x position of the track DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track -DECLARE_SOA_COLUMN(TPCPIDselection, tpcPIDselection, uint8_t); //! TPC PID selection -DECLARE_SOA_COLUMN(TOFPIDselection, tofPIDselection, uint8_t); //! TOF PID selection +DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection +DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma @@ -128,8 +138,8 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::DcaZ, resodaughter::X, resodaughter::Alpha, - resodaughter::TPCPIDselection, - resodaughter::TOFPIDselection, + resodaughter::TPCPIDselectionFlag, + resodaughter::TOFPIDselectionFlag, resodaughter::TPCnSigmaPi, resodaughter::TPCnSigmaKa, resodaughter::TPCnSigmaPr, @@ -150,214 +160,10 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::P); using ResoDaughter = ResoDaughters::iterator; -/// Reconstruction of track-track decay resonance candidates -/// -namespace reso2trktrkdata -{ -// Needed to have shorter table that does not rely on existing one (filtering!) -DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, Tracks, "_1"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, Tracks, "_2"); //! -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! - -// General two track properties: position, momentum -DECLARE_SOA_COLUMN(Trk1Sign, trk1Sign, int); //! track1 sign -DECLARE_SOA_COLUMN(Trk2Sign, trk2Sign, int); //! track2 sign -DECLARE_SOA_COLUMN(PxTrk1, pxTrk1, float); //! track1 px at min -DECLARE_SOA_COLUMN(PyTrk1, pyTrk1, float); //! track1 py at min -DECLARE_SOA_COLUMN(PzTrk1, pzTrk1, float); //! track1 pz at min -DECLARE_SOA_COLUMN(PxTrk2, pxTrk2, float); //! track2 px at min -DECLARE_SOA_COLUMN(PyTrk2, pyTrk2, float); //! track2 py at min -DECLARE_SOA_COLUMN(PzTrk2, pzTrk2, float); //! track2 pz at min - -// Saved from finding: DCAs -DECLARE_SOA_COLUMN(DCArTrk1ToPV, dcarTrk1toPV, float); //! DCA track1 to PVr -DECLARE_SOA_COLUMN(DCArTrk2ToPV, dcarTrk2toPV, float); //! DCA track2 to PVr -DECLARE_SOA_COLUMN(DCAzTrk1ToPV, dcazTrk1toPV, float); //! DCA track1 to PVz -DECLARE_SOA_COLUMN(DCAzTrk2ToPV, dcazTrk2toPV, float); //! DCA track2 to PVz - -// Derived expressions -// Momenta -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! resonance pT - [](float pxTrk1, float pyTrk1, float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1 + pxTrk2, pyTrk1 + pyTrk2); }); - -// Psi pair angle: angle between the plane defined by the electron and positron momenta and the xy plane -DECLARE_SOA_DYNAMIC_COLUMN(PsiPair, psiPair, //! psi pair angle - [](float pxTrk1, float pyTrk1, float pzTrk1, float pxTrk2, float pyTrk2, float pzTrk2) { - auto clipToPM1 = [](float x) { return x < -1.f ? -1.f : (x > 1.f ? 1.f : x); }; - float ptot2 = RecoDecay::p2(pxTrk1, pyTrk1, pzTrk1) * RecoDecay::p2(pxTrk2, pyTrk2, pzTrk2); - float argcos = RecoDecay::dotProd(array{pxTrk1, pyTrk1, pzTrk1}, array{pxTrk2, pyTrk2, pzTrk2}) / std::sqrt(ptot2); - float thetaPos = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1), pzTrk1); - float thetaNeg = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2), pzTrk2); - float argsin = (thetaNeg - thetaPos) / std::acos(clipToPM1(argcos)); - return std::asin(clipToPM1(argsin)); - }); - -DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Resonance eta - [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Resonance phi - [](float Px, float Py) -> float { return RecoDecay::phi(Px, Py); }); - -DECLARE_SOA_DYNAMIC_COLUMN(Track2Pt, track2Pt, //! Track2 daughter pT - [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Pt, track1Pt, //! Track1 daughter pT - [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Eta, track2Eta, //! Track2 daughter eta - [](float pxTrk2, float pyTrk2, float pzTrk2) -> float { return RecoDecay::eta(array{pxTrk2, pyTrk2, pzTrk2}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Phi, track2Phi, //! Track2 daughter phi - [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::phi(pxTrk2, pyTrk2); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Eta, track1Eta, //! Track1 daughter eta - [](float pxTrk1, float pyTrk1, float pzTrk1) -> float { return RecoDecay::eta(array{pxTrk1, pyTrk1, pzTrk1}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Phi, track1Phi, //! Track1 daughter phi - [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::phi(pxTrk1, pyTrk1); }); - -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! Resonance px - float, 1.f * aod::reso2trktrkdata::pxTrk1 + 1.f * aod::reso2trktrkdata::pxTrk2); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! Resonance py - float, 1.f * aod::reso2trktrkdata::pyTrk1 + 1.f * aod::reso2trktrkdata::pyTrk2); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! Resonance pz - float, 1.f * aod::reso2trktrkdata::pzTrk1 + 1.f * aod::reso2trktrkdata::pzTrk2); -} // namespace reso2trktrkdata - -DECLARE_SOA_TABLE_FULL(StoredReso2TrackTrackDatas, "Reso2TrackTrackDatas", "AOD", "Reso2TTDATA", //! - o2::soa::Index<>, reso2trktrkdata::Track1Id, reso2trktrkdata::Track2Id, reso2trktrkdata::CollisionId, - reso2trktrkdata::Trk1Sign, reso2trktrkdata::Trk2Sign, - reso2trktrkdata::PxTrk1, reso2trktrkdata::PyTrk1, reso2trktrkdata::PzTrk1, - reso2trktrkdata::PxTrk2, reso2trktrkdata::PyTrk2, reso2trktrkdata::PzTrk2, - - // Topological selections - reso2trktrkdata::DCArTrk1ToPV, reso2trktrkdata::DCArTrk2ToPV, - reso2trktrkdata::DCAzTrk1ToPV, reso2trktrkdata::DCAzTrk2ToPV, - - // Dynamic columns - reso2trktrkdata::Pt, - reso2trktrkdata::PsiPair, - - // Longitudinal - reso2trktrkdata::Eta, - reso2trktrkdata::Phi, - reso2trktrkdata::Track2Pt, - reso2trktrkdata::Track1Pt, - reso2trktrkdata::Track2Eta, - reso2trktrkdata::Track2Phi, - reso2trktrkdata::Track1Eta, - reso2trktrkdata::Track1Phi); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackTrackDatas, StoredReso2TrackTrackDatas, "Reso2TTDATAEXT", //! - reso2trktrkdata::Px, reso2trktrkdata::Py, reso2trktrkdata::Pz); // the table name has here to be the one with EXT which is not nice and under study - -using Reso2TrackTrackData = Reso2TrackTrackDatas::iterator; - -using Reso2TracksExt = soa::Join; +using Reso2TracksExt = soa::Join; using Reso2TracksMC = soa::Join; using Reso2TracksPID = soa::Join; -using Reso2TracksPIDExt = soa::Join; - -/// Reconstruction of track-v0 decay resonance candidates -/// -namespace reso2trkv0data -{ -// Needed to have shorter table that does not rely on existing one (filtering!) -DECLARE_SOA_INDEX_COLUMN_FULL(Track, track, int, Tracks, "_track"); //! -DECLARE_SOA_INDEX_COLUMN(V0, v0); //! -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! - -// General V0, track properties: position, momentum -DECLARE_SOA_COLUMN(Sign, sign, int); //! -DECLARE_SOA_COLUMN(PxPos, pxpos, float); //! -DECLARE_SOA_COLUMN(PyPos, pypos, float); //! -DECLARE_SOA_COLUMN(PzPos, pzpos, float); //! -DECLARE_SOA_COLUMN(PxNeg, pxneg, float); //! -DECLARE_SOA_COLUMN(PyNeg, pyneg, float); //! -DECLARE_SOA_COLUMN(PzNeg, pzneg, float); //! -DECLARE_SOA_COLUMN(PxTrack, pxtrack, float); //! -DECLARE_SOA_COLUMN(PyTrack, pytrack, float); //! -DECLARE_SOA_COLUMN(PzTrack, pztrack, float); //! -DECLARE_SOA_COLUMN(XV0, xV0, float); //! -DECLARE_SOA_COLUMN(YV0, yV0, float); //! -DECLARE_SOA_COLUMN(ZV0, zV0, float); //! - -// Saved from finding: DCAs -DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! -DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! -DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! -DECLARE_SOA_COLUMN(DCATrackToPV, dcatracktopv, float); //! - -// Derived expressions -// Momenta -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! - [](float Px, float Py) -> float { return RecoDecay::sqrtSumOfSquares(Px, Py); }); - -// Length quantities -DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, //! - [](float xV0, float yV0) -> float { return RecoDecay::sqrtSumOfSquares(xV0, yV0); }); - -// CosPAs -DECLARE_SOA_DYNAMIC_COLUMN(V0CosPA, v0cosPA, //! - [](float XV0, float YV0, float ZV0, float PxV0, float PyV0, float PzV0, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(array{pvX, pvY, pvZ}, array{XV0, YV0, ZV0}, array{PxV0, PyV0, PzV0}); }); -DECLARE_SOA_DYNAMIC_COLUMN(DCAV0ToPV, dcav0topv, //! - [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { 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)); }); - -// Calculated on the fly with mass assumption + dynamic tables -DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! mass under lambda hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kProton), RecoDecay::getMassPDG(kPiPlus)}); }); -DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda, mAntiLambda, //! mass under antilambda hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kProton)}); }); -DECLARE_SOA_DYNAMIC_COLUMN(MK0Short, mK0Short, //! mass under K0short hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kPiPlus)}); }); - -DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! - [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); - -DECLARE_SOA_EXPRESSION_COLUMN(PxV0, pxV0, //! - float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg); -DECLARE_SOA_EXPRESSION_COLUMN(PyV0, pyV0, //! - float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg); -DECLARE_SOA_EXPRESSION_COLUMN(PzV0, pzV0, //! - float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg); -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! - float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg + 1.f * aod::reso2trkv0data::pxtrack); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! - float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg + 1.f * aod::reso2trkv0data::pytrack); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! - float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg + 1.f * aod::reso2trkv0data::pztrack); -} // namespace reso2trkv0data - -DECLARE_SOA_TABLE(Reso2TrackV0Data, "AOD", "Reso2TVDATA", //! - o2::soa::Index<>, reso2trkv0data::TrackId, reso2trkv0data::V0Id, reso2trkv0data::CollisionId, - - // General V0, track properties: position, momentum - reso2trkv0data::Sign, - reso2trkv0data::PxPos, reso2trkv0data::PyPos, reso2trkv0data::PzPos, - reso2trkv0data::PxNeg, reso2trkv0data::PyNeg, reso2trkv0data::PzNeg, - reso2trkv0data::PxTrack, reso2trkv0data::PyTrack, reso2trkv0data::PzTrack, - reso2trkv0data::XV0, reso2trkv0data::YV0, reso2trkv0data::ZV0, - - // Saved from finding: DCAs - reso2trkv0data::DCAV0Daughters, - reso2trkv0data::DCAPosToPV, reso2trkv0data::DCANegToPV, reso2trkv0data::DCATrackToPV, - - // Dynamic columns - reso2trkv0data::Pt, - reso2trkv0data::V0Radius, - reso2trkv0data::V0CosPA, - reso2trkv0data::DCAV0ToPV, - - // V0 Invariant masses - reso2trkv0data::MLambda, - reso2trkv0data::MAntiLambda, - reso2trkv0data::MK0Short, - - reso2trkv0data::Eta); - -using Reso2TrackV0DataOrigin = Reso2TrackV0Data; - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackV0DataExt, Reso2TrackV0DataOrigin, "Reso2TVDATAEXT", //! - reso2trkv0data::PxV0, reso2trkv0data::PyV0, reso2trkv0data::PzV0, - reso2trkv0data::Px, reso2trkv0data::Py, reso2trkv0data::Pz); // the table name has here to be the one with EXT which is not nice and under study - -using Reso2TrackV0DataFull = Reso2TrackV0DataExt; +using Reso2TracksPIDExt = soa::Join; } // namespace o2::aod #endif // O2_ANALYSIS_LFRESONANCETABLES_H_ \ No newline at end of file diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index dbc232e0f27..4bdf6b1d5a6 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -37,9 +37,4 @@ o2physics_add_dpl_workflow(nucleustreecreator o2physics_add_dpl_workflow(reso2initializer SOURCES LFResonanceInitializer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(reso2trktrkbuilder - SOURCES LFResonanceCandidateProducerTrackTrack.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx deleted file mode 100644 index d3daae324a6..00000000000 --- a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx +++ /dev/null @@ -1,115 +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. - -/// \file LFResonanceCandidateProducerTrackTrack.cxx -/// \brief Reconstruction of track-track decay resonance candidates -/// -/// Inspired by lambdakzerofinder.cxx, -/// -/// \author Bong-Hwi Lim - -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectorPID.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/StrangenessTables.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "PWGLF/Utils/collisionCuts.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::soa; - -/// Reconstruction of track-track decay resonance candidates -struct reso2trktrkbuilder { - Produces reso2trktrkdata; - HistogramRegistry qaRegistry{"QAHistos", { - {"hReso2trktrckEvents", "hReso2trktrckEvents", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, - {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, - }, - OutputObjHandlingPolicy::QAObject}; - // Configurables - Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam - /// Selection criteria - Configurable selectUnLikeSignOnly{"selectUnLikeSignOnly", 1, "Select only unlike sign pair for resonance"}; - - // Pre-selection cuts - Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; - Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; - - /// DCA Selections - // DCAr to PV - Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1, "Track DCAr cut to PV Maximum"}; - // DCAz to PV - Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 5.0, "Track DCAz cut to PV Maximum"}; - Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; - - /// Partition for firstTrack - Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) - && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) - && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - - void process(aod::ResoCollision& collision, - aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) - { - // LOGF(info, "event id: %d", collision.bcId()); - auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - qaRegistry.fill(HIST("hReso2trktrckEvents"), 0.5); - - for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { - qaRegistry.fill(HIST("hReso2trktrckCandidate"), 0.5); - // Un-like sign pair only - if (selectUnLikeSignOnly && (trk1.sign() * trk2.sign() > 0)) - continue; - qaRegistry.fill(HIST("hReso2trktrckCandidate"), 1.5); - reso2trktrkdata( - trk1.globalIndex(), - trk2.globalIndex(), - trk1.resoCollisionId(), - trk1.sign(), trk2.sign(), - trk1.px(), trk1.py(), trk1.pz(), - trk2.px(), trk2.py(), trk2.pz(), - trk1.dcaXY(), trk2.dcaXY(), - trk1.dcaZ(), trk2.dcaZ()); - } - } -}; - -/// Extends the v0data table with expression columns -struct reso2trktrkinitializer { - Spawns reso2tracktrackdatas; - void init(InitContext const&) {} -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkbuilder"}), - adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkinitializer"})}; -} \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 3249449335d..5839202655d 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -80,7 +80,7 @@ struct reso2initializer { OutputObjHandlingPolicy::QAObject}; // Pre-filters for efficient process - Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF + // Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts @@ -117,19 +117,20 @@ struct reso2initializer { uint8_t tofPIDselections = 0; // TPC PID if (std::abs(track.tpcNSigmaPi()) < pidnSigmaPreSelectionCut) - tpcPIDselections &= BIT(0); + tpcPIDselections |= aod::resodaughter::PDGtype::kPion; if (std::abs(track.tpcNSigmaKa()) < pidnSigmaPreSelectionCut) - tpcPIDselections &= BIT(1); + tpcPIDselections |= aod::resodaughter::PDGtype::kKaon; if (std::abs(track.tpcNSigmaPr()) < pidnSigmaPreSelectionCut) - tpcPIDselections &= BIT(2); + tpcPIDselections |= aod::resodaughter::PDGtype::kProton; // TOF PID if (track.hasTOF()) { + tofPIDselections |= aod::resodaughter::PDGtype::kHasTOF; if (std::abs(track.tofNSigmaPi()) < pidnSigmaPreSelectionCut) - tofPIDselections &= BIT(0); + tofPIDselections |= aod::resodaughter::PDGtype::kPion; if (std::abs(track.tofNSigmaKa()) < pidnSigmaPreSelectionCut) - tofPIDselections &= BIT(1); + tofPIDselections |= aod::resodaughter::PDGtype::kKaon; if (std::abs(track.tofNSigmaPr()) < pidnSigmaPreSelectionCut) - tofPIDselections &= BIT(2); + tofPIDselections |= aod::resodaughter::PDGtype::kProton; } reso2tracks(resoCollisions.lastIndex(), diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 204a2ef8ef8..8d319ae25d5 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -99,7 +99,7 @@ o2physics_add_dpl_workflow(rsnanalysis PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(k892sample - SOURCES k892sample.cxx +o2physics_add_dpl_workflow(phisample + SOURCES phisample.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/Tasks/phisample.cxx b/PWGLF/Tasks/phisample.cxx new file mode 100644 index 00000000000..8e00d3690f8 --- /dev/null +++ b/PWGLF/Tasks/phisample.cxx @@ -0,0 +1,168 @@ +// 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 phisample.cxx +/// \brief Reconstruction of track-track decay resonance candidates +/// +/// +/// \author Bong-Hwi Lim + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include +#include "DataFormatsParameters/GRPObject.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct phisample { + framework::Service ccdb; /// Accessing the CCDB + ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + // Configurables + + // Pre-selection cuts + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + + /// DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 5.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + /// Partition for firstTrack + Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && requireTPCPIDKaonCutInFilter() + && requireTOFPIDKaonCutInFilter() + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && requireTPCPIDKaonCutInFilter() + && requireTOFPIDKaonCutInFilter() + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + void init(o2::framework::InitContext&) + { + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + AxisSpec vtxZAxis = {100, -20, 20}; + + std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; + AxisSpec centAxis = {centBinning, "V0M (%)"}; + std::vector ptBinning = {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., 5., 10., 20.}; + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + + // Mass QA (quick check) + histos.add("phiinvmass", "Invariant mass of Phi", kTH1F, {{500, 0.8, 1.3, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("phiinvmassME", "Invariant mass of Phi mixed event", kTH1F, {{500, 0.8, 1.3, "Invariant Mass (GeV/#it{c}^2)"}}); + + // 3d histogram + histos.add("h3phiinvmass", "Invariant mass of Phi", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); + } + + double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); + + void process(aod::ResoCollision& collision, + aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) + { + // LOGF(info, "event id: %d", collision.bcId()); + auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { + // Un-like sign pair only + if (trk1.sign() * trk2.sign() > 0) + continue; + + auto arrMom = array{ + array{trk1.px(), trk1.py(), trk1.pz()}, + array{trk2.px(), trk2.py(), trk2.pz()}}; + auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); + auto arrMass = array{massKa, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + histos.fill(HIST("phiinvmass"), mass); + histos.fill(HIST("h3phiinvmass"), collision.multV0M(), resoPt, mass); + } + } + + // Processing Event Mixing + void processME(o2::aod::ResoCollisions& collision, + o2::aod::BCsWithTimestamps const&, aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) + { + BinningPolicy colBinning{{CfgVtxBins, CfgMultBins}, true}; + + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, collision, collision)) { + + auto magFieldTesla1 = 0.0; + static o2::parameters::GRPObject* grpo1 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision1.timestamp()); + if (!grpo1) { + magFieldTesla1 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision1.timestamp(), grpo1->getNominalL3Field()); + magFieldTesla1 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto magFieldTesla2 = 0.0; + static o2::parameters::GRPObject* grpo2 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision2.timestamp()); + if (!grpo2) { + magFieldTesla2 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision2.timestamp(), grpo2->getNominalL3Field()); + magFieldTesla2 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision1.globalIndex()); + auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision2.globalIndex()); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { + if (trk1.sign() * trk2.sign() > 0) + continue; + + auto arrMom = array{ + array{trk1.px(), trk1.py(), trk1.pz()}, + array{trk2.px(), trk2.py(), trk2.pz()}}; + auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); + auto arrMass = array{massKa, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + histos.fill(HIST("phiinvmass"), mass); + histos.fill(HIST("h3phiinvmass"), collision1.multV0M(), resoPt, mass); + } + } + }; + PROCESS_SWITCH(phisample, processME, "Process EventMixing", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"lf-phisample"})}; +} \ No newline at end of file From a45d6841ab4277e76a9f6bfd50245ef5a87d5c6c Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 14:20:18 +0200 Subject: [PATCH 06/22] remove k892 sample and update phi sample --- PWGLF/Tasks/k892sample.cxx | 173 ------------------------------------- PWGLF/Tasks/phisample.cxx | 24 ++--- 2 files changed, 13 insertions(+), 184 deletions(-) delete mode 100644 PWGLF/Tasks/k892sample.cxx diff --git a/PWGLF/Tasks/k892sample.cxx b/PWGLF/Tasks/k892sample.cxx deleted file mode 100644 index 2d742bd825d..00000000000 --- a/PWGLF/Tasks/k892sample.cxx +++ /dev/null @@ -1,173 +0,0 @@ -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelectorPID.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include -#include "DataFormatsParameters/GRPObject.h" -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::soa; - -struct k892sample { - HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; - ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; - framework::Service ccdb; /// Accessing the CCDB - - - void init(o2::framework::InitContext&) - { - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - ccdb->setCreatedNotAfter(now); - - AxisSpec vtxZAxis = {100, -20, 20}; - - std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; - AxisSpec centAxis = {centBinning, "V0M (%)"}; - std::vector ptBinning = {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., 5., 10., 20.}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - - histos.add("EventQA/Centrality", "Centrality distribution (V0M)", kTH1F, {centAxis}); - histos.add("EventQA/VtxZBeforeSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); - histos.add("EventQA/VtxZAfterSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); - // Mass QA (quick check) - histos.add("k892invmass", "Invariant mass of K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - histos.add("antik892invmass", "Invariant mass of Anti-K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - histos.add("k892invmassME", "Invariant mass of K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - histos.add("antik892invmassME", "Invariant mass of Anti-K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - - // 3d histogram - histos.add("h3k892invmass", "Invariant mass of K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); - histos.add("h3antik892invmass", "Invariant mass of Anti-K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); - } - - double massPi = TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(); - double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); - - void process(o2::aod::ResoCollision& inputCollision, - aod::Reso2TrackTrackDatas const& reso2trktrk, aod::Reso2TracksPIDExt const& track) - { - - histos.fill(HIST("EventQA/VtxZAfterSel"), inputCollision.posZ()); - - // fill centrality histos - histos.fill(HIST("EventQA/Centrality"), inputCollision.multV0M()); - - for (auto reso2 : reso2trktrk) { - auto trackPos = (reso2.trk1Sign() > 0) ? reso2.track1_as() : reso2.track2_as(); // positive daughter - auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter - bool isK892 = false; - bool isAntiK892 = false; - - // PID cuts - if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ - isK892 = true; - if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) - isAntiK892 = true; - if (!isK892 && !isAntiK892) - continue; - - // TOF PID cut (if available) - if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) - continue; - if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) - continue; - - auto arrMom = array{ - array{reso2.pxTrk1(), reso2.pyTrk1(), reso2.pzTrk1()}, - array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; - auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; - auto mass = RecoDecay::m(arrMom, arrMass); - if (isK892) { - histos.fill(HIST("k892invmass"), mass); - histos.fill(HIST("h3k892invmass"), inputCollision.multV0M(), reso2.pt(), mass); - } - if (isAntiK892) { // Anti-matter - histos.fill(HIST("antik892invmass"), mass); - histos.fill(HIST("h3antik892invmass"), inputCollision.multV0M(), reso2.pt(), mass); - } - } - } - // Processing Event Mixing - void processME(o2::aod::ResoCollisions& inputCollision, - o2::aod::BCsWithTimestamps const&, aod::Reso2TrackTrackDatas & reso2trktrk, aod::Reso2TracksPIDExt const& track) - { - BinningPolicy colBinning{{CfgVtxBins, CfgMultBins}, true}; - - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, inputCollision, inputCollision)) { - - auto magFieldTesla1 = 0.0; - static o2::parameters::GRPObject* grpo1 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision1.timestamp()); - if (!grpo1) { - magFieldTesla1 = 0; - } else { - // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision1.timestamp(), grpo1->getNominalL3Field()); - magFieldTesla1 = 0.1 * (grpo1->getNominalL3Field()); - } - - auto magFieldTesla2 = 0.0; - static o2::parameters::GRPObject* grpo2 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision2.timestamp()); - if (!grpo2) { - magFieldTesla2 = 0; - } else { - // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision2.timestamp(), grpo2->getNominalL3Field()); - magFieldTesla2 = 0.1 * (grpo1->getNominalL3Field()); - } - - auto reso2trktrkPartOne = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision1.globalIndex()); - auto reso2trktrkPartTwo = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision2.globalIndex()); - - if (magFieldTesla1 != magFieldTesla2) { - continue; - } - for (auto& [reso1, reso2] : combinations(CombinationsStrictlyUpperIndexPolicy(reso2trktrkPartOne, reso2trktrkPartTwo))) { - auto trackPos = (reso1.trk1Sign() > 0) ? reso1.track1_as() : reso1.track2_as(); // positive daughter - auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter - bool isK892 = false; - bool isAntiK892 = false; - - // PID cuts - if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ - isK892 = true; - if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) - isAntiK892 = true; - if (!isK892 && !isAntiK892) - continue; - - // TOF PID cut (if available) - if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) - continue; - if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) - continue; - - auto arrMom = array{ - array{reso1.pxTrk1(), reso1.pyTrk1(), reso1.pzTrk1()}, - array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; - auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; - auto mass = RecoDecay::m(arrMom, arrMass); - if (isK892) { - histos.fill(HIST("k892invmassME"), mass); - } - if (isAntiK892) { // Anti-matter - histos.fill(HIST("antik892invmassME"), mass); - } - } - } - }; - PROCESS_SWITCH(k892sample, processME, "Process EventMixing", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} \ No newline at end of file diff --git a/PWGLF/Tasks/phisample.cxx b/PWGLF/Tasks/phisample.cxx index 8e00d3690f8..7d8ac928cec 100644 --- a/PWGLF/Tasks/phisample.cxx +++ b/PWGLF/Tasks/phisample.cxx @@ -85,6 +85,7 @@ struct phisample { // 3d histogram histos.add("h3phiinvmass", "Invariant mass of Phi", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); + histos.add("h3phiinvmassME", "Invariant mass of Phi mixed event", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); } double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); @@ -145,17 +146,18 @@ struct phisample { continue; } for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { - if (trk1.sign() * trk2.sign() > 0) - continue; - - auto arrMom = array{ - array{trk1.px(), trk1.py(), trk1.pz()}, - array{trk2.px(), trk2.py(), trk2.pz()}}; - auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); - auto arrMass = array{massKa, massKa}; - auto mass = RecoDecay::m(arrMom, arrMass); - histos.fill(HIST("phiinvmass"), mass); - histos.fill(HIST("h3phiinvmass"), collision1.multV0M(), resoPt, mass); + // Un-like sign pair only + if (trk1.sign() * trk2.sign() > 0) + continue; + + auto arrMom = array{ + array{trk1.px(), trk1.py(), trk1.pz()}, + array{trk2.px(), trk2.py(), trk2.pz()}}; + auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); + auto arrMass = array{massKa, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + histos.fill(HIST("phiinvmassME"), mass); + histos.fill(HIST("h3phiinvmassME"), collision1.multV0M(), resoPt, mass); } } }; From 8626386763633adf0cd5059995b19f14baecf9d3 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 15:55:34 +0200 Subject: [PATCH 07/22] remove the dynamic columns --- PWGLF/DataModel/LFResonanceTables.h | 98 ++++++++----------- .../TableProducer/LFResonanceInitializer.cxx | 6 ++ 2 files changed, 46 insertions(+), 58 deletions(-) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 0b98da0954f..4f73a04a17b 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -58,10 +58,10 @@ enum DaughterType { static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", "V0", "Cascade"}; //! Naming of the different particle types enum PDGtype { - kPion = BIT(0), - kKaon = BIT(1), - kProton = BIT(2), - kHasTOF = BIT(6) // Save hasTOF info for TOF selection + kPion = BIT(0), + kKaon = BIT(1), + kProton = BIT(2), + kHasTOF = BIT(6) // Save hasTOF info for TOF selection }; #define requireTPCPIDCutInFilter(mask) ((aod::resodaughter::tpcPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) @@ -74,59 +74,46 @@ enum PDGtype { #define requireTOFPIDProtonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kProton) DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); -DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) -DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta -DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi -DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType -DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) -DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations -DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge -DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows -DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy -DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z -DECLARE_SOA_COLUMN(X, x, float); //! x position of the track -DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track -DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection -DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection -DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma -DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma -DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma -DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma -DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma -DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma -DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters -DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda -DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda -DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex -DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex -DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex -DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex - -DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, //! Compute the theta of the track - [](float eta) -> float { - return 2.f * std::atan(std::exp(-eta)); - }); -DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Compute the momentum in x in GeV/c - [](float pt, float phi) -> float { - return pt * std::sin(phi); - }); -DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Compute the momentum in y in GeV/c - [](float pt, float phi) -> float { - return pt * std::cos(phi); - }); -DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Compute the momentum in z in GeV/c - [](float pt, float eta) -> float { - return pt * std::sinh(eta); - }); -DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Compute the overall momentum in GeV/c - [](float pt, float eta) -> float { - return pt * std::cosh(eta); - }); +DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) +DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c) +DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c) +DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! p (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi +DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType +DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) +DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge +DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy +DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z +DECLARE_SOA_COLUMN(X, x, float); //! x position of the track +DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track +DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection +DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection +DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma +DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters +DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda +DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda +DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex } // namespace resodaughter DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", o2::soa::Index<>, resodaughter::ResoCollisionId, resodaughter::Pt, + resodaughter::Px, + resodaughter::Py, + resodaughter::Pz, + resodaughter::P, resodaughter::Eta, resodaughter::Phi, resodaughter::PartType, @@ -152,12 +139,7 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::TransRadius, resodaughter::DecayVtxX, resodaughter::DecayVtxY, - resodaughter::DecayVtxZ, - resodaughter::Theta, - resodaughter::Px, - resodaughter::Py, - resodaughter::Pz, - resodaughter::P); + resodaughter::DecayVtxZ); using ResoDaughter = ResoDaughters::iterator; using Reso2TracksExt = soa::Join; diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 5839202655d..48082bfcb8f 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -135,6 +135,9 @@ struct reso2initializer { reso2tracks(resoCollisions.lastIndex(), track.pt(), + track.px(), + track.py(), + track.pz(), track.eta(), track.phi(), aod::resodaughter::DaughterType::kTrack, @@ -186,6 +189,9 @@ struct reso2initializer { childIDs[1] = v0.negTrackId(); reso2tracks(resoCollisions.lastIndex(), v0.pt(), + v0.px(), + v0.py(), + v0.pz(), v0.eta(), v0.phi(), aod::resodaughter::DaughterType::kV0, From 79fd9b8e3736414ef8590afaf47f9292cf2a51db Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 16:02:07 +0200 Subject: [PATCH 08/22] fix error --- PWGLF/TableProducer/LFResonanceInitializer.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 48082bfcb8f..13f32346072 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -138,6 +138,7 @@ struct reso2initializer { track.px(), track.py(), track.pz(), + track.p(), track.eta(), track.phi(), aod::resodaughter::DaughterType::kTrack, @@ -192,6 +193,7 @@ struct reso2initializer { v0.px(), v0.py(), v0.pz(), + RecoDecay::sqrtSumOfSquares(v0.px(), v0.py(), v0.pz()), v0.eta(), v0.phi(), aod::resodaughter::DaughterType::kV0, From 29480509ed090799ddf7b11084e964fc42f2b124 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 16:24:12 +0200 Subject: [PATCH 09/22] remove unused variables --- PWGLF/DataModel/LFResonanceTables.h | 2 -- PWGLF/TableProducer/LFResonanceInitializer.cxx | 2 -- 2 files changed, 4 deletions(-) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 4f73a04a17b..b5de7306108 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -78,7 +78,6 @@ DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T ( DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c) DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c) DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c) -DECLARE_SOA_COLUMN(P, p, float); //! p (GeV/c) DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType @@ -113,7 +112,6 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::Px, resodaughter::Py, resodaughter::Pz, - resodaughter::P, resodaughter::Eta, resodaughter::Phi, resodaughter::PartType, diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 13f32346072..48082bfcb8f 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -138,7 +138,6 @@ struct reso2initializer { track.px(), track.py(), track.pz(), - track.p(), track.eta(), track.phi(), aod::resodaughter::DaughterType::kTrack, @@ -193,7 +192,6 @@ struct reso2initializer { v0.px(), v0.py(), v0.pz(), - RecoDecay::sqrtSumOfSquares(v0.px(), v0.py(), v0.pz()), v0.eta(), v0.phi(), aod::resodaughter::DaughterType::kV0, From 2ba0bde53237b61d9bca445d95a40952bdfdae42 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Sat, 16 Jul 2022 11:18:27 +0200 Subject: [PATCH 10/22] Update version of Resonance Package --- PWGLF/DataModel/LFResonanceTables.h | 359 ++++++++++++++++++ PWGLF/TableProducer/CMakeLists.txt | 10 + .../LFResonanceCandidateProducer.cxx | 186 +++++++++ ...LFResonanceCandidateProducerTrackTrack.cxx | 120 ++++++ PWGLF/Tasks/CMakeLists.txt | 5 + PWGLF/Tasks/k892sample.cxx | 173 +++++++++ PWGLF/Utils/collisionCuts.h | 135 +++++++ 7 files changed, 988 insertions(+) create mode 100644 PWGLF/DataModel/LFResonanceTables.h create mode 100644 PWGLF/TableProducer/LFResonanceCandidateProducer.cxx create mode 100644 PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx create mode 100644 PWGLF/Tasks/k892sample.cxx create mode 100644 PWGLF/Utils/collisionCuts.h diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h new file mode 100644 index 00000000000..625796b7ab4 --- /dev/null +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -0,0 +1,359 @@ +// 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 LFResonanceTables.h +/// \brief Definitions of tables of resonance decay candidates +/// +/// Inspired by StrangenessTables.h, FemtoDerived.h +/// +/// \author Bong-Hwi Lim + +#ifndef O2_ANALYSIS_LFRESONANCETABLES_H_ +#define O2_ANALYSIS_LFRESONANCETABLES_H_ + +#include + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +/// Resonance Collisions +namespace resocollision +{ +DECLARE_SOA_COLUMN(MultV0M, multV0M, float); //! V0M multiplicity +DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event +} // namespace resocollision +DECLARE_SOA_TABLE(ResoCollisions, "AOD", "RESOCOL", + o2::soa::Index<>, + o2::aod::collision::PosX, + o2::aod::collision::PosY, + o2::aod::collision::PosZ, + resocollision::MultV0M, + resocollision::Sphericity, + timestamp::Timestamp); +using ResoCollision = ResoCollisions::iterator; + +// Resonance Daughters +// inspired from PWGCF/DataModel/FemtoDerived.h +namespace resodaughter +{ +/// Distinuishes the different daughter types +enum DaughterType { + kTrack, //! Track + kV0, //! V0 + kCascade, //! Cascade + kNDaughterTypes //! Number of Daughter types +}; +static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", "V0", "Cascade"}; //! Naming of the different particle types + +enum PDGtype { + kPion = BIT(0), + kKaon = BIT(1), + kProton = BIT(2) +}; + +DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); +DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi +DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType +DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) +DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge +DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy +DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z +DECLARE_SOA_COLUMN(X, x, float); //! x position of the track +DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track +DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma +DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters +DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda +DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda +DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex + +DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, //! Compute the theta of the track + [](float eta) -> float { + return 2.f * std::atan(std::exp(-eta)); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Compute the momentum in x in GeV/c + [](float pt, float phi) -> float { + return pt * std::sin(phi); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Compute the momentum in y in GeV/c + [](float pt, float phi) -> float { + return pt * std::cos(phi); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Compute the momentum in z in GeV/c + [](float pt, float eta) -> float { + return pt * std::sinh(eta); + }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Compute the overall momentum in GeV/c + [](float pt, float eta) -> float { + return pt * std::cosh(eta); + }); +} // namespace resodaughter +DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", + o2::soa::Index<>, + resodaughter::ResoCollisionId, + resodaughter::Pt, + resodaughter::Eta, + resodaughter::Phi, + resodaughter::PartType, + resodaughter::TempFitVar, + resodaughter::Indices, + resodaughter::Sign, + resodaughter::TPCNClsCrossedRows, + resodaughter::DcaXY, + resodaughter::DcaZ, + resodaughter::X, + resodaughter::Alpha, + resodaughter::TPCnSigmaPi, + resodaughter::TPCnSigmaKa, + resodaughter::TPCnSigmaPr, + resodaughter::TOFnSigmaPi, + resodaughter::TOFnSigmaKa, + resodaughter::TOFnSigmaPr, + resodaughter::DaughDCA, + resodaughter::MLambda, + resodaughter::MAntiLambda, + resodaughter::TransRadius, + resodaughter::DecayVtxX, + resodaughter::DecayVtxY, + resodaughter::DecayVtxZ, + resodaughter::Theta, + resodaughter::Px, + resodaughter::Py, + resodaughter::Pz, + resodaughter::P); +using ResoDaughter = ResoDaughters::iterator; + +/// Reconstruction of track-track decay resonance candidates +/// +namespace reso2trktrkdata +{ +// Needed to have shorter table that does not rely on existing one (filtering!) +DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, Tracks, "_1"); //! +DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, Tracks, "_2"); //! +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! + +// General two track properties: position, momentum +DECLARE_SOA_COLUMN(Trk1Sign, trk1Sign, int); //! track1 sign +DECLARE_SOA_COLUMN(Trk2Sign, trk2Sign, int); //! track2 sign +DECLARE_SOA_COLUMN(PxTrk1, pxTrk1, float); //! track1 px at min +DECLARE_SOA_COLUMN(PyTrk1, pyTrk1, float); //! track1 py at min +DECLARE_SOA_COLUMN(PzTrk1, pzTrk1, float); //! track1 pz at min +DECLARE_SOA_COLUMN(PxTrk2, pxTrk2, float); //! track2 px at min +DECLARE_SOA_COLUMN(PyTrk2, pyTrk2, float); //! track2 py at min +DECLARE_SOA_COLUMN(PzTrk2, pzTrk2, float); //! track2 pz at min + +// Saved from finding: DCAs +DECLARE_SOA_COLUMN(DCArTrk1ToPV, dcarTrk1toPV, float); //! DCA track1 to PVr +DECLARE_SOA_COLUMN(DCArTrk2ToPV, dcarTrk2toPV, float); //! DCA track2 to PVr +DECLARE_SOA_COLUMN(DCAzTrk1ToPV, dcazTrk1toPV, float); //! DCA track1 to PVz +DECLARE_SOA_COLUMN(DCAzTrk2ToPV, dcazTrk2toPV, float); //! DCA track2 to PVz + +// Derived expressions +// Momenta +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! resonance pT + [](float pxTrk1, float pyTrk1, float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1 + pxTrk2, pyTrk1 + pyTrk2); }); + +// Psi pair angle: angle between the plane defined by the electron and positron momenta and the xy plane +DECLARE_SOA_DYNAMIC_COLUMN(PsiPair, psiPair, //! psi pair angle + [](float pxTrk1, float pyTrk1, float pzTrk1, float pxTrk2, float pyTrk2, float pzTrk2) { + auto clipToPM1 = [](float x) { return x < -1.f ? -1.f : (x > 1.f ? 1.f : x); }; + float ptot2 = RecoDecay::p2(pxTrk1, pyTrk1, pzTrk1) * RecoDecay::p2(pxTrk2, pyTrk2, pzTrk2); + float argcos = RecoDecay::dotProd(array{pxTrk1, pyTrk1, pzTrk1}, array{pxTrk2, pyTrk2, pzTrk2}) / std::sqrt(ptot2); + float thetaPos = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1), pzTrk1); + float thetaNeg = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2), pzTrk2); + float argsin = (thetaNeg - thetaPos) / std::acos(clipToPM1(argcos)); + return std::asin(clipToPM1(argsin)); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Resonance eta + [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Resonance phi + [](float Px, float Py) -> float { return RecoDecay::phi(Px, Py); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Track2Pt, track2Pt, //! Track2 daughter pT + [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track1Pt, track1Pt, //! Track1 daughter pT + [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track2Eta, track2Eta, //! Track2 daughter eta + [](float pxTrk2, float pyTrk2, float pzTrk2) -> float { return RecoDecay::eta(array{pxTrk2, pyTrk2, pzTrk2}); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track2Phi, track2Phi, //! Track2 daughter phi + [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::phi(pxTrk2, pyTrk2); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track1Eta, track1Eta, //! Track1 daughter eta + [](float pxTrk1, float pyTrk1, float pzTrk1) -> float { return RecoDecay::eta(array{pxTrk1, pyTrk1, pzTrk1}); }); +DECLARE_SOA_DYNAMIC_COLUMN(Track1Phi, track1Phi, //! Track1 daughter phi + [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::phi(pxTrk1, pyTrk1); }); + +DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! Resonance px + float, 1.f * aod::reso2trktrkdata::pxTrk1 + 1.f * aod::reso2trktrkdata::pxTrk2); +DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! Resonance py + float, 1.f * aod::reso2trktrkdata::pyTrk1 + 1.f * aod::reso2trktrkdata::pyTrk2); +DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! Resonance pz + float, 1.f * aod::reso2trktrkdata::pzTrk1 + 1.f * aod::reso2trktrkdata::pzTrk2); +} // namespace reso2trktrkdata + +DECLARE_SOA_TABLE_FULL(StoredReso2TrackTrackDatas, "Reso2TrackTrackDatas", "AOD", "Reso2TTDATA", //! + o2::soa::Index<>, reso2trktrkdata::Track1Id, reso2trktrkdata::Track2Id, reso2trktrkdata::CollisionId, + reso2trktrkdata::Trk1Sign, reso2trktrkdata::Trk2Sign, + reso2trktrkdata::PxTrk1, reso2trktrkdata::PyTrk1, reso2trktrkdata::PzTrk1, + reso2trktrkdata::PxTrk2, reso2trktrkdata::PyTrk2, reso2trktrkdata::PzTrk2, + + // Topological selections + reso2trktrkdata::DCArTrk1ToPV, reso2trktrkdata::DCArTrk2ToPV, + reso2trktrkdata::DCAzTrk1ToPV, reso2trktrkdata::DCAzTrk2ToPV, + + // Dynamic columns + reso2trktrkdata::Pt, + reso2trktrkdata::PsiPair, + + // Longitudinal + reso2trktrkdata::Eta, + reso2trktrkdata::Phi, + reso2trktrkdata::Track2Pt, + reso2trktrkdata::Track1Pt, + reso2trktrkdata::Track2Eta, + reso2trktrkdata::Track2Phi, + reso2trktrkdata::Track1Eta, + reso2trktrkdata::Track1Phi); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackTrackDatas, StoredReso2TrackTrackDatas, "Reso2TTDATAEXT", //! + reso2trktrkdata::Px, reso2trktrkdata::Py, reso2trktrkdata::Pz); // the table name has here to be the one with EXT which is not nice and under study + +using Reso2TrackTrackData = Reso2TrackTrackDatas::iterator; + +using Reso2TracksExt = soa::Join; +using Reso2TracksMC = soa::Join; +using Reso2TracksPID = soa::Join; +using Reso2TracksPIDExt = soa::Join; + +/// Reconstruction of track-v0 decay resonance candidates +/// +namespace reso2trkv0data +{ +// Needed to have shorter table that does not rely on existing one (filtering!) +DECLARE_SOA_INDEX_COLUMN_FULL(Track, track, int, Tracks, "_track"); //! +DECLARE_SOA_INDEX_COLUMN(V0, v0); //! +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! + +// General V0, track properties: position, momentum +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(PxPos, pxpos, float); //! +DECLARE_SOA_COLUMN(PyPos, pypos, float); //! +DECLARE_SOA_COLUMN(PzPos, pzpos, float); //! +DECLARE_SOA_COLUMN(PxNeg, pxneg, float); //! +DECLARE_SOA_COLUMN(PyNeg, pyneg, float); //! +DECLARE_SOA_COLUMN(PzNeg, pzneg, float); //! +DECLARE_SOA_COLUMN(PxTrack, pxtrack, float); //! +DECLARE_SOA_COLUMN(PyTrack, pytrack, float); //! +DECLARE_SOA_COLUMN(PzTrack, pztrack, float); //! +DECLARE_SOA_COLUMN(XV0, xV0, float); //! +DECLARE_SOA_COLUMN(YV0, yV0, float); //! +DECLARE_SOA_COLUMN(ZV0, zV0, float); //! + +// Saved from finding: DCAs +DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! +DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! +DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! +DECLARE_SOA_COLUMN(DCATrackToPV, dcatracktopv, float); //! + +// Derived expressions +// Momenta +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! + [](float Px, float Py) -> float { return RecoDecay::sqrtSumOfSquares(Px, Py); }); + +// Length quantities +DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, //! + [](float xV0, float yV0) -> float { return RecoDecay::sqrtSumOfSquares(xV0, yV0); }); + +// CosPAs +DECLARE_SOA_DYNAMIC_COLUMN(V0CosPA, v0cosPA, //! + [](float XV0, float YV0, float ZV0, float PxV0, float PyV0, float PzV0, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(array{pvX, pvY, pvZ}, array{XV0, YV0, ZV0}, array{PxV0, PyV0, PzV0}); }); +DECLARE_SOA_DYNAMIC_COLUMN(DCAV0ToPV, dcav0topv, //! + [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { 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)); }); + +// Calculated on the fly with mass assumption + dynamic tables +DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! mass under lambda hypothesis + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kProton), RecoDecay::getMassPDG(kPiPlus)}); }); +DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda, mAntiLambda, //! mass under antilambda hypothesis + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kProton)}); }); +DECLARE_SOA_DYNAMIC_COLUMN(MK0Short, mK0Short, //! mass under K0short hypothesis + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kPiPlus)}); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! + [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); + +DECLARE_SOA_EXPRESSION_COLUMN(PxV0, pxV0, //! + float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg); +DECLARE_SOA_EXPRESSION_COLUMN(PyV0, pyV0, //! + float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg); +DECLARE_SOA_EXPRESSION_COLUMN(PzV0, pzV0, //! + float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg); +DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! + float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg + 1.f * aod::reso2trkv0data::pxtrack); +DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! + float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg + 1.f * aod::reso2trkv0data::pytrack); +DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! + float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg + 1.f * aod::reso2trkv0data::pztrack); +} // namespace reso2trkv0data + +DECLARE_SOA_TABLE(Reso2TrackV0Data, "AOD", "Reso2TVDATA", //! + o2::soa::Index<>, reso2trkv0data::TrackId, reso2trkv0data::V0Id, reso2trkv0data::CollisionId, + + // General V0, track properties: position, momentum + reso2trkv0data::Sign, + reso2trkv0data::PxPos, reso2trkv0data::PyPos, reso2trkv0data::PzPos, + reso2trkv0data::PxNeg, reso2trkv0data::PyNeg, reso2trkv0data::PzNeg, + reso2trkv0data::PxTrack, reso2trkv0data::PyTrack, reso2trkv0data::PzTrack, + reso2trkv0data::XV0, reso2trkv0data::YV0, reso2trkv0data::ZV0, + + // Saved from finding: DCAs + reso2trkv0data::DCAV0Daughters, + reso2trkv0data::DCAPosToPV, reso2trkv0data::DCANegToPV, reso2trkv0data::DCATrackToPV, + + // Dynamic columns + reso2trkv0data::Pt, + reso2trkv0data::V0Radius, + reso2trkv0data::V0CosPA, + reso2trkv0data::DCAV0ToPV, + + // V0 Invariant masses + reso2trkv0data::MLambda, + reso2trkv0data::MAntiLambda, + reso2trkv0data::MK0Short, + + reso2trkv0data::Eta); + +using Reso2TrackV0DataOrigin = Reso2TrackV0Data; + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackV0DataExt, Reso2TrackV0DataOrigin, "Reso2TVDATAEXT", //! + reso2trkv0data::PxV0, reso2trkv0data::PyV0, reso2trkv0data::PzV0, + reso2trkv0data::Px, reso2trkv0data::Py, reso2trkv0data::Pz); // the table name has here to be the one with EXT which is not nice and under study + +using Reso2TrackV0DataFull = Reso2TrackV0DataExt; + +} // namespace o2::aod +#endif // O2_ANALYSIS_LFRESONANCETABLES_H_ \ No newline at end of file diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index 02b921804ef..e38a61a70ae 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -32,4 +32,14 @@ o2physics_add_dpl_workflow(cascadefinder o2physics_add_dpl_workflow(nucleustreecreator SOURCES LFTreeCreatorNuclei.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(reso2initializer + SOURCES LFResonanceCandidateProducer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(reso2trktrkbuilder + SOURCES LFResonanceCandidateProducer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx new file mode 100644 index 00000000000..5d4e6b3f115 --- /dev/null +++ b/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx @@ -0,0 +1,186 @@ +// 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 LFResonanceCandidateProducer.cxx +/// \brief Initializes variables for the resonance candidate producers +/// +/// +/// \author Bong-Hwi Lim + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/StrangenessTables.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "PWGLF/Utils/collisionCuts.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +/// Initializer for the resonance candidate producers +struct reso2initializer { + + Produces resoCollisions; + Produces reso2tracks; + + // Configurables + Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam + Configurable ConfStoreV0{"ConfStoreV0", true, "True: store V0s"}; + + /// Event cuts + o2::analysis::CollisonCuts colCuts; + Configurable ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable ConfEvtTriggerCheck{"ConfEvtTriggerCheck", true, "Evt sel: check for trigger"}; + Configurable ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"}; + Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; + + // Pre-selection cuts + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 5.0f, "TPC and TOF PID cut (loose, improve performance)"}; + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + Configurable isRun2{"isRun2", 0, "if Run2: demand TPC refit"}; + + /// DCA Selections for V0 + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.05, "Track DCAr cut to PV Maximum"}; + Configurable cMinV0PosDCArToPVcut{"cMinV0PosDCArToPVcut", 0.05f, "V0 Positive Track DCAr cut to PV Minimum"}; // Pre-selection + Configurable cMinV0NegDCArToPVcut{"cMinV0NegDCArToPVcut", 0.05f, "V0 Negative Track DCAr cut to PV Minimum"}; // Pre-selection + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + Configurable cMinV0Radius{"cMinV0Radius", 5.0, "Minimum V0 radius from PV"}; + Configurable cMaxV0Radius{"cMaxV0Radius", 200.0, "Maximum V0 radius from PV"}; + Configurable cMinV0CosPA{"cMinV0CosPA", 0.995, "Minimum V0 CosPA to PV"}; + + HistogramRegistry qaRegistry{"QAHistos", { + {"hGoodTrackIndices", "hGoodTrackIndices", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, + {"hGoodV0Indices", "hGoodV0Indices", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, + }, + OutputObjHandlingPolicy::QAObject}; + + // Pre-filters for efficient process + Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF + Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC + Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut + Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts + + void init(InitContext&) + { + colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3); + colCuts.init(&qaRegistry); + } + + void process(const soa::Join::iterator& collision, + soa::Filtered const& tracks, o2::aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); /// adding timestamp to access magnetic field later + // Default event selection + if (!colCuts.isSelected(collision)) + return; + colCuts.fillQA(collision); + + if (ConfIsRun3) { + resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFT0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); + } else { + resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.centRun2V0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); + } + + int childIDs[2] = {0, 0}; // these IDs are necessary to keep track of the children + // Loop over tracks + for (auto& track : tracks) { + // Tracks are already filtered by the pre-filters + reso2tracks(resoCollisions.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::resodaughter::DaughterType::kTrack, + track.dcaXY(), + childIDs, + track.sign(), + (uint8_t)track.tpcNClsCrossedRows(), + track.dcaXY(), + track.dcaZ(), + track.x(), + track.alpha(), + track.tpcNSigmaPi(), + track.tpcNSigmaKa(), + track.tpcNSigmaPr(), + track.tofNSigmaPi(), + track.tofNSigmaKa(), + track.tofNSigmaPr(), + 0, 0, 0, + 0, 0, 0, 0); + } + /// V0s + if (ConfStoreV0) { + for (auto& v0 : V0s) { + qaRegistry.fill(HIST("hGoodV0Indices"), 0.5); + auto postrack = v0.posTrack_as(); + auto negtrack = v0.negTrack_as(); + + if (postrack.tpcNClsCrossedRows() < mincrossedrows) + continue; + if (negtrack.tpcNClsCrossedRows() < mincrossedrows) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 1.5); + + if (fabs(postrack.dcaXY()) < cMinV0PosDCArToPVcut) + continue; + if (fabs(negtrack.dcaXY()) < cMinV0NegDCArToPVcut) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 2.5); + + if ((v0.v0radius() > cMaxV0Radius) || (v0.v0radius() < cMinV0Radius)) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 3.5); + if (v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cMinV0CosPA) + continue; + qaRegistry.fill(HIST("hGoodV0Indices"), 4.5); + childIDs[0] = v0.posTrackId(); + childIDs[1] = v0.negTrackId(); + reso2tracks(resoCollisions.lastIndex(), + v0.pt(), + v0.eta(), + v0.phi(), + aod::resodaughter::DaughterType::kV0, + v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), + childIDs, + 0, + 0, + v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), + 0, + v0.x(), 0, 0, 0, 0, 0, 0, 0, + v0.dcaV0daughters(), v0.mLambda(), v0.mAntiLambda(), + v0.v0radius(), v0.x(), v0.y(), v0.z()); + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"lf-reso2initializer"}), + }; +} \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx new file mode 100644 index 00000000000..72c16e261a3 --- /dev/null +++ b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx @@ -0,0 +1,120 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file LFResonanceCandidateProducerTrackTrack.cxx +/// \brief Reconstruction of track-track decay resonance candidates +/// +/// Inspired by lambdakzerofinder.cxx, +/// +/// \author Bong-Hwi Lim + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/StrangenessTables.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "PWGLF/Utils/collisionCuts.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +/// Reconstruction of track-track decay resonance candidates +struct reso2trktrkbuilder { + Produces reso2trktrkdata; + + HistogramRegistry registry{ + "registry", + { + {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, + {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, + }, + OutputObjHandlingPolicy::QAObject + }; + + // Configurables + Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam + /// Selection criteria + Configurable selectUnLikeSignOnly{"selectUnLikeSignOnly", 1, "Select only unlike sign pair for resonance"}; + + // Pre-selection cuts + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + + /// DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 5.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + /// Partition for firstTrack + Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + + void process(aod::ResoCollision& collision, + aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) + { + // LOGF(info, "event id: %d", collision.bcId()); + auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { + registry.fill(HIST("hReso2trktrckCandidate"), 0.5); + // Un-like sign pair only + if (selectUnLikeSignOnly && (trk1.sign() * trk2.sign() > 0)) + continue; + registry.fill(HIST("hReso2trktrckCandidate"), 1.5); + reso2trktrkdata( + trk1.globalIndex(), + trk2.globalIndex(), + trk1.resoCollisionId(), + trk1.sign(), trk2.sign(), + trk1.px(), trk1.py(), trk1.pz(), + trk2.px(), trk2.py(), trk2.pz(), + trk1.dcaXY(), trk2.dcaXY(), + trk1.dcaZ(), trk2.dcaZ()); + } + } +}; + +/// Extends the v0data table with expression columns +struct reso2trktrkinitializer { + Spawns reso2tracktrackdatas; + void init(InitContext const&) {} +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkbuilder"}), + adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkinitializer"})}; +} \ No newline at end of file diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 19856979a23..204a2ef8ef8 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -97,4 +97,9 @@ o2physics_add_dpl_workflow(track-checks o2physics_add_dpl_workflow(rsnanalysis SOURCES rsnanalysis.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(k892sample + SOURCES k892sample.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/Tasks/k892sample.cxx b/PWGLF/Tasks/k892sample.cxx new file mode 100644 index 00000000000..2d742bd825d --- /dev/null +++ b/PWGLF/Tasks/k892sample.cxx @@ -0,0 +1,173 @@ +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include +#include "DataFormatsParameters/GRPObject.h" +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct k892sample { + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; + framework::Service ccdb; /// Accessing the CCDB + + + void init(o2::framework::InitContext&) + { + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + AxisSpec vtxZAxis = {100, -20, 20}; + + std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; + AxisSpec centAxis = {centBinning, "V0M (%)"}; + std::vector ptBinning = {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., 5., 10., 20.}; + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + + histos.add("EventQA/Centrality", "Centrality distribution (V0M)", kTH1F, {centAxis}); + histos.add("EventQA/VtxZBeforeSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); + histos.add("EventQA/VtxZAfterSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); + // Mass QA (quick check) + histos.add("k892invmass", "Invariant mass of K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("antik892invmass", "Invariant mass of Anti-K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("k892invmassME", "Invariant mass of K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("antik892invmassME", "Invariant mass of Anti-K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); + + // 3d histogram + histos.add("h3k892invmass", "Invariant mass of K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); + histos.add("h3antik892invmass", "Invariant mass of Anti-K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); + } + + double massPi = TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(); + double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); + + void process(o2::aod::ResoCollision& inputCollision, + aod::Reso2TrackTrackDatas const& reso2trktrk, aod::Reso2TracksPIDExt const& track) + { + + histos.fill(HIST("EventQA/VtxZAfterSel"), inputCollision.posZ()); + + // fill centrality histos + histos.fill(HIST("EventQA/Centrality"), inputCollision.multV0M()); + + for (auto reso2 : reso2trktrk) { + auto trackPos = (reso2.trk1Sign() > 0) ? reso2.track1_as() : reso2.track2_as(); // positive daughter + auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter + bool isK892 = false; + bool isAntiK892 = false; + + // PID cuts + if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ + isK892 = true; + if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) + isAntiK892 = true; + if (!isK892 && !isAntiK892) + continue; + + // TOF PID cut (if available) + if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) + continue; + if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) + continue; + + auto arrMom = array{ + array{reso2.pxTrk1(), reso2.pyTrk1(), reso2.pzTrk1()}, + array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; + auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + if (isK892) { + histos.fill(HIST("k892invmass"), mass); + histos.fill(HIST("h3k892invmass"), inputCollision.multV0M(), reso2.pt(), mass); + } + if (isAntiK892) { // Anti-matter + histos.fill(HIST("antik892invmass"), mass); + histos.fill(HIST("h3antik892invmass"), inputCollision.multV0M(), reso2.pt(), mass); + } + } + } + // Processing Event Mixing + void processME(o2::aod::ResoCollisions& inputCollision, + o2::aod::BCsWithTimestamps const&, aod::Reso2TrackTrackDatas & reso2trktrk, aod::Reso2TracksPIDExt const& track) + { + BinningPolicy colBinning{{CfgVtxBins, CfgMultBins}, true}; + + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, inputCollision, inputCollision)) { + + auto magFieldTesla1 = 0.0; + static o2::parameters::GRPObject* grpo1 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision1.timestamp()); + if (!grpo1) { + magFieldTesla1 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision1.timestamp(), grpo1->getNominalL3Field()); + magFieldTesla1 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto magFieldTesla2 = 0.0; + static o2::parameters::GRPObject* grpo2 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision2.timestamp()); + if (!grpo2) { + magFieldTesla2 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision2.timestamp(), grpo2->getNominalL3Field()); + magFieldTesla2 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto reso2trktrkPartOne = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision1.globalIndex()); + auto reso2trktrkPartTwo = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision2.globalIndex()); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + for (auto& [reso1, reso2] : combinations(CombinationsStrictlyUpperIndexPolicy(reso2trktrkPartOne, reso2trktrkPartTwo))) { + auto trackPos = (reso1.trk1Sign() > 0) ? reso1.track1_as() : reso1.track2_as(); // positive daughter + auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter + bool isK892 = false; + bool isAntiK892 = false; + + // PID cuts + if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ + isK892 = true; + if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) + isAntiK892 = true; + if (!isK892 && !isAntiK892) + continue; + + // TOF PID cut (if available) + if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) + continue; + if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) + continue; + + auto arrMom = array{ + array{reso1.pxTrk1(), reso1.pyTrk1(), reso1.pzTrk1()}, + array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; + auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + if (isK892) { + histos.fill(HIST("k892invmassME"), mass); + } + if (isAntiK892) { // Anti-matter + histos.fill(HIST("antik892invmassME"), mass); + } + } + } + }; + PROCESS_SWITCH(k892sample, processME, "Process EventMixing", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} \ No newline at end of file diff --git a/PWGLF/Utils/collisionCuts.h b/PWGLF/Utils/collisionCuts.h new file mode 100644 index 00000000000..8f8f2f6cde1 --- /dev/null +++ b/PWGLF/Utils/collisionCuts.h @@ -0,0 +1,135 @@ +// 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 collisionCuts.h +/// \brief Traditional event selection cuts for O2 analysis +/// +/// Simply copied from FemtoDreamCollisionSelection.h +/// original author: Laura Serksnyte, TU München +/// +/// \author Bong-Hwi Lim + +#ifndef ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ +#define ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ + +#include "Common/CCDB/TriggerAliases.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/Logger.h" + +using namespace o2::framework; + +namespace o2::analysis +{ + +class CollisonCuts +{ + public: + virtual ~CollisonCuts() = default; + + /// Pass the selection criteria to the class + /// \param zvtxMax Maximal value of the z-vertex + /// \param checkTrigger whether or not to check for the trigger alias + /// \param trig Requested trigger alias + /// \param checkOffline whether or not to check for offline selection criteria + void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool checkRun3) + { + mCutsSet = true; + mZvtxMax = zvtxMax; + mCheckTrigger = checkTrigger; + mTrigger = static_cast(trig); + mCheckOffline = checkOffline; + mCheckIsRun3 = checkRun3; + } + + /// Initializes histograms for the task + /// \param registry Histogram registry to be passed + void init(HistogramRegistry* registry) + { + if (!mCutsSet) { + LOGF(error, "Event selection not set - quitting!"); + } + mHistogramRegistry = registry; + mHistogramRegistry->add("Event/posZ", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultFV0M", "; vMultV0M; Entries", kTH1F, {{600, 0, 600}}); + mHistogramRegistry->add("Event/MultFT0M", "; vMultT0M; Entries", kTH1F, {{600, 0, 600}}); + } + + /// Print some debug information + void printCuts() + { + std::cout << "Debug information for CollisonCuts \n Max. z-vertex: " << mZvtxMax << "\n Check trigger: " << mCheckTrigger << "\n Trigger: " << mTrigger << "\n Check offline: " << mCheckOffline << "\n"; + } + + /// Check whether the collisions fulfills the specified selections + /// \tparam T type of the collision + /// \param col Collision + /// \return whether or not the collisions fulfills the specified selections + template + bool isSelected(T const& col) + { + if (std::abs(col.posZ()) > mZvtxMax) { + return false; + } + if (mCheckIsRun3) { + if (mCheckOffline && !col.sel8()) { + return false; + } + } else { + if (mCheckTrigger && !col.alias()[mTrigger]) { + return false; + } + if (mCheckOffline && !col.sel7()) { + return false; + } + } + return true; + } + + /// Some basic QA of the event + /// \tparam T type of the collision + /// \param col Collision + template + void fillQA(T const& col) + { + if (mHistogramRegistry) { + mHistogramRegistry->fill(HIST("Event/posZ"), col.posZ()); + mHistogramRegistry->fill(HIST("Event/MultFV0M"), col.multFV0M()); + mHistogramRegistry->fill(HIST("Event/MultFT0M"), col.multFT0M()); + } + } + + /// \todo to be implemented! + /// Compute the sphericity of an event + /// Important here is that the filter on tracks does not interfere here! + /// In Run 2 we used here global tracks within |eta| < 0.8 + /// \tparam T1 type of the collision + /// \tparam T2 type of the tracks + /// \param col Collision + /// \param tracks All tracks + /// \return value of the sphericity of the event + template + float computeSphericity(T1 const& col, T2 const& tracks) + { + return 2.f; + } + + private: + HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + bool mCutsSet = false; ///< Protection against running without cuts + bool mCheckTrigger = false; ///< Check for trigger + bool mCheckOffline = false; ///< Check for offline criteria (might change) + bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam + triggerAliases mTrigger = kINT7; ///< Trigger to check for + float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) +}; +} // namespace o2::analysis::femtoDream + +#endif /* ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ */ \ No newline at end of file From 585cdc1717971f827b66e717ecf9ac1c68512bc0 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 01:07:10 +0200 Subject: [PATCH 11/22] Change the name of task and add TPC/TOF selectors --- PWGLF/DataModel/LFResonanceTables.h | 10 ++++-- ...roducer.cxx => LFResonanceInitializer.cxx} | 32 ++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) rename PWGLF/TableProducer/{LFResonanceCandidateProducer.cxx => LFResonanceInitializer.cxx} (88%) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 625796b7ab4..ad370d767ad 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -76,6 +76,8 @@ DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z DECLARE_SOA_COLUMN(X, x, float); //! x position of the track DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track +DECLARE_SOA_COLUMN(TPCPIDselection, tpcPIDselection, uint8_t); //! TPC PID selection +DECLARE_SOA_COLUMN(TOFPIDselection, tofPIDselection, uint8_t); //! TOF PID selection DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma @@ -126,6 +128,8 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::DcaZ, resodaughter::X, resodaughter::Alpha, + resodaughter::TPCPIDselection, + resodaughter::TOFPIDselection, resodaughter::TPCnSigmaPi, resodaughter::TPCnSigmaKa, resodaughter::TPCnSigmaPr, @@ -244,9 +248,9 @@ DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackTrackDatas, StoredReso2TrackTrackDatas using Reso2TrackTrackData = Reso2TrackTrackDatas::iterator; -using Reso2TracksExt = soa::Join; -using Reso2TracksMC = soa::Join; -using Reso2TracksPID = soa::Join; +using Reso2TracksExt = soa::Join; +using Reso2TracksMC = soa::Join; +using Reso2TracksPID = soa::Join; using Reso2TracksPIDExt = soa::Join; /// Reconstruction of track-v0 decay resonance candidates diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx similarity index 88% rename from PWGLF/TableProducer/LFResonanceCandidateProducer.cxx rename to PWGLF/TableProducer/LFResonanceInitializer.cxx index 5d4e6b3f115..3249449335d 100644 --- a/PWGLF/TableProducer/LFResonanceCandidateProducer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file LFResonanceCandidateProducer.cxx +/// \file LFResonanceInitializer.cxx /// \brief Initializes variables for the resonance candidate producers /// /// @@ -91,7 +91,7 @@ struct reso2initializer { colCuts.init(&qaRegistry); } - void process(const soa::Join::iterator& collision, + void process(const soa::Join::iterator& collision, soa::Filtered const& tracks, o2::aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { auto bc = collision.bc_as(); /// adding timestamp to access magnetic field later @@ -103,13 +103,35 @@ struct reso2initializer { if (ConfIsRun3) { resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFT0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); } else { - resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.centRun2V0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); + resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFV0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp()); } int childIDs[2] = {0, 0}; // these IDs are necessary to keep track of the children // Loop over tracks for (auto& track : tracks) { // Tracks are already filtered by the pre-filters + qaRegistry.fill(HIST("hGoodTrackIndices"), 0.5); + + // Add PID selection criteria here + uint8_t tpcPIDselections = 0; + uint8_t tofPIDselections = 0; + // TPC PID + if (std::abs(track.tpcNSigmaPi()) < pidnSigmaPreSelectionCut) + tpcPIDselections &= BIT(0); + if (std::abs(track.tpcNSigmaKa()) < pidnSigmaPreSelectionCut) + tpcPIDselections &= BIT(1); + if (std::abs(track.tpcNSigmaPr()) < pidnSigmaPreSelectionCut) + tpcPIDselections &= BIT(2); + // TOF PID + if (track.hasTOF()) { + if (std::abs(track.tofNSigmaPi()) < pidnSigmaPreSelectionCut) + tofPIDselections &= BIT(0); + if (std::abs(track.tofNSigmaKa()) < pidnSigmaPreSelectionCut) + tofPIDselections &= BIT(1); + if (std::abs(track.tofNSigmaPr()) < pidnSigmaPreSelectionCut) + tofPIDselections &= BIT(2); + } + reso2tracks(resoCollisions.lastIndex(), track.pt(), track.eta(), @@ -123,6 +145,8 @@ struct reso2initializer { track.dcaZ(), track.x(), track.alpha(), + tpcPIDselections, + tofPIDselections, track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), @@ -170,7 +194,7 @@ struct reso2initializer { 0, v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), 0, - v0.x(), 0, 0, 0, 0, 0, 0, 0, + v0.x(), 0, 0, 0, 0, 0, 0, 0, 0, 0, v0.dcaV0daughters(), v0.mLambda(), v0.mAntiLambda(), v0.v0radius(), v0.x(), v0.y(), v0.z()); } From 99d3cd0e35b5f27e166da645243cfba0448f53cf Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 01:07:39 +0200 Subject: [PATCH 12/22] add cmake list --- PWGLF/TableProducer/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index e38a61a70ae..dbc232e0f27 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -35,11 +35,11 @@ o2physics_add_dpl_workflow(nucleustreecreator COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(reso2initializer - SOURCES LFResonanceCandidateProducer.cxx + SOURCES LFResonanceInitializer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(reso2trktrkbuilder - SOURCES LFResonanceCandidateProducer.cxx + SOURCES LFResonanceCandidateProducerTrackTrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file From 78f733985c4545354c7b701ca58d0d44e1fff285 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 01:08:07 +0200 Subject: [PATCH 13/22] remove unused QA histos --- ...LFResonanceCandidateProducerTrackTrack.cxx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx index 72c16e261a3..d3daae324a6 100644 --- a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx +++ b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx @@ -40,18 +40,14 @@ using namespace o2::soa; /// Reconstruction of track-track decay resonance candidates struct reso2trktrkbuilder { Produces reso2trktrkdata; - - HistogramRegistry registry{ - "registry", - { - {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, - {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, - }, - OutputObjHandlingPolicy::QAObject - }; - + HistogramRegistry qaRegistry{"QAHistos", { + {"hReso2trktrckEvents", "hReso2trktrckEvents", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, + {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, + }, + OutputObjHandlingPolicy::QAObject}; // Configurables Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam /// Selection criteria @@ -77,8 +73,6 @@ struct reso2trktrkbuilder { && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; void process(aod::ResoCollision& collision, aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) @@ -86,13 +80,14 @@ struct reso2trktrkbuilder { // LOGF(info, "event id: %d", collision.bcId()); auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - + qaRegistry.fill(HIST("hReso2trktrckEvents"), 0.5); + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { - registry.fill(HIST("hReso2trktrckCandidate"), 0.5); + qaRegistry.fill(HIST("hReso2trktrckCandidate"), 0.5); // Un-like sign pair only if (selectUnLikeSignOnly && (trk1.sign() * trk2.sign() > 0)) continue; - registry.fill(HIST("hReso2trktrckCandidate"), 1.5); + qaRegistry.fill(HIST("hReso2trktrckCandidate"), 1.5); reso2trktrkdata( trk1.globalIndex(), trk2.globalIndex(), From ae2bdfe7710f301426674e70cb924d888b023dac Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 14:02:19 +0200 Subject: [PATCH 14/22] drop the old producers and add phi sample --- PWGLF/DataModel/LFResonanceTables.h | 228 ++---------------- PWGLF/TableProducer/CMakeLists.txt | 5 - ...LFResonanceCandidateProducerTrackTrack.cxx | 115 --------- .../TableProducer/LFResonanceInitializer.cxx | 15 +- PWGLF/Tasks/CMakeLists.txt | 4 +- PWGLF/Tasks/phisample.cxx | 168 +++++++++++++ 6 files changed, 195 insertions(+), 340 deletions(-) delete mode 100644 PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx create mode 100644 PWGLF/Tasks/phisample.cxx diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index ad370d767ad..0b98da0954f 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -60,9 +60,19 @@ static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", enum PDGtype { kPion = BIT(0), kKaon = BIT(1), - kProton = BIT(2) + kProton = BIT(2), + kHasTOF = BIT(6) // Save hasTOF info for TOF selection }; +#define requireTPCPIDCutInFilter(mask) ((aod::resodaughter::tpcPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) +#define requireTOFPIDCutInFilter(mask) (((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::kHasTOF) != (uint8_t)aod::resodaughter::kHasTOF) || (((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) && ((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::kHasTOF) == (uint8_t)aod::resodaughter::kHasTOF))) +#define requireTPCPIDPionCutInFilter() requireTPCPIDCutInFilter(PDGtype::kPion) +#define requireTPCPIDKaonCutInFilter() requireTPCPIDCutInFilter(PDGtype::kKaon) +#define requireTPCPIDProtonCutInFilter() requireTPCPIDCutInFilter(PDGtype::kProton) +#define requireTOFPIDPionCutInFilter() requireTOFPIDCutInFilter(PDGtype::kPion) +#define requireTOFPIDKaonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kKaon) +#define requireTOFPIDProtonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kProton) + DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta @@ -76,8 +86,8 @@ DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z DECLARE_SOA_COLUMN(X, x, float); //! x position of the track DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track -DECLARE_SOA_COLUMN(TPCPIDselection, tpcPIDselection, uint8_t); //! TPC PID selection -DECLARE_SOA_COLUMN(TOFPIDselection, tofPIDselection, uint8_t); //! TOF PID selection +DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection +DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma @@ -128,8 +138,8 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::DcaZ, resodaughter::X, resodaughter::Alpha, - resodaughter::TPCPIDselection, - resodaughter::TOFPIDselection, + resodaughter::TPCPIDselectionFlag, + resodaughter::TOFPIDselectionFlag, resodaughter::TPCnSigmaPi, resodaughter::TPCnSigmaKa, resodaughter::TPCnSigmaPr, @@ -150,214 +160,10 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::P); using ResoDaughter = ResoDaughters::iterator; -/// Reconstruction of track-track decay resonance candidates -/// -namespace reso2trktrkdata -{ -// Needed to have shorter table that does not rely on existing one (filtering!) -DECLARE_SOA_INDEX_COLUMN_FULL(Track1, track1, int, Tracks, "_1"); //! -DECLARE_SOA_INDEX_COLUMN_FULL(Track2, track2, int, Tracks, "_2"); //! -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! - -// General two track properties: position, momentum -DECLARE_SOA_COLUMN(Trk1Sign, trk1Sign, int); //! track1 sign -DECLARE_SOA_COLUMN(Trk2Sign, trk2Sign, int); //! track2 sign -DECLARE_SOA_COLUMN(PxTrk1, pxTrk1, float); //! track1 px at min -DECLARE_SOA_COLUMN(PyTrk1, pyTrk1, float); //! track1 py at min -DECLARE_SOA_COLUMN(PzTrk1, pzTrk1, float); //! track1 pz at min -DECLARE_SOA_COLUMN(PxTrk2, pxTrk2, float); //! track2 px at min -DECLARE_SOA_COLUMN(PyTrk2, pyTrk2, float); //! track2 py at min -DECLARE_SOA_COLUMN(PzTrk2, pzTrk2, float); //! track2 pz at min - -// Saved from finding: DCAs -DECLARE_SOA_COLUMN(DCArTrk1ToPV, dcarTrk1toPV, float); //! DCA track1 to PVr -DECLARE_SOA_COLUMN(DCArTrk2ToPV, dcarTrk2toPV, float); //! DCA track2 to PVr -DECLARE_SOA_COLUMN(DCAzTrk1ToPV, dcazTrk1toPV, float); //! DCA track1 to PVz -DECLARE_SOA_COLUMN(DCAzTrk2ToPV, dcazTrk2toPV, float); //! DCA track2 to PVz - -// Derived expressions -// Momenta -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! resonance pT - [](float pxTrk1, float pyTrk1, float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1 + pxTrk2, pyTrk1 + pyTrk2); }); - -// Psi pair angle: angle between the plane defined by the electron and positron momenta and the xy plane -DECLARE_SOA_DYNAMIC_COLUMN(PsiPair, psiPair, //! psi pair angle - [](float pxTrk1, float pyTrk1, float pzTrk1, float pxTrk2, float pyTrk2, float pzTrk2) { - auto clipToPM1 = [](float x) { return x < -1.f ? -1.f : (x > 1.f ? 1.f : x); }; - float ptot2 = RecoDecay::p2(pxTrk1, pyTrk1, pzTrk1) * RecoDecay::p2(pxTrk2, pyTrk2, pzTrk2); - float argcos = RecoDecay::dotProd(array{pxTrk1, pyTrk1, pzTrk1}, array{pxTrk2, pyTrk2, pzTrk2}) / std::sqrt(ptot2); - float thetaPos = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1), pzTrk1); - float thetaNeg = std::atan2(RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2), pzTrk2); - float argsin = (thetaNeg - thetaPos) / std::acos(clipToPM1(argcos)); - return std::asin(clipToPM1(argsin)); - }); - -DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Resonance eta - [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Resonance phi - [](float Px, float Py) -> float { return RecoDecay::phi(Px, Py); }); - -DECLARE_SOA_DYNAMIC_COLUMN(Track2Pt, track2Pt, //! Track2 daughter pT - [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk2, pyTrk2); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Pt, track1Pt, //! Track1 daughter pT - [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::sqrtSumOfSquares(pxTrk1, pyTrk1); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Eta, track2Eta, //! Track2 daughter eta - [](float pxTrk2, float pyTrk2, float pzTrk2) -> float { return RecoDecay::eta(array{pxTrk2, pyTrk2, pzTrk2}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track2Phi, track2Phi, //! Track2 daughter phi - [](float pxTrk2, float pyTrk2) -> float { return RecoDecay::phi(pxTrk2, pyTrk2); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Eta, track1Eta, //! Track1 daughter eta - [](float pxTrk1, float pyTrk1, float pzTrk1) -> float { return RecoDecay::eta(array{pxTrk1, pyTrk1, pzTrk1}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Track1Phi, track1Phi, //! Track1 daughter phi - [](float pxTrk1, float pyTrk1) -> float { return RecoDecay::phi(pxTrk1, pyTrk1); }); - -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! Resonance px - float, 1.f * aod::reso2trktrkdata::pxTrk1 + 1.f * aod::reso2trktrkdata::pxTrk2); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! Resonance py - float, 1.f * aod::reso2trktrkdata::pyTrk1 + 1.f * aod::reso2trktrkdata::pyTrk2); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! Resonance pz - float, 1.f * aod::reso2trktrkdata::pzTrk1 + 1.f * aod::reso2trktrkdata::pzTrk2); -} // namespace reso2trktrkdata - -DECLARE_SOA_TABLE_FULL(StoredReso2TrackTrackDatas, "Reso2TrackTrackDatas", "AOD", "Reso2TTDATA", //! - o2::soa::Index<>, reso2trktrkdata::Track1Id, reso2trktrkdata::Track2Id, reso2trktrkdata::CollisionId, - reso2trktrkdata::Trk1Sign, reso2trktrkdata::Trk2Sign, - reso2trktrkdata::PxTrk1, reso2trktrkdata::PyTrk1, reso2trktrkdata::PzTrk1, - reso2trktrkdata::PxTrk2, reso2trktrkdata::PyTrk2, reso2trktrkdata::PzTrk2, - - // Topological selections - reso2trktrkdata::DCArTrk1ToPV, reso2trktrkdata::DCArTrk2ToPV, - reso2trktrkdata::DCAzTrk1ToPV, reso2trktrkdata::DCAzTrk2ToPV, - - // Dynamic columns - reso2trktrkdata::Pt, - reso2trktrkdata::PsiPair, - - // Longitudinal - reso2trktrkdata::Eta, - reso2trktrkdata::Phi, - reso2trktrkdata::Track2Pt, - reso2trktrkdata::Track1Pt, - reso2trktrkdata::Track2Eta, - reso2trktrkdata::Track2Phi, - reso2trktrkdata::Track1Eta, - reso2trktrkdata::Track1Phi); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackTrackDatas, StoredReso2TrackTrackDatas, "Reso2TTDATAEXT", //! - reso2trktrkdata::Px, reso2trktrkdata::Py, reso2trktrkdata::Pz); // the table name has here to be the one with EXT which is not nice and under study - -using Reso2TrackTrackData = Reso2TrackTrackDatas::iterator; - -using Reso2TracksExt = soa::Join; +using Reso2TracksExt = soa::Join; using Reso2TracksMC = soa::Join; using Reso2TracksPID = soa::Join; -using Reso2TracksPIDExt = soa::Join; - -/// Reconstruction of track-v0 decay resonance candidates -/// -namespace reso2trkv0data -{ -// Needed to have shorter table that does not rely on existing one (filtering!) -DECLARE_SOA_INDEX_COLUMN_FULL(Track, track, int, Tracks, "_track"); //! -DECLARE_SOA_INDEX_COLUMN(V0, v0); //! -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! - -// General V0, track properties: position, momentum -DECLARE_SOA_COLUMN(Sign, sign, int); //! -DECLARE_SOA_COLUMN(PxPos, pxpos, float); //! -DECLARE_SOA_COLUMN(PyPos, pypos, float); //! -DECLARE_SOA_COLUMN(PzPos, pzpos, float); //! -DECLARE_SOA_COLUMN(PxNeg, pxneg, float); //! -DECLARE_SOA_COLUMN(PyNeg, pyneg, float); //! -DECLARE_SOA_COLUMN(PzNeg, pzneg, float); //! -DECLARE_SOA_COLUMN(PxTrack, pxtrack, float); //! -DECLARE_SOA_COLUMN(PyTrack, pytrack, float); //! -DECLARE_SOA_COLUMN(PzTrack, pztrack, float); //! -DECLARE_SOA_COLUMN(XV0, xV0, float); //! -DECLARE_SOA_COLUMN(YV0, yV0, float); //! -DECLARE_SOA_COLUMN(ZV0, zV0, float); //! - -// Saved from finding: DCAs -DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! -DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! -DECLARE_SOA_COLUMN(DCANegToPV, dcanegtopv, float); //! -DECLARE_SOA_COLUMN(DCATrackToPV, dcatracktopv, float); //! - -// Derived expressions -// Momenta -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! - [](float Px, float Py) -> float { return RecoDecay::sqrtSumOfSquares(Px, Py); }); - -// Length quantities -DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, //! - [](float xV0, float yV0) -> float { return RecoDecay::sqrtSumOfSquares(xV0, yV0); }); - -// CosPAs -DECLARE_SOA_DYNAMIC_COLUMN(V0CosPA, v0cosPA, //! - [](float XV0, float YV0, float ZV0, float PxV0, float PyV0, float PzV0, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(array{pvX, pvY, pvZ}, array{XV0, YV0, ZV0}, array{PxV0, PyV0, PzV0}); }); -DECLARE_SOA_DYNAMIC_COLUMN(DCAV0ToPV, dcav0topv, //! - [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { 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)); }); - -// Calculated on the fly with mass assumption + dynamic tables -DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! mass under lambda hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kProton), RecoDecay::getMassPDG(kPiPlus)}); }); -DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda, mAntiLambda, //! mass under antilambda hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kProton)}); }); -DECLARE_SOA_DYNAMIC_COLUMN(MK0Short, mK0Short, //! mass under K0short hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(array{array{pxpos, pypos, pzpos}, array{pxneg, pyneg, pzneg}}, array{RecoDecay::getMassPDG(kPiPlus), RecoDecay::getMassPDG(kPiPlus)}); }); - -DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! - [](float Px, float Py, float Pz) -> float { return RecoDecay::eta(array{Px, Py, Pz}); }); - -DECLARE_SOA_EXPRESSION_COLUMN(PxV0, pxV0, //! - float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg); -DECLARE_SOA_EXPRESSION_COLUMN(PyV0, pyV0, //! - float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg); -DECLARE_SOA_EXPRESSION_COLUMN(PzV0, pzV0, //! - float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg); -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! - float, 1.f * aod::reso2trkv0data::pxpos + 1.f * aod::reso2trkv0data::pxneg + 1.f * aod::reso2trkv0data::pxtrack); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! - float, 1.f * aod::reso2trkv0data::pypos + 1.f * aod::reso2trkv0data::pyneg + 1.f * aod::reso2trkv0data::pytrack); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! - float, 1.f * aod::reso2trkv0data::pzpos + 1.f * aod::reso2trkv0data::pzneg + 1.f * aod::reso2trkv0data::pztrack); -} // namespace reso2trkv0data - -DECLARE_SOA_TABLE(Reso2TrackV0Data, "AOD", "Reso2TVDATA", //! - o2::soa::Index<>, reso2trkv0data::TrackId, reso2trkv0data::V0Id, reso2trkv0data::CollisionId, - - // General V0, track properties: position, momentum - reso2trkv0data::Sign, - reso2trkv0data::PxPos, reso2trkv0data::PyPos, reso2trkv0data::PzPos, - reso2trkv0data::PxNeg, reso2trkv0data::PyNeg, reso2trkv0data::PzNeg, - reso2trkv0data::PxTrack, reso2trkv0data::PyTrack, reso2trkv0data::PzTrack, - reso2trkv0data::XV0, reso2trkv0data::YV0, reso2trkv0data::ZV0, - - // Saved from finding: DCAs - reso2trkv0data::DCAV0Daughters, - reso2trkv0data::DCAPosToPV, reso2trkv0data::DCANegToPV, reso2trkv0data::DCATrackToPV, - - // Dynamic columns - reso2trkv0data::Pt, - reso2trkv0data::V0Radius, - reso2trkv0data::V0CosPA, - reso2trkv0data::DCAV0ToPV, - - // V0 Invariant masses - reso2trkv0data::MLambda, - reso2trkv0data::MAntiLambda, - reso2trkv0data::MK0Short, - - reso2trkv0data::Eta); - -using Reso2TrackV0DataOrigin = Reso2TrackV0Data; - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(Reso2TrackV0DataExt, Reso2TrackV0DataOrigin, "Reso2TVDATAEXT", //! - reso2trkv0data::PxV0, reso2trkv0data::PyV0, reso2trkv0data::PzV0, - reso2trkv0data::Px, reso2trkv0data::Py, reso2trkv0data::Pz); // the table name has here to be the one with EXT which is not nice and under study - -using Reso2TrackV0DataFull = Reso2TrackV0DataExt; +using Reso2TracksPIDExt = soa::Join; } // namespace o2::aod #endif // O2_ANALYSIS_LFRESONANCETABLES_H_ \ No newline at end of file diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index dbc232e0f27..4bdf6b1d5a6 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -37,9 +37,4 @@ o2physics_add_dpl_workflow(nucleustreecreator o2physics_add_dpl_workflow(reso2initializer SOURCES LFResonanceInitializer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(reso2trktrkbuilder - SOURCES LFResonanceCandidateProducerTrackTrack.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx b/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx deleted file mode 100644 index d3daae324a6..00000000000 --- a/PWGLF/TableProducer/LFResonanceCandidateProducerTrackTrack.cxx +++ /dev/null @@ -1,115 +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. - -/// \file LFResonanceCandidateProducerTrackTrack.cxx -/// \brief Reconstruction of track-track decay resonance candidates -/// -/// Inspired by lambdakzerofinder.cxx, -/// -/// \author Bong-Hwi Lim - -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectorPID.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/StrangenessTables.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "PWGLF/Utils/collisionCuts.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::soa; - -/// Reconstruction of track-track decay resonance candidates -struct reso2trktrkbuilder { - Produces reso2trktrkdata; - HistogramRegistry qaRegistry{"QAHistos", { - {"hReso2trktrckEvents", "hReso2trktrckEvents", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hReso2trktrckCandidate", "hReso2trktrckCandidate", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hCandidateDCAd", "hCandidateDCAd", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, - {"hCandidateCPA", "hCandidateCPA", {HistType::kTH1F, {{100, 0.9f, 1.0f}}}}, - {"hCandidateRadius", "hCandidateRadius", {HistType::kTH1F, {{200, 0.0f, 200.0f}}}}, - }, - OutputObjHandlingPolicy::QAObject}; - // Configurables - Configurable ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam - /// Selection criteria - Configurable selectUnLikeSignOnly{"selectUnLikeSignOnly", 1, "Select only unlike sign pair for resonance"}; - - // Pre-selection cuts - Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; - Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; - - /// DCA Selections - // DCAr to PV - Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1, "Track DCAr cut to PV Maximum"}; - // DCAz to PV - Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 5.0, "Track DCAz cut to PV Maximum"}; - Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; - - /// Partition for firstTrack - Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) - && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) - && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - - void process(aod::ResoCollision& collision, - aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) - { - // LOGF(info, "event id: %d", collision.bcId()); - auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - qaRegistry.fill(HIST("hReso2trktrckEvents"), 0.5); - - for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { - qaRegistry.fill(HIST("hReso2trktrckCandidate"), 0.5); - // Un-like sign pair only - if (selectUnLikeSignOnly && (trk1.sign() * trk2.sign() > 0)) - continue; - qaRegistry.fill(HIST("hReso2trktrckCandidate"), 1.5); - reso2trktrkdata( - trk1.globalIndex(), - trk2.globalIndex(), - trk1.resoCollisionId(), - trk1.sign(), trk2.sign(), - trk1.px(), trk1.py(), trk1.pz(), - trk2.px(), trk2.py(), trk2.pz(), - trk1.dcaXY(), trk2.dcaXY(), - trk1.dcaZ(), trk2.dcaZ()); - } - } -}; - -/// Extends the v0data table with expression columns -struct reso2trktrkinitializer { - Spawns reso2tracktrackdatas; - void init(InitContext const&) {} -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkbuilder"}), - adaptAnalysisTask(cfgc, TaskName{"lf-reso2trktrkinitializer"})}; -} \ No newline at end of file diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 3249449335d..5839202655d 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -80,7 +80,7 @@ struct reso2initializer { OutputObjHandlingPolicy::QAObject}; // Pre-filters for efficient process - Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF + // Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts @@ -117,19 +117,20 @@ struct reso2initializer { uint8_t tofPIDselections = 0; // TPC PID if (std::abs(track.tpcNSigmaPi()) < pidnSigmaPreSelectionCut) - tpcPIDselections &= BIT(0); + tpcPIDselections |= aod::resodaughter::PDGtype::kPion; if (std::abs(track.tpcNSigmaKa()) < pidnSigmaPreSelectionCut) - tpcPIDselections &= BIT(1); + tpcPIDselections |= aod::resodaughter::PDGtype::kKaon; if (std::abs(track.tpcNSigmaPr()) < pidnSigmaPreSelectionCut) - tpcPIDselections &= BIT(2); + tpcPIDselections |= aod::resodaughter::PDGtype::kProton; // TOF PID if (track.hasTOF()) { + tofPIDselections |= aod::resodaughter::PDGtype::kHasTOF; if (std::abs(track.tofNSigmaPi()) < pidnSigmaPreSelectionCut) - tofPIDselections &= BIT(0); + tofPIDselections |= aod::resodaughter::PDGtype::kPion; if (std::abs(track.tofNSigmaKa()) < pidnSigmaPreSelectionCut) - tofPIDselections &= BIT(1); + tofPIDselections |= aod::resodaughter::PDGtype::kKaon; if (std::abs(track.tofNSigmaPr()) < pidnSigmaPreSelectionCut) - tofPIDselections &= BIT(2); + tofPIDselections |= aod::resodaughter::PDGtype::kProton; } reso2tracks(resoCollisions.lastIndex(), diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 204a2ef8ef8..8d319ae25d5 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -99,7 +99,7 @@ o2physics_add_dpl_workflow(rsnanalysis PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(k892sample - SOURCES k892sample.cxx +o2physics_add_dpl_workflow(phisample + SOURCES phisample.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2::DetectorsVertexing COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/Tasks/phisample.cxx b/PWGLF/Tasks/phisample.cxx new file mode 100644 index 00000000000..8e00d3690f8 --- /dev/null +++ b/PWGLF/Tasks/phisample.cxx @@ -0,0 +1,168 @@ +// 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 phisample.cxx +/// \brief Reconstruction of track-track decay resonance candidates +/// +/// +/// \author Bong-Hwi Lim + +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/TrackSelectorPID.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include +#include "DataFormatsParameters/GRPObject.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct phisample { + framework::Service ccdb; /// Accessing the CCDB + ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + // Configurables + + // Pre-selection cuts + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + + /// DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 5.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; + + /// Partition for firstTrack + Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && requireTPCPIDKaonCutInFilter() + && requireTOFPIDKaonCutInFilter() + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) + && requireTPCPIDKaonCutInFilter() + && requireTOFPIDKaonCutInFilter() + && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) + && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + void init(o2::framework::InitContext&) + { + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + AxisSpec vtxZAxis = {100, -20, 20}; + + std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; + AxisSpec centAxis = {centBinning, "V0M (%)"}; + std::vector ptBinning = {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., 5., 10., 20.}; + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + + // Mass QA (quick check) + histos.add("phiinvmass", "Invariant mass of Phi", kTH1F, {{500, 0.8, 1.3, "Invariant Mass (GeV/#it{c}^2)"}}); + histos.add("phiinvmassME", "Invariant mass of Phi mixed event", kTH1F, {{500, 0.8, 1.3, "Invariant Mass (GeV/#it{c}^2)"}}); + + // 3d histogram + histos.add("h3phiinvmass", "Invariant mass of Phi", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); + } + + double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); + + void process(aod::ResoCollision& collision, + aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) + { + // LOGF(info, "event id: %d", collision.bcId()); + auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); + + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { + // Un-like sign pair only + if (trk1.sign() * trk2.sign() > 0) + continue; + + auto arrMom = array{ + array{trk1.px(), trk1.py(), trk1.pz()}, + array{trk2.px(), trk2.py(), trk2.pz()}}; + auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); + auto arrMass = array{massKa, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + histos.fill(HIST("phiinvmass"), mass); + histos.fill(HIST("h3phiinvmass"), collision.multV0M(), resoPt, mass); + } + } + + // Processing Event Mixing + void processME(o2::aod::ResoCollisions& collision, + o2::aod::BCsWithTimestamps const&, aod::ResoDaughters const&, aod::Reso2TracksPIDExt const&) + { + BinningPolicy colBinning{{CfgVtxBins, CfgMultBins}, true}; + + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, collision, collision)) { + + auto magFieldTesla1 = 0.0; + static o2::parameters::GRPObject* grpo1 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision1.timestamp()); + if (!grpo1) { + magFieldTesla1 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision1.timestamp(), grpo1->getNominalL3Field()); + magFieldTesla1 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto magFieldTesla2 = 0.0; + static o2::parameters::GRPObject* grpo2 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision2.timestamp()); + if (!grpo2) { + magFieldTesla2 = 0; + } else { + // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision2.timestamp(), grpo2->getNominalL3Field()); + magFieldTesla2 = 0.1 * (grpo1->getNominalL3Field()); + } + + auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision1.globalIndex()); + auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision2.globalIndex()); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { + if (trk1.sign() * trk2.sign() > 0) + continue; + + auto arrMom = array{ + array{trk1.px(), trk1.py(), trk1.pz()}, + array{trk2.px(), trk2.py(), trk2.pz()}}; + auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); + auto arrMass = array{massKa, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + histos.fill(HIST("phiinvmass"), mass); + histos.fill(HIST("h3phiinvmass"), collision1.multV0M(), resoPt, mass); + } + } + }; + PROCESS_SWITCH(phisample, processME, "Process EventMixing", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"lf-phisample"})}; +} \ No newline at end of file From 2f820ce76714335be6765b1f02b4fac59eea9f52 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 14:20:18 +0200 Subject: [PATCH 15/22] remove k892 sample and update phi sample --- PWGLF/Tasks/k892sample.cxx | 173 ------------------------------------- PWGLF/Tasks/phisample.cxx | 24 ++--- 2 files changed, 13 insertions(+), 184 deletions(-) delete mode 100644 PWGLF/Tasks/k892sample.cxx diff --git a/PWGLF/Tasks/k892sample.cxx b/PWGLF/Tasks/k892sample.cxx deleted file mode 100644 index 2d742bd825d..00000000000 --- a/PWGLF/Tasks/k892sample.cxx +++ /dev/null @@ -1,173 +0,0 @@ -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelectorPID.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include -#include "DataFormatsParameters/GRPObject.h" -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::soa; - -struct k892sample { - HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; - ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; - framework::Service ccdb; /// Accessing the CCDB - - - void init(o2::framework::InitContext&) - { - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - ccdb->setCreatedNotAfter(now); - - AxisSpec vtxZAxis = {100, -20, 20}; - - std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; - AxisSpec centAxis = {centBinning, "V0M (%)"}; - std::vector ptBinning = {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., 5., 10., 20.}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - - histos.add("EventQA/Centrality", "Centrality distribution (V0M)", kTH1F, {centAxis}); - histos.add("EventQA/VtxZBeforeSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); - histos.add("EventQA/VtxZAfterSel", "Vertex distribution in Z;Z (cm)", kTH1F, {vtxZAxis}); - // Mass QA (quick check) - histos.add("k892invmass", "Invariant mass of K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - histos.add("antik892invmass", "Invariant mass of Anti-K(892)", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - histos.add("k892invmassME", "Invariant mass of K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - histos.add("antik892invmassME", "Invariant mass of Anti-K(892) mixed event", kTH1F, {{500, 0.5, 1.1, "Invariant Mass (GeV/#it{c}^2)"}}); - - // 3d histogram - histos.add("h3k892invmass", "Invariant mass of K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); - histos.add("h3antik892invmass", "Invariant mass of Anti-K(892)", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.5, 1.1}}); - } - - double massPi = TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(); - double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); - - void process(o2::aod::ResoCollision& inputCollision, - aod::Reso2TrackTrackDatas const& reso2trktrk, aod::Reso2TracksPIDExt const& track) - { - - histos.fill(HIST("EventQA/VtxZAfterSel"), inputCollision.posZ()); - - // fill centrality histos - histos.fill(HIST("EventQA/Centrality"), inputCollision.multV0M()); - - for (auto reso2 : reso2trktrk) { - auto trackPos = (reso2.trk1Sign() > 0) ? reso2.track1_as() : reso2.track2_as(); // positive daughter - auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter - bool isK892 = false; - bool isAntiK892 = false; - - // PID cuts - if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ - isK892 = true; - if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) - isAntiK892 = true; - if (!isK892 && !isAntiK892) - continue; - - // TOF PID cut (if available) - if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) - continue; - if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) - continue; - - auto arrMom = array{ - array{reso2.pxTrk1(), reso2.pyTrk1(), reso2.pzTrk1()}, - array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; - auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; - auto mass = RecoDecay::m(arrMom, arrMass); - if (isK892) { - histos.fill(HIST("k892invmass"), mass); - histos.fill(HIST("h3k892invmass"), inputCollision.multV0M(), reso2.pt(), mass); - } - if (isAntiK892) { // Anti-matter - histos.fill(HIST("antik892invmass"), mass); - histos.fill(HIST("h3antik892invmass"), inputCollision.multV0M(), reso2.pt(), mass); - } - } - } - // Processing Event Mixing - void processME(o2::aod::ResoCollisions& inputCollision, - o2::aod::BCsWithTimestamps const&, aod::Reso2TrackTrackDatas & reso2trktrk, aod::Reso2TracksPIDExt const& track) - { - BinningPolicy colBinning{{CfgVtxBins, CfgMultBins}, true}; - - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, inputCollision, inputCollision)) { - - auto magFieldTesla1 = 0.0; - static o2::parameters::GRPObject* grpo1 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision1.timestamp()); - if (!grpo1) { - magFieldTesla1 = 0; - } else { - // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision1.timestamp(), grpo1->getNominalL3Field()); - magFieldTesla1 = 0.1 * (grpo1->getNominalL3Field()); - } - - auto magFieldTesla2 = 0.0; - static o2::parameters::GRPObject* grpo2 = ccdb->getForTimeStamp("GLO/GRP/GRP", collision2.timestamp()); - if (!grpo2) { - magFieldTesla2 = 0; - } else { - // LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", collision2.timestamp(), grpo2->getNominalL3Field()); - magFieldTesla2 = 0.1 * (grpo1->getNominalL3Field()); - } - - auto reso2trktrkPartOne = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision1.globalIndex()); - auto reso2trktrkPartTwo = reso2trktrk.sliceByCached(aod::reso2trktrkdata::collisionId, collision2.globalIndex()); - - if (magFieldTesla1 != magFieldTesla2) { - continue; - } - for (auto& [reso1, reso2] : combinations(CombinationsStrictlyUpperIndexPolicy(reso2trktrkPartOne, reso2trktrkPartTwo))) { - auto trackPos = (reso1.trk1Sign() > 0) ? reso1.track1_as() : reso1.track2_as(); // positive daughter - auto trackNeg = (reso2.trk1Sign() > 0) ? reso2.track2_as() : reso2.track1_as(); // negative daughter - bool isK892 = false; - bool isAntiK892 = false; - - // PID cuts - if ((std::abs(trackPos.tpcNSigmaKa()) < 3) && (std::abs(trackNeg.tpcNSigmaPi()) < 3)) // pi- + K+ - isK892 = true; - if ((std::abs(trackNeg.tpcNSigmaKa()) < 3) && (std::abs(trackPos.tpcNSigmaPi()) < 3)) // K- + pi+ (anti) - isAntiK892 = true; - if (!isK892 && !isAntiK892) - continue; - - // TOF PID cut (if available) - if (isK892 && trackPos.hasTOF() && (std::abs(trackPos.tofNSigmaKa()) > 3)) - continue; - if (isAntiK892 && trackNeg.hasTOF() && (std::abs(trackNeg.tofNSigmaKa()) > 3)) - continue; - - auto arrMom = array{ - array{reso1.pxTrk1(), reso1.pyTrk1(), reso1.pzTrk1()}, - array{reso2.pxTrk2(), reso2.pyTrk2(), reso2.pzTrk2()}}; - auto arrMass = (isK892) ? array{massKa, massPi} : array{massPi, massKa}; - auto mass = RecoDecay::m(arrMom, arrMass); - if (isK892) { - histos.fill(HIST("k892invmassME"), mass); - } - if (isAntiK892) { // Anti-matter - histos.fill(HIST("antik892invmassME"), mass); - } - } - } - }; - PROCESS_SWITCH(k892sample, processME, "Process EventMixing", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} \ No newline at end of file diff --git a/PWGLF/Tasks/phisample.cxx b/PWGLF/Tasks/phisample.cxx index 8e00d3690f8..7d8ac928cec 100644 --- a/PWGLF/Tasks/phisample.cxx +++ b/PWGLF/Tasks/phisample.cxx @@ -85,6 +85,7 @@ struct phisample { // 3d histogram histos.add("h3phiinvmass", "Invariant mass of Phi", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); + histos.add("h3phiinvmassME", "Invariant mass of Phi mixed event", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); } double massKa = TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(); @@ -145,17 +146,18 @@ struct phisample { continue; } for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { - if (trk1.sign() * trk2.sign() > 0) - continue; - - auto arrMom = array{ - array{trk1.px(), trk1.py(), trk1.pz()}, - array{trk2.px(), trk2.py(), trk2.pz()}}; - auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); - auto arrMass = array{massKa, massKa}; - auto mass = RecoDecay::m(arrMom, arrMass); - histos.fill(HIST("phiinvmass"), mass); - histos.fill(HIST("h3phiinvmass"), collision1.multV0M(), resoPt, mass); + // Un-like sign pair only + if (trk1.sign() * trk2.sign() > 0) + continue; + + auto arrMom = array{ + array{trk1.px(), trk1.py(), trk1.pz()}, + array{trk2.px(), trk2.py(), trk2.pz()}}; + auto resoPt = RecoDecay::sqrtSumOfSquares(trk1.px() + trk2.px(), trk1.py() + trk2.py()); + auto arrMass = array{massKa, massKa}; + auto mass = RecoDecay::m(arrMom, arrMass); + histos.fill(HIST("phiinvmassME"), mass); + histos.fill(HIST("h3phiinvmassME"), collision1.multV0M(), resoPt, mass); } } }; From 440ed96557f6759dfe8dae7defba07d0976a3ba6 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 15:55:34 +0200 Subject: [PATCH 16/22] remove the dynamic columns --- PWGLF/DataModel/LFResonanceTables.h | 98 ++++++++----------- .../TableProducer/LFResonanceInitializer.cxx | 6 ++ 2 files changed, 46 insertions(+), 58 deletions(-) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 0b98da0954f..4f73a04a17b 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -58,10 +58,10 @@ enum DaughterType { static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", "V0", "Cascade"}; //! Naming of the different particle types enum PDGtype { - kPion = BIT(0), - kKaon = BIT(1), - kProton = BIT(2), - kHasTOF = BIT(6) // Save hasTOF info for TOF selection + kPion = BIT(0), + kKaon = BIT(1), + kProton = BIT(2), + kHasTOF = BIT(6) // Save hasTOF info for TOF selection }; #define requireTPCPIDCutInFilter(mask) ((aod::resodaughter::tpcPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) @@ -74,59 +74,46 @@ enum PDGtype { #define requireTOFPIDProtonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kProton) DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision); -DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) -DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta -DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi -DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType -DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) -DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations -DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge -DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows -DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy -DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z -DECLARE_SOA_COLUMN(X, x, float); //! x position of the track -DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track -DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection -DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection -DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma -DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma -DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma -DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma -DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma -DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma -DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters -DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda -DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda -DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex -DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex -DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex -DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex - -DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, //! Compute the theta of the track - [](float eta) -> float { - return 2.f * std::atan(std::exp(-eta)); - }); -DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Compute the momentum in x in GeV/c - [](float pt, float phi) -> float { - return pt * std::sin(phi); - }); -DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Compute the momentum in y in GeV/c - [](float pt, float phi) -> float { - return pt * std::cos(phi); - }); -DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Compute the momentum in z in GeV/c - [](float pt, float eta) -> float { - return pt * std::sinh(eta); - }); -DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Compute the overall momentum in GeV/c - [](float pt, float eta) -> float { - return pt * std::cosh(eta); - }); +DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) +DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c) +DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c) +DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! p (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi +DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType +DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA) +DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge +DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy +DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z +DECLARE_SOA_COLUMN(X, x, float); //! x position of the track +DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track +DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection +DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection +DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma +DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma +DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma +DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters +DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda +DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda +DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex +DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex } // namespace resodaughter DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", o2::soa::Index<>, resodaughter::ResoCollisionId, resodaughter::Pt, + resodaughter::Px, + resodaughter::Py, + resodaughter::Pz, + resodaughter::P, resodaughter::Eta, resodaughter::Phi, resodaughter::PartType, @@ -152,12 +139,7 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::TransRadius, resodaughter::DecayVtxX, resodaughter::DecayVtxY, - resodaughter::DecayVtxZ, - resodaughter::Theta, - resodaughter::Px, - resodaughter::Py, - resodaughter::Pz, - resodaughter::P); + resodaughter::DecayVtxZ); using ResoDaughter = ResoDaughters::iterator; using Reso2TracksExt = soa::Join; diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 5839202655d..48082bfcb8f 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -135,6 +135,9 @@ struct reso2initializer { reso2tracks(resoCollisions.lastIndex(), track.pt(), + track.px(), + track.py(), + track.pz(), track.eta(), track.phi(), aod::resodaughter::DaughterType::kTrack, @@ -186,6 +189,9 @@ struct reso2initializer { childIDs[1] = v0.negTrackId(); reso2tracks(resoCollisions.lastIndex(), v0.pt(), + v0.px(), + v0.py(), + v0.pz(), v0.eta(), v0.phi(), aod::resodaughter::DaughterType::kV0, From e510f774af9acf3fc9bd4488af812fcd457fac56 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 16:02:07 +0200 Subject: [PATCH 17/22] fix error --- PWGLF/TableProducer/LFResonanceInitializer.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 48082bfcb8f..13f32346072 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -138,6 +138,7 @@ struct reso2initializer { track.px(), track.py(), track.pz(), + track.p(), track.eta(), track.phi(), aod::resodaughter::DaughterType::kTrack, @@ -192,6 +193,7 @@ struct reso2initializer { v0.px(), v0.py(), v0.pz(), + RecoDecay::sqrtSumOfSquares(v0.px(), v0.py(), v0.pz()), v0.eta(), v0.phi(), aod::resodaughter::DaughterType::kV0, From 43021b0692067ca1fd75d73e5f70b39cf2672e4d Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Wed, 20 Jul 2022 16:24:12 +0200 Subject: [PATCH 18/22] remove unused variables --- PWGLF/DataModel/LFResonanceTables.h | 2 -- PWGLF/TableProducer/LFResonanceInitializer.cxx | 2 -- 2 files changed, 4 deletions(-) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 4f73a04a17b..b5de7306108 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -78,7 +78,6 @@ DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T ( DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c) DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c) DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c) -DECLARE_SOA_COLUMN(P, p, float); //! p (GeV/c) DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType @@ -113,7 +112,6 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::Px, resodaughter::Py, resodaughter::Pz, - resodaughter::P, resodaughter::Eta, resodaughter::Phi, resodaughter::PartType, diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 13f32346072..48082bfcb8f 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -138,7 +138,6 @@ struct reso2initializer { track.px(), track.py(), track.pz(), - track.p(), track.eta(), track.phi(), aod::resodaughter::DaughterType::kTrack, @@ -193,7 +192,6 @@ struct reso2initializer { v0.px(), v0.py(), v0.pz(), - RecoDecay::sqrtSumOfSquares(v0.px(), v0.py(), v0.pz()), v0.eta(), v0.phi(), aod::resodaughter::DaughterType::kV0, From 9013fddaf078c9a11229d641b2c7769e25debb51 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Thu, 28 Jul 2022 16:31:25 +0200 Subject: [PATCH 19/22] Update to push master --- PWGLF/TableProducer/LFResonanceInitializer.cxx | 1 - PWGLF/Tasks/CMakeLists.txt | 6 +++--- PWGLF/Tasks/{phisample.cxx => phianalysis.cxx} | 9 ++++----- 3 files changed, 7 insertions(+), 9 deletions(-) rename PWGLF/Tasks/{phisample.cxx => phianalysis.cxx} (97%) diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 48082bfcb8f..96555ffd5ca 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -17,7 +17,6 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectorPID.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" #include "Common/Core/trackUtilities.h" diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 8d319ae25d5..10c85e09fdd 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -99,7 +99,7 @@ o2physics_add_dpl_workflow(rsnanalysis PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(phisample - SOURCES phisample.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2::DetectorsVertexing +o2physics_add_dpl_workflow(phianalysis + SOURCES phianalysis.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/Tasks/phisample.cxx b/PWGLF/Tasks/phianalysis.cxx similarity index 97% rename from PWGLF/Tasks/phisample.cxx rename to PWGLF/Tasks/phianalysis.cxx index 7d8ac928cec..8ac55bb2ff8 100644 --- a/PWGLF/Tasks/phisample.cxx +++ b/PWGLF/Tasks/phianalysis.cxx @@ -9,14 +9,13 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file phisample.cxx +/// \file phianalysis.cxx /// \brief Reconstruction of track-track decay resonance candidates /// /// /// \author Bong-Hwi Lim #include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelectorPID.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Framework/AnalysisTask.h" @@ -31,7 +30,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -struct phisample { +struct phianalysis { framework::Service ccdb; /// Accessing the CCDB ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; @@ -161,10 +160,10 @@ struct phisample { } } }; - PROCESS_SWITCH(phisample, processME, "Process EventMixing", false); + PROCESS_SWITCH(phianalysis, processME, "Process EventMixing", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"lf-phisample"})}; + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"lf-phianalysis"})}; } \ No newline at end of file From de8418670d9dc8a3f490c961168d1405e7de9f64 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Thu, 28 Jul 2022 16:49:50 +0200 Subject: [PATCH 20/22] update with clang format --- .../TableProducer/LFResonanceInitializer.cxx | 6 ++--- PWGLF/Tasks/phianalysis.cxx | 22 +++++-------------- PWGLF/Utils/collisionCuts.h | 2 +- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 96555ffd5ca..7f5456d3fc5 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -80,9 +80,9 @@ struct reso2initializer { // Pre-filters for efficient process // Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF - Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC - Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut - Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts + Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC + Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut + Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts void init(InitContext&) { diff --git a/PWGLF/Tasks/phianalysis.cxx b/PWGLF/Tasks/phianalysis.cxx index 8ac55bb2ff8..03932ce6a6d 100644 --- a/PWGLF/Tasks/phianalysis.cxx +++ b/PWGLF/Tasks/phianalysis.cxx @@ -34,7 +34,7 @@ struct phianalysis { framework::Service ccdb; /// Accessing the CCDB ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; ConfigurableAxis CfgVtxBins{"CfgVtxBins", {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"}; - + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; // Configurables @@ -51,18 +51,8 @@ struct phianalysis { Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; /// Partition for firstTrack - Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) - && requireTPCPIDKaonCutInFilter() - && requireTOFPIDKaonCutInFilter() - && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) - && requireTPCPIDKaonCutInFilter() - && requireTOFPIDKaonCutInFilter() - && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) - && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) && requireTPCPIDKaonCutInFilter() && requireTOFPIDKaonCutInFilter() && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) && requireTPCPIDKaonCutInFilter() && requireTOFPIDKaonCutInFilter() && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts void init(o2::framework::InitContext&) { ccdb->setURL("http://alice-ccdb.cern.ch"); @@ -81,7 +71,7 @@ struct phianalysis { // Mass QA (quick check) histos.add("phiinvmass", "Invariant mass of Phi", kTH1F, {{500, 0.8, 1.3, "Invariant Mass (GeV/#it{c}^2)"}}); histos.add("phiinvmassME", "Invariant mass of Phi mixed event", kTH1F, {{500, 0.8, 1.3, "Invariant Mass (GeV/#it{c}^2)"}}); - + // 3d histogram histos.add("h3phiinvmass", "Invariant mass of Phi", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); histos.add("h3phiinvmassME", "Invariant mass of Phi mixed event", kTH3F, {{100, 0.0f, 100.0f}, {100, 0.0f, 10.0f}, {500, 0.8, 1.3}}); @@ -95,7 +85,7 @@ struct phianalysis { // LOGF(info, "event id: %d", collision.bcId()); auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision.globalIndex()); - + for (auto& [trk1, trk2] : combinations(CombinationsStrictlyUpperIndexPolicy(group1, group2))) { // Un-like sign pair only if (trk1.sign() * trk2.sign() > 0) @@ -140,7 +130,7 @@ struct phianalysis { auto group1 = parts1->sliceByCached(aod::resodaughter::resoCollisionId, collision1.globalIndex()); auto group2 = parts2->sliceByCached(aod::resodaughter::resoCollisionId, collision2.globalIndex()); - + if (magFieldTesla1 != magFieldTesla2) { continue; } diff --git a/PWGLF/Utils/collisionCuts.h b/PWGLF/Utils/collisionCuts.h index 8f8f2f6cde1..5339e263eba 100644 --- a/PWGLF/Utils/collisionCuts.h +++ b/PWGLF/Utils/collisionCuts.h @@ -130,6 +130,6 @@ class CollisonCuts triggerAliases mTrigger = kINT7; ///< Trigger to check for float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) }; -} // namespace o2::analysis::femtoDream +} // namespace o2::analysis #endif /* ANALYSIS_TASKS_PWGLF_COLLISIONCUTS_H_ */ \ No newline at end of file From 1ce71f4431215a2a6144e0443eab56b9ef67ab0e Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Thu, 28 Jul 2022 17:28:34 +0200 Subject: [PATCH 21/22] remove spacing --- PWGLF/TableProducer/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index 4bdf6b1d5a6..11e3443808a 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -31,7 +31,7 @@ o2physics_add_dpl_workflow(cascadefinder o2physics_add_dpl_workflow(nucleustreecreator SOURCES LFTreeCreatorNuclei.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(reso2initializer From 0ece919b37ac1ac69e803e2adb72a607bba897b5 Mon Sep 17 00:00:00 2001 From: Bong-Hwi Lim Date: Thu, 28 Jul 2022 18:17:02 +0200 Subject: [PATCH 22/22] remove duplicated columns --- PWGLF/DataModel/LFResonanceTables.h | 30 ++++++++++------------------- PWGLF/Tasks/phianalysis.cxx | 4 ++-- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index b5de7306108..112b99ea42e 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -85,18 +85,8 @@ DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Obser DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows -DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! DCA_xy -DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! DCA_z -DECLARE_SOA_COLUMN(X, x, float); //! x position of the track -DECLARE_SOA_COLUMN(Alpha, alpha, float); //! alpha position of the track DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection -DECLARE_SOA_COLUMN(TPCnSigmaPi, tpcNSigmaPi, float); //! Pion TPC nSigma -DECLARE_SOA_COLUMN(TPCnSigmaKa, tpcNSigmaKa, float); //! Kaon TPC nSigma -DECLARE_SOA_COLUMN(TPCnSigmaPr, tpcNSigmaPr, float); //! Proton TPC nSigma -DECLARE_SOA_COLUMN(TOFnSigmaPi, tofNSigmaPi, float); //! Pion TOF nSigma -DECLARE_SOA_COLUMN(TOFnSigmaKa, tofNSigmaKa, float); //! Kaon TOF nSigma -DECLARE_SOA_COLUMN(TOFnSigmaPr, tofNSigmaPr, float); //! Proton TOF nSigma DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda @@ -119,18 +109,18 @@ DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS", resodaughter::Indices, resodaughter::Sign, resodaughter::TPCNClsCrossedRows, - resodaughter::DcaXY, - resodaughter::DcaZ, - resodaughter::X, - resodaughter::Alpha, + o2::aod::track::DcaXY, + o2::aod::track::DcaZ, + o2::aod::track::X, + o2::aod::track::Alpha, resodaughter::TPCPIDselectionFlag, resodaughter::TOFPIDselectionFlag, - resodaughter::TPCnSigmaPi, - resodaughter::TPCnSigmaKa, - resodaughter::TPCnSigmaPr, - resodaughter::TOFnSigmaPi, - resodaughter::TOFnSigmaKa, - resodaughter::TOFnSigmaPr, + o2::aod::pidtpc::TPCNSigmaPi, + o2::aod::pidtpc::TPCNSigmaKa, + o2::aod::pidtpc::TPCNSigmaPr, + o2::aod::pidtof::TOFNSigmaPi, + o2::aod::pidtof::TOFNSigmaKa, + o2::aod::pidtof::TOFNSigmaPr, resodaughter::DaughDCA, resodaughter::MLambda, resodaughter::MAntiLambda, diff --git a/PWGLF/Tasks/phianalysis.cxx b/PWGLF/Tasks/phianalysis.cxx index 03932ce6a6d..08bb4c08464 100644 --- a/PWGLF/Tasks/phianalysis.cxx +++ b/PWGLF/Tasks/phianalysis.cxx @@ -51,8 +51,8 @@ struct phianalysis { Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; /// Partition for firstTrack - Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) && requireTPCPIDKaonCutInFilter() && requireTOFPIDKaonCutInFilter() && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts - Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) && requireTPCPIDKaonCutInFilter() && requireTOFPIDKaonCutInFilter() && (nabs(aod::resodaughter::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(aod::resodaughter::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(aod::resodaughter::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts1 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) && requireTPCPIDKaonCutInFilter() && requireTOFPIDKaonCutInFilter() && (nabs(o2::aod::track::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(o2::aod::track::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(o2::aod::track::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts + Partition parts2 = (aod::resodaughter::partType == uint8_t(aod::resodaughter::DaughterType::kTrack)) && requireTPCPIDKaonCutInFilter() && requireTOFPIDKaonCutInFilter() && (nabs(o2::aod::track::dcaZ) > static_cast(cMinDCAzToPVcut)) && (nabs(o2::aod::track::dcaZ) < static_cast(cMaxDCAzToPVcut)) && (nabs(o2::aod::track::dcaXY) < static_cast(cMaxDCArToPVcut)); // Basic DCA cuts void init(o2::framework::InitContext&) { ccdb->setURL("http://alice-ccdb.cern.ch");