diff --git a/PWGLF/DataModel/LFLnnTables.h b/PWGLF/DataModel/LFLnnTables.h index 2ee0fa22839..c8e6a1e8f4f 100644 --- a/PWGLF/DataModel/LFLnnTables.h +++ b/PWGLF/DataModel/LFLnnTables.h @@ -58,6 +58,7 @@ DECLARE_SOA_COLUMN(TPCsignalPi, tpcSignalPi, uint16_t); // TPC DECLARE_SOA_COLUMN(Flags, flags, uint8_t); // Flags for PID in tracking (bits [0, 3] for negative daughter, [4,7] for positive daughter) DECLARE_SOA_COLUMN(TPCmom3H, tpcMom3H, float); // TPC momentum of the 3H daughter DECLARE_SOA_COLUMN(TPCmomPi, tpcMomPi, float); // TPC momentum of the Pi daughter +DECLARE_SOA_COLUMN(MassTrTOF, massTrTOF, float); // TOF 3H mass DECLARE_SOA_COLUMN(ITSclusterSizes3H, itsClusterSizes3H, uint32_t); // ITS cluster size of the 3H daughter DECLARE_SOA_COLUMN(ITSclusterSizesPi, itsClusterSizesPi, uint32_t); // ITS cluster size of the Pi daughter DECLARE_SOA_COLUMN(Dca3H, dca3H, float); // DCA between 3H daughter and V0 @@ -87,6 +88,7 @@ DECLARE_SOA_TABLE(DataLnnCands, "AOD", "LNNCANDS", lnnrec::DcaV0Daug, lnnrec::Dca3H, lnnrec::DcaPi, lnnrec::NSigma3H, lnnrec::NTPCclus3H, lnnrec::NTPCclusPi, lnnrec::TPCmom3H, lnnrec::TPCmomPi, lnnrec::TPCsignal3H, lnnrec::TPCsignalPi, + lnnrec::MassTrTOF, lnnrec::ITSclusterSizes3H, lnnrec::ITSclusterSizesPi, lnnrec::Flags); @@ -102,6 +104,7 @@ DECLARE_SOA_TABLE(MCLnnCands, "AOD", "MCLNNCANDS", lnnrec::DcaV0Daug, lnnrec::Dca3H, lnnrec::DcaPi, lnnrec::NSigma3H, lnnrec::NTPCclus3H, lnnrec::NTPCclusPi, lnnrec::TPCmom3H, lnnrec::TPCmomPi, lnnrec::TPCsignal3H, lnnrec::TPCsignalPi, + lnnrec::MassTrTOF, lnnrec::ITSclusterSizes3H, lnnrec::ITSclusterSizesPi, lnnrec::Flags, lnnrec::GenPt, @@ -119,4 +122,4 @@ using DataLnnCand = DataLnnCands::iterator; using MCLnnCand = MCLnnCands::iterator; } // namespace o2::aod -#endif // PWGLF_DATAMODEL_LFLNNTABLES_H_ \ No newline at end of file +#endif // PWGLF_DATAMODEL_LFLNNTABLES_H_ diff --git a/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx b/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx index 86f0609f662..8a74d4f39b0 100644 --- a/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx @@ -12,6 +12,7 @@ // Build \Lambda-n-n candidates from V0s and tracks // ============================================================================== #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -30,26 +31,36 @@ #include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" +#include "Common/DataModel/PIDResponse.h" + #include "Common/Core/PID/TPCPIDResponse.h" #include "DataFormatsTPC/BetheBlochAleph.h" #include "DCAFitter/DCAFitterN.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Common/Core/PID/PIDTOF.h" +#include "Common/TableProducer/PID/pidTOFBase.h" + #include "PWGLF/DataModel/LFLnnTables.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; -using TracksFull = soa::Join; +using TracksFull = soa::Join; +using TracksFullMC = soa::Join; using CollisionsFull = soa::Join; using CollisionsFullMC = soa::Join; +o2::pid::tof::Beta responseBeta; +o2::pid::tof::Beta responseBetaMC; + namespace { constexpr double betheBlochDefault[1][6]{{-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}}; static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; -static const std::vector particleNames{"3H"}; - +static const std::vector NucleiName{"3H"}; std::shared_ptr hEvents; std::shared_ptr hZvtx; std::shared_ptr hCentFT0A; @@ -87,6 +98,7 @@ struct lnnCandidate { float piDCAXY = -10; float mom3HTPC = -10.f; float momPiTPC = -10.f; + float massTrTOF = 10.f; std::array mom3H; std::array momPi; std::array decVtx; @@ -117,11 +129,14 @@ struct lnnRecoTask { Configurable v0cospa{"lnncospa", 0.95, "V0 CosPA"}; Configurable masswidth{"lnnmasswidth", 0.006, "Mass width (GeV/c^2)"}; Configurable dcav0dau{"lnndcaDau", 1.0, "DCA V0 Daughters"}; + Configurable Chi2nClusTPC{"Chi2NClusTPC", 4., "Chi2 / nClusTPC for triton track"}; + Configurable Chi2nClusITS{"Chi2NClusITS", 36., "Chi2 / nClusITS for triton track"}; Configurable ptMin{"ptMin", 0.5, "Minimum pT of the lnncandidate"}; - Configurable TPCRigidityMin3H{"TPCRigidityMin3H", 1, "Minimum rigidity of the triton candidate"}; - Configurable etaMax{"eta", 1., "eta daughter"}; - Configurable nSigmaMax3H{"nSigmaMax3H", 5, "triton dEdx cut (n sigma)"}; + Configurable etaMax{"eta", 0.8, "eta daughter"}; + Configurable TPCRigidityMin3H{"TPCRigidityMin3H", 0.5, "Minimum rigidity of the triton candidate"}; + Configurable nSigmaCutTPC{"nSigmaCutTPC", 4., "triton dEdx cut (n sigma)"}; Configurable nTPCClusMin3H{"nTPCClusMin3H", 80, "triton NTPC clusters cut"}; + Configurable nClusITS{"nClusITSMin3H", 5.0, "triton NITS clusters cut"}; Configurable mcSignalOnly{"mcSignalOnly", true, "If true, save only signal in MC"}; // Define o2 fitter, 2-prong, active memory (no need to redefine per event) @@ -132,7 +147,7 @@ struct lnnRecoTask { float piMass = o2::constants::physics::MassPionCharged; // bethe bloch parameters - Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 1, 6, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for 3H"}; + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 1, 6, NucleiName, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for 3H"}; Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; // CCDB options @@ -149,12 +164,12 @@ struct lnnRecoTask { Configurable lnnPdg{"lnnPdg", 1010000030, "PDG Lnn"}; // PDG Lnn // histogram axes - ConfigurableAxis rigidityBins{"rigidityBins", {200, -6.f, 6.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; - ConfigurableAxis dEdxBins{"dEdxBins", {1000, 0.f, 1000.f}, "Binning for dE/dx"}; + ConfigurableAxis rigidityBins{"rigidityBins", {200, -10.f, 10.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; + ConfigurableAxis dEdxBins{"dEdxBins", {5000, 0.f, 1000.f}, "Binning for dE/dx"}; ConfigurableAxis nSigmaBins{"nSigmaBins", {200, -5.f, 5.f}, "Binning for n sigma"}; ConfigurableAxis zVtxBins{"zVtxBins", {100, -20.f, 20.f}, "Binning for n sigma"}; ConfigurableAxis centBins{"centBins", {100, 0.f, 100.f}, "Binning for centrality"}; - ConfigurableAxis TritMomBins{"TritMom", {100, 0.f, 6.f}, "Binning for Triton TPC momentum"}; + ConfigurableAxis TritMomBins{"TritMom", {100, 0.f, 10.f}, "Binning for Triton TPC momentum"}; // std vector of candidates std::vector lnnCandidates; @@ -278,6 +293,7 @@ struct lnnRecoTask { if (mBBparams3H[5] < 0) { LOG(fatal) << "Bethe-Bloch parameters for 3H not set, please check your CCDB and configuration"; } + for (auto& v0 : V0s) { auto posTrack = v0.posTrack_as(); @@ -290,9 +306,6 @@ struct lnnRecoTask { float posRigidity = posTrack.tpcInnerParam(); float negRigidity = negTrack.tpcInnerParam(); - hdEdxTot->Fill(posRigidity, posTrack.tpcSignal()); - hdEdxTot->Fill(-negRigidity, negTrack.tpcSignal()); - // Bethe-Bloch calcution for 3H & nSigma calculation double expBethePos{tpc::BetheBlochAleph(static_cast(posRigidity / constants::physics::MassTriton), mBBparams3H[0], mBBparams3H[1], mBBparams3H[2], mBBparams3H[3], mBBparams3H[4])}; double expBetheNeg{tpc::BetheBlochAleph(static_cast(negRigidity / constants::physics::MassTriton), mBBparams3H[0], mBBparams3H[1], mBBparams3H[2], mBBparams3H[3], mBBparams3H[4])}; @@ -302,8 +315,8 @@ struct lnnRecoTask { auto nSigmaTPCneg = static_cast((negTrack.tpcSignal() - expBetheNeg) / expSigmaNeg); // ITS only tracks do not have TPC information. TPCnSigma: only lower cut to allow for triton reconstruction - bool is3H = posTrack.hasTPC() && nSigmaTPCpos > -1 * nSigmaMax3H; - bool isAnti3H = negTrack.hasTPC() && nSigmaTPCneg > -1 * nSigmaMax3H; + bool is3H = posTrack.hasTPC() && nSigmaTPCpos > -1 * nSigmaCutTPC; + bool isAnti3H = negTrack.hasTPC() && nSigmaTPCneg > -1 * nSigmaCutTPC; if (!is3H && !isAnti3H) continue; @@ -313,17 +326,21 @@ struct lnnRecoTask { lnnCand.isMatter = is3H && isAnti3H ? std::abs(nSigmaTPCpos) < std::abs(nSigmaTPCneg) : is3H; auto& h3track = lnnCand.isMatter ? posTrack : negTrack; auto& h3Rigidity = lnnCand.isMatter ? posRigidity : negRigidity; - if (h3track.tpcNClsFound() < nTPCClusMin3H || h3Rigidity < TPCRigidityMin3H) { + + if (h3Rigidity < TPCRigidityMin3H || + h3track.tpcNClsFound() < nTPCClusMin3H || + h3track.tpcChi2NCl() > Chi2nClusTPC || + h3track.itsChi2NCl() > Chi2nClusITS || + h3track.itsNCls() < nClusITS) { continue; } lnnCand.nSigma3H = lnnCand.isMatter ? nSigmaTPCpos : nSigmaTPCneg; - lnnCand.nTPCClusters3H = lnnCand.isMatter ? posTrack.tpcNClsFound() : negTrack.tpcNClsFound(); - lnnCand.tpcSignal3H = lnnCand.isMatter ? posTrack.tpcSignal() : negTrack.tpcSignal(); - lnnCand.clusterSizeITS3H = lnnCand.isMatter ? posTrack.itsClusterSizes() : negTrack.itsClusterSizes(); - lnnCand.nTPCClustersPi = !lnnCand.isMatter ? posTrack.tpcNClsFound() : negTrack.tpcNClsFound(); - lnnCand.tpcSignalPi = !lnnCand.isMatter ? posTrack.tpcSignal() : negTrack.tpcSignal(); - lnnCand.clusterSizeITSPi = !lnnCand.isMatter ? posTrack.itsClusterSizes() : negTrack.itsClusterSizes(); + lnnCand.nTPCClusters3H = lnnCand.isMatter ? h3track.tpcNClsFound() : negTrack.tpcNClsFound(); + lnnCand.clusterSizeITS3H = lnnCand.isMatter ? h3track.itsClusterSizes() : negTrack.itsClusterSizes(); + lnnCand.nTPCClustersPi = !lnnCand.isMatter ? h3track.tpcNClsFound() : negTrack.tpcNClsFound(); + lnnCand.tpcSignalPi = !lnnCand.isMatter ? h3track.tpcSignal() : negTrack.tpcSignal(); + lnnCand.clusterSizeITSPi = !lnnCand.isMatter ? h3track.itsClusterSizes() : negTrack.itsClusterSizes(); lnnCand.mom3HTPC = lnnCand.isMatter ? posRigidity : negRigidity; lnnCand.momPiTPC = !lnnCand.isMatter ? posRigidity : negRigidity; @@ -399,6 +416,13 @@ struct lnnRecoTask { lnnCand.decVtx[i] = lnnCand.decVtx[i] - primVtx[i]; } + if (h3track.hasTOF()) { + float beta = responseBeta.GetBeta(h3track); + beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); /// sometimes beta > 1 or < 0, to be checked + float TPCinnerParam3H = h3track.tpcInnerParam(); + lnnCand.massTrTOF = TPCinnerParam3H * std::sqrt(1.f / (beta * beta) - 1.f); + } + // if survived all selections, propagate decay daughters to PV gpu::gpustd::array dcaInfo; @@ -413,14 +437,17 @@ struct lnnRecoTask { lnnCand.posTrackID = posTrack.globalIndex(); lnnCand.negTrackID = negTrack.globalIndex(); + hdEdxTot->Fill(posRigidity, posTrack.tpcSignal()); + hdEdxTot->Fill(-negRigidity, negTrack.tpcSignal()); int chargeFactor = -1 + 2 * lnnCand.isMatter; hdEdx3HSel->Fill(chargeFactor * lnnCand.mom3HTPC, h3track.tpcSignal()); hNsigma3HSel->Fill(chargeFactor * lnnCand.mom3HTPC, lnnCand.nSigma3H); - lnnCandidates.push_back(lnnCand); if (is3H) { hdEdx3HTPCMom->Fill(lnnCand.mom3HTPC, h3track.tpcSignal()); } + + lnnCandidates.push_back(lnnCand); } } @@ -504,6 +531,7 @@ struct lnnRecoTask { lnnCand.dcaV0dau, lnnCand.h3DCAXY, lnnCand.piDCAXY, lnnCand.nSigma3H, lnnCand.nTPCClusters3H, lnnCand.nTPCClustersPi, lnnCand.mom3HTPC, lnnCand.momPiTPC, lnnCand.tpcSignal3H, lnnCand.tpcSignalPi, + lnnCand.massTrTOF, lnnCand.clusterSizeITS3H, lnnCand.clusterSizeITSPi, lnnCand.flags); } } @@ -511,7 +539,7 @@ struct lnnRecoTask { PROCESS_SWITCH(lnnRecoTask, processData, "Data analysis", true); // MC process - void processMC(CollisionsFullMC const& collisions, aod::McCollisions const& mcCollisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) + void processMC(CollisionsFullMC const& collisions, aod::McCollisions const& mcCollisions, aod::V0s const& V0s, TracksFullMC const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) { filledMothers.clear(); @@ -525,7 +553,7 @@ struct lnnRecoTask { hEvents->Fill(0.); - if ((collision.posZ()) > 10) { + if (std::abs(collision.posZ()) > 10) { continue; } hEvents->Fill(1.); @@ -560,6 +588,7 @@ struct lnnRecoTask { lnnCand.dcaV0dau, lnnCand.h3DCAXY, lnnCand.piDCAXY, lnnCand.nSigma3H, lnnCand.nTPCClusters3H, lnnCand.nTPCClustersPi, lnnCand.mom3HTPC, lnnCand.momPiTPC, lnnCand.tpcSignal3H, lnnCand.tpcSignalPi, + lnnCand.massTrTOF, lnnCand.clusterSizeITS3H, lnnCand.clusterSizeITSPi, lnnCand.flags, chargeFactor * lnnCand.genPt(), lnnCand.genPhi(), lnnCand.genEta(), lnnCand.genPt3H(), lnnCand.gDecVtx[0], lnnCand.gDecVtx[1], lnnCand.gDecVtx[2], lnnCand.isReco, lnnCand.isSignal, lnnCand.survEvSelection); @@ -629,6 +658,7 @@ struct lnnRecoTask { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, chargeFactor * lnnCand.genPt(), lnnCand.genPhi(), lnnCand.genEta(), lnnCand.genPt3H(), lnnCand.gDecVtx[0], lnnCand.gDecVtx[1], lnnCand.gDecVtx[2], lnnCand.isReco, lnnCand.isSignal, lnnCand.survEvSelection);