diff --git a/PWGHF/Core/SelectorCuts.h b/PWGHF/Core/SelectorCuts.h index a3df78aee0f..070a0cdf105 100644 --- a/PWGHF/Core/SelectorCuts.h +++ b/PWGHF/Core/SelectorCuts.h @@ -842,6 +842,93 @@ static const std::vector labelsPt = { static const std::vector labelsCutVar = {"m", "pT p", "pT K", "pT Pi", "chi2PCA", "decay length", "cos pointing angle", "decLengthXY", "normDecLXY", "ct", "impParXY"}; } // namespace hf_cuts_xic_to_p_k_pi +namespace hf_cuts_to_xi_pi +{ +static constexpr int NBinsPt = 13; +static constexpr int NCutVars = 26; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double BinsPt[NBinsPt + 1] = { + 0., + 1., + 2., + 3., + 4., + 5., + 6., + 7., + 8., + 9., + 10., + 11., + 12., + 20.}; +auto vecBinsPt = std::vector{BinsPt, BinsPt + NBinsPt + 1}; + +// default values for the cuts +constexpr double Cuts[NBinsPt][NCutVars] = { + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, + {2.0, 3.1, 0.01, 0.01, 0.2, 0.15, 1.0, 1.0, 2.0, 0.06, 0.06, 0.04, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.0, 10.0, 0.97, 0.97, 0.6, 1.2, 1.0, 0.8}, +}; + +// row labels +static const std::vector labelsPt = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11", + "pT bin 12"}; + +// column labels +static const std::vector labelsCutVar = { + "mCharmBaryonMin", + "mCharmBaryonMax", + "massWindowCascade", + "massWindowV0", // Invariant mass + "ptCharmBachelorMin", + "ptBachelorMin", // pt of daughter + "dcaCascDauMax", + "dcaV0DauMax", + "dcaCharmBaryonDauMax", // dca between daughters + "dcaxyV0PosDauToPvMin", + "dcaxyV0NegDauToPvMin", + "dcaxyBachToPvMin", // DCAXY(impact parameter) + "impactParXYCharmBachelorMin", + "impactParXYCharmBachelorMax", + "impactParZCharmBachelorMin", + "impactParZCharmBachelorMax", // DCAXY(impact parameter) + "impactParXYCascMin", + "impactParXYCascMax", + "impactParZCascMin", + "impactParZCascMax", // DCAXY(impact parameter) + "cosPaCascMin", + "cosPaV0Min", // CosPa + "radiusCascMin", + "radiusV0Min", // radius + "etaTrackLFDauMax", + "etaTrackCharmBachMax" // eta cut to daughter tracks +}; +} // namespace hf_cuts_to_xi_pi + namespace hf_cuts_xic_to_xi_pi_pi { static constexpr int NBinsPt = 13; diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx index 5f3e0b3ebba..f78515a4df8 100644 --- a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx +++ b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx @@ -9,2508 +9,1541 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file candidateCreatorXic0Omegac0.cxx -/// \brief Reconstruction of Omegac0 and Xic0 decays candidates -/// \author Federica Zanone , Heidelberg University -/// \author Ruiqi Yin , Fudan University -/// \author Yunfan Liu , China University of Geosciences -/// \author Ran Tu , Fudan University -/// \author Tao Fang , Central China Normal University +/// \file candidateCreatorXic0Omegac0Qa.cxx +/// \brief Reconstruction of Xic0 and Xicp candiates with hadronic decay chain +/// +/// \author Jinhyun Park , Pusan National University +/// \author Krista Smith , Pusan National University #ifndef HomogeneousField #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) #endif -#include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/mcCentrality.h" -#include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" -#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Tools/KFparticle/KFUtilities.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/DCA.h" + #include #include #include #include +#include +#include -#include - -#include -#include -#include +#include #include -#include -#include #include +#include #include using namespace o2; -using namespace o2::track; using namespace o2::aod; -using namespace o2::aod::cascdata; -using namespace o2::aod::v0data; -using namespace o2::aod::hf_track_index; -using namespace o2::hf_centrality; -using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::hf_centrality; +using namespace o2::hf_occupancy; +using namespace o2::constants::physics; using namespace o2::hf_evsel; -enum McMatchFlag : uint8_t { - None = 0, - CharmbaryonUnmatched, - CascUnmatched, - V0Unmatched -}; - -// Reconstruction of omegac0 and xic0 candidates -struct HfCandidateCreatorXic0Omegac0 { - Produces rowCandToXiPi; - Produces rowCandToOmegaPi; - Produces rowCandToOmegaK; - Produces kfCandidateData; - Produces kfCandidateXicData; - Produces rowKfXic0Qa; - Produces kfCandidateOmegaKaData; - - Configurable propagateToPCA{"propagateToPCA", false, "create tracks version propagated to PCA"}; - Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; - Configurable useWeightedFinalPCA{"useWeightedFinalPCA", true, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; - Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; - Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; - Configurable maxDXYIni{"maxDXYIni", 4., "reject (if>0) PCA candidate if tracks DXY exceeds threshold"}; - Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; - Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations is chi2/chi2old > this"}; - Configurable maxChi2{"maxChi2", 100., "discard vertices with chi2/Nprongs > this (or sum{DCAi^2}/Nprongs for abs. distance minimization)"}; - Configurable refitWithMatCorr{"refitWithMatCorr", true, "when doing propagateTracksToVertex, propagate tracks to vtx with material corrections and rerun minimization"}; - Configurable rejDiffCollTrack{"rejDiffCollTrack", true, "Reject tracks coming from different collisions"}; - Configurable fillAllHist{"fillAllHist", true, "Fill additional KF histograms to check selector cuts"}; - Configurable doCascadePreselection{"doCascadePreselection", true, "Use invariant mass and dcaXY cuts to preselect cascade candidates"}; - Configurable dcaXYToPVCascadeMax{"dcaXYToPVCascadeMax", 3.0, "Max cascade DCA to PV in xy plane"}; - Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 1.0, "Max DCA of V0 daughter"}; - Configurable dcaCascDaughtersMax{"dcaCascDaughtersMax", 1.0, "Max DCA of cascade daughter"}; - - // magnetic field setting from CCDB - Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; - Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; - Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; - - // KFParticle process setting - // V0 cuts - Configurable lambdaMassWindow{"lambdaMassWindow", 0.0075, "Distance from Lambda mass"}; - // cascade cuts - Configurable massToleranceCascade{"massToleranceCascade", 0.01, "Invariant mass tolerance for cascade"}; - Configurable massToleranceCascadeRej{"massToleranceCascadeRej", 0.01, "Invariant mass tolerance for rejected Xi"}; - // for KF particle operation - Configurable kfConstructMethod{"kfConstructMethod", 2, "KF Construct Method"}; - Configurable kfUseV0MassConstraint{"kfUseV0MassConstraint", false, "KF: use Lambda mass constraint"}; - Configurable kfUseCascadeMassConstraint{"kfUseCascadeMassConstraint", false, "KF: use Cascade mass constraint"}; - Configurable kfResolutionQA{"kfResolutionQA", false, "KF: KFParticle Quality Assurance"}; - - HfEventSelection hfEvSel; // event selection and monitoring - o2::vertexing::DCAFitterN<2> df; // 2-prong vertex fitter to build the omegac/xic vertex +struct HfCandidateCreatorXic0Omegac0Qa { + + // Cursor to fill tables + struct : ProducesGroup { + // Candidates created with DCAFitter + Produces rowCandToXiPi; + Produces rowCandToOmegaPi; + Produces rowCandToOmegaKa; + // Candidate created with KFParticle + Produces rowCandToXiPiKf; + Produces rowCandToOmegaPiKf; + Produces rowCandToOmegaKaKf; + } cursors; + + // Configurables + struct : ConfigurableGroup { + // Switch for filling histograms + Configurable fillHistograms{"fillHistograms", true, "fill validation plots"}; + // Magnetic field setting from CCDB + Configurable isRun2{"isRun2", false, "enable Run2 or Run3 GRP objects for magnetic field"}; + Configurable ccdbUrl{"ccdbUrl", "https://alice-ccdb.cern.ch", "url of the ccdb object"}; + Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parameterization"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "path of the group file (Run2)"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run3)"}; + // Cascade preselection + Configurable doCascadePreselection{"doCascadePreselection", true, "Use invariant mass and dcaXY cuts to preselect cascade candidates"}; + Configurable massToleranceCascade{"massToleranceCascade", 0.01, "Invariant mass tolerance for cascades"}; + Configurable dcaXYToPVCascadeMax{"dcaXYToPVCascadeMax", 3, "Max cascade DCA to PV in XY plane"}; + Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 1.0, "Max DCA of V0 daughter"}; + Configurable dcaCascDaughtersMax{"dcaCascDaughtersMax", 1.0, "Max DCA of cascade daughter"}; + // DCAFitter + Configurable propagateToPCA{"propagateToPCA", true, "Create tracks version propagated to PCA"}; + Configurable maxR{"maxR", 200., "Reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 4., "Reject (if>0) PCA candidate if tracks DZ exceeds this threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3, "Stop iteration if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9, "Stop iteration if Chi2/Chi2old > this"}; + Configurable useAbsDCA{"useAbsDCA", false, "Minimise abs. distance rather than chi2"}; + Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariance, effective only if useAbsDCA is true"}; + // KFParticle + Configurable kfConstructMethod{"kfConstructMethod", 2, "2 : Daughter particle masses stay fixed in construction process"}; + Configurable rejDiffCollTrack{"rejDiffCollTrack", true, "Reject tracks comming from different collisions(effective only for KFParticle w/o derived data)"}; + Configurable kfDoCascadePreselection{"kfDoCascadePreselection", false, "Use invariant mass and dcaXY cuts to preselect cascade candidates"}; + Configurable kfConstrainInvMassV0{"kfConstrainInvMassV0", false, "KF : Use Lambda mass constraint"}; + // Configurable kfConstrainTopoV0ToCasc{"kfConstrainTopoV0ToCasc", false, "KF : Use Lambda topo constraint"}; // -> Not sure if this will be used... + Configurable kfConstrainInvMassCasc{"kfConstrainInvMassCasc", true, "use mass constraint for cascade"}; + // Configurable kfConstrainTopoCascToCharmBaryon{"kfConstrainTopoCascToCharmBaryon", true, "use topo constraint for cascade"}; + Configurable kfConstrainInvMassCharmBaryon{"kfConstrainInvMassCharmBaryon", false, "constrain invariant mass of charm baryon candidate"}; + // Configurable constrainTopoCascToChramBaryon{"constrainTopoCascToChramBaryon", false, "constrain Casc to Charm Baryon"}; + // Configurable kfConstrainTopoCharmBaryon{"kfConstrainTopoCharmBaryon", false, "constrain charm baryon candidate to decay vertex"}; + // configurbles for histogram binning + Configurable nBinXiMass{"nBinXiMass", 1000, "nBinXiMass"}; + Configurable xiMassMin{"xiMassMin", 1.0, "xiMassMin"}; + Configurable xiMassMax{"xiMassMax", 2.0, "xiMassMax"}; + Configurable nBinXic0Mass{"nBinXic0Mass", 3000, "nBinXic0Mass"}; + Configurable xic0MassMin{"xic0MassMin", 1.0, "xic0MassMin"}; + Configurable xic0MassMax{"xic0MassMax", 4.0, "xic0MassMax"}; + Configurable nBinCpa2Prong{"nBinCpa2Prong", 240, "nBinCpa2Prong"}; + Configurable cpa2ProngMin{"cpa2ProngMin", -1.2, "cpa2ProngMin"}; + Configurable cpa2ProngMax{"cpa2ProngMax", 1.2, "cpa2ProngMax"}; + Configurable nBinImpParXYXi{"nBinImpParXYXi", 30, "nBinImpParXYXi"}; + Configurable impParXYXiMin{"impParXYXiMin", -1.5, "impParXYXiMin"}; + Configurable impParXYXiMax{"impParXYXiMax", 1.5, "impParXYXiMax"}; + Configurable nBinImpParXYPi{"nBinImpParXYPi", 30, "nBinImpParXYPi"}; + Configurable impParXYPiMin{"impParXYPiMin", -1.5, "impParXYPiMin"}; + Configurable impParXYPiMax{"impParXYPiMax", 1.5, "impParXYPiMax"}; + Configurable nBinPtXi{"nBinPtXi", 100, "nBinPtXi"}; + Configurable ptXiMin{"ptXiMin", 0.0, "ptXiMin"}; + Configurable ptXiMax{"ptXiMax", 20.0, "ptXiMax"}; + Configurable nBinPtPi{"nBinPtPi", 100, "nBinPtPi"}; + Configurable ptPiMin{"ptPiMin", 0.0, "ptPiMin"}; + Configurable ptPiMax{"ptPiMax", 20.0, "ptPiMax"}; + } configs; + + // For magnetic field Service ccdb; o2::base::MatLayerCylSet* lut; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - int runNumber{-1}; - double magneticField{0.}; - - using MyCascTable = soa::Join; - using MyTraCascTable = soa::Join; // to use strangeness tracking - using CascadesLinked = soa::Join; - using TraCascadesLinked = soa::Join; - using MyV0Table = soa::Join; - using MyLFTracksWCov = soa::Join; - - using MyKfTracksIU = soa::Join; - using MyKfTracks = soa::Join; - using MyKfCascTable = soa::Join; - using KFCascadesLinked = soa::Join; - std::shared_ptr hInvMassCharmBaryonToXiPi, hInvMassCharmBaryonToOmegaPi, hInvMassCharmBaryonToOmegaK, hFitterStatusToXiPi, hFitterStatusToOmegaPi, hFitterStatusToOmegaK, hCandidateCounterToXiPi, hCandidateCounterToOmegaPi, hCandidateCounterToOmegaK, hCascadesCounterToXiPi, hCascadesCounterToOmegaPi, hCascadesCounterToOmegaK; - - HistogramRegistry registry{"registry"}; - // Helper struct to pass information - struct { - float chi2GeoV0; - float ldlV0; - float chi2NdfTopoV0ToPv; - float chi2GeoCasc; - float ldlCasc; - float chi2NdfTopoCascToPv; - float decayLenXYLambda; - float decayLenXYCasc; - float cosPaV0ToCasc; - float cosPaXYV0ToCasc; - float cosPaV0ToPv; - float cosPaXYV0ToPv; - float cosPaCascToOmegac; - float cosPaXYCascToOmegac; - float cosPaCascToPv; - float cosPaXYCascToPv; - float massV0; - float massCasc; - float ptPiFromOmegac; - float ptOmegac; - float rapOmegac; - float massOmegac; - float cosThetaStarPiFromOmegac; - float chi2NdfTopoPiFromOmegacToPv; - float deviationPiFromOmegacToPv; - float kfDcaXYPiFromOmegac; - float chi2NdfTopoV0ToCasc; - float chi2NdfTopoCascToOmegac; - float decayLenXYOmegac; - float chi2GeoOmegac; - float kfDcaV0Dau; - float kfDcaCascDau; - float kfDcaOmegacDau; - float kfDcaXYCascToPv; - float chi2NdfTopoOmegacToPv; - float cosPaOmegacToPv; - float cosPaXYOmegacToPv; - float ldlOmegac; - float ctV0; - float ctCasc; - float ctOmegac; - float chi2MassV0; - float chi2MassCasc; - float etaOmegac; - float cascRejectInvmass; // rej - } kfOmegac0Candidate; - - struct { - float chi2GeoV0; - float ldlV0; - float chi2NdfTopoV0ToPv; - float chi2GeoCasc; - float ldlCasc; - float chi2NdfTopoCascToPv; - float decayLenXYLambda; - float decayLenXYCasc; - float cosPaV0ToCasc; - float cosPaXYV0ToCasc; - float cosPaV0ToPv; - float cosPaXYV0ToPv; - float cosPaCascToXic; - float cosPaXYCascToXic; - float cosPaCascToPv; - float cosPaXYCascToPv; - float massV0; - float massCasc; - float rapXic; - float massXic; - float cosThetaStarPiFromXic; - float chi2NdfTopoPiFromXicToPv; - float kfDcaXYPiFromXic; - float chi2NdfTopoV0ToCasc; - float chi2NdfTopoCascToXic; - float decayLenXYXic; - float chi2GeoXic; - float kfDcaV0Dau; - float kfDcaCascDau; - float kfDcaXicDau; - float kfDcaXYCascToPv; - float chi2NdfTopoXicToPv; - float cosPaXicToPv; - float cosPaXYXicToPv; - float ldlXic; - float ctV0; - float ctCasc; - float ctXic; - float chi2MassV0; - float chi2MassCasc; - float etaXic; - } kfXic0Candidate; + // DCAFitter + o2::vertexing::DCAFitterN<2> df; + + int runNumber{0}; + double bz{0.}; + float massCharmBaryonCand{0.}; + + enum CharmBaryonCandCounter { All = 0, + HfFlagPass, + CascPreSel, + VertexFit }; + + using SelectedCollisions = soa::Join; + // Tracked cascades + using TrackedCascFull = soa::Join; + using TrackedCascLinked = soa::Join; + // For DCAFitter + using CascFull = soa::Join; + using CascadesLinked = soa::Join; + // For KFParticle + using KFCascFull = soa::Join; + using KFCascadesLinked = soa::Join; + using TracksWCovDcaExtraPidPrPiKa = soa::Join; + + HistogramRegistry registry{"hists"}; + HfEventSelection hfEvSel; + + // For candidate reconstruction in different PID hypothesis + // Each decay channel assgined by following hf_cand_casc_lf_DecayType2Prong enum + // Index 0: Xic0/Omegac0 -> Xi- Pi+ Index 1: Omegac0 -> Omega- Pi+ Index 2: Omegac0 -> Omega- K+ + // Xi- -> Lambda0 pi-, Omeag- -> Lambda0 K- + // Lambda0 -> Pr+ Pi- + std::array pdgOfCharmBaryon = {+kXiC0, +kOmegaC0, +kOmegaC0}; // -> This need to be fixed...? +kXiC0, +kOmegaC0, +kOmegaC0, +kOmeagC0 + std::array pdgOfCharmBach = {+kPiPlus, +kPiPlus, +kKPlus}; + std::array pdgOfCascade = {+kXiMinus, +kOmegaMinus, +kOmegaMinus}; + std::array pdgOfBach = {+kPiMinus, +kKMinus, +kKMinus}; + std::array pdgOfV0 = {+kLambda0, +kLambda0, +kLambda0}; + std::array pdgOfV0DauPos = {+kProton, +kProton, +kProton}; + std::array pdgOfV0DauNeg = {+kPiMinus, +kPiMinus, +kPiMinus}; + + std::array trackPidOfCascade = {o2::track::PID::XiMinus, o2::track::PID::OmegaMinus, o2::track::PID::OmegaMinus}; + std::array massOfCascades = {MassXiMinus, MassOmegaMinus, MassOmegaMinus}; + std::array massOfCharmBach = {MassPiPlus, MassPiPlus, MassKPlus}; + + // Pointer of histograms for QA + std::shared_ptr hInvMassCharmBaryonToXiPi, hInvMassCharmBaryonToOmegaPi, hInvMassCharmBaryonToOmegaKa; + std::shared_ptr hCandidateCounterToXiPi, hCandidateCounterToOmegaPi, hCandidateCounterToOmegaKa; + std::shared_ptr hCascadesCounterToXiPi, hCascadesCounterToOmegaPi, hCascadesCounterToOmegaKa; void init(InitContext const&) { - std::array allProcesses = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentToOmegaPi, doprocessNoCentOmegacToOmegaPiWithKFParticle, doprocessCentFT0COmegacToOmegaPiWithKFParticle, doprocessCentFT0MOmegacToOmegaPiWithKFParticle, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK, doprocessNoCentXicToXiPiWithKFParticle, doprocessCentFT0CXicToXiPiWithKFParticle, doprocessCentFT0MXicToXiPiWithKFParticle}; - if (std::accumulate(allProcesses.begin(), allProcesses.end(), 0) == 0) { - LOGP(fatal, "No process function enabled, please select one for at least one channel."); + std::vector processesToXiPiDca{doprocessToXiPiWithDCAFitterNoCent, doprocessToXiPiWithDCAFitterNoCentWithTrackedCasc, doprocessToXiPiWithDCAFitterCentFT0C, doprocessToXiPiWithDCAFitterCentFT0M}; + std::vector processesToOmegaPiDca{doprocessToOmegaPiWithDCAFitterNoCent, doprocessToOmegaPiWithDCAFitterCentFT0C, doprocessToOmegaPiWithDCAFitterCentFT0M}; + std::vector processesToOmegaKaDca{doprocessToOmegaKaWithDCAFitterNoCent, doprocessToOmegaKaWithDCAFitterCentFT0C, doprocessToOmegaKaWithDCAFitterCentFT0M}; + std::vector processesToXiPiKf{doprocessToXiPiWithKFParticleNoCent, doprocessToXiPiWithKFParticleCentFT0C, doprocessToXiPiWithKFParticleCentFT0M}; + std::vector processesToOmegaPiKf{doprocessToOmegaPiWithKFParticleNoCent, doprocessToOmegaPiWithKFParticleCentFT0C, doprocessToOmegaPiWithKFParticleCentFT0M}; + std::vector processesToOmegaKaKf{doprocessToOmegaKaWithKFParticleNoCent, doprocessToOmegaKaWithKFParticleCentFT0C, doprocessToOmegaKaWithKFParticleCentFT0M}; + std::vector processesCollMonitoring{doprocessCollisionsNoCent, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; + + int xipiEnabledDca = std::accumulate(processesToXiPiDca.begin(), processesToXiPiDca.end(), 0); + int xipiEnabledKf = std::accumulate(processesToXiPiKf.begin(), processesToXiPiKf.end(), 0); + int omegapiEnabledDca = std::accumulate(processesToOmegaPiDca.begin(), processesToOmegaPiDca.end(), 0); + int omegapiEnabledKf = std::accumulate(processesToOmegaPiKf.begin(), processesToOmegaPiKf.end(), 0); + int omegakaEnabledDca = std::accumulate(processesToOmegaKaDca.begin(), processesToOmegaKaDca.end(), 0); + int omegakaEnabledKf = std::accumulate(processesToOmegaKaKf.begin(), processesToOmegaKaKf.end(), 0); + + // Exit if workflow is not configured correctly - More than one process function enabled for candidate to XiPi + if ((xipiEnabledDca > 0) && (xipiEnabledKf > 0)) { + LOGP(fatal, "More than one process function enabled for candidte decaying to xi pi"); } - std::array processesToXiPi = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentXicToXiPiWithKFParticle, doprocessCentFT0CXicToXiPiWithKFParticle, doprocessCentFT0MXicToXiPiWithKFParticle}; - if (std::accumulate(processesToXiPi.begin(), processesToXiPi.end(), 0) > 1) { - LOGP(fatal, "One and only one ToXiPi process function must be enabled at a time."); - } - std::array processesToOmegaPi = {doprocessNoCentToOmegaPi, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentOmegacToOmegaPiWithKFParticle, doprocessCentFT0COmegacToOmegaPiWithKFParticle, doprocessCentFT0MOmegacToOmegaPiWithKFParticle}; - if (std::accumulate(processesToOmegaPi.begin(), processesToOmegaPi.end(), 0) > 1) { - LOGP(fatal, "One and only one process ToOmegaPi function must be enabled at a time."); - } - std::array processesToOmegaK = {doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK}; - if (std::accumulate(processesToOmegaK.begin(), processesToOmegaK.end(), 0) > 1) { - LOGP(fatal, "One and only one process ToOmegaK function must be enabled at a time."); + // Exit if workflow is not configured correctly - More than one process function enabled for candidate to OmegaPi + if ((omegapiEnabledDca > 0) && (omegapiEnabledKf > 0)) { + LOGP(fatal, "More than one process function enabled for candidte decaying to omega pi"); } - std::array processesCollisions = {doprocessCollisions, doprocessCollisionsCentFT0C, doprocessCollisionsCentFT0M}; - const int nProcessesCollisions = std::accumulate(processesCollisions.begin(), processesCollisions.end(), 0); - if (nProcessesCollisions > 1) { - LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); + // Exit if workflow is not configured correctly - More than one process function enabled for candidate to OmegaKa + if ((omegakaEnabledDca > 0) && (omegakaEnabledKf > 0)) { + LOGP(fatal, "More than one process function enabled for candidte decaying to omega ka"); } - if (nProcessesCollisions == 1) { - if ((doprocessNoCentToXiPi && !doprocessCollisions) || (doprocessNoCentToXiPiTraCasc && !doprocessCollisions) || (doprocessNoCentToOmegaPi && !doprocessCollisions) || (doprocessNoCentToOmegaK && !doprocessCollisions) || (doprocessNoCentOmegacToOmegaPiWithKFParticle && !doprocessCollisions) || (doprocessNoCentXicToXiPiWithKFParticle && !doprocessCollisions)) { - LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); - } - if ((doprocessCentFT0CToXiPi && !doprocessCollisionsCentFT0C) || (doprocessCentFT0CToOmegaPi && !doprocessCollisionsCentFT0C) || (doprocessCentFT0CToOmegaK && !doprocessCollisionsCentFT0C)) { - LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0C\"?"); - } - if ((doprocessCentFT0MToXiPi && !doprocessCollisionsCentFT0M) || (doprocessCentFT0MToOmegaPi && !doprocessCollisionsCentFT0M) || (doprocessCentFT0MToOmegaK && !doprocessCollisionsCentFT0M)) { - LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisionsCentFT0M\"?"); - } + + // Exit if workflow is not configured correctly - More than one process enabled for collision monitoring + if (std::accumulate(processesCollMonitoring.begin(), processesCollMonitoring.end(), 0) > 1) { + LOGP(fatal, "More than one process fucntion for CollMonitoring was enabled. Please choose only one process function"); } + // Add histogram to indicate which sv method was used + registry.add("hVertexerType", "Use KF of DCAFitterN;Vertexer type;entries", {kTH1F, {{2, -0.5, 1.5}}}); + + // Histograms for QA hInvMassCharmBaryonToXiPi = registry.add("hInvMassCharmBaryonToXiPi", "Charm baryon invariant mass - #Xi #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); hInvMassCharmBaryonToOmegaPi = registry.add("hInvMassCharmBaryonToOmegaPi", "Charm baryon invariant mass - #Omega #pi decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); - hInvMassCharmBaryonToOmegaK = registry.add("hInvMassCharmBaryonToOmegaK", "Charm baryon invariant mass - #Omega K decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); - hFitterStatusToXiPi = registry.add("hFitterStatusToXiPi", "Charm DCAFitter status - #Xi #pi vtx;status;entries", {HistType::kTH1D, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) - hFitterStatusToOmegaPi = registry.add("hFitterStatusToOmegaPi", "Charm DCAFitter status - #Omega #pi vtx ;status;entries", {HistType::kTH1D, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) - hFitterStatusToOmegaK = registry.add("hFitterStatusToOmegaK", "Charm DCAFitter status - #Omega K vtx;status;entries", {HistType::kTH1D, {{3, -0.5, 2.5}}}); // 0 --> vertex(es) found, 1 --> exception found, 2 --> no vertex found (but no exception) - hCandidateCounterToXiPi = registry.add("hCandidateCounterToXiPi", "Candidate counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table - hCandidateCounterToOmegaPi = registry.add("hCandidateCounterToOmegaPi", "Candidate counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table - hCandidateCounterToOmegaK = registry.add("hCandidateCounterToOmegaK", "Candidate counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); // 0 --> candidates in derived data table, 1 --> candidates passing testbit selection, 2 --> candidates passing fitter step 3 --> candidates filled in new table - hCascadesCounterToXiPi = registry.add("hCascadesCounterToXiPi", "Cascades counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table - hCascadesCounterToOmegaPi = registry.add("hCascadesCounterToOmegaPi", "Cascades counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table - hCascadesCounterToOmegaK = registry.add("hCascadesCounterToOmegaK", "Cascades counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table - - // KFParticle Variables Histograms - registry.add("hKFParticleV0TopoChi2", "hKFParticleV0TopoChi2", kTH1D, {{1000, -0.10f, 100.0f}}); - registry.add("hKFParticleCascTopoChi2", "hKFParticleCascTopoChi2", kTH1D, {{1000, -0.1f, 100.0f}}); - registry.add("hKfChi2TopoPiFromCharmBaryon", "hKfChi2TopoPifromCharmBaryon", kTH1F, {{2000, -0.1f, 1000.0f}}); - registry.add("hKfNdfPiFromCharmBaryon", "hKfNDfPifromCharmBaryon", kTH1F, {{2000, -0.1f, 200.0f}}); - registry.add("hKfChi2OverNdfPiFromCharmBaryon", "hKfChi2OverNdfPifromCharmBaryon", kTH1F, {{1000, -0.1f, 200.0f}}); - registry.add("hKFParticlechi2TopoOmegacToPv", "hKFParticlechi2TopoOmegacToPv", kTH1D, {{1000, -0.1f, 100.0f}}); - registry.add("hKfNdfOmegacToPv", "hKfNDfOmegacToPv", kTH1F, {{2000, -0.1f, 200.0f}}); - registry.add("hKfChi2TopoOmegacToPv", "hKfChi2TopoOmegacToPv", kTH1F, {{1000, -0.1f, 200.0f}}); - registry.add("hKfDeviationPiFromCharmBaryon", "hKfDeviationPiFromCharmBaryon", kTH1F, {{1000, -0.1f, 200.0f}}); - registry.add("hKFParticleCascBachTopoChi2", "hKFParticleCascBachTopoChi2", kTH1D, {{1000, -0.1f, 100.0f}}); - registry.add("hKFParticleDcaCharmBaryonDau", "hKFParticleDcaCharmBaryonDau", kTH1D, {{1000, -0.1f, 1.0f}}); - registry.add("hKFParticleDcaXYCascBachToPv", "hKFParticleDcaXYCascBachToPv", kTH1D, {{1000, -0.1f, 15.0f}}); - registry.add("hKfLambda_ldl", "hKfLambda_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); - registry.add("hKfOmega_ldl", "hKfOmega_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); - registry.add("hKfXi_ldl", "hKfXi_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); - registry.add("hKfOmegaC0_ldl", "hKfOmegaC0_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); - registry.add("hKfXiC0_ldl", "hKfXiC0_ldl", kTH1D, {{1000, 0.0f, 1000.0f}}); - registry.add("hDcaXYCascadeToPVKf", "hDcaXYCascadeToPVKf", kTH1D, {{1000, 0.0f, 2.0f}}); - registry.add("hInvMassOmegaMinus", "hInvMassOmegaMinus", kTH1D, {{1000, 1.6f, 2.0f}}); - registry.add("hInvMassXiMinus", "hInvMassXiMinus", kTH1D, {{1000, 1.25f, 1.65f}}); - registry.add("hInvMassXiMinus_rej", "hInvMassXiMinus_rej", kTH1D, {{1000, 1.25f, 1.65f}}); - registry.add("hKFParticlechi2TopoCascToPv", "hKFParticlechi2TopoCascToPv", kTH1D, {{1000, -0.1f, 100.0f}}); - registry.add("hKFParticleDcaXYV0DauPosToPv", "hKFParticleDcaXYV0DauPosToPv", kTH1D, {{1000, -0.1f, 30.0f}}); - registry.add("hKFParticleDcaXYV0DauNegToPv", "hKFParticleDcaXYV0DauNegToPv", kTH1D, {{1000, -0.1f, 30.0f}}); - - // Additional KFParticle Histograms - if (fillAllHist) { - registry.add("hEtaV0PosDau", "hEtaV0PosDau", kTH1D, {{1000, -5.0f, 5.0f}}); - registry.add("hEtaV0NegDau", "hEtaV0NegDau", kTH1D, {{1000, -5.0f, 5.0f}}); - registry.add("hEtaKaFromCasc", "hEtaKaFromCasc", kTH1D, {{1000, -5.0f, 5.0f}}); - registry.add("hEtaPiFromCharmBaryon", "hEtaPiFromCharmBaryon", kTH1D, {{1000, -5.0f, 5.0f}}); - registry.add("hCascradius", "hCascradius", kTH1D, {{1000, 0.0f, 50.0f}}); - registry.add("hV0radius", "hV0radius", kTH1D, {{1000, 0.0f, 50.0f}}); - registry.add("hCosPACasc", "hCosPACasc", kTH1D, {{5000, 0.8f, 1.1f}}); - registry.add("hCosPAV0", "hCosPAV0", kTH1D, {{5000, 0.8f, 1.1f}}); - registry.add("hDcaCascDau", "hDcaCascDau", kTH1D, {{1000, -0.1f, 10.0f}}); - registry.add("hDcaV0Dau", "hDcaV0Dau", kTH1D, {{1000, -0.1f, 10.0f}}); - registry.add("hDcaXYToPvKa", "hDcaXYToPvKa", kTH1D, {{1000, -0.1f, 10.0f}}); - registry.add("hImpactParBachFromCharmBaryonXY", "hImpactParBachFromCharmBaryonXY", kTH1D, {{1000, -1.0f, 1.0f}}); - registry.add("hImpactParBachFromCharmBaryonZ", "hImpactParBachFromCharmBaryonZ", kTH1D, {{1000, -2.0f, 2.0f}}); - registry.add("hImpactParCascXY", "hImpactParCascXY", kTH1D, {{1000, -4.0f, 4.0f}}); - registry.add("hImpactParCascZ", "hImpactParCascZ", kTH1D, {{1000, -5.0f, 5.0f}}); - registry.add("hPtKaFromCasc", "hPtKaFromCasc", kTH1D, {{1000, 0.0f, 5.0f}}); - registry.add("hPtPiFromCharmBaryon", "hPtPiFromCharmBaryon", kTH1D, {{1000, 0.0f, 5.0f}}); - registry.add("hCTauOmegac", "hCTauOmegac", kTH1D, {{1000, 0.0f, 0.1f}}); - registry.add("hKFGeoV0Chi2OverNdf", "hKFGeoV0Chi2OverNdf", kTH1D, {{1000, 0.0f, 100.0f}}); - registry.add("hKFGeoCascChi2OverNdf", "hKFGeoCascChi2OverNdf", kTH1D, {{1000, 0.0f, 100.0f}}); - registry.add("hKFGeoCharmbaryonChi2OverNdf", "hKFGeoCharmbaryonChi2OverNdf", kTH1D, {{1000, 0.0f, 100.0f}}); - registry.add("hKFdecayLenXYLambda", "hKFdecayLenXYLambda", kTH1D, {{1000, 0.0f, 50.0f}}); - registry.add("hKFdecayLenXYCasc", "hKFdecayLenXYCasc", kTH1D, {{1000, 0.0f, 50.0f}}); - registry.add("hKFdecayLenXYOmegac", "hKFdecayLenXYOmegac", kTH1D, {{1000, 0.0f, 50.0f}}); - registry.add("hKFcosPaV0ToCasc", "hKFcosPaV0ToCasc", kTH1D, {{5000, 0.8f, 1.1f}}); - registry.add("hKFcosPaCascToOmegac", "hKFcosPaCascToOmegac", kTH1D, {{5000, 0.8f, 1.1f}}); + hInvMassCharmBaryonToOmegaKa = registry.add("hInvMassCharmBaryonToOmegaKa", "Charm baryon invariant mass - #Omega K decay;inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 2.2, 3.1}}}); + hCandidateCounterToXiPi = registry.add("hCandidateCounterToXiPi", "Candidate counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); + hCandidateCounterToOmegaPi = registry.add("hCandidateCounterToOmegaPi", "Candidate counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); + hCandidateCounterToOmegaKa = registry.add("hCandidateCounterToOmegaKa", "Candidate counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{4, -0.5, 3.5}}}); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + All, "Total"); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + CascPreSel, "CascPreSel"); + registry.get(HIST("hCandidateCounterToXiPi"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + All, "Total"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + CascPreSel, "CascPreSel"); + registry.get(HIST("hCandidateCounterToOmegaPi"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + All, "Total"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + HfFlagPass, "HfFlagPass"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + CascPreSel, "CascPreSel"); + registry.get(HIST("hCandidateCounterToOmegaKa"))->GetXaxis()->SetBinLabel(1 + VertexFit, "VertexFit"); + hCascadesCounterToXiPi = registry.add("hCascadesCounterToXiPi", "Cascades counter wrt derived data - #Xi #pi decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table + hCascadesCounterToOmegaPi = registry.add("hCascadesCounterToOmegaPi", "Cascades counter wrt derived data - #Omega #pi decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table + hCascadesCounterToOmegaKa = registry.add("hCascadesCounterToOmegaKa", "Cascades counter wrt derived data - #Omega K decay;status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> cascades in derived data table (and stored in AOD table), 1 --> cascades in derived data table and also accessible in cascData table + + // Extra initialization for DCAFitter + if (xipiEnabledDca == 1 || omegapiEnabledDca == 1 || omegakaEnabledDca == 1) { + registry.get(HIST("hVertexerType"))->Fill(aod::hf_cand::VertexerType::DCAFitter); + df.setPropagateToPCA(configs.propagateToPCA); + df.setMaxR(configs.maxR); + df.setMaxDZIni(configs.maxDZIni); + df.setMinParamChange(configs.minParamChange); + df.setUseAbsDCA(configs.useAbsDCA); + df.setWeightedFinalPCA(configs.useWeightedFinalPCA); } - // init HF event selection helper - hfEvSel.init(registry); + // Extra initialization for KFParticle + if (xipiEnabledKf == 1 || omegapiEnabledKf == 1 || omegakaEnabledKf == 1) { + registry.get(HIST("hVertexerType"))->Fill(aod::hf_cand::VertexerType::KfParticle); + } - df.setPropagateToPCA(propagateToPCA); - df.setMaxR(maxR); - df.setMaxDZIni(maxDZIni); - df.setMaxDXYIni(maxDXYIni); - df.setMinParamChange(minParamChange); - df.setMinRelChi2Change(minRelChi2Change); - df.setMaxChi2(maxChi2); - df.setUseAbsDCA(useAbsDCA); - df.setWeightedFinalPCA(useWeightedFinalPCA); - df.setRefitWithMatCorr(refitWithMatCorr); - - ccdb->setURL(ccdbUrl); + // initialize ccdb + ccdb->setURL(configs.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(configs.ccdbPathLut)); runNumber = 0; - } - template - void runXic0Omegac0Creator(Coll const&, - aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, - MyLFTracksWCov const& lfTracks, - TracksWCovDca const& tracks, - TCascTable const&, TCascLinkTable const&, - aod::HfCascLf2Prongs const& candidates, - Hist& hInvMassCharmBaryon, - Hist& hFitterStatus, - Hist& hCandidateCounter, - Hist& hCascadesCounter) - { + // initailize HF event selection helper + hfEvSel.init(registry); - if constexpr (decayChannel != hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi && decayChannel != hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi && decayChannel != hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { - LOGP(fatal, "Decay channel not recognized!"); - } + } // end of initialization + + //////////////////////////////////////////////////////////// + // // + // Candidate reconstruction with DCAFitter // + // // + //////////////////////////////////////////////////////////// + + // template function for running charm baryon reconstruction with DCAFitter + /// \brief centEstimator is for different centrality estimators + /// \brief decayChannel is for different decay channels. 0 for XiczeroOmegaczeroToXiPi, 1 for OmegaczeroToOmegaPi, 2 for OmegaczeroToOmeagaK + /// \brief Colls is for collision tables joined with different centraltiy estimators + /// \brief Hist is for QA histograms + template + void runCreatorWithDCAFitter(Colls const&, + aod::HfCascLf2Prongs const& candidates, + TCascFull const&, + TCascLinked const&, + TracksWCovDcaExtraPidPrPiKa const&, + aod::BCsWithTimestamps const&, + Hist& hInvMassCharmBaryon, + Hist& hCandCounter) + { + // arrays which holds values for different decay channel reconstruction - for (const auto& cand : candidates) { + // Loop over candidate + for (auto const& cand : candidates) { - hCandidateCounter->Fill(0); + // Fill cascandidates before selection + if (configs.fillHistograms) { + hCandCounter->Fill(All); + } - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - if (!TESTBIT(cand.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi)) { - continue; - } - } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { - if (!TESTBIT(cand.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi)) { - continue; - } - } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { - if (!TESTBIT(cand.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK)) { - continue; - } + // Apply hfflag selection for different candidate reconstruction + if (!TESTBIT(cand.hfflag(), decayChannel)) { + continue; } - hCandidateCounter->Fill(1); + // Fill casccandidate passed hfflag selection + if (configs.fillHistograms) { + hCandCounter->Fill(HfFlagPass); + } - auto collision = cand.collision_as(); + // Event selection + auto collision = cand.collision_as(); float centrality{-1.f}; const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (rejectionMask != 0) { - /// at least one event selection not satisfied --> reject the candidate + /// at least one event selection not satisfied --> Reject the candidate continue; } - // set the magnetic field from CCDB - auto bc = collision.template bc_as(); - if (runNumber != bc.runNumber()) { - LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); - magneticField = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << ">>>>>>>>>>>> Magnetic field: " << magneticField; - runNumber = bc.runNumber(); - } - df.setBz(magneticField); - - auto trackCharmBachelorId = cand.prong0Id(); - auto trackCharmBachelor = tracks.rawIteratorAt(trackCharmBachelorId); + //------------------------------Cascade pre-selection------------------------------ - auto cascAodElement = cand.template cascade_as(); - hCascadesCounter->Fill(0); - int v0index = cascAodElement.v0Id(); + // Retrieving skimmed cascade and bachelor tracks + // If there is no related tracks, skip + auto cascAodElement = cand.cascade_as(); + if (!cascAodElement.has_cascData()) { + continue; + } - // check if the cascade from AO2D has data - bool hasData = false; - if constexpr (requires { cascAodElement.cascDataId(); }) { // check if it's the CascDataLink - if (cascAodElement.has_cascData()) { - hasData = true; + auto casc = cascAodElement.cascData_as(); + auto chargeCasc = casc.sign() > 0 ? 1 : -1; + float massCasc = -1.0f; + if (configs.doCascadePreselection) { + if (std::abs(casc.dcaXYCascToPV()) > configs.dcaXYToPVCascadeMax) { + continue; } - } - if constexpr (requires { cascAodElement.traCascDataId(); }) { // check if it's the TraCascDataLink - if (cascAodElement.has_traCascData()) { - hasData = true; + + massCasc = (decayChannel == 0) ? casc.mXi() : casc.mOmega(); + if (std::abs(massCasc - massOfCascades[decayChannel]) > configs.massToleranceCascade) { + continue; } } - if (!hasData) { - continue; - } - typename TCascTable::iterator casc; - if constexpr (requires { cascAodElement.cascDataId(); }) { // check if it's the CascDataLink - casc = cascAodElement.template cascData_as(); - } - if constexpr (requires { cascAodElement.traCascDataId(); }) { // check if it's the TraCascDataLink - casc = cascAodElement.template traCascData_as(); + if (configs.fillHistograms) { + hCandCounter->Fill(CascPreSel); } - hCascadesCounter->Fill(1); - auto trackCascDauChargedId = casc.bachelorId(); // pion <- xi track - auto trackV0Dau0Id = casc.posTrackId(); // V0 positive daughter track - auto trackV0Dau1Id = casc.negTrackId(); // V0 negative daughter track - auto trackCascDauCharged = lfTracks.rawIteratorAt(trackCascDauChargedId); // pion <- xi track - auto trackV0Dau0 = lfTracks.rawIteratorAt(trackV0Dau0Id); // V0 positive daughter track - auto trackV0Dau1 = lfTracks.rawIteratorAt(trackV0Dau1Id); // V0 negative daughter track - - //-------------------------- V0 info--------------------------- - // pseudorapidity - float pseudorapV0Dau0 = casc.positiveeta(); - float pseudorapV0Dau1 = casc.negativeeta(); + //------------------------------Set Magnetic field------------------------------ + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>> Current run Number : " << runNumber; + initCCDB(bc, runNumber, ccdb, configs.isRun2 ? configs.ccdbPathGrp : configs.ccdbPathGrpMag, lut, configs.isRun2); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>> Magnetic field: " << bz; + } + df.setBz(bz); - // info from LF table - std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; + //------------------------------Info of V0 and cascade tracks from LF table------------------------------ + // -> This quantities are used for physical properties of selected candidates + // -> Not used for candidate creation std::array vertexV0 = {casc.xlambda(), casc.ylambda(), casc.zlambda()}; - std::array pVecV0Dau0 = {casc.pxpos(), casc.pypos(), casc.pzpos()}; - std::array pVecV0Dau1 = {casc.pxneg(), casc.pyneg(), casc.pzneg()}; - - //-------------------reconstruct cascade track------------------ - // pseudorapidity - float pseudorapCascBachelor = casc.bacheloreta(); - - // info from LF table + std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; + std::array pVecV0DauPos = {casc.pxpos(), casc.pypos(), casc.pzpos()}; + std::array pVecV0DauNeg = {casc.pxneg(), casc.pyneg(), casc.pzneg()}; std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; std::array covCasc = {0.}; - constexpr int NumCovElements = 6; - constexpr int MomInd[NumCovElements] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < NumCovElements; i++) { - covCasc[MomInd[i]] = casc.momentumCovMat()[i]; + + //------------------------------Create cascade track------------------------------ + + constexpr std::size_t NElementsCovMatrix{6u}; + constexpr std::array MomInd = {9, 13, 14, 18, 19, 20}; + for (auto i = 0u; i < NElementsCovMatrix; i++) { covCasc[i] = casc.positionCovMat()[i]; + covCasc[MomInd[i]] = casc.momentumCovMat()[i]; } - // create cascade track + o2::track::TrackParCov trackCasc; - if (trackCascDauCharged.sign() > 0) { - trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); - } else if (trackCascDauCharged.sign() < 0) { + if (chargeCasc < 0) { // Xi- or Omega- trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); + } else if (chargeCasc > 0) { // Xi+ or Omega+ + trackCasc = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); } else { continue; } - trackCasc.setAbsCharge(1); - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - trackCasc.setPID(o2::track::PID::XiMinus); - } else { - trackCasc.setPID(o2::track::PID::OmegaMinus); - } - std::array pVecCascBachelor = {casc.pxbach(), casc.pybach(), casc.pzbach()}; + trackCasc.setAbsCharge(1); + trackCasc.setPID(trackPidOfCascade[decayChannel]); - //------------reconstruct charm baryon decay vtx--------------- - auto trackParVarCharmBachelor = getTrackParCov(trackCharmBachelor); // charm bachelor pion track to be processed with DCAFitter + //------------------------------Fit SV & Create Cascade track------------------------------ - // reconstruct charm baryon with DCAFitter - int nVtxFromFitterCharmBaryon = 0; + // Perform secondary vertex fitting + auto trackCharmBachelor = cand.prong0_as(); + auto trackParCovCharmBachelor = getTrackParCov(trackCharmBachelor); try { - nVtxFromFitterCharmBaryon = df.process(trackCasc, trackParVarCharmBachelor); - } catch (...) { - LOG(error) << "Exception caught in charm DCA fitter process call!"; - hFitterStatus->Fill(1); - continue; - } - if (nVtxFromFitterCharmBaryon == 0) { - hFitterStatus->Fill(2); + if (df.process(trackCasc, trackParCovCharmBachelor) == 0) { + continue; + } + } catch (const std::runtime_error& e) { + LOG(info) << "Run time error found : " << e.what() << ".DCAFitter cannot work with this candidate. SKIP!"; continue; } - hFitterStatus->Fill(0); - hCandidateCounter->Fill(2); - auto vertexCharmBaryonFromFitter = df.getPCACandidate(); - std::array pVecCascAsD; - std::array pVecCharmBachelorAsD; + + // Propagate tracks to vertex df.propagateTracksToVertex(); if (!df.isPropagateTracksToVertexDone()) { continue; } - df.getTrack(0).getPxPyPzGlo(pVecCascAsD); - df.getTrack(1).getPxPyPzGlo(pVecCharmBachelorAsD); - std::array pVecCharmBaryon = {pVecCascAsD[0] + pVecCharmBachelorAsD[0], pVecCascAsD[1] + pVecCharmBachelorAsD[1], pVecCascAsD[2] + pVecCharmBachelorAsD[2]}; - std::array coordVtxCharmBaryon = df.getPCACandidatePos(); - std::array covVtxCharmBaryon = df.calcPCACovMatrixFlat(); + if (configs.fillHistograms) { + hCandCounter->Fill(VertexFit); + } - // pseudorapidity - float pseudorapCharmBachelor = trackCharmBachelor.eta(); + //------------------------------Calculate physical properties----------------------------- - // primary vertex of the collision - auto primaryVertex = getPrimaryVertex(collision); // get the associated covariance matrix with auto covMatrixPV = primaryVertex.getCov(); + // get track momenta + std::array pVecCascAsD, pVecCharmBachAsD; + df.getTrack(0).getPxPyPzGlo(pVecCascAsD); + df.getTrack(1).getPxPyPzGlo(pVecCharmBachAsD); + std::array pVecCharmBaryon = {pVecCascAsD[0] + pVecCharmBachAsD[0], pVecCascAsD[1] + pVecCharmBachAsD[1], pVecCascAsD[2] + pVecCharmBachAsD[2]}; + std::array pVecBach = {casc.pxbach(), casc.pybach(), casc.pzbach()}; + + // // get track momenta -> Previous version... + // trackCasc = df.getTrack(0); + // trackParCovCharmBachelor = df.getTrack(1); + // std::array pVecCasc, pVecBach; + // trackCasc.getPxPyPzGlo(pVecCasc); + // trackParCovCharmBachelor.getPxPyPzGlo(pVecBach); + + // get PV Properties + auto primaryVertex = getPrimaryVertex(collision); + auto covMatrixPV = primaryVertex.getCov(); std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - // DCAxy and DCAz (computed with propagateToDCABxByBz method) - o2::dataformats::DCA impactParameterV0Dau0; - o2::dataformats::DCA impactParameterV0Dau1; - o2::dataformats::DCA impactParameterCascDauCharged; - auto trackParVarV0Dau0 = getTrackParCov(trackV0Dau0); - auto trackParVarV0Dau1 = getTrackParCov(trackV0Dau1); - auto trackParVarCascDauCharged = getTrackParCov(trackCascDauCharged); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarV0Dau0, 2.f, matCorr, &impactParameterV0Dau0); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarV0Dau1, 2.f, matCorr, &impactParameterV0Dau1); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarCascDauCharged, 2.f, matCorr, &impactParameterCascDauCharged); - float dcaxyV0Dau0 = impactParameterV0Dau0.getY(); - float dcaxyV0Dau1 = impactParameterV0Dau1.getY(); - float dcaxyCascBachelor = impactParameterCascDauCharged.getY(); - float dcazV0Dau0 = impactParameterV0Dau0.getZ(); - float dcazV0Dau1 = impactParameterV0Dau1.getZ(); - float dcazCascBachelor = impactParameterCascDauCharged.getZ(); - - // impact parameters - o2::dataformats::DCA impactParameterCasc; - o2::dataformats::DCA impactParameterCharmBachelor; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarCharmBachelor, 2.f, matCorr, &impactParameterCharmBachelor); - float impactParBachFromCharmBaryonXY = impactParameterCharmBachelor.getY(); - float impactParBachFromCharmBaryonZ = impactParameterCharmBachelor.getZ(); - - // invariant mass under the hypothesis of particles ID corresponding to the decay chain - float mLambda = casc.mLambda(); // from LF table, V0 mass under lambda hypothesis - float mCasc = 0.; - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - mCasc = casc.mXi(); - } else { - mCasc = casc.mOmega(); + // get SV Properties + auto const& secondaryVertex = df.getPCACandidate(); + auto chi2SV = df.getChi2AtPCACandidate(); + auto covMatrixSV = df.calcPCACovMatrixFlat(); + + // DCAxy and DCAz. Computed with propagatToDCABxByBz method + auto trackV0DauPos = casc.posTrack_as(); + auto trackV0DauNeg = casc.negTrack_as(); + auto trackBach = casc.bachelor_as(); + auto trackParCovV0DauPos = getTrackParCov(trackV0DauPos); + auto trackParCovV0DauNeg = getTrackParCov(trackV0DauNeg); + auto trackParCovBach = getTrackParCov(trackBach); + o2::dataformats::DCA impactParameterV0DauPos, impactParameterV0DauNeg, impactParameterBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauPos, 2.f, matCorr, &impactParameterV0DauPos); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovV0DauNeg, 2.f, matCorr, &impactParameterV0DauNeg); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovBach, 2.f, matCorr, &impactParameterBach); + + float dcaxyV0DauPos = impactParameterV0DauPos.getY(); + float dcaxyV0DauNeg = impactParameterV0DauNeg.getY(); + float dcaxyBach = impactParameterBach.getY(); + float dcazV0DauPos = impactParameterV0DauPos.getZ(); + float dcazV0DauNeg = impactParameterV0DauNeg.getZ(); + float dcazBach = impactParameterBach.getZ(); + + // get impact parameter. Compute with propagateToDCABxByBz method + o2::dataformats::DCA impactParameterCasc, impactParameterCharmBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); // trackCasc is TrackParCov object + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCharmBachelor, 2.f, matCorr, &impactParameterCharmBach); + + // float impactParCharmBachXY = impactParameterCharmBach.getY(); + // float impactParCharmBachZ = impactParameterCharmBach.getZ(); + + // // get impact parameter -> Previous version... + // //! This process modifies track momenta + // // calculate impact parameter + // o2::dataformats::DCA impactParameterCasc, impactParameterCharmBach; + // trackCasc.propagateToDCA(primaryVertex, bz, &impactParameterCasc); + // trackParCovCharmBachelor.propagateToDCA(primaryVertex, bz, &impactParameterCharmBach); + + // get invariant mass + float massLambda = casc.mLambda(); // mass of V0(lambda0) + auto arrMomenta = std::array{pVecCascAsD, pVecCharmBachAsD}; + massCharmBaryonCand = RecoDecay::m(arrMomenta, std::array{massOfCascades[decayChannel], massOfCharmBach[decayChannel]}); + if (configs.fillHistograms) { + hInvMassCharmBaryon->Fill(massCharmBaryonCand); } - auto arrMassCharmBaryon = std::array{0., 0.}; - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - arrMassCharmBaryon = {MassXiMinus, MassPiPlus}; - } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { - arrMassCharmBaryon = {MassOmegaMinus, MassPiPlus}; - } else { - arrMassCharmBaryon = {MassOmegaMinus, MassKPlus}; - } - float mCharmBaryon = RecoDecay::m(std::array{pVecCascAsD, pVecCharmBachelorAsD}, arrMassCharmBaryon); - // computing cosPA + // calculate cosine of pointing angle + std::array vtxCoordCharmBaryon = df.getPCACandidatePos(); float cpaV0 = casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); - float cpaCharmBaryon = RecoDecay::cpa(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); + float cpaCharmBaryon = RecoDecay::cpa(pvCoord, vtxCoordCharmBaryon, pVecCharmBaryon); float cpaCasc = casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()); float cpaxyV0 = RecoDecay::cpaXY(pvCoord, vertexV0, pVecV0); - float cpaxyCharmBaryon = RecoDecay::cpaXY(pvCoord, coordVtxCharmBaryon, pVecCharmBaryon); + float cpaxyCharmBaryon = RecoDecay::cpaXY(pvCoord, vtxCoordCharmBaryon, pVecCharmBaryon); float cpaxyCasc = RecoDecay::cpaXY(pvCoord, vertexCasc, pVecCasc); - // computing decay length and ctau - float decLenCharmBaryon = RecoDecay::distance(pvCoord, coordVtxCharmBaryon); - float decLenCascade = RecoDecay::distance(coordVtxCharmBaryon, vertexCasc); - float decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); - - double phiCharmBaryon, thetaCharmBaryon; - getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, coordVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon); - auto errorDecayLengthCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); - auto errorDecayLengthXYCharmBaryon = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phiCharmBaryon, 0.) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, 0.)); + // float cosPaV0ToPvToCasc = RecoDecay::cpa(vertexCasc, vertexV0, pVecV0); + // float cpaXYLambdaToCasc = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); - float ctOmegac = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, MassOmegaC0); - float ctXic = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, MassXiC0); - float ctCascade = 0.; - if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - ctCascade = RecoDecay::ct(pVecCasc, decLenCascade, MassXiMinus); - } else { - ctCascade = RecoDecay::ct(pVecCasc, decLenCascade, MassOmegaMinus); - } + // calculate decay length + float decLenCharmBaryon = RecoDecay::distance(pvCoord, vtxCoordCharmBaryon); + float decLenCasc = RecoDecay::distance(vtxCoordCharmBaryon, vertexCasc); + float decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); + // get uncertainty of the decay length -> Used in previous code... + float phi, theta; + getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, secondaryVertex, phi, theta); + auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixSV, phi, theta)); + auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixSV, phi, 0.)); + + // calcuate ctau + float ctOmegac0 = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, MassOmegaC0); + float ctXic0 = RecoDecay::ct(pVecCharmBaryon, decLenCharmBaryon, MassXiC0); float ctV0 = RecoDecay::ct(pVecV0, decLenV0, MassLambda0); + float ctCasc = RecoDecay::ct(pVecCasc, decLenCasc, massOfCascades[decayChannel]); - // computing eta - float pseudorapCharmBaryon = RecoDecay::eta(pVecCharmBaryon); - float pseudorapCascade = RecoDecay::eta(pVecCasc); - float pseudorapV0 = RecoDecay::eta(pVecV0); + // get eta + float etaV0DauPos = casc.positiveeta(); + float etaV0DauNeg = casc.negativeeta(); + float etaBach = casc.bacheloreta(); + float etaCharmBach = trackCharmBachelor.eta(); + float etaCharmBaryon = RecoDecay::eta(pVecCharmBaryon); + float etaCasc = RecoDecay::eta(pVecCasc); + float etaV0 = RecoDecay::eta(pVecV0); // DCA between daughters float dcaCascDau = casc.dcacascdaughters(); float dcaV0Dau = casc.dcaV0daughters(); float dcaCharmBaryonDau = std::sqrt(df.getChi2AtPCACandidate()); - // fill test histograms - hInvMassCharmBaryon->Fill(mCharmBaryon); - hCandidateCounter->Fill(3); + //------------------------------Fill QA histograms----------------------------- - // fill the table + //------------------------------Fill the table----------------------------- if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { - rowCandToXiPi(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackCascDauCharged.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], - pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecCascBachelor[0], pVecCascBachelor[1], pVecCascBachelor[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - impactParameterCasc.getY(), impactParBachFromCharmBaryonXY, - impactParameterCasc.getZ(), impactParBachFromCharmBaryonZ, - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), - v0index, casc.posTrackId(), casc.negTrackId(), - casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), - mLambda, mCasc, mCharmBaryon, - cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac, ctCascade, ctV0, ctXic, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapCascBachelor, pseudorapCharmBachelor, - pseudorapCharmBaryon, pseudorapCascade, pseudorapV0, - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyCascBachelor, - dcazV0Dau0, dcazV0Dau1, dcazCascBachelor, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon); + cursors.rowCandToXiPi(collision.globalIndex(), + pvCoord[0], pvCoord[1], pvCoord[2], + secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], // From DCAFitter + vertexCasc[0], vertexCasc[1], vertexCasc[2], // From LF table + vertexV0[0], vertexV0[1], vertexV0[2], // From LF table + trackBach.sign(), // From LF table + covMatrixSV[0], covMatrixSV[1], covMatrixSV[2], covMatrixSV[3], covMatrixSV[4], covMatrixSV[5], // From DCAFittre + pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], // From DCAFitter + pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], // From DCAFitter + pVecCharmBachAsD[0], pVecCharmBachAsD[1], pVecCharmBachAsD[2], // From DCAFitter + pVecV0[0], pVecV0[1], pVecV0[2], // From LF table + pVecBach[0], pVecBach[1], pVecBach[2], // From LF table + pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], // From LF table + pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], // From LF table + impactParameterCasc.getY(), impactParameterCharmBach.getY(), + impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), + cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), + casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + casc.mLambda(), massCasc, massCharmBaryonCand, + cpaV0, cpaCharmBaryon, cpaCasc, + cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, + ctOmegac0, ctCasc, ctV0, ctXic0, + etaV0DauPos, etaV0DauNeg, etaBach, etaCharmBach, etaCharmBaryon, etaCasc, etaV0, + dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, + dcazV0DauPos, dcazV0DauNeg, dcazBach, + dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, + decLenCharmBaryon, decLenCasc, decLenV0, errorDecayLength, errorDecayLengthXY); } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { - rowCandToOmegaPi(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackCascDauCharged.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], - pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecCascBachelor[0], pVecCascBachelor[1], pVecCascBachelor[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - impactParameterCasc.getY(), impactParBachFromCharmBaryonXY, - impactParameterCasc.getZ(), impactParBachFromCharmBaryonZ, - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), - v0index, casc.posTrackId(), casc.negTrackId(), - casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), - mLambda, mCasc, mCharmBaryon, - cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac, ctCascade, ctV0, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapCascBachelor, pseudorapCharmBachelor, - pseudorapCharmBaryon, pseudorapCascade, pseudorapV0, - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyCascBachelor, - dcazV0Dau0, dcazV0Dau1, dcazCascBachelor, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon, cand.hfflag()); - + cursors.rowCandToOmegaPi(collision.globalIndex(), + pvCoord[0], pvCoord[1], pvCoord[2], + secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], // From DCAFitter + vertexCasc[0], vertexCasc[1], vertexCasc[2], // From LF table + vertexV0[0], vertexV0[1], vertexV0[2], // From LF table + trackBach.sign(), // From LF table + covMatrixSV[0], covMatrixSV[1], covMatrixSV[2], covMatrixSV[3], covMatrixSV[4], covMatrixSV[5], // From DCAFittre + pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], // From DCAFitter + pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], // From DCAFitter + pVecCharmBachAsD[0], pVecCharmBachAsD[1], pVecCharmBachAsD[2], // From DCAFitter + pVecV0[0], pVecV0[1], pVecV0[2], // From LF table + pVecBach[0], pVecBach[1], pVecBach[2], // From LF table + pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], // From LF table + pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], // From LF table + impactParameterCasc.getY(), impactParameterCharmBach.getY(), + impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), + cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), + casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + casc.mLambda(), massCasc, massCharmBaryonCand, + cpaV0, cpaCharmBaryon, cpaCasc, + cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, + ctOmegac0, ctCasc, ctV0, + etaV0DauPos, etaV0DauNeg, etaBach, etaCharmBach, etaCharmBaryon, etaCasc, etaV0, + dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, + dcazV0DauPos, dcazV0DauNeg, dcazBach, + dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, + decLenCharmBaryon, decLenCasc, decLenV0, errorDecayLength, errorDecayLengthXY, cand.hfflag()); } else { - rowCandToOmegaK( - collision.globalIndex(), pvCoord[0], pvCoord[1], pvCoord[2], - vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackCascDauCharged.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], - pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecCascBachelor[0], pVecCascBachelor[1], pVecCascBachelor[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - impactParameterCasc.getY(), impactParBachFromCharmBaryonXY, - impactParameterCasc.getZ(), impactParBachFromCharmBaryonZ, - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), - v0index, casc.posTrackId(), casc.negTrackId(), - casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), - mLambda, mCasc, mCharmBaryon, - cpaV0, cpaCharmBaryon, cpaCasc, cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, - ctOmegac, ctCascade, ctV0, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapCascBachelor, pseudorapCharmBachelor, - pseudorapCharmBaryon, pseudorapCascade, pseudorapV0, - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyCascBachelor, - dcazV0Dau0, dcazV0Dau1, dcazCascBachelor, - dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, - decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon); + cursors.rowCandToOmegaKa(collision.globalIndex(), + pvCoord[0], pvCoord[1], pvCoord[2], + secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], // From DCAFitter + vertexCasc[0], vertexCasc[1], vertexCasc[2], // From LF table + vertexV0[0], vertexV0[1], vertexV0[2], // From LF table + trackBach.sign(), // From LF table + covMatrixSV[0], covMatrixSV[1], covMatrixSV[2], covMatrixSV[3], covMatrixSV[4], covMatrixSV[5], // From DCAFittre + pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], // From DCAFitter + pVecCascAsD[0], pVecCascAsD[1], pVecCascAsD[2], // From DCAFitter + pVecCharmBachAsD[0], pVecCharmBachAsD[1], pVecCharmBachAsD[2], // From DCAFitter + pVecV0[0], pVecV0[1], pVecV0[2], // From LF table + pVecBach[0], pVecBach[1], pVecBach[2], // From LF table + pVecV0DauPos[0], pVecV0DauPos[1], pVecV0DauPos[2], // From LF table + pVecV0DauNeg[0], pVecV0DauNeg[1], pVecV0DauNeg[2], // From LF table + impactParameterCasc.getY(), impactParameterCharmBach.getY(), + impactParameterCasc.getZ(), impactParameterCharmBach.getZ(), + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBach.getSigmaY2()), + cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), + casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + casc.mLambda(), massCasc, massCharmBaryonCand, + cpaV0, cpaCharmBaryon, cpaCasc, + cpaxyV0, cpaxyCharmBaryon, cpaxyCasc, + ctOmegac0, ctCasc, ctV0, + etaV0DauPos, etaV0DauNeg, etaBach, etaCharmBach, etaCharmBaryon, etaCasc, etaV0, + dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, + dcazV0DauPos, dcazV0DauNeg, dcazBach, + dcaCascDau, dcaV0Dau, dcaCharmBaryonDau, + decLenCharmBaryon, decLenCasc, decLenV0, errorDecayLength, errorDecayLengthXY); } - - } // loop over LF Cascade-bachelor candidates + } // candidate loop } // end of run function - template - void runKfOmegac0CreatorWithKFParticle(Coll const&, - aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const&, KFCascadesLinked const&, - aod::HfCascLf2Prongs const& candidates, - Hist& hInvMassCharmBaryon, - Hist& hFitterStatus, - Hist& hCandidateCounter, - Hist& hCascadesCounter) + // template function for running Charm Baryon reconstruction via KFParticle method + /// \brief centEstimator is for different centrality estimators + /// \brief decayChannel is for different decay channels. 0 for XiczeroOmegaczeroToXiPi, 1 for OmegaczeroToOmegaPi, 2 for OmegaczeroToOmegaK + /// \brief Colls is for collision tables joined with different centrality estimators + /// \brief Hist is for QA histograms + template + void runCreatorWithKfParticle(Colls const&, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const&, + KFCascadesLinked const&, + TracksWCovDcaExtraPidPrPiKa const&, + aod::BCsWithTimestamps const&, + Hist& hInvMassCharmBaryon, + Hist& hCandCounter) { - for (const auto& cand : candidates) { - hCandidateCounter->Fill(1); + // Loop over candidates + for (auto const& cand : candidates) { + + // Fill cascandidates before selection + if (configs.fillHistograms) { + hCandCounter->Fill(All); + } - auto collision = cand.collision_as(); + // Apply hfflag selection + if (!TESTBIT(cand.hfflag(), decayChannel)) { + continue; + } + + // Fill casccandidates after hfflag selection + if (configs.fillHistograms) { + hCandCounter->Fill(HfFlagPass); + } + + // Event selection + auto collision = cand.collision_as(); float centrality{-1.f}; const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (rejectionMask != 0) { - /// at least one event selection not satisfied --> reject the candidate continue; } - // set the magnetic field from CCDB - auto bc = collision.template bc_as(); - if (runNumber != bc.runNumber()) { - LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); - magneticField = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << ">>>>>>>>>>>> Magnetic field: " << magneticField; - runNumber = bc.runNumber(); - } - df.setBz(magneticField); - KFParticle::SetField(magneticField); - // bachelor from Omegac0 - auto trackCharmBachelorId = cand.prong0Id(); - auto trackCharmBachelor = tracks.rawIteratorAt(trackCharmBachelorId); - auto cascAodElement = cand.cascade_as(); - hCascadesCounter->Fill(0); - int v0index = cascAodElement.v0Id(); + //------------------------------Cascade pre-selection------------------------------ + + // Retrieving skimmed cascade and charm bachelor tracks + // If there is no related tracks, skip + auto cascAodElement = cand.cascade_as(); if (!cascAodElement.has_kfCascData()) { continue; } - auto casc = cascAodElement.kfCascData_as(); - hCascadesCounter->Fill(1); - auto trackCascDauChargedId = casc.bachelorId(); - auto trackV0Dau0Id = casc.posTrackId(); - auto trackV0Dau1Id = casc.negTrackId(); - auto trackCascDauCharged = tracksIU.rawIteratorAt(trackCascDauChargedId); // pion <- xi track - auto trackV0Dau0 = tracksIU.rawIteratorAt(trackV0Dau0Id); // V0 positive daughter track - auto trackV0Dau1 = tracksIU.rawIteratorAt(trackV0Dau1Id); // V0 negative daughter track - - auto bachCharge = trackCascDauCharged.signed1Pt() > 0 ? +1 : -1; - - //// pion & p TrackParCov - auto trackParCovV0Dau0 = getTrackParCov(trackV0Dau0); - auto trackParCovV0Dau1 = getTrackParCov(trackV0Dau1); - // kaon <- casc TrackParCov - auto omegaDauChargedTrackParCov = getTrackParCov(trackCascDauCharged); - // convert tracks into KFParticle object - KFPTrack kfTrack0 = createKFPTrackFromTrack(trackV0Dau0); - KFPTrack kfTrack1 = createKFPTrackFromTrack(trackV0Dau1); - KFPTrack kfTrackBach = createKFPTrackFromTrack(trackCascDauCharged); - - KFParticle kfPosPr(kfTrack0, kProton); - KFParticle kfNegPi(kfTrack1, kPiMinus); - KFParticle kfNegKa(kfTrackBach, kKMinus); - KFParticle kfNegPiRej(kfTrackBach, kPiMinus); // rej - KFParticle kfPosPi(kfTrack0, kPiPlus); - KFParticle kfNegPr(kfTrack1, kProton); - KFParticle kfPosKa(kfTrackBach, kKPlus); - KFParticle kfPosPiRej(kfTrackBach, kPiPlus); // rej - - KFParticle kfBachKaon; - KFParticle kfPos; - KFParticle kfNeg; - KFParticle kfBachPionRej; // rej - if (bachCharge < 0) { - kfPos = kfPosPr; - kfNeg = kfNegPi; - kfBachKaon = kfNegKa; - kfBachPionRej = kfNegPiRej; // rej - } else { - kfPos = kfPosPi; - kfNeg = kfNegPr; - kfBachKaon = kfPosKa; - kfBachPionRej = kfPosPiRej; // rej - } + auto casc = cascAodElement.kfCascData_as(); // -> Need to understand this + auto chargeCasc = casc.sign() > 0 ? 1 : -1; + float massCasc = (decayChannel == 0) ? casc.mXi() : casc.mOmega(); - //__________________________________________ - //*>~<* step 1 : construct V0 with KF - const KFParticle* v0Daughters[2] = {&kfPos, &kfNeg}; - // construct V0 - KFParticle kfV0; - kfV0.SetConstructMethod(kfConstructMethod); - try { - kfV0.Construct(v0Daughters, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct cascade V0 from daughter tracks: " << e.what(); - continue; + if (configs.kfDoCascadePreselection) { + if (std::abs(casc.dcaXYCascToPV()) > configs.dcaXYToPVCascadeMax) { + continue; + } + if (std::abs(casc.dcaV0daughters()) > configs.dcaV0DaughtersMax) { + continue; + } + if (std::abs(casc.dcacascdaughters()) > configs.dcaCascDaughtersMax) { + continue; + } + if (std::abs(massCasc - massOfCascades[decayChannel]) > configs.massToleranceCascade) { + continue; + } } - // mass window cut on lambda before mass constraint - float massLam, sigLam; - kfV0.GetMass(massLam, sigLam); - if (std::abs(massLam - MassLambda0) > lambdaMassWindow) - continue; - // err_mass>0 of Lambda - if (sigLam <= 0) - continue; - kfOmegac0Candidate.chi2GeoV0 = kfV0.GetChi2(); - KFParticle kfV0MassConstrained = kfV0; - kfV0MassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassLambda); // set mass constrain to Lambda - if (kfUseV0MassConstraint) { - KFParticle kfV0 = kfV0MassConstrained; + if (configs.fillHistograms) { + hCandCounter->Fill(CascPreSel); } - kfV0.TransportToDecayVertex(); - - //__________________________________________ - //*>~<* step 2 : reconstruct cascade(Omega) with KF - const KFParticle* omegaDaugthers[2] = {&kfBachKaon, &kfV0}; - const KFParticle* omegaDaugthersRej[2] = {&kfBachPionRej, &kfV0}; // rej - // construct cascade - KFParticle kfOmega; - KFParticle kfOmegarej; // rej - kfOmega.SetConstructMethod(kfConstructMethod); - kfOmegarej.SetConstructMethod(kfConstructMethod); // rej - try { - kfOmega.Construct(omegaDaugthers, 2); - kfOmegarej.Construct(omegaDaugthersRej, 2); // rej - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct Omega or Omega_rej from V0 and bachelor track: " << e.what(); - continue; + + //------------------------------Set Magnetic field------------------------------ + auto bc = collision.template bc_as(); + if (runNumber != bc.runNumber()) { + LOG(info) << ">>>>>>>>>> Current run Number : " << runNumber; + initCCDB(bc, runNumber, ccdb, configs.isRun2 ? configs.ccdbPathGrp : configs.ccdbPathGrpMag, lut, configs.isRun2); + bz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << ">>>>>>>>>> Magnetic field: " << bz; } - float massCasc, sigCasc; - float massCascrej, sigCascrej; - kfOmega.GetMass(massCasc, sigCasc); - kfOmegarej.GetMass(massCascrej, sigCascrej); // rej - // err_massOmega > 0 - if (sigCasc <= 0) - continue; - if (std::abs(massCasc - MassOmegaMinus) > massToleranceCascade) - continue; + KFParticle::SetField(bz); + + //------------------------------Info of V0 and cascade tracks from LF table------------------------------ + // -> This quantities are used for physical properties of selected candidates + // -> Not used for candidate creation + std::array vertexV0 = {casc.xlambda(), casc.ylambda(), casc.zlambda()}; + std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; + std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; + std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; - kfOmegac0Candidate.chi2GeoCasc = kfOmega.GetChi2(); - kfOmegac0Candidate.cascRejectInvmass = massCascrej; - registry.fill(HIST("hInvMassXiMinus_rej"), massCascrej); // rej - KFParticle kfOmegaMassConstrained = kfOmega; - kfOmegaMassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassOmegaMinus); // set mass constrain to OmegaMinus - if (kfUseCascadeMassConstraint) { - // set mass constraint if requested - KFParticle kfOmega = kfOmegaMassConstrained; + //------------------------------Create Charm Baryon as KF Particle object------------------------------ + + // initialize primary vertex + KFPVertex kfpVertex = createKFPVertexFromCollision(collision); + float covMatrixPV[6]; + kfpVertex.GetCovarianceMatrix(covMatrixPV); + KFParticle kfPv(kfpVertex); // -> For calculation of DCAs to PV + + //~~~~~create charm bachelor track into KFParticle object~~~~~// + auto trackCharmBachelor = cand.prong0_as(); + KFPTrack kfpTrackCharmBachelor = createKFPTrackFromTrack(trackCharmBachelor); + KFParticle kfCharmBachelor(kfpTrackCharmBachelor, pdgOfCharmBach[decayChannel]); + + //~~~~~create Cascade as KFParticle object~~~~~// + // -> This process is essential in building Charm baryon via KFParticle package. + // Since we don't have any information given from other tables about Charm baryon, + // only way to construct Charm baryon is to construct Charm baryon from it's daughters. + constexpr std::size_t NElementsStateVectorCasc{6}; + std::array xyzpxpypzCasc = {vertexCasc[0], vertexCasc[1], vertexCasc[2], pVecCasc[0], pVecCasc[1], pVecCasc[2]}; + float parPosMomCasc[NElementsStateVectorCasc]; + std::copy(xyzpxpypzCasc.begin(), xyzpxpypzCasc.end(), parPosMomCasc); + + KFParticle kfCasc; + kfCasc.Create(parPosMomCasc, casc.kfTrackCovMat(), casc.sign(), massCasc); + if (configs.kfConstrainInvMassCasc) { + kfCasc.SetNonlinearMassConstraint(massOfCascades[decayChannel]); } - registry.fill(HIST("hInvMassOmegaMinus"), massCasc); - kfOmega.TransportToDecayVertex(); - // rej: Add competing rejection to minimize misidentified Xi impact. Reject if kfBachPionRej is Pion and the constructed cascade has Xi's invariant mass. - - //__________________________________________ - //*>~<* step 3 : reconstruc Omegac0 with KF - // Create KF charm bach Pion from track - KFPTrack kfTrackBachPion = createKFPTrackFromTrack(trackCharmBachelor); - KFParticle kfBachPion(kfTrackBachPion, kPiPlus); - const KFParticle* omegaC0Daugthers[2] = {&kfBachPion, &kfOmega}; - - // construct OmegaC0 - KFParticle kfOmegaC0; - kfOmegaC0.SetConstructMethod(kfConstructMethod); + + //~~~~~~Create Charm Baryon as KFParticle object~~~~~// + KFParticle kfCharmBaryon; + const KFParticle* kfDaughterCharmBaryon[2] = {&kfCharmBachelor, &kfCasc}; + kfCharmBaryon.SetConstructMethod(configs.kfConstructMethod); try { - kfOmegaC0.Construct(omegaC0Daugthers, 2); + kfCharmBaryon.Construct(kfDaughterCharmBaryon, 2); } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct OmegaC0 from Cascade and bachelor pion track: " << e.what(); + LOG(debug) << "Failed to construct Charm Baryon : " << e.what(); continue; } - float massOmegaC0, sigOmegaC0; - kfOmegaC0.GetMass(massOmegaC0, sigOmegaC0); - if (sigOmegaC0 <= 0) - continue; - hFitterStatus->Fill(0); - hCandidateCounter->Fill(2); - kfOmegaC0.TransportToDecayVertex(); - // PV - KFPVertex kfVertex = createKFPVertexFromCollision(collision); - KFParticle kfPV(kfVertex); - - // set production vertex; - kfNeg.SetProductionVertex(kfV0); - kfPos.SetProductionVertex(kfV0); - - KFParticle kfBachKaonToOmega = kfBachKaon; - KFParticle kfV0ToCasc = kfV0; - kfBachKaonToOmega.SetProductionVertex(kfOmega); - kfV0ToCasc.SetProductionVertex(kfOmega); - - KFParticle kfOmegaToOmegaC = kfOmega; - KFParticle kfBachPionToOmegaC = kfBachPion; - kfBachPionToOmegaC.SetProductionVertex(kfOmegaC0); - kfOmegaToOmegaC.SetProductionVertex(kfOmegaC0); - - // KFParticle to PV - KFParticle kfV0ToPv = kfV0; - KFParticle kfOmegaToPv = kfOmega; - KFParticle kfOmegac0ToPv = kfOmegaC0; - KFParticle kfPiFromOmegacToPv = kfBachPion; - - kfV0ToPv.SetProductionVertex(kfPV); - kfOmegaToPv.SetProductionVertex(kfPV); - kfOmegac0ToPv.SetProductionVertex(kfPV); - kfPiFromOmegacToPv.SetProductionVertex(kfPV); - //------------get updated daughter tracks after vertex fit --------------- - auto trackParVarCharmBachelor = getTrackParCovFromKFP(kfBachPionToOmegaC, o2::track::PID::Pion, -bachCharge); // chrambaryon bach pion - trackParVarCharmBachelor.setAbsCharge(1); - - omegaDauChargedTrackParCov = getTrackParCovFromKFP(kfBachKaonToOmega, o2::track::PID::Kaon, bachCharge); // Cascade bach kaon - omegaDauChargedTrackParCov.setAbsCharge(1); - o2::track::TrackParCov trackCasc = getTrackParCovFromKFP(kfOmegaToOmegaC, kfOmegaToOmegaC.GetPDG(), bachCharge); - trackCasc.setAbsCharge(1); - - trackParCovV0Dau0 = getTrackParCovFromKFP(kfPos, kfPos.GetPDG(), 1); // V0 postive daughter - trackParCovV0Dau0.setAbsCharge(1); - trackParCovV0Dau1 = getTrackParCovFromKFP(kfNeg, kfNeg.GetPDG(), -1); // V0 negtive daughter - trackParCovV0Dau1.setAbsCharge(1); + // Get covariance matrix of Charm Baryon + auto covMatrixCharmBaryon = kfCharmBaryon.CovarianceMatrix(); - //-------------------------- V0 info--------------------------- - // pseudorapidity - float pseudorapV0Dau0 = kfPos.GetEta(); - float pseudorapV0Dau1 = kfNeg.GetEta(); + // transport Charm Baryon daughters to Charm Baryon to decay vertex => Is this necessary? + float secondaryVertex[3] = {kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}; + kfCasc.TransportToPoint(secondaryVertex); + kfCharmBachelor.TransportToPoint(secondaryVertex); - // info from from KFParticle - std::array pVecV0 = {kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz()}; // pVec stands for vector containing the 3-momentum components - std::array vertexV0 = {kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}; - std::array pVecV0Dau0 = {kfPos.GetPx(), kfPos.GetPy(), kfPos.GetPz()}; - std::array pVecV0Dau1 = {kfNeg.GetPx(), kfNeg.GetPy(), kfNeg.GetPz()}; - - //-------------------reconstruct cascade track------------------ - // pseudorapidity - float pseudorapCascBachelor = kfBachKaonToOmega.GetEta(); + // Fill histogram + if (configs.fillHistograms) { + hCandCounter->Fill(VertexFit); + hInvMassCharmBaryon->Fill(kfCharmBaryon.GetMass()); + } - // info from KFParticle - std::array vertexCasc = {kfOmega.GetX(), kfOmega.GetY(), kfOmega.GetZ()}; - std::array pVecCascBachelor = {kfBachKaonToOmega.GetPx(), kfBachKaonToOmega.GetPy(), kfBachKaonToOmega.GetPz()}; + // Transport cascade and charm baryon to decay vertex(just to be sure) + kfCharmBaryon.TransportToDecayVertex(); + kfCasc.TransportToDecayVertex(); - auto primaryVertex = getPrimaryVertex(collision); - std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - std::array vertexCharmBaryonFromFitter = {0.0, 0.0, 0.0}; // This variable get from DCAfitter in default process, in KF process it is set as 0. - std::array pVecCharmBachelorAsD; - pVecCharmBachelorAsD[0] = kfBachPionToOmegaC.GetPx(); - pVecCharmBachelorAsD[1] = kfBachPionToOmegaC.GetPy(); - pVecCharmBachelorAsD[2] = kfBachPionToOmegaC.GetPz(); - - std::array pVecCharmBaryon = {kfOmegaC0.GetPx(), kfOmegaC0.GetPy(), kfOmegaC0.GetPz()}; - std::array coordVtxCharmBaryon = {kfOmegaC0.GetX(), kfOmegaC0.GetY(), kfOmegaC0.GetZ()}; - auto covVtxCharmBaryon = kfOmegaC0.CovarianceMatrix(); - float covMatrixPV[6]; - kfVertex.GetCovarianceMatrix(covMatrixPV); + //!~~~~~Extra calculations for QA~~~~~~!// + /// These quantities were calculated to fill in existing output tables & QA purpose + /// In the future, these calculation can be skipped? This must be dicussed. - // impact parameters - std::array impactParameterV0Dau0; - std::array impactParameterV0Dau1; - std::array impactParameterKaFromCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Dau0, 2.f, matCorr, &impactParameterV0Dau0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Dau1, 2.f, matCorr, &impactParameterV0Dau1); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, omegaDauChargedTrackParCov, 2.f, matCorr, &impactParameterKaFromCasc); - float dcaxyV0Dau0 = impactParameterV0Dau0[0]; - float dcaxyV0Dau1 = impactParameterV0Dau1[0]; - float dcaxyCascBachelor = impactParameterKaFromCasc[0]; - float dcazV0Dau0 = impactParameterV0Dau0[1]; - float dcazV0Dau1 = impactParameterV0Dau1[1]; - float dcazCascBachelor = impactParameterKaFromCasc[1]; - - // pseudorapidity - float pseudorapCharmBachelor = kfBachPionToOmegaC.GetEta(); + /// Extra calculation for V0 daughters + auto trackV0DauPos = casc.posTrack_as(); + auto trackV0DauNeg = casc.negTrack_as(); - // impact parameters - o2::dataformats::DCA impactParameterCasc; - o2::dataformats::DCA impactParameterCharmBachelor; - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackCasc, 2.f, matCorr, &impactParameterCasc); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParVarCharmBachelor, 2.f, matCorr, &impactParameterCharmBachelor); - float impactParBachFromCharmBaryonXY = impactParameterCharmBachelor.getY(); - float impactParBachFromCharmBaryonZ = impactParameterCharmBachelor.getZ(); - - // computing decay length and ctau - float decLenCharmBaryon = RecoDecay::distance(pvCoord, coordVtxCharmBaryon); - float decLenCascade = RecoDecay::distance(coordVtxCharmBaryon, vertexCasc); - float decLenV0 = RecoDecay::distance(vertexCasc, vertexV0); + KFPTrack kfpTrackV0Pos = createKFPTrackFromTrack(trackV0DauPos); + KFPTrack kfpTrackV0Neg = createKFPTrackFromTrack(trackV0DauNeg); - double phiCharmBaryon, thetaCharmBaryon; - getPointDirection(std::array{kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}, coordVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon); - auto errorDecayLengthCharmBaryon = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); - auto errorDecayLengthXYCharmBaryon = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phiCharmBaryon, 0.) + getRotatedCovMatrixXX(covVtxCharmBaryon, phiCharmBaryon, 0.)); - - // fill test histograms - hInvMassCharmBaryon->Fill(massOmegaC0); - hCandidateCounter->Fill(3); - - //// KFParticle table information - // KF chi2 - auto v0NDF = kfV0.GetNDF(); - auto v0Chi2OverNdf = kfOmegac0Candidate.chi2GeoV0 / v0NDF; - - auto cascNDF = kfOmega.GetNDF(); - auto cascChi2OverNdf = kfOmegac0Candidate.chi2GeoCasc / cascNDF; - - kfOmegac0Candidate.chi2GeoOmegac = kfOmegaC0.GetChi2(); - auto charmbaryonNDF = kfOmegaC0.GetNDF(); - auto charmbaryonChi2OverNdf = kfOmegac0Candidate.chi2GeoOmegac / charmbaryonNDF; - - kfOmegac0Candidate.chi2MassV0 = kfV0MassConstrained.GetChi2(); - auto v0Ndfm = kfV0MassConstrained.GetNDF(); - auto v0Chi2OverNdfm = kfOmegac0Candidate.chi2MassV0 / v0Ndfm; - - kfOmegac0Candidate.chi2MassCasc = kfOmegaMassConstrained.GetChi2(); - auto cascNdfm = kfOmegaMassConstrained.GetNDF(); - auto cascChi2OverNdfm = kfOmegac0Candidate.chi2MassCasc / cascNdfm; - - // KF topo Chi2 over NDF - kfOmegac0Candidate.chi2NdfTopoV0ToPv = kfV0ToPv.GetChi2() / kfV0ToPv.GetNDF(); - kfOmegac0Candidate.chi2NdfTopoCascToPv = kfOmegaToPv.GetChi2() / kfOmegaToPv.GetNDF(); - kfOmegac0Candidate.chi2NdfTopoPiFromOmegacToPv = kfPiFromOmegacToPv.GetChi2() / kfPiFromOmegacToPv.GetNDF(); - kfOmegac0Candidate.chi2NdfTopoOmegacToPv = kfOmegac0ToPv.GetChi2() / kfOmegac0ToPv.GetNDF(); - kfOmegac0Candidate.deviationPiFromOmegacToPv = kfCalculateChi2ToPrimaryVertex(kfOmegaC0, kfPV); - - auto cascBachTopoChi2Ndf = kfBachKaonToOmega.GetChi2() / kfBachKaonToOmega.GetNDF(); - kfOmegac0Candidate.chi2NdfTopoV0ToCasc = kfV0ToCasc.GetChi2() / kfV0ToCasc.GetNDF(); - kfOmegac0Candidate.chi2NdfTopoCascToOmegac = kfOmegaToOmegaC.GetChi2() / kfOmegaToOmegaC.GetNDF(); - - // KF ldl - kfOmegac0Candidate.ldlV0 = ldlFromKF(kfV0, kfPV); - kfOmegac0Candidate.ldlCasc = ldlFromKF(kfOmega, kfPV); - kfOmegac0Candidate.ldlOmegac = ldlFromKF(kfOmegaC0, kfPV); - - // KF dca - kfOmegac0Candidate.kfDcaXYPiFromOmegac = kfBachPionToOmegaC.GetDistanceFromVertexXY(kfPV); - kfOmegac0Candidate.kfDcaV0Dau = kfNeg.GetDistanceFromParticle(kfPos); - kfOmegac0Candidate.kfDcaCascDau = kfBachKaonToOmega.GetDistanceFromParticle(kfV0ToCasc); - kfOmegac0Candidate.kfDcaXYCascToPv = kfOmegaToOmegaC.GetDistanceFromVertexXY(kfPV); - kfOmegac0Candidate.kfDcaOmegacDau = kfBachPionToOmegaC.GetDistanceFromParticle(kfOmegaToOmegaC); - - // KF decay length - float decayLxyLam, errDecayLxyLam; - kfV0ToCasc.GetDecayLengthXY(decayLxyLam, errDecayLxyLam); - kfOmegac0Candidate.decayLenXYLambda = decayLxyLam; - - float decayLxyCasc, errDecayLxyCasc; - kfOmegaToOmegaC.GetDecayLengthXY(decayLxyCasc, errDecayLxyCasc); - kfOmegac0Candidate.decayLenXYCasc = decayLxyCasc; - - float decayLxyOmegac0, errDecayLxyOmegac0; - kfOmegac0ToPv.GetDecayLengthXY(decayLxyOmegac0, errDecayLxyOmegac0); - kfOmegac0Candidate.decayLenXYOmegac = decayLxyOmegac0; - - // KF cosPA - kfOmegac0Candidate.cosPaV0ToPv = cpaFromKF(kfV0, kfPV); - kfOmegac0Candidate.cosPaCascToPv = cpaFromKF(kfOmega, kfPV); - kfOmegac0Candidate.cosPaOmegacToPv = cpaFromKF(kfOmegaC0, kfPV); - kfOmegac0Candidate.cosPaXYV0ToPv = cpaXYFromKF(kfV0, kfPV); - kfOmegac0Candidate.cosPaXYCascToPv = cpaXYFromKF(kfOmega, kfPV); - kfOmegac0Candidate.cosPaXYOmegacToPv = cpaXYFromKF(kfOmegaC0, kfPV); - - kfOmegac0Candidate.cosPaV0ToCasc = cpaFromKF(kfV0, kfOmega); - kfOmegac0Candidate.cosPaCascToOmegac = cpaFromKF(kfOmega, kfOmegaC0); - kfOmegac0Candidate.cosPaXYV0ToCasc = cpaXYFromKF(kfV0, kfOmega); - kfOmegac0Candidate.cosPaXYCascToOmegac = cpaXYFromKF(kfOmega, kfOmegaC0); - // KF mass - kfOmegac0Candidate.massV0 = massLam; - kfOmegac0Candidate.massCasc = massCasc; - kfOmegac0Candidate.massOmegac = massOmegaC0; - - // KF pT - kfOmegac0Candidate.ptPiFromOmegac = kfBachPionToOmegaC.GetPt(); - kfOmegac0Candidate.ptOmegac = kfOmegaC0.GetPt(); - - // KF rapidity - kfOmegac0Candidate.rapOmegac = kfOmegaC0.GetRapidity(); - - // KF cosThetaStar - kfOmegac0Candidate.cosThetaStarPiFromOmegac = cosThetaStarFromKF(0, 4332, 211, 3312, kfBachPionToOmegaC, kfOmegaToOmegaC); + int pdgV0Pos = (trackCharmBachelor.sign() > 0) ? kProton : kPiPlus; + int pdgV0Neg = (trackCharmBachelor.sign() > 0) ? kPiMinus : -kProton; - // KF ct - kfOmegac0Candidate.ctV0 = kfV0.GetLifeTime(); - kfOmegac0Candidate.ctCasc = kfOmega.GetLifeTime(); - kfOmegac0Candidate.ctOmegac = kfOmegaC0.GetLifeTime(); - - // KF eta - kfOmegac0Candidate.etaOmegac = kfOmegaC0.GetEta(); - - // fill KF hist - registry.fill(HIST("hKFParticleCascBachTopoChi2"), cascBachTopoChi2Ndf); - registry.fill(HIST("hKFParticleV0TopoChi2"), kfOmegac0Candidate.chi2NdfTopoV0ToCasc); - registry.fill(HIST("hKFParticleCascTopoChi2"), kfOmegac0Candidate.chi2NdfTopoCascToOmegac); - registry.fill(HIST("hKFParticlechi2TopoOmegacToPv"), kfOmegac0Candidate.chi2NdfTopoOmegacToPv); - registry.fill(HIST("hKfChi2TopoOmegacToPv"), kfOmegac0ToPv.GetChi2()); - registry.fill(HIST("hKfNdfOmegacToPv"), kfOmegac0ToPv.GetNDF()); - registry.fill(HIST("hKFParticlechi2TopoCascToPv"), kfOmegac0Candidate.chi2NdfTopoCascToPv); - registry.fill(HIST("hKFParticleDcaCharmBaryonDau"), kfOmegac0Candidate.kfDcaOmegacDau); - registry.fill(HIST("hKFParticleDcaXYCascBachToPv"), dcaxyCascBachelor); - registry.fill(HIST("hKFParticleDcaXYV0DauPosToPv"), dcaxyV0Dau0); - registry.fill(HIST("hKFParticleDcaXYV0DauNegToPv"), dcaxyV0Dau1); - registry.fill(HIST("hKfLambda_ldl"), kfOmegac0Candidate.ldlV0); - registry.fill(HIST("hKfOmega_ldl"), kfOmegac0Candidate.ldlCasc); - registry.fill(HIST("hKfOmegaC0_ldl"), kfOmegac0Candidate.ldlOmegac); - registry.fill(HIST("hDcaXYCascadeToPVKf"), kfOmegac0Candidate.kfDcaXYCascToPv); - registry.fill(HIST("hKfChi2TopoPiFromCharmBaryon"), kfPiFromOmegacToPv.GetChi2()); - registry.fill(HIST("hKfNdfPiFromCharmBaryon"), kfPiFromOmegacToPv.GetNDF()); - registry.fill(HIST("hKfChi2OverNdfPiFromCharmBaryon"), kfOmegac0Candidate.chi2NdfTopoPiFromOmegacToPv); - registry.fill(HIST("hKfDeviationPiFromCharmBaryon"), kfOmegac0Candidate.deviationPiFromOmegacToPv); - // Additional histograms - if (fillAllHist) { - registry.fill(HIST("hEtaV0PosDau"), kfPos.GetEta()); - registry.fill(HIST("hEtaV0NegDau"), kfNeg.GetEta()); - registry.fill(HIST("hEtaKaFromCasc"), kfBachKaonToOmega.GetEta()); - registry.fill(HIST("hEtaPiFromCharmBaryon"), kfBachPionToOmegaC.GetEta()); - registry.fill(HIST("hCascradius"), RecoDecay::sqrtSumOfSquares(vertexCasc[0], vertexCasc[1])); - registry.fill(HIST("hV0radius"), RecoDecay::sqrtSumOfSquares(vertexV0[0], vertexV0[1])); - registry.fill(HIST("hCosPACasc"), kfOmegac0Candidate.cosPaCascToPv); - registry.fill(HIST("hCosPAV0"), kfOmegac0Candidate.cosPaV0ToPv); - registry.fill(HIST("hDcaCascDau"), kfOmegac0Candidate.kfDcaCascDau); - registry.fill(HIST("hDcaV0Dau"), kfOmegac0Candidate.kfDcaV0Dau); - registry.fill(HIST("hDcaXYToPvKa"), dcaxyCascBachelor); - registry.fill(HIST("hImpactParBachFromCharmBaryonXY"), impactParBachFromCharmBaryonXY); - registry.fill(HIST("hImpactParBachFromCharmBaryonZ"), impactParBachFromCharmBaryonZ); - registry.fill(HIST("hImpactParCascXY"), impactParameterCasc.getY()); - registry.fill(HIST("hImpactParCascZ"), impactParameterCasc.getZ()); - registry.fill(HIST("hPtKaFromCasc"), RecoDecay::sqrtSumOfSquares(pVecCascBachelor[0], pVecCascBachelor[1])); - registry.fill(HIST("hPtPiFromCharmBaryon"), RecoDecay::sqrtSumOfSquares(pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1])); - registry.fill(HIST("hCTauOmegac"), kfOmegac0Candidate.ctOmegac); - registry.fill(HIST("hKFGeoV0Chi2OverNdf"), v0Chi2OverNdf); - registry.fill(HIST("hKFGeoCascChi2OverNdf"), cascChi2OverNdf); - registry.fill(HIST("hKFGeoCharmbaryonChi2OverNdf"), charmbaryonChi2OverNdf); - registry.fill(HIST("hKFdecayLenXYLambda"), kfOmegac0Candidate.decayLenXYLambda); - registry.fill(HIST("hKFdecayLenXYCasc"), kfOmegac0Candidate.decayLenXYCasc); - registry.fill(HIST("hKFdecayLenXYOmegac"), kfOmegac0Candidate.decayLenXYOmegac); - registry.fill(HIST("hKFcosPaV0ToCasc"), kfOmegac0Candidate.cosPaV0ToCasc); - registry.fill(HIST("hKFcosPaCascToOmegac"), kfOmegac0Candidate.cosPaCascToOmegac); - } + KFParticle kfV0Pos(kfpTrackV0Pos, pdgV0Pos); + KFParticle kfV0Neg(kfpTrackV0Neg, pdgV0Neg); - // fill the table - rowCandToOmegaPi(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - vertexCharmBaryonFromFitter[0], vertexCharmBaryonFromFitter[1], vertexCharmBaryonFromFitter[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackCascDauCharged.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - kfOmegaToOmegaC.GetPx(), kfOmegaToOmegaC.GetPy(), kfOmegaToOmegaC.GetPz(), - pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecCascBachelor[0], pVecCascBachelor[1], pVecCascBachelor[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - impactParameterCasc.getY(), impactParBachFromCharmBaryonXY, - impactParameterCasc.getZ(), impactParBachFromCharmBaryonZ, - std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), - v0index, casc.posTrackId(), casc.negTrackId(), - casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), - kfOmegac0Candidate.massV0, kfOmegac0Candidate.massCasc, kfOmegac0Candidate.massOmegac, - kfOmegac0Candidate.cosPaV0ToPv, kfOmegac0Candidate.cosPaOmegacToPv, kfOmegac0Candidate.cosPaCascToPv, kfOmegac0Candidate.cosPaXYV0ToPv, kfOmegac0Candidate.cosPaXYOmegacToPv, kfOmegac0Candidate.cosPaXYCascToPv, - kfOmegac0Candidate.ctOmegac, kfOmegac0Candidate.ctCasc, kfOmegac0Candidate.ctV0, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapCascBachelor, pseudorapCharmBachelor, - kfOmegac0Candidate.etaOmegac, kfOmega.GetEta(), kfV0.GetEta(), - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyCascBachelor, - dcazV0Dau0, dcazV0Dau1, dcazCascBachelor, - kfOmegac0Candidate.kfDcaCascDau, kfOmegac0Candidate.kfDcaV0Dau, kfOmegac0Candidate.kfDcaOmegacDau, - decLenCharmBaryon, decLenCascade, decLenV0, errorDecayLengthCharmBaryon, errorDecayLengthXYCharmBaryon, cand.hfflag()); - // fill kf table - kfCandidateData(kfOmegac0Candidate.kfDcaXYPiFromOmegac, kfOmegac0Candidate.kfDcaXYCascToPv, - kfOmegac0Candidate.chi2GeoV0, kfOmegac0Candidate.chi2GeoCasc, kfOmegac0Candidate.chi2GeoOmegac, kfOmegac0Candidate.chi2MassV0, kfOmegac0Candidate.chi2MassCasc, - kfOmegac0Candidate.ldlV0, kfOmegac0Candidate.ldlCasc, kfOmegac0Candidate.ldlOmegac, - kfOmegac0Candidate.chi2NdfTopoV0ToPv, kfOmegac0Candidate.chi2NdfTopoCascToPv, kfOmegac0Candidate.chi2NdfTopoPiFromOmegacToPv, kfOmegac0Candidate.chi2NdfTopoOmegacToPv, kfOmegac0Candidate.deviationPiFromOmegacToPv, - kfOmegac0Candidate.chi2NdfTopoV0ToCasc, kfOmegac0Candidate.chi2NdfTopoCascToOmegac, - kfOmegac0Candidate.decayLenXYLambda, kfOmegac0Candidate.decayLenXYCasc, kfOmegac0Candidate.decayLenXYOmegac, - kfOmegac0Candidate.cosPaV0ToCasc, kfOmegac0Candidate.cosPaCascToOmegac, kfOmegac0Candidate.cosPaXYV0ToCasc, kfOmegac0Candidate.cosPaXYCascToOmegac, - kfOmegac0Candidate.rapOmegac, kfOmegac0Candidate.ptPiFromOmegac, kfOmegac0Candidate.ptOmegac, - kfOmegac0Candidate.cosThetaStarPiFromOmegac, - v0NDF, cascNDF, charmbaryonNDF, v0Ndfm, cascNdfm, - v0Chi2OverNdf, cascChi2OverNdf, charmbaryonChi2OverNdf, v0Chi2OverNdfm, cascChi2OverNdfm, kfOmegac0Candidate.cascRejectInvmass); - - } // loop over LF Cascade-bachelor candidates - } // end of run function - //========================================================== - template - void runKfXic0CreatorWithKFParticle(Coll const&, - aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const&, KFCascadesLinked const&, - aod::HfCascLf2Prongs const& candidates, - Hist& hInvMassCharmBaryon, - Hist& hFitterStatus, - Hist& hCandidateCounter, - Hist& hCascadesCounter) - { - for (const auto& cand : candidates) { - hCandidateCounter->Fill(1); - if (!TESTBIT(cand.hfflag(), aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi)) { - continue; - } - auto collision = cand.collision_as(); + auto trackParCovV0Pos = getTrackParCovFromKFP(kfV0Pos, kfV0Pos.GetPDG(), 1); + auto trackParCovV0Neg = getTrackParCovFromKFP(kfV0Neg, kfV0Neg.GetPDG(), -1); - float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - if (rejectionMask != 0) { - /// at least one event selection not satisfied --> reject the candidate - continue; - } - - // set the magnetic field from CCDB - auto bc = collision.template bc_as(); - if (runNumber != bc.runNumber()) { - LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); - magneticField = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << ">>>>>>>>>>>> Magnetic field: " << magneticField; - runNumber = bc.runNumber(); - } - df.setBz(magneticField); - KFParticle::SetField(magneticField); - // bachelor from Xic0 - auto trackCharmBachelorId = cand.prong0Id(); - auto trackCharmBachelor = tracks.rawIteratorAt(trackCharmBachelorId); - auto cascAodElement = cand.cascade_as(); - hCascadesCounter->Fill(0); - int v0index = cascAodElement.v0Id(); - if (!cascAodElement.has_kfCascData()) { - continue; - } - auto casc = cascAodElement.kfCascData_as(); - hCascadesCounter->Fill(1); - auto trackCascDauChargedId = casc.bachelorId(); - auto trackV0Dau0Id = casc.posTrackId(); - auto trackV0Dau1Id = casc.negTrackId(); - auto trackCascDauCharged = tracksIU.rawIteratorAt(trackCascDauChargedId); // pion <- xi track - auto trackV0Dau0 = tracksIU.rawIteratorAt(trackV0Dau0Id); // V0 positive daughter track - auto trackV0Dau1 = tracksIU.rawIteratorAt(trackV0Dau1Id); // V0 negative daughter track - - auto bachCharge = trackCascDauCharged.signed1Pt() > 0 ? +1 : -1; - - //// pion & p TrackParCov - auto trackParCovV0Dau0 = getTrackParCov(trackV0Dau0); - auto trackParCovV0Dau1 = getTrackParCov(trackV0Dau1); - // pion <- casc TrackParCov - auto xiDauChargedTrackParCov = getTrackParCov(trackCascDauCharged); - - // convert tracks into KFParticle object - KFPTrack kfTrack0 = createKFPTrackFromTrack(trackV0Dau0); - KFPTrack kfTrack1 = createKFPTrackFromTrack(trackV0Dau1); - KFPTrack kfTrackBach = createKFPTrackFromTrack(trackCascDauCharged); - - KFParticle kfPosPr(kfTrack0, kProton); - KFParticle kfNegPi(kfTrack1, kPiMinus); - KFParticle kfNegBachPi(kfTrackBach, kPiMinus); - KFParticle kfPosPi(kfTrack0, kPiPlus); - KFParticle kfNegPr(kfTrack1, kProton); - KFParticle kfPosBachPi(kfTrackBach, kPiPlus); - - KFParticle kfBachPion; - KFParticle kfPos; - KFParticle kfNeg; - if (bachCharge < 0) { - kfPos = kfPosPr; - kfNeg = kfNegPi; - kfBachPion = kfNegBachPi; - } else { - kfPos = kfPosPi; - kfNeg = kfNegPr; - kfBachPion = kfPosBachPi; - } - - //__________________________________________ - //*>~<* step 1 : construct V0 with KF - const KFParticle* v0Daughters[2] = {&kfPos, &kfNeg}; - // construct V0 + /// Extra calculations for V0 KFParticle kfV0; - kfV0.SetConstructMethod(kfConstructMethod); - try { - kfV0.Construct(v0Daughters, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct cascade V0 from daughter tracks: " << e.what(); - continue; + float xyzpxpypzV0[6] = {vertexV0[0], vertexV0[1], vertexV0[2], pVecV0[0], pVecV0[1], pVecV0[2]}; + kfV0.Create(xyzpxpypzV0, casc.kfTrackCovMatV0(), 0, MassLambda0); + if (configs.kfConstrainInvMassV0) { + kfV0.SetNonlinearMassConstraint(MassLambda); } - // mass window cut on lambda before mass constraint - float massLam, sigLam; - kfV0.GetMass(massLam, sigLam); - if (std::abs(massLam - MassLambda0) > lambdaMassWindow) - continue; + float kfMassV0, kfSigMassV0; + kfV0.GetMass(kfMassV0, kfSigMassV0); - // err_mass>0 of Lambda - if (sigLam <= 0) - continue; - // chi2>0 && NDF>0 for selecting Lambda - if ((kfV0.GetNDF() <= 0 || kfV0.GetChi2() <= 0)) - continue; + KFParticle kfV0ConstrainedToPv = kfV0; + KFParticle kfV0ConstrainedToCasc = kfV0; + kfV0ConstrainedToPv.SetProductionVertex(kfPv); + kfV0ConstrainedToCasc.SetProductionVertex(kfCasc); - kfXic0Candidate.chi2GeoV0 = kfV0.GetChi2(); - KFParticle kfV0MassConstrained = kfV0; - kfV0MassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassLambda); // set mass constrain to Lambda - if (kfUseV0MassConstraint) { - kfV0 = kfV0MassConstrained; - } - kfV0.TransportToDecayVertex(); - - //__________________________________________ - //*>~<* step 2 : reconstruct cascade(Xi) with KF - const KFParticle* xiDaugthers[2] = {&kfBachPion, &kfV0}; - // construct cascade - KFParticle kfXi; - kfXi.SetConstructMethod(kfConstructMethod); - try { - kfXi.Construct(xiDaugthers, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct Xi from V0 and bachelor track: " << e.what(); - continue; - } + /// Extra calculations for bachelor + auto trackBach = casc.bachelor_as(); + KFPTrack kfpTrackBach = createKFPTrackFromTrack(trackBach); + KFParticle kfBach(kfpTrackBach, pdgOfBach[decayChannel]); - float massCasc, sigCasc; - kfXi.GetMass(massCasc, sigCasc); - // err_massXi > 0 - if (sigCasc <= 0) - continue; + KFParticle kfBachConstrainedToPv = kfBach; + KFParticle kfBachConstrainedToCasc = kfBach; + kfBachConstrainedToPv.SetProductionVertex(kfPv); + kfBachConstrainedToCasc.SetProductionVertex(kfCasc); - if (std::abs(massCasc - MassXiMinus) > massToleranceCascade) - continue; - // chi2>0 && NDF>0 - if (kfXi.GetNDF() <= 0 || kfXi.GetChi2() <= 0) - continue; - kfXic0Candidate.chi2GeoCasc = kfXi.GetChi2(); - KFParticle kfXiMassConstrained = kfXi; - kfXiMassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassXiMinus); // set mass constrain to XiMinus - if (kfUseCascadeMassConstraint) { - // set mass constraint if requested - KFParticle kfXi = kfXiMassConstrained; - } - registry.fill(HIST("hInvMassXiMinus"), massCasc); - kfXi.TransportToDecayVertex(); - - //__________________________________________ - //*>~<* step 3 : reconstruc Xic0 with KF - // Create KF charm bach Pion from track - KFPTrack kfTrackBachPion = createKFPTrackFromTrack(trackCharmBachelor); - KFParticle kfCharmBachPion(kfTrackBachPion, kPiPlus); - const KFParticle* xiC0Daugthers[2] = {&kfCharmBachPion, &kfXi}; - - // construct XiC0 - KFParticle kfXiC0; - kfXiC0.SetConstructMethod(kfConstructMethod); - try { - kfXiC0.Construct(xiC0Daugthers, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct XiC0 from Cascade and bachelor pion track: " << e.what(); - continue; - } - float massXiC0, sigXiC0; - kfXiC0.GetMass(massXiC0, sigXiC0); - if (sigXiC0 <= 0) - continue; - // chi2>0 && NDF>0 - if (kfXiC0.GetNDF() <= 0 || kfXiC0.GetChi2() <= 0) - continue; + auto trackParCovBach = getTrackParCovFromKFP(kfBachConstrainedToCasc, kfBachConstrainedToCasc.GetPDG(), trackBach.sign()); - hFitterStatus->Fill(0); - hCandidateCounter->Fill(2); - kfXiC0.TransportToDecayVertex(); - // PV - KFPVertex kfVertex = createKFPVertexFromCollision(collision); - KFParticle kfPV(kfVertex); - - KFParticle kfPosOrigin = kfPos; - KFParticle kfNegOrigin = kfNeg; - // set production vertex; - kfNeg.SetProductionVertex(kfV0); - kfPos.SetProductionVertex(kfV0); - - KFParticle kfBachPionToXi = kfBachPion; - KFParticle kfV0ToCasc = kfV0; - kfBachPionToXi.SetProductionVertex(kfXi); - kfV0ToCasc.SetProductionVertex(kfXi); - - KFParticle kfXiToXiC = kfXi; - KFParticle kfCharmBachPionToXiC = kfCharmBachPion; - kfCharmBachPionToXiC.SetProductionVertex(kfXiC0); - kfXiToXiC.SetProductionVertex(kfXiC0); - - // KFParticle to PV - KFParticle kfV0ToPv = kfV0; - KFParticle kfXiToPv = kfXi; - KFParticle kfXic0ToPv = kfXiC0; - KFParticle kfPiFromXicToPv = kfCharmBachPion; - - kfV0ToPv.SetProductionVertex(kfPV); - kfXiToPv.SetProductionVertex(kfPV); - kfXic0ToPv.SetProductionVertex(kfPV); - kfPiFromXicToPv.SetProductionVertex(kfPV); - //------------get updated daughter tracks after vertex fit --------------- - auto trackParVarCharmBachelor = getTrackParCovFromKFP(kfCharmBachPionToXiC, o2::track::PID::Pion, -bachCharge); // chrambaryon bach pion - trackParVarCharmBachelor.setAbsCharge(1); - - xiDauChargedTrackParCov = getTrackParCovFromKFP(kfBachPionToXi, o2::track::PID::Pion, bachCharge); // Cascade bach pion - xiDauChargedTrackParCov.setAbsCharge(1); - o2::track::TrackParCov trackCasc = getTrackParCovFromKFP(kfXiToXiC, kfXiToXiC.GetPDG(), bachCharge); - trackCasc.setAbsCharge(1); - - trackParCovV0Dau0 = getTrackParCovFromKFP(kfPos, kfPos.GetPDG(), 1); // V0 postive daughter - trackParCovV0Dau0.setAbsCharge(1); - trackParCovV0Dau1 = getTrackParCovFromKFP(kfNeg, kfNeg.GetPDG(), -1); // V0 negtive daughter - trackParCovV0Dau1.setAbsCharge(1); + /// Extra calculations for casc + float kfMassCasc, kfSigMassCasc; + kfCasc.GetMass(kfMassCasc, kfSigMassCasc); - //-------------------------- V0 info--------------------------- - // pseudorapidity - float pseudorapV0Dau0 = kfPos.GetEta(); - float pseudorapV0Dau1 = kfNeg.GetEta(); + KFParticle kfCascConstrainedToPv = kfCasc; + KFParticle kfCascConstrainedToCharmBaryon = kfCasc; + kfCascConstrainedToPv.SetProductionVertex(kfPv); + kfCascConstrainedToCharmBaryon.SetProductionVertex(kfCharmBaryon); - // info from from KFParticle - std::array pVecV0 = {kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz()}; // pVec stands for vector containing the 3-momentum components - std::array vertexV0 = {kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}; - std::array pVecV0Dau0 = {kfPos.GetPx(), kfPos.GetPy(), kfPos.GetPz()}; - std::array pVecV0Dau1 = {kfNeg.GetPx(), kfNeg.GetPy(), kfNeg.GetPz()}; + /// Extra calculation for charm bachelor + KFParticle kfCharmBachelorConstrainedToPv = kfCharmBachelor; + KFParticle kfCharmBachelorConstrainedToCharmBaryon = kfCharmBachelor; + kfCharmBachelorConstrainedToPv.SetProductionVertex(kfPv); + kfCharmBachelorConstrainedToCharmBaryon.SetProductionVertex(kfCharmBaryon); - //-------------------reconstruct cascade track------------------ - // pseudorapidity - float pseudorapCascBachelor = kfBachPionToXi.GetEta(); + /// Extra calculation for charm baryon + float kfMassCharmBaryon, kfSigMassCharmBaryon; + kfCharmBaryon.GetMass(kfMassCharmBaryon, kfSigMassCharmBaryon); - // info from KFParticle - std::array vertexCasc = {kfXi.GetX(), kfXi.GetY(), kfXi.GetZ()}; - std::array pVecCascBachelor = {kfBachPionToXi.GetPx(), kfBachPionToXi.GetPy(), kfBachPionToXi.GetPz()}; + KFParticle kfCharmBaryonConstrainedToPv = kfCharmBaryon; + kfCharmBaryonConstrainedToPv.SetProductionVertex(kfPv); - std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; - std::array pVecCharmBachelorAsD; - pVecCharmBachelorAsD[0] = kfCharmBachPionToXiC.GetPx(); - pVecCharmBachelorAsD[1] = kfCharmBachPionToXiC.GetPy(); - pVecCharmBachelorAsD[2] = kfCharmBachPionToXiC.GetPz(); + //------------------------------Calculate physical quantities and fill candidate table------------------------------ - std::array pVecCharmBaryon = {kfXiC0.GetPx(), kfXiC0.GetPy(), kfXiC0.GetPz()}; - auto covVtxCharmBaryon = kfXiC0.CovarianceMatrix(); - float covMatrixPV[6]; - kfVertex.GetCovarianceMatrix(covMatrixPV); + // Get updated daughter tracks after vertex fit + o2::track::TrackParCov trackParCovCasc = getTrackParCovFromKFP(kfCascConstrainedToCharmBaryon, kfCascConstrainedToCharmBaryon.GetPDG(), kfBach.GetQ()); + trackParCovCasc.setAbsCharge(1); + o2::track::TrackParCov trackParCovCharmBachelor = getTrackParCovFromKFP(kfCharmBachelorConstrainedToCharmBaryon, kfCharmBachelorConstrainedToCharmBaryon.GetPDG(), -kfBach.GetQ()); + trackParCovCharmBachelor.setAbsCharge(1); // impact parameters - std::array impactParameterV0Dau0; - std::array impactParameterV0Dau1; - std::array impactParameterPiFromCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Dau0, 2.f, matCorr, &impactParameterV0Dau0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Dau1, 2.f, matCorr, &impactParameterV0Dau1); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, xiDauChargedTrackParCov, 2.f, matCorr, &impactParameterPiFromCasc); - float dcaxyV0Dau0 = impactParameterV0Dau0[0]; - float dcaxyV0Dau1 = impactParameterV0Dau1[0]; - float dcaxyCascBachelor = impactParameterPiFromCasc[0]; - - // pseudorapidity - float pseudorapCharmBachelor = kfCharmBachPionToXiC.GetEta(); - - // fill test histograms - hInvMassCharmBaryon->Fill(massXiC0); - hCandidateCounter->Fill(3); - - //// KFParticle table information - // KF chi2 - auto v0NDF = kfV0.GetNDF(); - auto v0Chi2OverNdf = kfXic0Candidate.chi2GeoV0 / v0NDF; - - auto cascNDF = kfXi.GetNDF(); - auto cascChi2OverNdf = kfXic0Candidate.chi2GeoCasc / cascNDF; - - kfXic0Candidate.chi2GeoXic = kfXiC0.GetChi2(); - auto charmbaryonNDF = kfXiC0.GetNDF(); - auto charmbaryonChi2OverNdf = kfXic0Candidate.chi2GeoXic / charmbaryonNDF; - - kfXic0Candidate.chi2MassV0 = kfV0MassConstrained.GetChi2(); - auto v0Ndfm = kfV0MassConstrained.GetNDF(); - auto v0Chi2OverNdfm = kfXic0Candidate.chi2MassV0 / v0Ndfm; - - kfXic0Candidate.chi2MassCasc = kfXiMassConstrained.GetChi2(); - auto cascNdfm = kfXiMassConstrained.GetNDF(); - auto cascChi2OverNdfm = kfXic0Candidate.chi2MassCasc / cascNdfm; - - // KF topo Chi2 - kfXic0Candidate.chi2NdfTopoV0ToPv = kfV0ToPv.GetChi2() / kfV0ToPv.GetNDF(); - kfXic0Candidate.chi2NdfTopoCascToPv = kfXiToPv.GetChi2() / kfXiToPv.GetNDF(); - kfXic0Candidate.chi2NdfTopoPiFromXicToPv = kfPiFromXicToPv.GetChi2() / kfPiFromXicToPv.GetNDF(); - kfXic0Candidate.chi2NdfTopoXicToPv = kfXic0ToPv.GetChi2() / kfXic0ToPv.GetNDF(); - - auto cascBachTopoChi2 = kfBachPionToXi.GetChi2(); - kfXic0Candidate.chi2NdfTopoV0ToCasc = kfV0ToCasc.GetChi2() / kfV0ToCasc.GetNDF(); - kfXic0Candidate.chi2NdfTopoCascToXic = kfXiToXiC.GetChi2() / kfXiToXiC.GetNDF(); - - // KF ldl - kfXic0Candidate.ldlV0 = ldlFromKF(kfV0, kfPV); - kfXic0Candidate.ldlCasc = ldlFromKF(kfXi, kfPV); - kfXic0Candidate.ldlXic = ldlFromKF(kfXiC0, kfPV); - - // KF dca - kfXic0Candidate.kfDcaXYPiFromXic = kfCharmBachPionToXiC.GetDistanceFromVertexXY(kfPV); - kfXic0Candidate.kfDcaV0Dau = kfNeg.GetDistanceFromParticle(kfPos); - kfXic0Candidate.kfDcaCascDau = kfBachPionToXi.GetDistanceFromParticle(kfV0ToCasc); - kfXic0Candidate.kfDcaXYCascToPv = kfXiToXiC.GetDistanceFromVertexXY(kfPV); - kfXic0Candidate.kfDcaXicDau = kfCharmBachPionToXiC.GetDistanceFromParticle(kfXiToXiC); - - // KF decay length - float decayLxyLam, errDecayLxyLam; - kfV0ToCasc.GetDecayLengthXY(decayLxyLam, errDecayLxyLam); - kfXic0Candidate.decayLenXYLambda = decayLxyLam; - - float decayLxyCasc, errDecayLxyCasc; - kfXiToXiC.GetDecayLengthXY(decayLxyCasc, errDecayLxyCasc); - kfXic0Candidate.decayLenXYCasc = decayLxyCasc; - - float decayLxyXic0, errDecayLxyXic0; - kfXic0ToPv.GetDecayLengthXY(decayLxyXic0, errDecayLxyXic0); - kfXic0Candidate.decayLenXYXic = decayLxyXic0; - - // KF cosPA - kfXic0Candidate.cosPaV0ToPv = cpaFromKF(kfV0, kfPV); - kfXic0Candidate.cosPaCascToPv = cpaFromKF(kfXi, kfPV); - kfXic0Candidate.cosPaXicToPv = cpaFromKF(kfXiC0, kfPV); - kfXic0Candidate.cosPaXYV0ToPv = cpaXYFromKF(kfV0, kfPV); - kfXic0Candidate.cosPaXYCascToPv = cpaXYFromKF(kfXi, kfPV); - kfXic0Candidate.cosPaXYXicToPv = cpaXYFromKF(kfXiC0, kfPV); - - kfXic0Candidate.cosPaV0ToCasc = cpaFromKF(kfV0, kfXi); - kfXic0Candidate.cosPaCascToXic = cpaFromKF(kfXi, kfXiC0); - kfXic0Candidate.cosPaXYV0ToCasc = cpaXYFromKF(kfV0, kfXi); - kfXic0Candidate.cosPaXYCascToXic = cpaXYFromKF(kfXi, kfXiC0); - // KF mass - kfXic0Candidate.massV0 = massLam; - kfXic0Candidate.massCasc = massCasc; - kfXic0Candidate.massXic = massXiC0; - - // KF rapidity - kfXic0Candidate.rapXic = kfXiC0.GetRapidity(); - - // KF cosThetaStar - kfXic0Candidate.cosThetaStarPiFromXic = cosThetaStarFromKF(0, 4132, 211, 3312, kfCharmBachPionToXiC, kfXiToXiC); + std::array impactParameterV0DauPos; + std::array impactParameterV0DauNeg; + std::array impactParameterBach; + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Pos, 2.f, matCorr, &impactParameterV0DauPos); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovV0Neg, 2.f, matCorr, &impactParameterV0DauNeg); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovBach, 2.f, matCorr, &impactParameterBach); + float dcaxyV0DauPos = impactParameterV0DauPos[0]; + float dcaxyV0DauNeg = impactParameterV0DauNeg[0]; + float dcaxyBach = impactParameterBach[0]; + float dcazV0DauPos = impactParameterV0DauPos[1]; + float dcazV0DauNeg = impactParameterV0DauNeg[1]; + float dcazBach = impactParameterBach[1]; + + o2::dataformats::DCA impactParameterCasc, impactParameterCharmBachelor; + auto primaryVertex = getPrimaryVertex(collision); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCasc, 2.f, matCorr, &impactParameterCasc); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovCharmBachelor, 2.f, matCorr, &impactParameterCharmBachelor); + + // get Chi2Topo/NDF + float chi2NdfTopoV0ToPv = kfV0ConstrainedToPv.GetChi2() / kfV0ConstrainedToPv.GetNDF(); + float chi2NdfTopoV0ToCasc = kfV0ConstrainedToPv.GetChi2() / kfV0ConstrainedToPv.GetNDF(); + float chi2NdfTopoBachToPv = kfBachConstrainedToPv.GetChi2() / kfBachConstrainedToPv.GetNDF(); + float chi2NdfTopoBachToCasc = kfBachConstrainedToCasc.GetChi2() / kfBachConstrainedToCasc.GetNDF(); + float chi2NdfTopoCascToPv = kfCascConstrainedToPv.GetChi2() / kfCascConstrainedToPv.GetNDF(); + float chi2NdfTopoCascToCharmBaryon = kfCascConstrainedToCharmBaryon.GetChi2() / kfCascConstrainedToCharmBaryon.GetNDF(); + float chi2NdfTopoCharmBachelorToPv = kfCharmBachelorConstrainedToPv.GetChi2() / kfCharmBachelorConstrainedToPv.GetNDF(); + float chi2NdfTopoCharmBachelorToCharmBaryon = kfCharmBachelorConstrainedToCharmBaryon.GetChi2() / kfCharmBachelorConstrainedToCharmBaryon.GetNDF(); + float chi2NdfTopoCharmBaryonToPv = kfCharmBachelorConstrainedToPv.GetChi2() / kfCharmBachelorConstrainedToPv.GetNDF(); + + float deviationCharmBachelorToPv = kfCalculateChi2ToPrimaryVertex(kfCharmBachelor, kfPv); + float chi2NdfBach = kfBach.GetChi2() / kfBach.GetNDF(); + + // get ldl + float ldlV0 = ldlFromKF(kfV0, kfPv); + float ldlCasc = ldlFromKF(kfCasc, kfPv); + float ldlCharmBaryon = ldlFromKF(kfCharmBaryon, kfPv); - // KF ct - kfXic0Candidate.ctV0 = kfV0ToCasc.GetLifeTime(); - kfXic0Candidate.ctCasc = kfXiToXiC.GetLifeTime(); - kfXic0Candidate.ctXic = kfXic0ToPv.GetLifeTime(); - // KF eta - kfXic0Candidate.etaXic = kfXiC0.GetEta(); - - // fill KF hist - registry.fill(HIST("hKFParticleCascBachTopoChi2"), cascBachTopoChi2); - registry.fill(HIST("hKfXiC0_ldl"), kfXic0Candidate.ldlXic); - - // fill kf table - kfCandidateXicData(collision.globalIndex(), - pvCoord[0], pvCoord[1], pvCoord[2], - vertexCasc[0], vertexCasc[1], vertexCasc[2], - vertexV0[0], vertexV0[1], vertexV0[2], - trackCascDauCharged.sign(), - covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], - pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], - kfXiToXiC.GetPx(), kfXiToXiC.GetPy(), kfXiToXiC.GetPz(), - pVecCharmBachelorAsD[0], pVecCharmBachelorAsD[1], pVecCharmBachelorAsD[2], - pVecV0[0], pVecV0[1], pVecV0[2], - pVecCascBachelor[0], pVecCascBachelor[1], pVecCascBachelor[2], - pVecV0Dau0[0], pVecV0Dau0[1], pVecV0Dau0[2], - pVecV0Dau1[0], pVecV0Dau1[1], pVecV0Dau1[2], - v0index, casc.posTrackId(), casc.negTrackId(), - casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), - kfXic0Candidate.massV0, kfXic0Candidate.massCasc, kfXic0Candidate.massXic, - kfXic0Candidate.cosPaV0ToPv, kfXic0Candidate.cosPaCascToPv, - kfXic0Candidate.ctCasc, kfXic0Candidate.ctV0, kfXic0Candidate.ctXic, - pseudorapV0Dau0, pseudorapV0Dau1, pseudorapCascBachelor, pseudorapCharmBachelor, - kfXic0Candidate.etaXic, kfXi.GetEta(), kfV0.GetEta(), - dcaxyV0Dau0, dcaxyV0Dau1, dcaxyCascBachelor, - kfXic0Candidate.kfDcaCascDau, kfXic0Candidate.kfDcaV0Dau, kfXic0Candidate.kfDcaXicDau, - kfXic0Candidate.kfDcaXYPiFromXic, kfXic0Candidate.kfDcaXYCascToPv, - kfXic0Candidate.chi2GeoV0, kfXic0Candidate.chi2GeoCasc, kfXic0Candidate.chi2GeoXic, kfXic0Candidate.chi2MassV0, kfXic0Candidate.chi2MassCasc, - kfXic0Candidate.ldlV0, kfXic0Candidate.ldlCasc, - kfXic0Candidate.chi2NdfTopoV0ToPv, kfXic0Candidate.chi2NdfTopoCascToPv, kfXic0Candidate.chi2NdfTopoPiFromXicToPv, kfXic0Candidate.chi2NdfTopoXicToPv, - kfXic0Candidate.chi2NdfTopoV0ToCasc, kfXic0Candidate.chi2NdfTopoCascToXic, - kfXic0Candidate.decayLenXYLambda, kfXic0Candidate.decayLenXYCasc, kfXic0Candidate.decayLenXYXic, - kfXic0Candidate.cosPaV0ToCasc, kfXic0Candidate.cosPaCascToXic, - kfXic0Candidate.rapXic, - kfXic0Candidate.cosThetaStarPiFromXic, - v0NDF, cascNDF, charmbaryonNDF, v0Ndfm, cascNdfm, - v0Chi2OverNdf, cascChi2OverNdf, charmbaryonChi2OverNdf, v0Chi2OverNdfm, cascChi2OverNdfm); - // fill QA table - if (kfResolutionQA) { - rowKfXic0Qa(massLam, massCasc, massXiC0, sigLam, sigCasc, sigXiC0, - collision.globalIndex(), v0index, casc.posTrackId(), casc.negTrackId(), casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), - kfPos.GetX(), kfPos.GetY(), kfPos.GetZ(), kfPos.GetErrX(), kfPos.GetErrY(), kfPos.GetErrZ(), kfPos.GetPt(), - kfNeg.GetX(), kfNeg.GetY(), kfNeg.GetZ(), kfNeg.GetErrX(), kfNeg.GetErrY(), kfNeg.GetErrZ(), kfNeg.GetPt(), - kfV0.GetX(), kfV0.GetY(), kfV0.GetZ(), kfV0.GetErrX(), kfV0.GetErrY(), kfV0.GetErrZ(), kfV0.GetPt(), - kfBachPionToXi.GetX(), kfBachPionToXi.GetY(), kfBachPionToXi.GetZ(), kfBachPionToXi.GetErrX(), kfBachPionToXi.GetErrY(), kfBachPionToXi.GetErrZ(), kfBachPionToXi.GetPt(), - kfXi.GetX(), kfXi.GetY(), kfXi.GetZ(), kfXi.GetErrX(), kfXi.GetErrY(), kfXi.GetErrZ(), kfXi.GetPt(), - kfCharmBachPionToXiC.GetX(), kfCharmBachPionToXiC.GetY(), kfCharmBachPionToXiC.GetZ(), kfCharmBachPionToXiC.GetErrX(), kfCharmBachPionToXiC.GetErrY(), kfCharmBachPionToXiC.GetErrZ(), kfCharmBachPionToXiC.GetPt(), - kfXiC0.GetX(), kfXiC0.GetY(), kfXiC0.GetZ(), kfXiC0.GetErrX(), kfXiC0.GetErrY(), kfXiC0.GetErrZ(), kfXiC0.GetPt(), - casc.xlambda(), casc.ylambda(), casc.zlambda(), casc.x(), casc.y(), casc.z()); - } - } // loop over LF Cascade-bachelor candidates - } + // get DCAs + float kfDcaV0Daughters = casc.dcaV0daughters(); + float kfDcaCascDaughters = kfBachConstrainedToCasc.GetDistanceFromParticle(kfV0ConstrainedToCasc); + float kfDcaCharmBaryonDaughters = kfCharmBachelorConstrainedToCharmBaryon.GetDistanceFromParticle(kfCascConstrainedToCharmBaryon); + float kfDcaXYCharmBachelorToPv = kfCharmBachelorConstrainedToCharmBaryon.GetDistanceFromVertexXY(kfPv); + float kfDcaXYCascToPv = kfCascConstrainedToCharmBaryon.GetDistanceFromVertexXY(kfPv); - template - void runOmegac0Xic0ToOmegaKaCreatorWithKFParticle(Coll const&, - aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const&, KFCascadesLinked const&, - aod::HfCascLf2Prongs const& candidates, - Hist& hInvMassCharmBaryon, - Hist& hFitterStatus, - Hist& hCandidateCounter, - Hist& hCascadesCounter) - { - for (const auto& cand : candidates) { - hCandidateCounter->Fill(1); + // get decay length - In XY + float decayLXYV0, errDecayLXYV0; + kfV0ConstrainedToCasc.GetDecayLengthXY(decayLXYV0, errDecayLXYV0); - //----------------------check if the event is selected----------------------------- - auto collision = cand.collision_as(); - float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - if (rejectionMask != 0) { - /// at least one event selection not satisfied --> reject the candidate - continue; - } + float decayLXYCasc, errDecayLXYCasc; + kfCascConstrainedToCharmBaryon.GetDecayLengthXY(decayLXYCasc, decayLXYCasc); - //----------------------Set the magnetic field from ccdb----------------------------- - auto bc = collision.template bc_as(); - if (runNumber != bc.runNumber()) { - LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); - magneticField = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << ">>>>>>>>>>>> Magnetic field: " << magneticField; - runNumber = bc.runNumber(); - } - KFParticle::SetField(magneticField); + float decayLXYCharmBaryon, errDecayLXYCharmBaryon; + kfCharmBaryonConstrainedToPv.GetDecayLengthXY(decayLXYCharmBaryon, errDecayLXYCharmBaryon); - // Retrieve skimmed cascade and pion tracks - auto cascAodElement = cand.cascade_as(); - hCascadesCounter->Fill(0); - if (!cascAodElement.has_kfCascData()) { - continue; - } - auto casc = cascAodElement.kfCascData_as(); - hCascadesCounter->Fill(1); - - // convert KaonFromCharm&KaFromOmega&V0DauPos&V0DauNeg tracks into KFParticle object - auto trackCharmBachelorId = cand.prong0Id(); - auto trackKaFromCharm = tracks.rawIteratorAt(trackCharmBachelorId); - auto trackCascDauChargedId = casc.bachelorId(); - auto trackV0Dau0Id = casc.posTrackId(); - auto trackV0Dau1Id = casc.negTrackId(); - auto trackKaFromOmega = tracksIU.rawIteratorAt(trackCascDauChargedId); // Ka <- Omega track - auto trackV0DauPos = tracksIU.rawIteratorAt(trackV0Dau0Id); // V0 positive daughter track - auto trackV0DauNeg = tracksIU.rawIteratorAt(trackV0Dau1Id); // V0 negative daughter track - auto kaFromOmegaCharge = trackKaFromOmega.sign(); - auto signOmega = casc.sign(); - - KFPTrack kfpTrackKaFromCharm = createKFPTrackFromTrack(trackKaFromCharm); - KFPTrack kfpTrackKaFromOmega = createKFPTrackFromTrack(trackKaFromOmega); - KFPTrack kfpTrackV0DauPos = createKFPTrackFromTrack(trackV0DauPos); - KFPTrack kfpTrackV0DauNeg = createKFPTrackFromTrack(trackV0DauNeg); - - KFParticle kfPrFromV0(kfpTrackV0DauPos, kProton); - KFParticle kfPiFromV0(kfpTrackV0DauNeg, kPiMinus); - KFParticle kfKaFromOmega(kfpTrackKaFromOmega, kKMinus); - KFParticle kfPiFromXiRej(kfpTrackKaFromOmega, kPiMinus); // rej - KFParticle kfKaFromCharm(kfpTrackKaFromCharm, kKPlus); - - if (signOmega == 0 || kaFromOmegaCharge == 0 || kaFromOmegaCharge != signOmega) { - continue; - } - // convert for Pos and Neg Particles - if (signOmega > 0) { - kfPiFromV0 = KFParticle(kfpTrackV0DauPos, kPiPlus); - kfPrFromV0 = KFParticle(kfpTrackV0DauNeg, -kProton); - kfKaFromOmega = KFParticle(kfpTrackKaFromOmega, kKPlus); - kfPiFromXiRej = KFParticle(kfpTrackKaFromOmega, kPiPlus); // rej - kfKaFromCharm = KFParticle(kfpTrackKaFromCharm, kKMinus); - } - - if (doCascadePreselection) { - if (std::abs(casc.dcaXYCascToPV()) > dcaXYToPVCascadeMax) { - continue; - } - if (std::abs(casc.dcaV0daughters()) > dcaV0DaughtersMax) { - continue; - } - if (std::abs(casc.dcacascdaughters()) > dcaCascDaughtersMax) { - continue; - } - if (std::abs(casc.mOmega() - MassOmegaMinus) > massToleranceCascade) { - continue; - } - } + // get decay length - In XYZ + float decayLCharmBaryon = RecoDecay::distance(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}); + float decayLCasc = RecoDecay::distance(std::array{kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}, std::array{kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ()}); + float decayLV0 = RecoDecay::distance(std::array{kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ()}, std::array{kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}); - //----------------------info of V0 and cascade tracks from LF-table------------------ - std::array vertexV0 = {casc.xlambda(), casc.ylambda(), casc.zlambda()}; - std::array pVecV0 = {casc.pxlambda(), casc.pylambda(), casc.pzlambda()}; - std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; - std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; + double phiCharmBaryon, thetaCharmBaryon; + getPointDirection(std::array{kfV0.GetX(), kfV0.GetY(), kfV0.GetZ()}, std::array{kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ()}, phiCharmBaryon, thetaCharmBaryon); + float errDecayLCharmBaryon = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phiCharmBaryon, thetaCharmBaryon) + getRotatedCovMatrixXX(covMatrixCharmBaryon, phiCharmBaryon, thetaCharmBaryon)); - // step 1 : construct V0 with KF - const KFParticle* v0Daughters[2] = {&kfPrFromV0, &kfPiFromV0}; - // construct V0 - KFParticle kfV0; - kfV0.SetConstructMethod(kfConstructMethod); - try { - kfV0.Construct(v0Daughters, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct cascade V0 from daughter tracks: " << e.what(); - continue; - } - // mass window cut on lambda before mass constraint - float massLam, sigLam; - kfV0.GetMass(massLam, sigLam); - if (std::abs(massLam - MassLambda0) > lambdaMassWindow) - continue; - // err_mass>0 of Lambda - if (sigLam <= 0) - continue; - // chi2>0 && NDF>0 for selecting Lambda - if ((kfV0.GetNDF() <= 0 || kfV0.GetChi2() <= 0)) - continue; - KFParticle kfV0MassConstrained = kfV0; - kfV0MassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassLambda); // set mass constrain to Lambda - if (kfUseV0MassConstraint) { - kfV0 = kfV0MassConstrained; - } - kfV0.TransportToDecayVertex(); - - // step 2 : reconstruct cascade(Omega) with KF - const KFParticle* omegaDaugthers[2] = {&kfKaFromOmega, &kfV0}; - const KFParticle* omegaDaugthersRej[2] = {&kfPiFromXiRej, &kfV0}; // rej - // construct cascade - KFParticle kfOmega; - KFParticle kfOmegarej; // rej - kfOmega.SetConstructMethod(kfConstructMethod); - kfOmegarej.SetConstructMethod(kfConstructMethod); // rej - try { - kfOmega.Construct(omegaDaugthers, 2); - kfOmegarej.Construct(omegaDaugthersRej, 2); // rej - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct Omega or Omega_rej from V0 and bachelor track: " << e.what(); - continue; - } - float massCasc, sigCasc; - float massCascrej, sigCascrej; - kfOmega.GetMass(massCasc, sigCasc); - kfOmegarej.GetMass(massCascrej, sigCascrej); // rej - // err_massOmega and err_massXiRej > 0 - if (sigCasc <= 0 || sigCascrej <= 0) - continue; - // chi2>0 && NDF>0 - if (kfOmega.GetNDF() <= 0 || kfOmega.GetChi2() <= 0) - continue; - if ((std::abs(massCasc - MassOmegaMinus) > massToleranceCascade) || (std::abs(massCascrej - MassXiMinus) < massToleranceCascadeRej)) - continue; - registry.fill(HIST("hInvMassXiMinus_rej"), massCascrej); // rej: Add competing rejection to minimize misidentified Xi impact. Reject if kfBachPionRej is Pion and the constructed cascade has Xi's invariant mass. - KFParticle kfOmegaMassConstrained = kfOmega; - kfOmegaMassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassOmegaMinus); // set mass constrain to XiMinus - if (kfUseCascadeMassConstraint) { - // set mass constraint if requested - kfOmega = kfOmegaMassConstrained; - } - registry.fill(HIST("hInvMassXiMinus"), massCasc); - kfOmega.TransportToDecayVertex(); - // rej: Add competing rejection to minimize misidentified Xi impact. Reject if kfBachPionRej is Pion and the constructed cascade has Xi's invariant mass. - - // step 3 : reconstruc OmegaKa with KF - // Create KF charm bach Pion from track - const KFParticle* omegaKaDaugthers[2] = {&kfKaFromCharm, &kfOmega}; - // construct Omegac0 or Xic0 - KFParticle kfOmegaKa; - kfOmegaKa.SetConstructMethod(kfConstructMethod); - try { - kfOmegaKa.Construct(omegaKaDaugthers, 2); - } catch (std::runtime_error& e) { - LOG(debug) << "Failed to construct OmegaKa from Cascade and bachelor pion track: " << e.what(); - continue; + // get cosine of pointing angle + std::array pvCoord = {collision.posX(), collision.posY(), collision.posZ()}; + float cosPaV0ToPv = casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + float cosPaCascToPv = cpaFromKF(kfCasc, kfPv); + float cosPaCharmBaryonToPv = cpaFromKF(kfCharmBaryon, kfPv); + + float cosPaXYV0ToPv = RecoDecay::cpaXY(pvCoord, vertexV0, pVecV0); + float cosPaXYCascToPv = cpaXYFromKF(kfCasc, kfPv); + float cosPaXYCharmBaryonToPv = cpaXYFromKF(kfCharmBaryon, kfPv); + + float cosPaV0ToCasc = RecoDecay::cpa(vertexCasc, vertexV0, pVecV0); + float cosPaCascToCharmBaryon = cpaFromKF(kfCasc, kfCharmBaryon); + float cosPaXYV0ToCasc = RecoDecay::cpaXY(vertexCasc, vertexV0, pVecV0); + float cosPaXYCascToCharmBaryon = cpaXYFromKF(kfCasc, kfCharmBaryon); + + // KF pT, eta + float ptCasc = kfCascConstrainedToCharmBaryon.GetPt(); + float ptCharmBachelor = kfCharmBachelorConstrainedToCharmBaryon.GetPt(); + float ptCharmBaryon = kfCharmBaryon.GetPt(); + float yCharmBaryon = kfCharmBaryon.GetRapidity(); + + // get KF cosThetaStar(?) + float cosThetaStarCharmBachelorXic0, cosThetaStarCharmBachelorOmegac0; + if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { + cosThetaStarCharmBachelorXic0 = cosThetaStarFromKF(0, pdgOfCharmBaryon[decayChannel], pdgOfCascade[decayChannel], pdgOfCharmBach[decayChannel], kfCascConstrainedToCharmBaryon, kfCharmBachelorConstrainedToCharmBaryon); + cosThetaStarCharmBachelorOmegac0 = cosThetaStarFromKF(0, pdgOfCharmBaryon[decayChannel + 1], pdgOfCascade[decayChannel], pdgOfCharmBach[decayChannel], kfCascConstrainedToCharmBaryon, kfCharmBachelorConstrainedToCharmBaryon); + } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { + cosThetaStarCharmBachelorOmegac0 = cosThetaStarFromKF(0, pdgOfCharmBaryon[decayChannel + 1], pdgOfCascade[decayChannel], pdgOfCharmBach[decayChannel], kfCascConstrainedToCharmBaryon, kfCharmBachelorConstrainedToCharmBaryon); + } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { + cosThetaStarCharmBachelorXic0 = cosThetaStarFromKF(0, +kXiC0, pdgOfCascade[decayChannel], pdgOfCharmBach[decayChannel], kfCascConstrainedToCharmBaryon, kfCharmBachelorConstrainedToCharmBaryon); + cosThetaStarCharmBachelorOmegac0 = cosThetaStarFromKF(0, +kOmegaC0, pdgOfCascade[decayChannel], pdgOfCharmBach[decayChannel], kfCascConstrainedToCharmBaryon, kfCharmBachelorConstrainedToCharmBaryon); } - float massOmegaKa, sigOmegaKa; - kfOmegaKa.GetMass(massOmegaKa, sigOmegaKa); - if (sigOmegaKa <= 0) - continue; - if (kfOmegaKa.GetNDF() <= 0 || kfOmegaKa.GetChi2() <= 0) - continue; - kfOmegaKa.TransportToDecayVertex(); - hFitterStatus->Fill(0); - hCandidateCounter->Fill(2); - // initialize primary vertex - KFPVertex kfpVertex = createKFPVertexFromCollision(collision); - float covMatrixPV[6]; - kfpVertex.GetCovarianceMatrix(covMatrixPV); - KFParticle kfPv(kfpVertex); // for calculation of DCAs to PV - - // fill test histograms - hInvMassCharmBaryon->Fill(massOmegaKa); - - // topological constraint of daughter to mother - KFParticle kfKaFromCharmToOmegaKa = kfKaFromCharm; - KFParticle kfOmegaToOmegaKa = kfOmega; - KFParticle kfV0ToOmega = kfV0; - KFParticle kfKaToOmega = kfKaFromOmega; - KFParticle kfPrToV0 = kfPrFromV0; - KFParticle kfPiToV0 = kfPiFromV0; - - kfPrToV0.SetProductionVertex(kfV0); - kfPiToV0.SetProductionVertex(kfV0); - kfV0ToOmega.SetProductionVertex(kfOmega); - kfKaToOmega.SetProductionVertex(kfOmega); - kfKaFromCharmToOmegaKa.SetProductionVertex(kfOmegaKa); - kfOmegaToOmegaKa.SetProductionVertex(kfOmegaKa); - - // topological constraint to PV - // KFParticle to PV - KFParticle kfV0ToPv = kfV0; - KFParticle kfOmegaToPv = kfOmega; - KFParticle kfCharmToPv = kfOmegaKa; - KFParticle kfKaFromCharmToPv = kfKaFromCharm; - - kfV0ToPv.SetProductionVertex(kfPv); - kfOmegaToPv.SetProductionVertex(kfPv); - kfCharmToPv.SetProductionVertex(kfPv); - kfKaFromCharmToPv.SetProductionVertex(kfPv); - - //---------------------calculate physical parameters of OmegaKa candidate---------------------- - - // transport OmegaKa daughters to decay vertex (secondary vertex) - float secondaryVertex[3] = {0.}; - secondaryVertex[0] = kfOmegaKa.GetX(); - secondaryVertex[1] = kfOmegaKa.GetY(); - secondaryVertex[2] = kfOmegaKa.GetZ(); - kfKaFromCharm.TransportToPoint(secondaryVertex); - kfOmega.TransportToPoint(secondaryVertex); - - // get impact parameters of OmegaKa daughters - float impactParameterKaFromCharmXY = 0., errImpactParameterKaFromCharmXY = 0.; - float impactParameterOmegaXY = 0., errImpactParameterOmegaXY = 0.; - kfKaFromCharm.GetDistanceFromVertexXY(kfPv, impactParameterKaFromCharmXY, errImpactParameterKaFromCharmXY); - kfOmega.GetDistanceFromVertexXY(kfPv, impactParameterOmegaXY, errImpactParameterOmegaXY); + // KF ct + float ctV0 = kfV0ConstrainedToCasc.GetLifeTime(); + float ctCasc = kfCascConstrainedToCharmBaryon.GetLifeTime(); + float ctCharmBaryon = kfCharmBachelorConstrainedToPv.GetLifeTime(); - // calculate cosine of pointing angle - float cosPaV0ToPv = cpaFromKF(kfV0, kfPv); - float cosPaCascToPv = cpaFromKF(kfOmega, kfPv); - float cosPaOmegaKaToPv = cpaFromKF(kfOmegaKa, kfPv); - float cosPaXYV0ToPv = cpaXYFromKF(kfV0, kfPv); - float cosPaXYCascToPv = cpaXYFromKF(kfOmega, kfPv); - float cosPaXYOmegaKaToPv = cpaXYFromKF(kfOmegaKa, kfPv); - float cosPaV0ToCasc = cpaFromKF(kfV0, kfOmega); - float cosPaCascToOmegaKa = cpaFromKF(kfOmega, kfOmegaKa); - float cosPaXYV0ToCasc = cpaXYFromKF(kfV0, kfOmega); - float cosPaXYCascToOmegaKa = cpaXYFromKF(kfOmega, kfOmegaKa); - - // Get Chi2Geo/NDF - float chi2GeoV0 = kfV0.GetChi2() / kfV0.GetNDF(); - float chi2GeoCasc = kfOmega.GetChi2() / kfOmega.GetNDF(); - float chi2GeoOmegaKa = kfOmegaKa.GetChi2() / kfOmegaKa.GetNDF(); - - // Get Chi2Topo/NDF - float chi2NdfTopoV0ToCasc = kfV0ToOmega.GetChi2() / kfV0ToOmega.GetNDF(); - float chi2NdfTopoKaToCasc = kfKaToOmega.GetChi2() / kfKaToOmega.GetNDF(); - float chi2NdfTopoKaFromOmegaKaToOmegaKa = kfKaFromCharmToOmegaKa.GetChi2() / kfKaFromCharmToOmegaKa.GetNDF(); - float chi2NdfTopoCascToOmegaKa = kfOmegaToOmegaKa.GetChi2() / kfOmegaToOmegaKa.GetNDF(); - float chi2NdfTopoV0ToPv = kfV0ToPv.GetChi2() / kfV0ToPv.GetNDF(); - float chi2NdfTopoCascToPv = kfOmegaToPv.GetChi2() / kfOmegaToPv.GetNDF(); - float chi2NdfTopoOmegaKaToPv = kfCharmToPv.GetChi2() / kfCharmToPv.GetNDF(); - float chi2NdfTopoKaFromOmegaKaToPv = kfKaFromCharmToPv.GetChi2() / kfKaFromCharmToPv.GetNDF(); - - // Get MassChi2/NDF - auto v0Chi2OverNdfm = kfV0MassConstrained.GetChi2() / kfV0MassConstrained.GetNDF(); - auto cascChi2OverNdfm = kfOmegaMassConstrained.GetChi2() / kfOmegaMassConstrained.GetNDF(); - - // KF ldl - float ldlV0 = ldlFromKF(kfV0, kfPv); - float ldlCasc = ldlFromKF(kfOmega, kfPv); - float ldlOmegaKa = ldlFromKF(kfOmegaKa, kfPv); - - // KF decay length - float decayLxyLam, errDecayLxyLam; - kfV0ToOmega.GetDecayLengthXY(decayLxyLam, errDecayLxyLam); - float decayLxyCasc, errDecayLxyCasc; - kfOmegaToOmegaKa.GetDecayLengthXY(decayLxyCasc, errDecayLxyCasc); - float decayLxyOmegaKa, errDecayLxyOmegaKa; - kfCharmToPv.GetDecayLengthXY(decayLxyOmegaKa, errDecayLxyOmegaKa); - - // KF pT - float ptOmegaKa = kfOmegaKa.GetPt(); - float ptKaFromCharm = kfKaFromCharm.GetPt(); - float ptOmega = kfOmega.GetPt(); - - // KF cosThetaStar - float cosThetaStarKaFromOmegac = cosThetaStarFromKF(0, 4332, 321, 3334, kfKaFromCharmToOmegaKa, kfOmegaToOmegaKa); - float cosThetaStarKaFromXic = cosThetaStarFromKF(0, 4132, 321, 3334, kfKaFromCharmToOmegaKa, kfOmegaToOmegaKa); + //------------------------------Calculate physical quantities and fill candidate table------------------------------ - // KF ct - float ctV0 = kfV0ToOmega.GetLifeTime(); - float ctCasc = kfOmegaToOmegaKa.GetLifeTime(); - float ctOmegaKa = kfCharmToPv.GetLifeTime(); - - hCandidateCounter->Fill(3); - - // fill full kf table - kfCandidateOmegaKaData(collision.globalIndex(), - collision.posX(), collision.posY(), collision.posZ(), // PV Coord - kfPv.GetX(), kfPv.GetY(), kfPv.GetZ(), // PV KF - vertexV0[0], vertexV0[1], vertexV0[2], // V0 Vtx from LF-table - pVecV0[0], pVecV0[1], pVecV0[2], // V0 P from LF-table - vertexCasc[0], vertexCasc[1], vertexCasc[2], // Casc Vtx from LF-table - pVecCasc[0], pVecCasc[1], pVecCasc[2], // Casc P from LF-table - kfV0.GetX(), kfV0.GetY(), kfV0.GetZ(), // V0 Vtx KF - kfV0.GetPx(), kfV0.GetPy(), kfV0.GetPz(), // V0 P KF - kfOmega.GetX(), kfOmega.GetY(), kfOmega.GetZ(), // Omega Vtx KF - kfOmega.GetPx(), kfOmega.GetPx(), kfOmega.GetPx(), // Omega Vtx KF - kfOmegaKa.GetX(), kfOmegaKa.GetY(), kfOmegaKa.GetZ(), // OmegaKa Vtx KF (SecondaryVertex) - kfOmegaKa.GetPx(), kfOmegaKa.GetPx(), kfOmegaKa.GetPx(), // OmegaKa P KF - signOmega, // Check Omega sign - kfPrFromV0.GetEta(), kfPiFromV0.GetEta(), kfKaFromOmega.GetEta(), kfKaFromCharm.GetEta(), kfV0.GetEta(), kfOmega.GetEta(), kfOmegaKa.GetEta(), kfOmegaKa.GetRapidity(), // Eta of daughters and mothers. Rapidity of OmegaKa - impactParameterKaFromCharmXY, errImpactParameterKaFromCharmXY, impactParameterOmegaXY, errImpactParameterOmegaXY, // DCAXY of KaFromCharm and Omega - kfPrToV0.GetDistanceFromParticle(kfPiToV0), kfV0ToOmega.GetDistanceFromParticle(kfKaToOmega), kfOmegaToOmegaKa.GetDistanceFromParticle(kfKaFromCharmToOmegaKa), // DCA of daughters - cosPaV0ToPv, cosPaCascToPv, cosPaOmegaKaToPv, cosPaXYV0ToPv, cosPaXYCascToPv, cosPaXYOmegaKaToPv, cosPaV0ToCasc, cosPaCascToOmegaKa, cosPaXYV0ToCasc, cosPaXYCascToOmegaKa, // CosPA of PV and mothers - chi2GeoV0, chi2GeoCasc, chi2GeoOmegaKa, // Chi2Geo/NDF - v0Chi2OverNdfm, cascChi2OverNdfm, // Chi2Mass/NDF - chi2NdfTopoV0ToCasc, chi2NdfTopoKaToCasc, chi2NdfTopoKaFromOmegaKaToOmegaKa, chi2NdfTopoCascToOmegaKa, chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoKaFromOmegaKaToPv, chi2NdfTopoOmegaKaToPv, // Chi2Topo/NDF - ldlV0, ldlCasc, ldlOmegaKa, // ldl - decayLxyLam, decayLxyCasc, decayLxyOmegaKa, // DecaylengthXY - massLam, sigLam, massCasc, sigCasc, massCascrej, sigCascrej, massOmegaKa, sigOmegaKa, // massKF and masserror - ptOmegaKa, ptKaFromCharm, ptOmega, // pT - cosThetaStarKaFromOmegac, cosThetaStarKaFromXic, ctV0, ctCasc, ctOmegaKa, // cosThetaStar & ct - cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), casc.cascadeId(), casc.bachelorId(), trackKaFromCharm.globalIndex()); - } - } + //------------------------------Fill the table------------------------------ + if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi) { + cursors.rowCandToXiPiKf(collision.globalIndex(), // Global index of collision + pvCoord[0], pvCoord[1], pvCoord[2], // coordination of PV + kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ(), // Decay position of kfCasc + casc.xlambda(), casc.ylambda(), casc.zlambda(), // Decay position of KfV0. This values can be also taken from LF table + trackBach.sign(), // Sign of bachelor + covMatrixCharmBaryon[0], covMatrixCharmBaryon[1], covMatrixCharmBaryon[2], covMatrixCharmBaryon[3], covMatrixCharmBaryon[4], covMatrixCharmBaryon[5], + kfCharmBaryon.GetPx(), kfCharmBaryon.GetPy(), kfCharmBaryon.GetPz(), // x, y, z momentum of charm baryon + kfCascConstrainedToCharmBaryon.GetPx(), kfCascConstrainedToCharmBaryon.GetPy(), kfCascConstrainedToCharmBaryon.GetPz(), + kfCharmBachelorConstrainedToCharmBaryon.GetPx(), kfCharmBachelorConstrainedToCharmBaryon.GetPy(), kfCharmBachelorConstrainedToCharmBaryon.GetPz(), + casc.kfpxv0(), casc.kfpyv0(), casc.kfpzv0(), // -> This can be also taken from LF table + kfBachConstrainedToCasc.GetPx(), kfBachConstrainedToCasc.GetPy(), kfBachConstrainedToCasc.GetPz(), + casc.pxpos(), casc.pypos(), casc.pzpos(), + casc.pxneg(), casc.pyneg(), casc.pzneg(), + // impactParameterCasc.getY(), impactParameterCharmBachelor.getY(), + // impactParameterCasc.getZ(), impactParameterCharmBachelor.getZ(), + // std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), + cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), + casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + casc.mLambda(), kfCasc.GetMass(), kfCharmBaryon.GetMass(), + cosPaV0ToPv, cosPaCascToPv, + // cosPaCharmBaryonToPv, cosPaXYV0ToPv, cosPaXYCharmBaryonToPv, cosPaXYCascToPv, + ctCasc, ctV0, ctCharmBaryon, + casc.positiveeta(), casc.negativeeta(), casc.bacheloreta(), kfCharmBachelorConstrainedToCharmBaryon.GetEta(), + kfCharmBaryon.GetEta(), kfCasc.GetEta(), kfV0.GetEta(), + dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, + // dcazV0DauPos, dcazV0DauNeg, dcazBach, + kfDcaCascDaughters, kfDcaV0Daughters, kfDcaCharmBaryonDaughters, + // decayLCharmBaryon, decayLCasc, decayLV0, errDecayLCharmBaryon, errDecayLXYCharmBaryon, + kfDcaXYCharmBachelorToPv, kfDcaXYCascToPv, + casc.kfV0Chi2(), kfCasc.GetChi2(), kfCharmBaryon.GetChi2(), + /*FIXME chi2 of mass constrained, V0 and casc*/ kfV0.GetChi2(), kfCasc.GetChi2(), + ldlV0, ldlCasc, // ldlCharmBaryon, + chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoCharmBachelorToPv, chi2NdfTopoCharmBaryonToPv, + chi2NdfTopoV0ToCasc, chi2NdfTopoCascToCharmBaryon, + decayLXYV0, decayLXYCasc, decayLXYCharmBaryon, + cosPaV0ToCasc, cosPaCascToCharmBaryon, // cosPaXYV0ToCasc, cosPaXYCascToCharmBaryon, + yCharmBaryon, // ptCharmBachelor, ptCharmBaryon, + cosThetaStarCharmBachelorXic0, + kfV0.GetNDF(), kfCasc.GetNDF(), kfCharmBaryon.GetNDF(), /*FIXME chi2, NDF of mass constrained V0/casc*/ kfV0.GetNDF(), kfCasc.GetNDF(), + kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.GetChi2() / kfCasc.GetNDF(), kfCharmBaryon.GetChi2() / kfCharmBaryon.GetNDF(), /*FIXME chi2, NDF of mass constrained V0/casc*/ kfV0.GetChi2() / kfV0.GetNDF(), kfV0.GetChi2() / kfV0.GetNDF()); - /// @brief process function w/o centrality selections - void processNoCentToXiPi(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + } else if constexpr (decayChannel == hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { + cursors.rowCandToOmegaPi(collision.globalIndex(), + pvCoord[0], pvCoord[1], pvCoord[2], + /*vertexCharmBaryonFromFitter. For KF, this is 0*/ 0.f, 0.f, 0.f, + kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ(), + /*V0 decay position. Taken from LF*/ casc.xlambda(), casc.ylambda(), casc.zlambda(), + trackCharmBachelor.sign(), + covMatrixCharmBaryon[0], covMatrixCharmBaryon[1], covMatrixCharmBaryon[2], covMatrixCharmBaryon[3], covMatrixCharmBaryon[4], covMatrixCharmBaryon[5], + kfCharmBaryon.GetPx(), kfCharmBaryon.GetPy(), kfCharmBaryon.GetPz(), + kfCascConstrainedToCharmBaryon.GetPx(), kfCascConstrainedToCharmBaryon.GetPy(), kfCascConstrainedToCharmBaryon.GetPz(), + kfCharmBachelorConstrainedToCharmBaryon.GetPx(), kfCharmBachelorConstrainedToCharmBaryon.GetPy(), kfCharmBachelorConstrainedToCharmBaryon.GetPz(), + /*V0 momentum. Taken from LF*/ casc.kfpxv0(), casc.kfpyv0(), casc.kfpzv0(), + kfBachConstrainedToCasc.GetPx(), kfBachConstrainedToCasc.GetPy(), kfBachConstrainedToCasc.GetPz(), + /*V0 pos daughter momentum. Taken from LF*/ casc.pxpos(), casc.pypos(), casc.pzpos(), + /*V0 neg daughter momentum. Taken from LF*/ casc.pxneg(), casc.pyneg(), casc.pzneg(), + impactParameterCasc.getY(), impactParameterCharmBachelor.getY(), + impactParameterCasc.getZ(), impactParameterCharmBachelor.getZ(), + std::sqrt(impactParameterCasc.getSigmaY2()), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), + cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), + casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + /*V0 mass. Taken from LF*/ casc.mLambda(), kfMassCasc, kfMassCharmBaryon, + cosPaV0ToPv, cosPaCharmBaryonToPv, cosPaCascToPv, cosPaXYV0ToPv, cosPaXYCharmBaryonToPv, cosPaXYCascToPv, + ctCharmBaryon, ctCasc, ctV0, + /*V0 pos daughter eta. Taken from LF*/ casc.positiveeta(), /*V0 pos daughter eta. Taken from LF*/ casc.negativeeta(), /*Bachelor eta. Taken from LF*/ casc.bacheloreta(), kfCharmBachelorConstrainedToCharmBaryon.GetEta(), + kfCharmBaryon.GetEta(), kfCasc.GetEta(), kfV0.GetEta(), + dcaxyV0DauPos, dcaxyV0DauNeg, dcaxyBach, + dcazV0DauPos, dcazV0DauNeg, dcazBach, + kfDcaCascDaughters, /*DCA between V0 daughters. Taken From LF*/ casc.dcaV0daughters(), kfDcaCharmBaryonDaughters, + decayLCharmBaryon, decayLCasc, decayLV0, errDecayLCharmBaryon, errDecayLXYCharmBaryon, cand.hfflag()); + + cursors.rowCandToOmegaPiKf(kfDcaXYCharmBachelorToPv, kfDcaXYCascToPv, + /*V0 chi2. Taken from LF*/ casc.kfV0Chi2(), kfCasc.GetChi2(), kfCharmBaryon.GetChi2(), /*Mass constraint only done when requested*/ casc.kfV0Chi2(), /*Mass constraint only done when requested*/ kfCasc.GetChi2(), + ldlV0, ldlCasc, ldlCharmBaryon, + chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoCharmBachelorToPv, chi2NdfTopoCharmBaryonToPv, deviationCharmBachelorToPv, + chi2NdfTopoV0ToCasc, chi2NdfTopoCascToCharmBaryon, + decayLXYV0, decayLXYCasc, decayLXYCharmBaryon, + cosPaV0ToCasc, cosPaCascToCharmBaryon, cosPaXYV0ToCasc, cosPaXYCascToCharmBaryon, + kfCharmBaryon.GetRapidity(), ptCharmBachelor, ptCharmBaryon, + cosThetaStarCharmBachelorOmegac0, + kfV0.GetNDF(), kfCasc.GetNDF(), kfCharmBaryon.GetNDF(), /*Mass constraint only done when requested*/ kfV0.GetNDF(), /*Mass constraint only done when requested*/ kfCasc.GetNDF(), + kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.Chi2() / kfCasc.GetNDF(), kfCharmBaryon.GetChi2() / kfCharmBaryon.GetNDF(), + /*Mass constraint only done when requested*/ kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.Chi2() / kfCasc.GetNDF(), + /*casc-rej not calculated. For now, fill in mass of KFCasc. Need to fix this*/ kfCasc.GetMass()); + + } else { + cursors.rowCandToOmegaKaKf(collision.globalIndex(), + collision.posX(), collision.posY(), collision.posZ(), + kfPv.GetX(), kfPv.GetY(), kfPv.GetZ(), + vertexV0[0], vertexV0[1], vertexV0[2], + pVecV0[0], pVecV0[1], pVecV0[2], + vertexCasc[0], vertexCasc[1], vertexCasc[2], + pVecCasc[0], pVecCasc[1], pVecCasc[2], + casc.xlambda(), casc.ylambda(), casc.zlambda(), + casc.kfpxv0(), casc.kfpyv0(), casc.kfpzv0(), + kfCasc.GetX(), kfCasc.GetY(), kfCasc.GetZ(), + kfCasc.GetPx(), kfCasc.GetPy(), kfCasc.GetPz(), + kfCharmBaryon.GetX(), kfCharmBaryon.GetY(), kfCharmBaryon.GetZ(), + kfCharmBaryon.GetPx(), kfCharmBaryon.GetPy(), kfCharmBaryon.GetPz(), + casc.sign(), + casc.positiveeta(), casc.negativeeta(), casc.bacheloreta(), kfCharmBachelor.GetEta(), kfV0.GetEta(), kfCasc.GetEta(), kfCharmBaryon.GetEta(), kfCharmBaryon.GetRapidity(), + impactParameterCharmBachelor.getY(), std::sqrt(impactParameterCharmBachelor.getSigmaY2()), impactParameterCasc.getY(), std::sqrt(impactParameterCasc.getSigmaY2()), + kfDcaV0Daughters, kfDcaCascDaughters, kfDcaCharmBaryonDaughters, + cosPaV0ToPv, cosPaCascToPv, cosPaCharmBaryonToPv, cosPaXYV0ToPv, cosPaXYCascToPv, cosPaXYCharmBaryonToPv, cosPaV0ToCasc, cosPaCascToCharmBaryon, cosPaXYV0ToCasc, cosPaXYCascToCharmBaryon, + kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.GetChi2() / kfCasc.GetNDF(), kfCharmBaryon.GetChi2() / kfCharmBaryon.GetNDF(), + /*FIXME mass constraint is optional*/ kfV0.GetChi2() / kfV0.GetNDF(), kfCasc.GetChi2() / kfCasc.GetNDF(), + chi2NdfTopoV0ToCasc, chi2NdfTopoBachToCasc, chi2NdfTopoCharmBachelorToCharmBaryon, chi2NdfTopoCascToCharmBaryon, // Topological constraints to mother + chi2NdfTopoV0ToPv, chi2NdfTopoCascToPv, chi2NdfTopoCharmBachelorToPv, chi2NdfTopoCharmBaryonToPv, // Topological constraints to PV + ldlV0, ldlCasc, ldlCharmBaryon, + decayLXYV0, decayLXYCasc, decayLXYCharmBaryon, + kfMassV0, kfSigMassV0, kfMassCasc, kfSigMassCasc, /*FIXME no -rej has been made*/ kfMassCasc, /*FIXME no -rej has been made*/ kfSigMassCasc, kfMassCharmBaryon, kfSigMassCharmBaryon, + ptCharmBaryon, ptCharmBachelor, ptCasc, + cosThetaStarCharmBachelorOmegac0, cosThetaStarCharmBachelorXic0, ctV0, ctCasc, ctCharmBaryon, + cascAodElement.v0Id(), casc.posTrackId(), casc.negTrackId(), casc.cascadeId(), casc.bachelorId(), trackCharmBachelor.globalIndex()); + } + } // end candidate loop + } // end of runCreator + + ///////////////////////////////////////////////////// + /// /// + /// Process functions with DCAFitter /// + /// /// + ///////////////////////////////////////////////////// + + /*~~~~~~~~~~~~~~*/ + /*~~~To Xi Pi~~~*/ + /*~~~~~~~~~~~~~~*/ + void processToXiPiWithDCAFitterNoCent(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentToXiPi, "Run candidate creator w/o centrality selections for xi pi decay channel", true); - - void processNoCentToXiPiTraCasc(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyTraCascTable const& traCascades, - TraCascadesLinked const& traCascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterNoCent, "Charm candidte reconstruction with Xi Pi via DcaFitter method, no centrality", true); + + void processToXiPiWithDCAFitterNoCentWithTrackedCasc(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + TrackedCascFull const& trackedCascFull, + TrackedCascLinked const& trackedCascLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, traCascades, traCascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithDCAFitter(collisions, candidates, trackedCascFull, trackedCascLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentToXiPiTraCasc, "Run candidate creator w/o centrality selections for xi pi decay channel with tracked cascades", false); - - void processNoCentToOmegaPi(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterNoCentWithTrackedCasc, "Charm candidte reconstruction with Xi Pi via DcaFitter method with tracked cascade, no centrality", false); + + void processToXiPiWithDCAFitterCentFT0C(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentToOmegaPi, "Run candidate creator w/o centrality selections for omega pi decay channel", false); - - void processNoCentOmegacToOmegaPiWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterCentFT0C, "Charm candidate reconstruction with Xi Pi via DcaFitter method, centrality selection on FT0C", false); + + void processToXiPiWithDCAFitterCentFT0M(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentOmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); - - void processNoCentOmegac0Xic0ToOmegaKaCreatorWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithDCAFitterCentFT0M, "Charm candidate reconstruction with Xi Pi via DcaFitter method, centrality selection on FT0M", false); + + /*~~~~~~~~~~~~~~~~~*/ + /*~~~To Omega Pi~~~*/ + /*~~~~~~~~~~~~~~~~~*/ + void processToOmegaPiWithDCAFitterNoCent(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runOmegac0Xic0ToOmegaKaCreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaK, hFitterStatusToOmegaK, hCandidateCounterToOmegaK, hCascadesCounterToOmegaK); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentOmegac0Xic0ToOmegaKaCreatorWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega ka decay channel using KFParticle", false); - - void processNoCentXicToXiPiWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithDCAFitterNoCent, "Charm candidte reconstruction with Omega Pi via DcaFitter method, no centrality", false); + + void processToOmegaPiWithDCAFitterCentFT0C(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentXicToXiPiWithKFParticle, "Run candidate creator w/o centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); - - void processNoCentToOmegaK(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithDCAFitterCentFT0C, "Charm candidate reconstruction with Omega Pi via DcaFitter method, centrality selection on FT0C", false); + + void processToOmegaPiWithDCAFitterCentFT0M(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaK, hFitterStatusToOmegaK, hCandidateCounterToOmegaK, hCascadesCounterToOmegaK); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hInvMassCharmBaryonToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentToOmegaK, "Run candidate creator w/o centrality selections for omega K decay channel", false); - - /// @brief process function w/ FT0C centrality selections - void processCentFT0CToXiPi(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithDCAFitterCentFT0M, "Charm candidate reconstruction with Omega Pi via DcaFitter method, centrality selection on FT0M", false); + + /*~~~~~~~~~~~~~~~~~*/ + /*~~~To Omega Ka~~~*/ + /*~~~~~~~~~~~~~~~~~*/ + void processToOmegaKaWithDCAFitterNoCent(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0CToXiPi, "Run candidate creator w/ centrality selection on FT0C for xi pi channel", false); - - void processCentFT0CToOmegaPi(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithDCAFitterNoCent, "Charm candidte reconstruction with Omega Ka via DcaFitter method, no centrality", false); + + void processToOmegaKaWithDCAFitterCentFT0C(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0CToOmegaPi, "Run candidate creator w/ centrality selection on FT0C for omega pi channel", false); - - void processCentFT0COmegacToOmegaPiWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithDCAFitterCentFT0C, "Charm candidate reconstruction with Omega Ka via DcaFitter method, centrality selection on FT0C", false); + + void processToOmegaKaWithDCAFitterCentFT0M(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + CascFull const& cascFull, + CascadesLinked const& cascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runCreatorWithDCAFitter(collisions, candidates, cascFull, cascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0COmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); - - void processCentFT0COmegac0Xic0ToOmegaKaCreatorWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithDCAFitterCentFT0M, "Charm candidate reconstruction with Omega Ka via DcaFitter method, centrality selection on FT0M", false); + + ///////////////////////////////////////////////////// + /// /// + /// Process functions with KFParticle /// + /// /// + ///////////////////////////////////////////////////// + + /*~~~~~~~~~~~~~~*/ + /*~~~To Xi Pi~~~*/ + /*~~~~~~~~~~~~~~*/ + void processToXiPiWithKFParticleNoCent(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runOmegac0Xic0ToOmegaKaCreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaK, hFitterStatusToOmegaK, hCandidateCounterToOmegaK, hCascadesCounterToOmegaK); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0COmegac0Xic0ToOmegaKaCreatorWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega ka decay channel using KFParticle", false); - - void processCentFT0CXicToXiPiWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithKFParticleNoCent, "Charm Baryon decaying to Xi Pi reconstruction via KFParticle method, no centrality", false); + + void processToXiPiWithKFParticleCentFT0C(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0CXicToXiPiWithKFParticle, "Run candidate creator w FT0C centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); - - void processCentFT0CToOmegaK(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithKFParticleCentFT0C, "Charm Baryon decaying to Xi Pi reconstruction via KFParticle method, centrality on FT0C", false); + + void processToXiPiWithKFParticleCentFT0M(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaK, hFitterStatusToOmegaK, hCandidateCounterToOmegaK, hCascadesCounterToOmegaK); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToXiPi, hCandidateCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0CToOmegaK, "Run candidate creator w/ centrality selection on FT0C for omega K channel", false); - - /// @brief process function w/ FT0M centrality selections - void processCentFT0MToXiPi(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToXiPiWithKFParticleCentFT0M, "Charm Baryon decaying to Xi Pireconstruction via KFParticle method, centrality on FT0M", false); + + /*~~~~~~~~~~~~~~~~~*/ + /*~~~To Omega Pi~~~*/ + /*~~~~~~~~~~~~~~~~~*/ + void processToOmegaPiWithKFParticleNoCent(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MToXiPi, "Run candidate creator w/ centrality selection on FT0M for xi pi channel", false); - - void processCentFT0MToOmegaPi(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithKFParticleNoCent, "Charm Baryon decaying to Omega Pi reconstruction via KFParticle method, no centrality", false); + + void processToOmegaPiWithKFParticleCentFT0C(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MToOmegaPi, "Run candidate creator w/ centrality selection on FT0M for omega pi channel", false); - - void processCentFT0MOmegacToOmegaPiWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithKFParticleCentFT0C, "Charm Baryon decaying to Omega Pi reconstruction via KFParticle method, centrality on FT0C", false); + + void processToOmegaPiWithKFParticleCentFT0M(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaPi, hCandidateCounterToOmegaPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MOmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); - - void processCentFT0MOmegac0Xic0ToOmegaKaCreatorWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaPiWithKFParticleCentFT0M, "Charm Baryong decaying to Omega Pi reconstruction via KFParticle method, centrality on FT0M", false); + + /*~~~~~~~~~~~~~~~~~*/ + /*~~~To Omega Ka~~~*/ + /*~~~~~~~~~~~~~~~~~*/ + void processToOmegaKaWithKFParticleNoCent(SelectedCollisions const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runOmegac0Xic0ToOmegaKaCreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaK, hFitterStatusToOmegaK, hCandidateCounterToOmegaK, hCascadesCounterToOmegaK); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MOmegac0Xic0ToOmegaKaCreatorWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega ka decay channel using KFParticle", false); - - void processCentFT0MXicToXiPiWithKFParticle(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracksIU const& tracksIU, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithKFParticleNoCent, "Charm Baryon decaying to Omega Ka reconstruction via KFParticle method, no centrality", false); + + void processToOmegaKaWithKFParticleCentFT0C(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracksIU, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MXicToXiPiWithKFParticle, "Run candidate creator w FT0M centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); - - void processCentFT0MToOmegaK(soa::Join const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - TracksWCovDca const& tracks, - MyLFTracksWCov const& lfTracks, - MyCascTable const& cascades, - CascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithKFParticleCentFT0C, "Charm Baryon decaying to Omega Ka reconstruction via KFParticle method, centrality on FT0C", false); + + void processToOmegaKaWithKFParticleCentFT0M(soa::Join const& collisions, + aod::HfCascLf2Prongs const& candidates, + KFCascFull const& kfCascFull, + KFCascadesLinked const& kfCascadesLinked, + TracksWCovDcaExtraPidPrPiKa const& tracks, + aod::BCsWithTimestamps const& bcsWithTimestamps) { - runXic0Omegac0Creator(collisions, bcWithTimeStamps, lfTracks, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaK, hFitterStatusToOmegaK, hCandidateCounterToOmegaK, hCascadesCounterToOmegaK); + runCreatorWithKfParticle(collisions, candidates, kfCascFull, kfCascadesLinked, tracks, bcsWithTimestamps, hInvMassCharmBaryonToOmegaKa, hCandidateCounterToOmegaKa); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MToOmegaK, "Run candidate creator w/ centrality selection on FT0M for omega K channel", false); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processToOmegaKaWithKFParticleCentFT0M, "Charm Baryong decaying to Omega Ka reconstruction via KFParticle method, centrality on FT0M", false); - /////////////////////////////////////////////////////////// - /// /// - /// Process functions only for collision monitoring /// - /// /// - /////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// + /// /// + /// Process functions for Collision monitoring /// + /// /// + /////////////////////////////////////////////////////////////// - /// @brief process function to monitor collisions - no centrality - void processCollisions(soa::Join const& collisions, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/) + void processCollisionsNoCent(soa::Join const& collisions, + aod::BCsWithTimestamps const&) { - /// loop over collisions for (const auto& collision : collisions) { - /// bitmask with event. selection info + // bitmask with event selection info float centrality{-1.f}; + float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); - - } /// end loop over collisions + // monitor the satisfied event selection + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + } } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCollisions, "Collision monitoring - no centrality", true); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processCollisionsNoCent, "Collision monitoring - No Centrality", true); - /// @brief process function to monitor collisions - FT0C centrality - void processCollisionsCentFT0C(soa::Join const& collisions, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/) + void processCollisionsCentFT0C(soa::Join const& collisions, + aod::BCsWithTimestamps const&) { - /// loop over collisions for (const auto& collision : collisions) { - /// bitmask with event. selection info + // bitmask with event selection info float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - - /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - } /// end loop over collisions + // monitor the satisfied event selection + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + } } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCollisionsCentFT0C, "Collision monitoring - FT0C centrality", false); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processCollisionsCentFT0C, "Collision monitoring - Centrality selection with FT0C", false); - /// @brief process function to monitor collisions - FT0M centrality - void processCollisionsCentFT0M(soa::Join const& collisions, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/) + void processCollisionsCentFT0M(soa::Join const& collisions, + aod::BCsWithTimestamps const&) { - /// loop over collisions for (const auto& collision : collisions) { - /// bitmask with event. selection info + // bitmask with event selection info float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - - /// monitor the satisfied event selections - hfEvSel.fillHistograms(collision, rejectionMask, centrality); + float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - } /// end loop over collisions + // monitor the satisfied event selection + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + } } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCollisionsCentFT0M, "Collision monitoring - FT0M centrality", false); - -}; // end of struct - -/// Performs MC matching. -struct HfCandidateCreatorXic0Omegac0Mc { - Produces rowMCMatchRecXicToXiPi; - Produces rowMCMatchGenXicToXiPi; - Produces rowMCMatchRecOmegacToXiPi; - Produces rowMCMatchGenOmegacToXiPi; - Produces rowMCMatchRecToOmegaPi; - Produces rowMCMatchGenToOmegaPi; - Produces rowMCMatchRecToOmegaK; - Produces rowMCMatchGenToOmegaK; - - // Configuration - Configurable rejectBackground{"rejectBackground", true, "Reject particles from background events"}; - Configurable acceptTrackIntWithMaterial{"acceptTrackIntWithMaterial", false, " switch to accept candidates with final (i.e. p, K, pi) daughter tracks interacting with material"}; - - using MyTracksWMc = soa::Join; + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Qa, processCollisionsCentFT0M, "Collision monitoring - Centrality selection with FT0M", false); +}; + +struct HfCandidateCreatorXic0Omegac0QaMc { + + struct : ProducesGroup { + + Produces rowMcMatchRecXicToXiPi; + Produces rowMcMatchGenXicToXiPi; + Produces rowMcMatchRecOmegacToXiPi; + Produces rowMcMatchGenOmegacToXiPi; + Produces rowMcMatchRecToOmegaPi; + Produces rowMcMatchGenToOmegaPi; + Produces rowMcMatchRecToOmegaKa; + Produces rowMcMatchGenToOmegaKa; + + } cursors; + + struct : ConfigurableGroup { + + Configurable rejectBackground{"rejectBackground", true, "Reject particles from background events"}; // -> Used for only Xic0 + Configurable acceptTrackInteractionWithMaterial{"acceptTrackInteractionWithMaterial", false, "Accept candidates with final daughters interacting with materials"}; + Configurable fillMcHistograms{"fillMcHistograms", true, "Fill validation plots"}; + Configurable fillResidualTable{"fillResidualTable", true, "Fill table contaning residuals and pulls of PV and SV"}; + // Configurable matchDecayedPions{"matchedDecayedPions", true, "Match also candidates with daughter pion tracks that decay with kinked toploogy"}; + + } configs; + + enum McMatchFlag : uint8_t { + None = 0, + CharmBaryonUnmatched, + CascUnmatched, + V0Unmatched, + NumberMcMatchFlag + }; + + std::array pdgOfCharmBaryon{+kXiC0, +kOmegaC0, +kOmegaC0, +kOmegaC0}; + std::array pdgOfCascade{+kXiMinus, +kXiMinus, +kOmegaMinus, +kOmegaMinus}; + std::array pdgOfCharmBachelor{+kPiPlus, +kPiPlus, +kPiPlus, +kKPlus}; + std::array pdgOfBachelor{+kPiMinus, +kPiMinus, +kKMinus, +kKMinus}; + + // Table aliases using McCollisionsNoCents = soa::Join; using McCollisionsFT0Cs = soa::Join; using McCollisionsFT0Ms = soa::Join; - using McCollisionsCentFT0Ms = soa::Join; + using McCollisionsCentFT0Ms = soa::Join; // -> Used for subscription for process functions of centrality with FT0Ms using BCsInfo = soa::Join; Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; - PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; // -> Why use unsorted?? PresliceUnsorted colPerMcCollisionFT0C = aod::mccollisionlabel::mcCollisionId; PresliceUnsorted colPerMcCollisionFT0M = aod::mccollisionlabel::mcCollisionId; - HfEventSelectionMc hfEvSelMc; // mc event selection and monitoring - - std::shared_ptr hGenCharmBaryonPtRapidityTightXicToXiPi, hGenCharmBaryonPtRapidityLooseXicToXiPi, hGenCharmBaryonPtRapidityTightOmegacToXiPi, hGenCharmBaryonPtRapidityLooseOmegacToXiPi, hGenCharmBaryonPtRapidityTightOmegacToOmegaPi, hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi, hGenCharmBaryonPtRapidityTightOmegacToOmegaK, hGenCharmBaryonPtRapidityLooseOmegacToOmegaK; - HistogramRegistry registry{"registry"}; + HfEventSelectionMc hfEvSelMc; - // inspect for which zPvPosMax cut was set for reconstructed void init(InitContext& initContext) { - std::array procCollisionsXicToXiPi{doprocessMcXicToXiPi, doprocessMcXicToXiPiFT0m, doprocessMcXicToXiPiFT0c, doprocessMcXicToXiPiKf, doprocessMcXicToXiPiKfQa}; - if (std::accumulate(procCollisionsXicToXiPi.begin(), procCollisionsXicToXiPi.end(), 0) > 1) { - LOGP(fatal, "At most one process function for XicToXiPi collision study can be enabled at a time."); - } - std::array procCollisionsOmegacToXiPi{doprocessMcOmegacToXiPi, doprocessMcOmegacToXiPiFT0m, doprocessMcOmegacToXiPiFT0c}; - if (std::accumulate(procCollisionsOmegacToXiPi.begin(), procCollisionsOmegacToXiPi.end(), 0) > 1) { - LOGP(fatal, "At most one process function for OmegacToXiPi collision study can be enabled at a time."); - } - std::array procCollisionsOmegacToOmegaPi{doprocessMcOmegacToOmegaPi, doprocessMcOmegacToOmegaPiFT0m, doprocessMcOmegacToOmegaPiFT0c}; - if (std::accumulate(procCollisionsOmegacToOmegaPi.begin(), procCollisionsOmegacToOmegaPi.end(), 0) > 1) { - LOGP(fatal, "At most one process function for OmegacToOmegaPi collision study can be enabled at a time."); - } - std::array procCollisionsOmegacToOmegaK{doprocessMcOmegacToOmegaK, doprocessMcOmegacToOmegaKFT0m, doprocessMcOmegacToOmegaKFT0c}; - if (std::accumulate(procCollisionsOmegacToOmegaK.begin(), procCollisionsOmegacToOmegaK.end(), 0) > 1) { - LOGP(fatal, "At most one process function for OmegacToOmegaK collision study can be enabled at a time."); - } - const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { - if (device.name.compare("hf-candidate-creator-xic0-omegac0") == 0) { - // init HF event selection helper + if (device.name.compare("hf-candidate-creator-xic0-omegac0-qa") == 0) { hfEvSelMc.init(device, registry); break; } } - hGenCharmBaryonPtRapidityTightXicToXiPi = registry.add("hGenCharmBaryonPtRapidityTightXicToXiPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); // keep track of generated candidates pt when |y|<0.5 - hGenCharmBaryonPtRapidityLooseXicToXiPi = registry.add("hGenCharmBaryonPtRapidityLooseXicToXiPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); // keep track of generated candidates pt when |y|<0.8 - - hGenCharmBaryonPtRapidityTightOmegacToXiPi = registry.add("hGenCharmBaryonPtRapidityTightOmegacToXiPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - hGenCharmBaryonPtRapidityLooseOmegacToXiPi = registry.add("hGenCharmBaryonPtRapidityLooseOmegacToXiPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - - hGenCharmBaryonPtRapidityTightOmegacToOmegaPi = registry.add("hGenCharmBaryonPtRapidityTightOmegacToOmegaPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi = registry.add("hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - - hGenCharmBaryonPtRapidityTightOmegacToOmegaK = registry.add("hGenCharmBaryonPtRapidityTightOmegacToOmegaK", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - hGenCharmBaryonPtRapidityLooseOmegacToOmegaK = registry.add("hGenCharmBaryonPtRapidityLooseOmegacToOmegaK", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); - - // QA - if (doprocessMcXicToXiPiKfQa) { - AxisSpec axisPt{20, 0., 20.}; - AxisSpec axisDelta{1000, -0.5, 0.5}; - AxisSpec axisPull{2000, -10., 10.}; - AxisSpec axisPtRes{400, -0.2, 0.2}; - // mass over pt - registry.add("hV0MassPullVsPt", "m_{PULL}(V0) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXiMassPullVsPt", "m_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXic0MassPullVsPt", "m_{PULL}(#Xic0) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - // delta - registry.add("hV0DauPosXDelta", "x^{p} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hV0DauPosYDelta", "y^{p} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hV0DauPosZDelta", "z^{p} - z^{MC}", kTH1D, {axisDelta}); - registry.add("hV0DauNegXDelta", "x^{#pi^{-}} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hV0DauNegYDelta", "y^{#pi^{-}} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hV0DauNegZDelta", "z^{#pi^{-}} - z^{MC}", kTH1D, {axisDelta}); - registry.add("hV0XDelta", "x^{#Lambda} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hV0YDelta", "y^{#Lambda} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hV0ZDelta", "z^{#Lambda} - z^{MC}", kTH1D, {axisDelta}); - - registry.add("hXiBachelorXDelta", "x^{#pi^{-} from #Xi^{-}} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hXiBachelorYDelta", "y^{#pi^{-} from #Xi^{-}} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hXiBachelorZDelta", "z^{#pi^{-} from #Xi^{-}} - z^{MC}", kTH1D, {axisDelta}); - - registry.add("hXiXDelta", "x^{#Xi^{-}} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hXiYDelta", "y^{#Xi^{-}} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hXiZDelta", "z^{#Xi^{-}} - z^{MC}", kTH1D, {axisDelta}); - - registry.add("hXic0BachelorXDelta", "x^{#pi^{+} from #Xi_{c}^{0}} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hXic0BachelorYDelta", "y^{#pi^{+} from #Xi_{c}^{0}} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hXic0BachelorZDelta", "z^{#pi^{+} from #Xi_{c}^{0}} - z^{MC}", kTH1D, {axisDelta}); - - registry.add("hXic0XDelta", "x^{#Xi_(c)^(0)} - x^{MC}", kTH1D, {axisDelta}); - registry.add("hXic0YDelta", "y^{#Xi_(c)^(0)} - y^{MC}", kTH1D, {axisDelta}); - registry.add("hXic0ZDelta", "z^{#Xi_(c)^(0)} - z^{MC}", kTH1D, {axisDelta}); - // delta over pt - registry.add("hV0DauPosXDeltaVsPt", "#Delta_{x}(p) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0DauPosYDeltaVsPt", "#Delta_{y}(p) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0DauPosZDeltaVsPt", "#Delta_{z}(p) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0DauNegXDeltaVsPt", "#Delta_{x}(#pi) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0DauNegYDeltaVsPt", "#Delta_{y}(#pi) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0DauNegZDeltaVsPt", "#Delta_{z}(#pi) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0XDeltaVsPt", "#Delta_{x}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0YDeltaVsPt", "#Delta_{y}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hV0ZDeltaVsPt", "#Delta_{z}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - - registry.add("hXiBachelorXDeltaVsPt", "#Delta_{x}(#pi^{-} from #Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXiBachelorYDeltaVsPt", "#Delta_{y}(#pi^{-} from #Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXiBachelorZDeltaVsPt", "#Delta_{z}(#pi^{-} from #Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - - registry.add("hXiXDeltaVsPt", "#Delta_{x}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXiYDeltaVsPt", "#Delta_{y}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXiZDeltaVsPt", "#Delta_{z}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - - registry.add("hXic0BachelorXDeltaVsPt", "#Delta_{x}(#pi^{+} from #Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXic0BachelorYDeltaVsPt", "#Delta_{y}(#pi^{+} from #Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXic0BachelorZDeltaVsPt", "#Delta_{z}(#pi^{+} from #Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - - registry.add("hXic0XDeltaVsPt", "#Delta_{x}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXic0YDeltaVsPt", "#Delta_{y}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - registry.add("hXic0ZDeltaVsPt", "#Delta_{z}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisDelta}); - - // pull - registry.add("hV0DauPosXPull", "x^{PULL}", kTH1D, {axisPull}); - registry.add("hV0DauPosYPull", "y^{PULL}", kTH1D, {axisPull}); - registry.add("hV0DauPosZPull", "z^{PULL}", kTH1D, {axisPull}); - registry.add("hV0DauNegXPull", "x^{PULL}", kTH1D, {axisPull}); - registry.add("hV0DauNegYPull", "y^{PULL}", kTH1D, {axisPull}); - registry.add("hV0DauNegZPull", "z^{PULL}", kTH1D, {axisPull}); - registry.add("hV0XPull", "x^{PULL}(#Lambda)", kTH1D, {axisPull}); - registry.add("hV0YPull", "y^{PULL}(#Lambda)", kTH1D, {axisPull}); - registry.add("hV0ZPull", "z^{PULL}(#Lambda)", kTH1D, {axisPull}); - - registry.add("hXiBachelorXPull", "x^{PULL}", kTH1D, {axisPull}); - registry.add("hXiBachelorYPull", "y^{PULL}", kTH1D, {axisPull}); - registry.add("hXiBachelorZPull", "z^{PULL}", kTH1D, {axisPull}); - - registry.add("hXiXPull", "x^{PULL}(#Xi^{-})", kTH1D, {axisPull}); - registry.add("hXiYPull", "y^{PULL}(#Xi^{-})", kTH1D, {axisPull}); - registry.add("hXiZPull", "z^{PULL}(#Xi^{-})", kTH1D, {axisPull}); - - registry.add("hXic0BachelorXPull", "x^{PULL}", kTH1D, {axisPull}); - registry.add("hXic0BachelorYPull", "y^{PULL}", kTH1D, {axisPull}); - registry.add("hXic0BachelorZPull", "z^{PULL}", kTH1D, {axisPull}); - - registry.add("hXic0XPull", "x^{PULL}(#Xi_{c}^{0})", kTH1D, {axisPull}); - registry.add("hXic0YPull", "y^{PULL}(#Xi_{c}^{0})", kTH1D, {axisPull}); - registry.add("hXic0ZPull", "z^{PULL}(#Xi_{c}^{0})", kTH1D, {axisPull}); - // pull over pt - registry.add("hV0DauPosXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0DauPosYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0DauPosZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0DauNegXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0DauNegYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0DauNegZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0XPullVsPt", "x_{PULL}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0YPullVsPt", "y_{PULL}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hV0ZPullVsPt", "z_{PULL}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - - registry.add("hXiBachelorXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXiBachelorYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXiBachelorZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - - registry.add("hXiXPullVsPt", "x_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXiYPullVsPt", "y_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXiZPullVsPt", "z_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - - registry.add("hXic0BachelorXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXic0BachelorYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXic0BachelorZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - - registry.add("hXic0XPullVsPt", "x_{PULL}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXic0YPullVsPt", "y_{PULL}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - registry.add("hXic0ZPullVsPt", "z_{PULL}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); - - // Defaut delta - registry.add("hLambdaXDelta", "x^{#Lambda} - x^{MC}(Default)", kTH1D, {axisDelta}); - registry.add("hLambdaYDelta", "y^{#Lambda} - y^{MC}(Default)", kTH1D, {axisDelta}); - registry.add("hLambdaZDelta", "z^{#Lambda} - z^{MC}(Default)", kTH1D, {axisDelta}); - - registry.add("hCascXDelta", "x^{#Xi^{-}} - x^{MC}(Default)", kTH1D, {axisDelta}); - registry.add("hCascYDelta", "y^{#Xi^{-}} - y^{MC}(Default)", kTH1D, {axisDelta}); - registry.add("hCascZDelta", "z^{#Xi^{-}} - z^{MC}(Default)", kTH1D, {axisDelta}); - - // Pt Resolution - registry.add("hV0DauPosPtRes", "Pt Resolution (p)", kTH1D, {axisPtRes}); - registry.add("hV0DauNegPtRes", "Pt Resolution (#pi^{-} from #Lambda)", kTH1D, {axisPtRes}); - registry.add("hV0PtRes", "Pt Resolution (V0)", kTH1D, {axisPtRes}); - registry.add("hXiBachelorPtRes", "Pt Resolution (#pi^{-} from #Xi^{-})", kTH1D, {axisPtRes}); - registry.add("hXiPtRes", "Pt Resolution (#Xi^{-})", kTH1D, {axisPtRes}); - registry.add("hXic0BachelorPtRes", "Pt Resolution (#pi^{+} from #Xi_{c}^{0})", kTH1D, {axisPtRes}); - registry.add("hXic0PtRes", "Pt Resolution (#Xi_{c}^{0})", kTH1D, {axisPtRes}); + // Add histograms for QA + if (configs.fillMcHistograms) { + registry.add("hDebugStatusRec", "hDebugStatusRec", {HistType::kTH1D, {{NumberMcMatchFlag, 0, NumberMcMatchFlag}}}); + registry.add("hDebugStatusGen", "hDebugStatusGen", {HistType::kTH1D, {{NumberMcMatchFlag, 0, NumberMcMatchFlag}}}); + TString labels[McMatchFlag::NumberMcMatchFlag]; + labels[McMatchFlag::None] = "None"; + labels[McMatchFlag::CharmBaryonUnmatched] = "CharmBaryonUnmatched"; + labels[McMatchFlag::CascUnmatched] = "CascUnmatched"; + labels[McMatchFlag::V0Unmatched] = "V0Unmatched"; + for (int iBin = 0; iBin < McMatchFlag::NumberMcMatchFlag; iBin++) { + registry.get(HIST("hDebugStatusRec"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin]); + registry.get(HIST("hDebugStatusGen"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin]); + } + } + } + + // Helper function to fill in table for MC Rec + ///@brief decay Channel is the chosen reconstruction channel + ///@brief flag + ///@brief debug + ///@brief origin + ///@brief collisionMatched + ///@brief pt + ///@brief pdgcode + template + void fillRecoMcTableByDecayChannel(int8_t flag, int8_t debug, int8_t origin, bool collisionMatched, float pt, int pdgCode) + { + if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { + cursors.rowMcMatchRecXicToXiPi(flag, debug, origin, collisionMatched, pt, pdgCode); + } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { + cursors.rowMcMatchRecOmegacToXiPi(flag, debug, origin, collisionMatched, pt, pdgCode); + } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { + cursors.rowMcMatchRecToOmegaPi(flag, debug, origin, collisionMatched, pt, pdgCode); + } else { + cursors.rowMcMatchRecToOmegaKa(flag, debug, origin, collisionMatched, pt, pdgCode); + } + } + + // Helper function to fill in table for MC Gen + ///@brief decay Channel is the chosen reconstruction channel + ///@brief flag + ///@brief debug + ///@brief origin + ///@brief collisionMatched + ///@brief pt + ///@brief pdgcode + template + void fillGenMcTableByDecayChannel(int8_t flag, int8_t debugGenCharmBaryon, int8_t debugGenCascade, int8_t debugGenLambda, float ptCharmBaryon, float yCharmBaryon, int8_t origin, int idxMother) + { + if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { + cursors.rowMcMatchGenXicToXiPi(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); + } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { + cursors.rowMcMatchGenOmegacToXiPi(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); + } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { + cursors.rowMcMatchGenToOmegaPi(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); + } else { + cursors.rowMcMatchGenToOmegaKa(flag, debugGenCharmBaryon, debugGenCascade, debugGenLambda, ptCharmBaryon, yCharmBaryon, origin, idxMother); } } - template - void runXic0Omegac0Mc(TMyRecoCand const& candidates, - MyTracksWMc const&, + template + void runXic0Omegac0Mc(TRecoCand const& candidates, + TracksWMc const& tracks, aod::McParticles const& mcParticles, Colls const& collsWithMcLabels, McCollisions const& mcCollisions, BCsInfo const&) { - float ptCharmBaryonGen = -999.; - float rapidityCharmBaryonGen = -999.; - int indexRec = -1; - int indexRecCharmBaryon = -1; - int8_t sign = -9; - int8_t signCasc = -9; - int8_t signV0 = -9; - int8_t flag = 0; - int8_t origin = 0; // to be used for prompt/non prompt - McMatchFlag debug{McMatchFlag::None}; - int8_t debugGenCharmBar = 0; - int8_t debugGenCasc = 0; - int8_t debugGenLambda = 0; - int8_t nPiToMuV0{0}, nPiToMuCasc{0}, nPiToMuOmegac0{0}; - int8_t nKaToPiCasc{0}, nKaToPiOmegac0{0}; + int indexRec{-1}; + int indexRecCharmBaryon{-1}; + int8_t sign{-9}; + int8_t signCasc{-9}; + int8_t signV0{-9}; + int8_t flag{0}; + int8_t origin{0}; + int8_t debug{0}; + int8_t debugGenCharmBaryon{0}; + int8_t debugGenCasc{0}; + int8_t debugGenV0{0}; bool collisionMatched = false; + float ptCharmBaryonGen = -999.; + float yCharmBaryonGen = -999.; + + //////////////////////////////////// + // Match reconstructed candidates // + //////////////////////////////////// - // Match reconstructed candidates. for (const auto& candidate : candidates) { + flag = 0; origin = RecoDecay::OriginType::None; debug = McMatchFlag::None; collisionMatched = false; std::vector idxBhadMothers{}; - auto arrayDaughters = std::array{candidate.template bachelorFromCharmBaryon_as(), // bachelor <- charm baryon - candidate.template bachelor_as(), // bachelor <- cascade - candidate.template posTrack_as(), // p <- lambda - candidate.template negTrack_as()}; // pi <- lambda - auto arrayDaughtersCasc = std::array{candidate.template bachelor_as(), - candidate.template posTrack_as(), - candidate.template negTrack_as()}; - auto arrayDaughtersV0 = std::array{candidate.template posTrack_as(), - candidate.template negTrack_as()}; - - // Check whether the particle is from background events. If so, reject it. - if (rejectBackground) { + auto arrayDaughters = std::array{candidate.template bachelorFromCharmBaryon_as(), + candidate.template bachelor_as(), + candidate.template posTrack_as(), + candidate.template negTrack_as()}; + auto arrayDaughtersCasc = std::array{candidate.template bachelor_as(), + candidate.template posTrack_as(), + candidate.template negTrack_as()}; + auto arrayDaughtersV0 = std::array{candidate.template posTrack_as(), + candidate.template negTrack_as()}; + + // Reject particles from background events + if (configs.rejectBackground) { bool fromBkg{false}; - for (const auto& daughter : arrayDaughters) { + for (auto const& daughter : arrayDaughters) { if (daughter.has_mcParticle()) { auto mcParticle = daughter.mcParticle(); if (mcParticle.fromBackgroundEvent()) { @@ -2520,837 +1553,326 @@ struct HfCandidateCreatorXic0Omegac0Mc { } } if (fromBkg) { - rowMCMatchRecXicToXiPi(flag, debug, origin, collisionMatched, -1.f, 0); - rowMCMatchRecOmegacToXiPi(flag, debug, origin, collisionMatched, -1.f, 0); - rowMCMatchRecToOmegaPi(flag, debug, origin, collisionMatched, -1.f, 0); - rowMCMatchRecToOmegaK(flag, debug, origin, collisionMatched, -1.f, 0); + // fill the tables + fillRecoMcTableByDecayChannel(flag, debug, origin, collisionMatched, -1.f, 0); continue; } } - // Xic0 -> xi pi matching - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - // Xic → pi pi pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kXiC0, std::array{+kPiPlus, +kPiMinus, +kProton, +kPiMinus}, true, &sign, 3); - indexRecCharmBaryon = indexRec; - if (indexRec == -1) { - debug = McMatchFlag::CharmbaryonUnmatched; - } - if (indexRec > -1) { - // Xi- → pi pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kXiMinus, std::array{+kPiMinus, +kProton, +kPiMinus}, true, &signCasc, 2); - if (indexRec == -1) { - debug = McMatchFlag::CascUnmatched; - } - if (indexRec > -1) { - // Lambda → p pi - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); - if (indexRec == -1) { - debug = McMatchFlag::V0Unmatched; - } - if (indexRec > -1) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } - } - } - // Check whether the charm baryon is non-prompt (from a b quark). - if (flag != 0) { - auto particle = mcParticles.rawIteratorAt(indexRecCharmBaryon); - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - } - if (origin == RecoDecay::OriginType::NonPrompt) { - auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); - rowMCMatchRecXicToXiPi(flag, debug, origin, collisionMatched, bHadMother.pt(), bHadMother.pdgCode()); - } else { - rowMCMatchRecXicToXiPi(flag, debug, origin, collisionMatched, -1.f, 0); - } - if (debug == McMatchFlag::CascUnmatched || debug == McMatchFlag::V0Unmatched) { - LOGF(info, "WARNING: Xic0ToXiPi decays in the expected final state but the condition on the intermediate states are not fulfilled"); - } - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { // Omegac -> xi pi matching - // Omegac → pi pi pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kOmegaC0, std::array{+kPiPlus, +kPiMinus, +kProton, +kPiMinus}, true, &sign, 3); - indexRecCharmBaryon = indexRec; - if (indexRec == -1) { - debug = McMatchFlag::CharmbaryonUnmatched; - } - if (indexRec > -1) { - // Xi- → pi pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kXiMinus, std::array{+kPiMinus, +kProton, +kPiMinus}, true, &signCasc, 2); - if (indexRec == -1) { - debug = McMatchFlag::CascUnmatched; - } - if (indexRec > -1) { - // Lambda → p pi - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); - if (indexRec == -1) { - debug = McMatchFlag::V0Unmatched; - } - if (indexRec > -1) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } - } - } - // Check whether the charm baryon is non-prompt (from a b quark). - if (flag != 0) { - auto particle = mcParticles.rawIteratorAt(indexRecCharmBaryon); - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - } - if (origin == RecoDecay::OriginType::NonPrompt) { - auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); - rowMCMatchRecOmegacToXiPi(flag, debug, origin, collisionMatched, bHadMother.pt(), bHadMother.pdgCode()); - } else { - rowMCMatchRecOmegacToXiPi(flag, debug, origin, collisionMatched, -1.f, 0); - } - if (debug == McMatchFlag::CascUnmatched || debug == McMatchFlag::V0Unmatched) { - LOGF(info, "WARNING: Omegac0ToXiPi decays in the expected final state but the condition on the intermediate states are not fulfilled"); - } - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { // Omegac0 -> omega pi matching - if (acceptTrackIntWithMaterial) { - // Omegac → pi K pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kOmegaC0, std::array{+kPiPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3, &nPiToMuOmegac0, &nKaToPiOmegac0); - indexRecCharmBaryon = indexRec; - if (indexRec == -1) { - debug = McMatchFlag::CharmbaryonUnmatched; - } - if (indexRec > -1) { - // Omega- → K pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2, &nPiToMuCasc, &nKaToPiCasc); - if (indexRec == -1) { - debug = McMatchFlag::CascUnmatched; - } - if (indexRec > -1) { - // Lambda → p pi - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1, &nPiToMuV0); - if (indexRec == -1) { - debug = McMatchFlag::V0Unmatched; - } - if (indexRec > -1 && nPiToMuOmegac0 >= 1 && nKaToPiOmegac0 == 0) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPiOneMu); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } else if (indexRec > -1 && nPiToMuOmegac0 == 0 && nKaToPiOmegac0 == 0) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } - } - } - } else { - // Omegac → pi K pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kOmegaC0, std::array{+kPiPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3, &nPiToMuOmegac0, &nKaToPiOmegac0); - indexRecCharmBaryon = indexRec; - if (indexRec == -1) { - debug = McMatchFlag::CharmbaryonUnmatched; - } - if (indexRec > -1) { - // Omega- → K pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2, &nPiToMuCasc, &nKaToPiCasc); - if (indexRec == -1) { - debug = McMatchFlag::CascUnmatched; - } - if (indexRec > -1) { - // Lambda → p pi - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1, &nPiToMuV0); - if (indexRec == -1) { - debug = McMatchFlag::V0Unmatched; - } - if (indexRec > -1 && nPiToMuOmegac0 >= 1 && nKaToPiOmegac0 == 0) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPiOneMu); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } else if (indexRec > -1 && nPiToMuOmegac0 == 0 && nKaToPiOmegac0 == 0) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } - } - } - } - // Check whether the charm baryon is non-prompt (from a b quark). - if (flag != 0) { - auto particle = mcParticles.rawIteratorAt(indexRecCharmBaryon); - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - } - if (origin == RecoDecay::OriginType::NonPrompt) { - auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); - rowMCMatchRecToOmegaPi(flag, debug, origin, collisionMatched, bHadMother.pt(), bHadMother.pdgCode()); - } else { - rowMCMatchRecToOmegaPi(flag, debug, origin, collisionMatched, -1.f, 0); - } - if (debug == McMatchFlag::CascUnmatched || debug == McMatchFlag::V0Unmatched) { - LOGF(info, "WARNING: Omegac0ToOmegaPi decays in the expected final state but the condition on the intermediate states are not fulfilled"); - } - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaK) { // Omegac0 -> omega K matching - // Omegac → K K pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kOmegaC0, std::array{+kKPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3); - indexRecCharmBaryon = indexRec; - if (indexRec == -1) { - debug = McMatchFlag::CharmbaryonUnmatched; + + // CharmBaryon -> Charm bachelor + Cascade + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, pdgOfCharmBaryon[decayChannel], std::array{pdgOfCharmBachelor[decayChannel], pdgOfBachelor[decayChannel], +kProton, +kPiMinus}, true, &sign, 3); + indexRecCharmBaryon = indexRec; + if (indexRec == -1) { // Xic0 not reconstructed + debug = McMatchFlag::CharmBaryonUnmatched; + } + if (indexRec > -1) { + // Cascade -> Bachelor + V0 + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, pdgOfCascade[decayChannel], std::array{pdgOfBachelor[decayChannel], +kProton, +kPiMinus}, true, &signCasc, 2); + if (indexRec == -1) { // Xi- not reconstructed + debug = McMatchFlag::CascUnmatched; } if (indexRec > -1) { - // Omega- → K pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2); - if (indexRec == -1) { - debug = McMatchFlag::CascUnmatched; + // V0 -> Pos + Neg + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); + if (indexRec == -1) { // V0 not reconstructed + debug = McMatchFlag::V0Unmatched; } if (indexRec > -1) { - // Lambda → p pi - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); - if (indexRec == -1) { - debug = McMatchFlag::V0Unmatched; - } - if (indexRec > -1) { - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaK); - collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); - } + flag = sign * (1 << decayChannel); + collisionMatched = candidate.template collision_as().mcCollisionId() == mcParticles.iteratorAt(indexRecCharmBaryon).mcCollisionId(); } } - // Check whether the charm baryon is non-prompt (from a b quark). - if (flag != 0) { - auto particle = mcParticles.rawIteratorAt(indexRecCharmBaryon); - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - } - if (origin == RecoDecay::OriginType::NonPrompt) { - auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); - rowMCMatchRecToOmegaK(flag, debug, origin, collisionMatched, bHadMother.pt(), bHadMother.pdgCode()); - } else { - rowMCMatchRecToOmegaK(flag, debug, origin, collisionMatched, -1.f, 0); - } - if (debug == McMatchFlag::CascUnmatched || debug == McMatchFlag::V0Unmatched) { - LOGF(info, "WARNING: Omegac0ToOmegaK decays in the expected final state but the condition on the intermediate states are not fulfilled"); - } } - } // close loop over candidates - for (const auto& mcCollision : mcCollisions) { + // Check if Xic0 is from b-hadron decay(prompt vs non-prompt) + if (flag != 0) { + auto particle = mcParticles.rawIteratorAt(indexRecCharmBaryon); + origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); + } + if (origin == RecoDecay::OriginType::NonPrompt) { + auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); + fillRecoMcTableByDecayChannel(flag, debug, origin, collisionMatched, bHadMother.pt(), bHadMother.pdgCode()); + } else { + fillRecoMcTableByDecayChannel(flag, debug, origin, collisionMatched, -1.f, 0); + } + } // candidate loop + + /////////////////////////////// + // Match generated particles // + /////////////////////////////// + + for (auto const& mcCollision : mcCollisions) { + + auto const mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); - // Slice the particles table to get the particles for the current MC collision - const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); - // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; - int nSplitColl = 0; - if constexpr (centEstimator == CentralityEstimator::FT0C) { + uint16_t rejectionMask{0}; + int nSplitColl{0}; + + if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::None) { + const auto collSlice = collsWithMcLabels.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0C) { const auto collSlice = collsWithMcLabels.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); - nSplitColl = collSlice.size(); - } else if constexpr (centEstimator == CentralityEstimator::FT0M) { + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0M) { const auto collSlice = collsWithMcLabels.sliceBy(colPerMcCollisionFT0M, mcCollision.globalIndex()); rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); - nSplitColl = collSlice.size(); - } else if constexpr (centEstimator == CentralityEstimator::None) { - const auto collSlice = collsWithMcLabels.sliceBy(colPerMcCollision, mcCollision.globalIndex()); - rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); - nSplitColl = collSlice.size(); } - hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); - if (rejectionMask != 0) { - /// at least one event selection not satisfied --> reject all particles from this collision + + hfEvSelMc.fillHistograms(mcCollision, rejectionMask); + + if (rejectionMask != 0) { // none of the event selection was satisfied(?) -> Reject all particles from this event for (unsigned int i = 0; i < mcParticlesPerMcColl.size(); ++i) { - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - rowMCMatchGenXicToXiPi(0, 0, 0, 0, -999., -999., RecoDecay::OriginType::None, -1); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { - rowMCMatchGenOmegacToXiPi(0, 0, 0, 0, -999., -999., RecoDecay::OriginType::None, -1); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { - rowMCMatchGenToOmegaPi(0, 0, 0, 0, -999., -999., RecoDecay::OriginType::None, -1); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaK) { - rowMCMatchGenToOmegaK(0, 0, 0, 0, -999., -999., RecoDecay::OriginType::None, -1); - } + fillGenMcTableByDecayChannel(0, 0, 0, 0, -999., -999., RecoDecay::OriginType::None, -1); } continue; } - // Match generated particles. - for (const auto& particle : mcParticlesPerMcColl) { + // Match generated particles + for (auto const& particle : mcParticlesPerMcColl) { ptCharmBaryonGen = -999.; - rapidityCharmBaryonGen = -999.; + yCharmBaryonGen = -999.; flag = 0; - sign = -9; - debugGenCharmBar = 0; + sign = 0; + debugGenCharmBaryon = 0; debugGenCasc = 0; - debugGenLambda = 0; + debugGenV0 = 0; origin = RecoDecay::OriginType::None; std::vector idxBhadMothers{}; - float kRapidityCutTight = 0.5; - float kRapidityCutLoose = 0.8; + float kYCutTight = 0.5; + float kYCutLoose = 0.8; // Reject particles from background events - if (particle.fromBackgroundEvent() && rejectBackground) { - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - rowMCMatchGenXicToXiPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { - rowMCMatchGenOmegacToXiPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { - rowMCMatchGenToOmegaPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaK) { - rowMCMatchGenToOmegaK(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } + if (particle.fromBackgroundEvent() && configs.rejectBackground) { + fillGenMcTableByDecayChannel(flag, debugGenCharmBaryon, debugGenCasc, debugGenV0, ptCharmBaryonGen, yCharmBaryonGen, origin, -1); continue; } - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - // Xic → Xi pi - if (RecoDecay::isMatchedMCGen(mcParticles, particle, +kXiC0, std::array{+kXiMinus, +kPiPlus}, true, &sign)) { - debugGenCharmBar = 1; - ptCharmBaryonGen = particle.pt(); - rapidityCharmBaryonGen = particle.y(); - for (const auto& daughterCharm : particle.template daughters_as()) { - if (std::abs(daughterCharm.pdgCode()) != +kXiMinus) { - continue; - } - // Xi -> Lambda pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, +kXiMinus, std::array{+kLambda0, +kPiMinus}, true)) { - debugGenCasc = 1; - for (const auto& daughterCascade : daughterCharm.template daughters_as()) { - if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { - continue; - } - // Lambda -> p pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { - debugGenLambda = 1; - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi); - } - } - } - } - } - // Check whether the charm baryon is non-prompt (from a b quark) - if (flag != 0) { - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutTight) { - hGenCharmBaryonPtRapidityTightXicToXiPi->SetBinContent(hGenCharmBaryonPtRapidityTightXicToXiPi->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityTightXicToXiPi->GetBinContent(hGenCharmBaryonPtRapidityTightXicToXiPi->FindBin(ptCharmBaryonGen)) + 1); - } - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutLoose) { - hGenCharmBaryonPtRapidityLooseXicToXiPi->SetBinContent(hGenCharmBaryonPtRapidityLooseXicToXiPi->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityLooseXicToXiPi->GetBinContent(hGenCharmBaryonPtRapidityLooseXicToXiPi->FindBin(ptCharmBaryonGen)) + 1); - } - } - if (origin == RecoDecay::OriginType::NonPrompt) { - rowMCMatchGenXicToXiPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, idxBhadMothers[0]); - } else { - rowMCMatchGenXicToXiPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } + // Charm Baryon -> Cascade + Charm bachelor + if (RecoDecay::isMatchedMCGen(mcParticles, particle, pdgOfCharmBaryon[decayChannel], std::array{pdgOfCascade[decayChannel], pdgOfCharmBachelor[decayChannel]}, true, &sign)) { + debugGenCharmBaryon = 1; + ptCharmBaryonGen = particle.pt(); + yCharmBaryonGen = particle.y(); + debug = 1; // -> Matched Xic0 - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi) { - // Omegac → Xi pi - if (RecoDecay::isMatchedMCGen(mcParticles, particle, +kOmegaC0, std::array{+kXiMinus, +kPiPlus}, true, &sign)) { - debugGenCharmBar = 1; - ptCharmBaryonGen = particle.pt(); - rapidityCharmBaryonGen = particle.y(); - for (const auto& daughterCharm : particle.template daughters_as()) { - if (std::abs(daughterCharm.pdgCode()) != +kXiMinus) { - continue; - } - // Xi -> Lambda pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, +kXiMinus, std::array{+kLambda0, +kPiMinus}, true)) { - debugGenCasc = 1; - for (const auto& daughterCascade : daughterCharm.template daughters_as()) { - if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { - continue; - } - // Lambda -> p pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { - debugGenLambda = 1; - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToXiPi); - } - } - } - } - } - // Check whether the charm baryon is non-prompt (from a b quark) - if (flag != 0) { - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutTight) { - hGenCharmBaryonPtRapidityTightOmegacToXiPi->SetBinContent(hGenCharmBaryonPtRapidityTightOmegacToXiPi->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityTightOmegacToXiPi->GetBinContent(hGenCharmBaryonPtRapidityTightOmegacToXiPi->FindBin(ptCharmBaryonGen)) + 1); - } - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutLoose) { - hGenCharmBaryonPtRapidityLooseOmegacToXiPi->SetBinContent(hGenCharmBaryonPtRapidityLooseOmegacToXiPi->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityLooseOmegacToXiPi->GetBinContent(hGenCharmBaryonPtRapidityLooseOmegacToXiPi->FindBin(ptCharmBaryonGen)) + 1); + for (auto const& daughterCharm : particle.template daughters_as()) { + if (std::abs(daughterCharm.pdgCode()) != pdgOfCascade[decayChannel]) { + continue; } - } - if (origin == RecoDecay::OriginType::NonPrompt) { - rowMCMatchGenOmegacToXiPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, idxBhadMothers[0]); - } else { - rowMCMatchGenOmegacToXiPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } - - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi) { - // Omegac → Omega pi - if (RecoDecay::isMatchedMCGen(mcParticles, particle, +kOmegaC0, std::array{+kOmegaMinus, +kPiPlus}, true, &sign)) { - debugGenCharmBar = 1; - ptCharmBaryonGen = particle.pt(); - rapidityCharmBaryonGen = particle.y(); - for (const auto& daughterCharm : particle.template daughters_as()) { - if (std::abs(daughterCharm.pdgCode()) != +kOmegaMinus) { - continue; - } - // Omega -> Lambda K - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, +kOmegaMinus, std::array{+kLambda0, +kKMinus}, true)) { - debugGenCasc = 1; - for (const auto& daughterCascade : daughterCharm.template daughters_as()) { - if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { - continue; - } - // Lambda -> p pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { - debugGenLambda = 1; - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi); - } + // Xi -> Lambda + pi + if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, pdgOfCascade[decayChannel], std::array{+kLambda0, pdgOfBachelor[decayChannel]}, true)) { + debugGenCasc = 1; // -> Matched Xi- + for (auto const& daughterCascade : daughterCharm.template daughters_as()) { + if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { + continue; } - } - } - } - // Check whether the charm baryon is non-prompt (from a b quark) - if (flag != 0) { - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutTight) { - hGenCharmBaryonPtRapidityTightOmegacToOmegaPi->SetBinContent(hGenCharmBaryonPtRapidityTightOmegacToOmegaPi->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityTightOmegacToOmegaPi->GetBinContent(hGenCharmBaryonPtRapidityTightOmegacToOmegaPi->FindBin(ptCharmBaryonGen)) + 1); - } - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutLoose) { - hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi->SetBinContent(hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi->GetBinContent(hGenCharmBaryonPtRapidityLooseOmegacToOmegaPi->FindBin(ptCharmBaryonGen)) + 1); - } - } - if (origin == RecoDecay::OriginType::NonPrompt) { - rowMCMatchGenToOmegaPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, idxBhadMothers[0]); - } else { - rowMCMatchGenToOmegaPi(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } - } else if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaK) { - // Omegac → Omega K - if (RecoDecay::isMatchedMCGen(mcParticles, particle, +kOmegaC0, std::array{+kOmegaMinus, +kKPlus}, true, &sign)) { - debugGenCharmBar = 1; - ptCharmBaryonGen = particle.pt(); - rapidityCharmBaryonGen = particle.y(); - for (const auto& daughterCharm : particle.template daughters_as()) { - if (std::abs(daughterCharm.pdgCode()) != +kOmegaMinus) { - continue; - } - // Omega -> Lambda K - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCharm, +kOmegaMinus, std::array{+kLambda0, +kKMinus}, true)) { - debugGenCasc = 1; - for (const auto& daughterCascade : daughterCharm.template daughters_as()) { - if (std::abs(daughterCascade.pdgCode()) != +kLambda0) { - continue; - } - // Lambda -> p pi - if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { - debugGenLambda = 1; - flag = sign * (1 << aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaK); - } + // Lambda -> p + pi + if (RecoDecay::isMatchedMCGen(mcParticles, daughterCascade, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { + debugGenV0 = 1; // -> Matched Lambda0 + flag = sign * (1 << decayChannel); } - } - } + } // V0 daughter loop + } // cascade daughter loop } - // Check whether the charm baryon is non-prompt (from a b quark) - if (flag != 0) { - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutTight) { - hGenCharmBaryonPtRapidityTightOmegacToOmegaK->SetBinContent(hGenCharmBaryonPtRapidityTightOmegacToOmegaK->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityTightOmegacToOmegaK->GetBinContent(hGenCharmBaryonPtRapidityTightOmegacToOmegaK->FindBin(ptCharmBaryonGen)) + 1); - } - if (std::abs(rapidityCharmBaryonGen) < kRapidityCutLoose) { - hGenCharmBaryonPtRapidityLooseOmegacToOmegaK->SetBinContent(hGenCharmBaryonPtRapidityLooseOmegacToOmegaK->FindBin(ptCharmBaryonGen), hGenCharmBaryonPtRapidityLooseOmegacToOmegaK->GetBinContent(hGenCharmBaryonPtRapidityLooseOmegacToOmegaK->FindBin(ptCharmBaryonGen)) + 1); - } - } - if (origin == RecoDecay::OriginType::NonPrompt) { - rowMCMatchGenToOmegaK(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, idxBhadMothers[0]); - } else { - rowMCMatchGenToOmegaK(flag, debugGenCharmBar, debugGenCasc, debugGenLambda, ptCharmBaryonGen, rapidityCharmBaryonGen, origin, -1); - } - } - } // close loop on MCParticles - } // close loop on MCCollisions - } // close process - - template - void runXic0Omegac0McQa(TMyRecoCand const& candidates, - MyTracksWMc const&, - aod::McParticles const& mcParticles, - BCsInfo const&) - { - int indexRec = -1; - int8_t sign = -9; - int8_t signCasc = -9; - int8_t signV0 = -9; + } // charm daughter loop - for (const auto& candidate : candidates) { + // Check if charm is prompt or non-prompt + if (flag != 0) { + origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); + } + if (std::abs(yCharmBaryonGen) < kYCutTight) { + // Fill in some QA histogram. Will be implemented later + } + if (std::abs(yCharmBaryonGen) < kYCutLoose) { + // Fill in some QA histograms. Will be implemented later + } - auto arrayDaughters = std::array{candidate.template bachelorFromCharmBaryon_as(), // bachelor <- charm baryon - candidate.template bachelor_as(), // bachelor <- cascade - candidate.template posTrack_as(), // p <- lambda - candidate.template negTrack_as()}; // pi <- lambda - auto arrayDaughtersCasc = std::array{candidate.template bachelor_as(), - candidate.template posTrack_as(), - candidate.template negTrack_as()}; - auto arrayDaughtersV0 = std::array{candidate.template posTrack_as(), - candidate.template negTrack_as()}; - - auto mcV0DauPos = arrayDaughtersV0[0].mcParticle(); - auto mcV0DauNeg = arrayDaughtersV0[1].mcParticle(); - auto mcXiBachelor = arrayDaughtersCasc[0].mcParticle(); - auto mcXic0Bachelor = arrayDaughters[0].mcParticle(); - - // Xic0 -> xi pi matching - if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { - // Lambda → p pi - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); - if (indexRec > -1 && signV0 == 1) { - auto mcV0 = mcParticles.rawIteratorAt(indexRec - mcParticles.offset()); - - float v0MassPull = (candidate.invMassLambda() - MassLambda0) / candidate.invMassV0Err(); - registry.fill(HIST("hV0MassPullVsPt"), candidate.v0Pt(), v0MassPull); - - float v0DauPosXDelta = candidate.v0DauPosX() - mcV0DauPos.vx(); - float v0DauPosYDelta = candidate.v0DauPosY() - mcV0DauPos.vy(); - float v0DauPosZDelta = candidate.v0DauPosZ() - mcV0DauPos.vz(); - float v0DauPosPt = mcV0DauPos.pt(); - float v0DauPosXPull = v0DauPosXDelta / candidate.v0DauPosXError(); - float v0DauPosYPull = v0DauPosYDelta / candidate.v0DauPosYError(); - float v0DauPosZPull = v0DauPosZDelta / candidate.v0DauPosZError(); - - float v0DauNegXDelta = candidate.v0DauNegX() - mcV0DauNeg.vx(); - float v0DauNegYDelta = candidate.v0DauNegY() - mcV0DauNeg.vy(); - float v0DauNegZDelta = candidate.v0DauNegZ() - mcV0DauNeg.vz(); - float v0DauNegPt = mcV0DauNeg.pt(); - float v0DauNegXPull = v0DauNegXDelta / candidate.v0DauNegXError(); - float v0DauNegYPull = v0DauNegYDelta / candidate.v0DauNegYError(); - float v0DauNegZPull = v0DauNegZDelta / candidate.v0DauNegZError(); - - float v0XDelta = candidate.v0VtxX() - mcV0DauNeg.vx(); - float v0YDelta = candidate.v0VtxY() - mcV0DauNeg.vy(); - float v0ZDelta = candidate.v0VtxZ() - mcV0DauNeg.vz(); - float v0Pt = mcV0.pt(); - float v0XPull = v0XDelta / candidate.v0XError(); - float v0YPull = v0YDelta / candidate.v0YError(); - float v0ZPull = v0ZDelta / candidate.v0ZError(); - - float lambdaXDelta = candidate.v0X() - mcV0DauNeg.vx(); - float lambdaYDelta = candidate.v0Y() - mcV0DauNeg.vy(); - float lambdaZDelta = candidate.v0Z() - mcV0DauNeg.vz(); - registry.fill(HIST("hV0DauPosXDelta"), v0DauPosXDelta); - registry.fill(HIST("hV0DauPosYDelta"), v0DauPosYDelta); - registry.fill(HIST("hV0DauPosZDelta"), v0DauPosZDelta); - registry.fill(HIST("hV0DauPosXDeltaVsPt"), v0DauPosPt, v0DauPosXDelta); - registry.fill(HIST("hV0DauPosYDeltaVsPt"), v0DauPosPt, v0DauPosYDelta); - registry.fill(HIST("hV0DauPosZDeltaVsPt"), v0DauPosPt, v0DauPosZDelta); - registry.fill(HIST("hV0DauPosXPull"), v0DauPosXPull); - registry.fill(HIST("hV0DauPosYPull"), v0DauPosYPull); - registry.fill(HIST("hV0DauPosZPull"), v0DauPosZPull); - registry.fill(HIST("hV0DauPosXPullVsPt"), v0DauPosPt, v0DauPosXPull); - registry.fill(HIST("hV0DauPosYPullVsPt"), v0DauPosPt, v0DauPosYPull); - registry.fill(HIST("hV0DauPosZPullVsPt"), v0DauPosPt, v0DauPosZPull); - - registry.fill(HIST("hV0DauNegXDelta"), v0DauNegXDelta); - registry.fill(HIST("hV0DauNegYDelta"), v0DauNegYDelta); - registry.fill(HIST("hV0DauNegZDelta"), v0DauNegZDelta); - registry.fill(HIST("hV0DauNegXDeltaVsPt"), v0DauNegPt, v0DauNegXDelta); - registry.fill(HIST("hV0DauNegYDeltaVsPt"), v0DauNegPt, v0DauNegYDelta); - registry.fill(HIST("hV0DauNegZDeltaVsPt"), v0DauNegPt, v0DauNegZDelta); - registry.fill(HIST("hV0DauNegXPull"), v0DauNegXPull); - registry.fill(HIST("hV0DauNegYPull"), v0DauNegYPull); - registry.fill(HIST("hV0DauNegZPull"), v0DauNegZPull); - registry.fill(HIST("hV0DauNegXPullVsPt"), v0DauNegPt, v0DauNegXPull); - registry.fill(HIST("hV0DauNegYPullVsPt"), v0DauNegPt, v0DauNegYPull); - registry.fill(HIST("hV0DauNegZPullVsPt"), v0DauNegPt, v0DauNegZPull); - - registry.fill(HIST("hV0XDelta"), v0XDelta); - registry.fill(HIST("hV0YDelta"), v0YDelta); - registry.fill(HIST("hV0ZDelta"), v0ZDelta); - registry.fill(HIST("hV0XDeltaVsPt"), v0Pt, v0XDelta); - registry.fill(HIST("hV0YDeltaVsPt"), v0Pt, v0YDelta); - registry.fill(HIST("hV0ZDeltaVsPt"), v0Pt, v0ZDelta); - registry.fill(HIST("hV0XPull"), v0XPull); - registry.fill(HIST("hV0YPull"), v0YPull); - registry.fill(HIST("hV0ZPull"), v0ZPull); - registry.fill(HIST("hV0XPullVsPt"), v0Pt, v0XPull); - registry.fill(HIST("hV0YPullVsPt"), v0Pt, v0YPull); - registry.fill(HIST("hV0ZPullVsPt"), v0Pt, v0ZPull); - - registry.fill(HIST("hLambdaXDelta"), lambdaXDelta); - registry.fill(HIST("hLambdaYDelta"), lambdaYDelta); - registry.fill(HIST("hLambdaZDelta"), lambdaZDelta); - - registry.fill(HIST("hV0DauPosPtRes"), (candidate.v0DauPosPt() - mcV0DauPos.pt()) / candidate.v0DauPosPt()); - registry.fill(HIST("hV0DauNegPtRes"), (candidate.v0DauNegPt() - mcV0DauNeg.pt()) / candidate.v0DauNegPt()); - registry.fill(HIST("hV0PtRes"), (candidate.v0Pt() - mcV0.pt()) / candidate.v0Pt()); - // Xi- → pi pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kXiMinus, std::array{+kPiMinus, +kProton, +kPiMinus}, true, &signCasc, 2); - if (indexRec > -1 && signCasc == 1) { - // QA - float xiMassPull = (candidate.invMassCascade() - MassXiMinus) / candidate.invMassXiErr(); - registry.fill(HIST("hXiMassPullVsPt"), candidate.xiPt(), xiMassPull); - - float xiBachelorXDelta = candidate.xiBachelorX() - mcXiBachelor.vx(); - float xiBachelorYDelta = candidate.xiBachelorY() - mcXiBachelor.vy(); - float xiBachelorZDelta = candidate.xiBachelorZ() - mcXiBachelor.vz(); - float xiBachelorPt = mcXiBachelor.pt(); - float xiBachelorXPull = xiBachelorXDelta / candidate.xiBachelorXError(); - float xiBachelorYPull = xiBachelorYDelta / candidate.xiBachelorYError(); - float xiBachelorZPull = xiBachelorZDelta / candidate.xiBachelorZError(); - - auto mcXi = mcParticles.rawIteratorAt(indexRec - mcParticles.offset()); - - float xiXDelta = candidate.xiX() - mcXiBachelor.vx(); - float xiYDelta = candidate.xiY() - mcXiBachelor.vy(); - float xiZDelta = candidate.xiZ() - mcXiBachelor.vz(); - float xiPt = mcXi.pt(); - float xiXPull = xiXDelta / candidate.xiXError(); - float xiYPull = xiYDelta / candidate.xiYError(); - float xiZPull = xiZDelta / candidate.xiZError(); - - float cascXDelta = candidate.xDecayVtxCascade() - mcXiBachelor.vx(); - float cascYDelta = candidate.yDecayVtxCascade() - mcXiBachelor.vy(); - float cascZDelta = candidate.zDecayVtxCascade() - mcXiBachelor.vz(); - - registry.fill(HIST("hXiBachelorXDelta"), xiBachelorXDelta); - registry.fill(HIST("hXiBachelorYDelta"), xiBachelorYDelta); - registry.fill(HIST("hXiBachelorZDelta"), xiBachelorZDelta); - registry.fill(HIST("hXiBachelorXDeltaVsPt"), xiBachelorPt, xiBachelorXDelta); - registry.fill(HIST("hXiBachelorYDeltaVsPt"), xiBachelorPt, xiBachelorYDelta); - registry.fill(HIST("hXiBachelorZDeltaVsPt"), xiBachelorPt, xiBachelorZDelta); - registry.fill(HIST("hXiBachelorXPull"), xiBachelorXPull); - registry.fill(HIST("hXiBachelorYPull"), xiBachelorYPull); - registry.fill(HIST("hXiBachelorZPull"), xiBachelorZPull); - registry.fill(HIST("hXiBachelorXPullVsPt"), xiBachelorPt, xiBachelorXPull); - registry.fill(HIST("hXiBachelorYPullVsPt"), xiBachelorPt, xiBachelorYPull); - registry.fill(HIST("hXiBachelorZPullVsPt"), xiBachelorPt, xiBachelorZPull); - - registry.fill(HIST("hXiXDelta"), xiXDelta); - registry.fill(HIST("hXiYDelta"), xiYDelta); - registry.fill(HIST("hXiZDelta"), xiZDelta); - registry.fill(HIST("hXiXDeltaVsPt"), xiPt, xiXDelta); - registry.fill(HIST("hXiYDeltaVsPt"), xiPt, xiYDelta); - registry.fill(HIST("hXiZDeltaVsPt"), xiPt, xiZDelta); - registry.fill(HIST("hXiXPull"), xiXPull); - registry.fill(HIST("hXiYPull"), xiYPull); - registry.fill(HIST("hXiZPull"), xiZPull); - registry.fill(HIST("hXiXPullVsPt"), xiPt, xiXPull); - registry.fill(HIST("hXiYPullVsPt"), xiPt, xiYPull); - registry.fill(HIST("hXiZPullVsPt"), xiPt, xiZPull); - - registry.fill(HIST("hCascXDelta"), cascXDelta); - registry.fill(HIST("hCascYDelta"), cascYDelta); - registry.fill(HIST("hCascZDelta"), cascZDelta); - - registry.fill(HIST("hXiBachelorPtRes"), (candidate.xiBachelorPt() - mcXiBachelor.pt()) / candidate.xiBachelorPt()); - registry.fill(HIST("hXiPtRes"), (candidate.xiPt() - mcXi.pt()) / candidate.xiPt()); - - // Xic → pi pi pi p - indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kXiC0, std::array{+kPiPlus, +kPiMinus, +kProton, +kPiMinus}, true, &sign, 3); - if (indexRec > -1 && sign == 1) { - auto mcXic0 = mcParticles.rawIteratorAt(indexRec - mcParticles.offset()); - float xic0MassPull = (candidate.invMassCharmBaryon() - MassXiC0) / candidate.invMassXic0Err(); - registry.fill(HIST("hXic0MassPullVsPt"), candidate.xic0Pt(), xic0MassPull); - - float xic0BachelorXDelta = candidate.xic0BachelorX() - mcXic0Bachelor.vx(); - float xic0BachelorYDelta = candidate.xic0BachelorY() - mcXic0Bachelor.vy(); - float xic0BachelorZDelta = candidate.xic0BachelorZ() - mcXic0Bachelor.vz(); - float xic0BachelorPt = mcXic0Bachelor.pt(); - float xic0BachelorXPull = xic0BachelorXDelta / candidate.xic0BachelorXError(); - float xic0BachelorYPull = xic0BachelorYDelta / candidate.xic0BachelorYError(); - float xic0BachelorZPull = xic0BachelorZDelta / candidate.xic0BachelorZError(); - - float xic0XDelta = candidate.xDecayVtxCharmBaryon() - mcXic0Bachelor.vx(); - float xic0YDelta = candidate.yDecayVtxCharmBaryon() - mcXic0Bachelor.vy(); - float xic0ZDelta = candidate.zDecayVtxCharmBaryon() - mcXic0Bachelor.vz(); - float xic0Pt = mcXic0.pt(); - float xic0XPull = xic0XDelta / candidate.xic0XError(); - float xic0YPull = xic0YDelta / candidate.xic0YError(); - float xic0ZPull = xic0ZDelta / candidate.xic0ZError(); - registry.fill(HIST("hXic0BachelorXDelta"), xic0BachelorXDelta); - registry.fill(HIST("hXic0BachelorYDelta"), xic0BachelorYDelta); - registry.fill(HIST("hXic0BachelorZDelta"), xic0BachelorZDelta); - registry.fill(HIST("hXic0BachelorXDeltaVsPt"), xic0BachelorPt, xic0BachelorXDelta); - registry.fill(HIST("hXic0BachelorYDeltaVsPt"), xic0BachelorPt, xic0BachelorYDelta); - registry.fill(HIST("hXic0BachelorZDeltaVsPt"), xic0BachelorPt, xic0BachelorZDelta); - registry.fill(HIST("hXic0BachelorXPull"), xic0BachelorXPull); - registry.fill(HIST("hXic0BachelorYPull"), xic0BachelorYPull); - registry.fill(HIST("hXic0BachelorZPull"), xic0BachelorZPull); - registry.fill(HIST("hXic0BachelorXPullVsPt"), xic0BachelorPt, xic0BachelorXPull); - registry.fill(HIST("hXic0BachelorYPullVsPt"), xic0BachelorPt, xic0BachelorYPull); - registry.fill(HIST("hXic0BachelorZPullVsPt"), xic0BachelorPt, xic0BachelorZPull); - - registry.fill(HIST("hXic0XDelta"), xic0XDelta); - registry.fill(HIST("hXic0YDelta"), xic0YDelta); - registry.fill(HIST("hXic0ZDelta"), xic0ZDelta); - registry.fill(HIST("hXic0XDeltaVsPt"), xic0Pt, xic0XDelta); - registry.fill(HIST("hXic0YDeltaVsPt"), xic0Pt, xic0YDelta); - registry.fill(HIST("hXic0ZDeltaVsPt"), xic0Pt, xic0ZDelta); - registry.fill(HIST("hXic0XPull"), xic0XPull); - registry.fill(HIST("hXic0YPull"), xic0YPull); - registry.fill(HIST("hXic0ZPull"), xic0ZPull); - registry.fill(HIST("hXic0XPullVsPt"), xic0Pt, xic0XPull); - registry.fill(HIST("hXic0YPullVsPt"), xic0Pt, xic0YPull); - registry.fill(HIST("hXic0ZPullVsPt"), xic0Pt, xic0ZPull); - - registry.fill(HIST("hXic0BachelorPtRes"), (candidate.xic0BachelorPt() - mcXic0Bachelor.pt()) / candidate.xic0BachelorPt()); - registry.fill(HIST("hXic0PtRes"), (candidate.xic0Pt() - mcXic0.pt()) / candidate.xic0Pt()); - } - } + if (origin == RecoDecay::OriginType::NonPrompt) { + fillGenMcTableByDecayChannel(flag, debugGenCharmBaryon, debugGenCasc, debugGenV0, ptCharmBaryonGen, yCharmBaryonGen, origin, idxBhadMothers[0]); + } else { + fillGenMcTableByDecayChannel(flag, debugGenCharmBaryon, debugGenCasc, debugGenV0, ptCharmBaryonGen, yCharmBaryonGen, origin, -1); } - } - } - } - void processDoNoMc(aod::Collisions::iterator const&) - { - // dummy process function - should not be required in the future - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processDoNoMc, "Do not run any MC process function", true); - - void processMcXicToXiPi(aod::HfCandToXiPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + } // particle loop + + } // end of collision loop + + } // template run function + + void processMcEmpty(aod::Collisions const&) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPi, "Run Xic0 to xi pi MC process function - no centrality", false); - - void processMcXicToXiPiKf(aod::HfCandToXiPiKf const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcEmpty, "Empty process function to prevent workflow from getting stuck", true); + + ///////////////////////////////////////////////////// + /// /// + /// Process functions with DCAFitter /// + /// /// + ///////////////////////////////////////////////////// + + //~~~~~~~~~~~~~~~~// + //~~~~To Xi Pi~~~~// + //~~~~~~~~~~~~~~~~// + void processMcXicToXiPiWithDCAFitterNoCent(aod::HfCandToXiPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiKf, "Run Xic0 to xi pi MC process function - no centrality", false); - - void processMcXicToXiPiKfQa(aod::HfCandToXiPiKfQa const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. No cents", false); + + void processMcXicToXiPiWithDCAFitterCentFT0C(aod::HfCandToXiPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsFT0Cs const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0McQa(candidates, tracks, mcParticles, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiKfQa, "Run Xic0 to xi pi MC QA process function - no centrality", false); - - void processMcXicToXiPiFT0m(aod::HfCandToXiPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcColls, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. Cents with FT0C", false); + + void processMcXicToXiPiWithDCAFitterCentFT0M(aod::HfCandToXiPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Ms const& mcCollisions, + McCollisionsFT0Ms const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiFT0m, "Run Xic0 to xi pi MC process function - FT0M", false); - - void processMcXicToXiPiFT0c(aod::HfCandToXiPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. Cents with FT0M", false); + + void processMcOmegacToXiPiWithDCAFitterNoCent(aod::HfCandToXiPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiFT0c, "Run Xic0 to xi pi MC process function - FT0C", false); - - void processMcOmegacToXiPi(aod::HfCandToXiPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToXiPiWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Omegac0 to Xi Pi. No cents", false); + + void processMcOmegacToXiPiWithDCAFitterCentFT0C(aod::HfCandToXiPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsFT0Cs const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToXiPi, "Run Omegac0 to xi pi MC process function - no centrality", false); - - void processMcOmegacToXiPiFT0m(aod::HfCandToXiPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcColls, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToXiPiWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Omeagc0 to Xi Pi. Cents with FT0C", false); + + void processMcOmegacToXiPiWithDCAFitterCentFT0M(aod::HfCandToXiPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Ms const& mcCollisions, + McCollisionsFT0Ms const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToXiPiFT0m, "Run Omegac0 to xi pi MC process function - FT0M", false); - - void processMcOmegacToXiPiFT0c(aod::HfCandToXiPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToXiPiWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Omegac0 to Xi Pi. Cents with FT0M", false); + + //~~~~~~~~~~~~~~~~~~~// + //~~~~To Omega Pi~~~~// + //~~~~~~~~~~~~~~~~~~~// + void processMcOmegacToOmegaPiWithDCAFitterNoCent(aod::HfCandToOmegaPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToXiPiFT0c, "Run Omegac0 to xi pi MC process function - FT0C", false); - - void processMcOmegacToOmegaPi(aod::HfCandToOmegaPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaPiWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Pi. No cents", false); + + void processMcOmegacToOmegaPiWithDCAFitterCentFT0C(aod::HfCandToOmegaPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsFT0Cs const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToOmegaPi, "Run Omegac0 to omega pi MC process function - no centrality", false); - - void processMcOmegacToOmegaPiFT0m(aod::HfCandToOmegaPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcColls, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaPiWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Pi. Cents with FT0C", false); + + void processMcOmegacToOmegaPiWithDCAFitterCentFT0M(aod::HfCandToOmegaPi const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Ms const& mcCollisions, + McCollisionsFT0Ms const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToOmegaPiFT0m, "Run Omegac0 to omega pi MC process function - FT0M", false); - - void processMcOmegacToOmegaPiFT0c(aod::HfCandToOmegaPi const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaPiWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Pi. Cents with FT0M", false); + + //~~~~~~~~~~~~~~~~~~// + //~~~~To Omega Ka~~~~// + //~~~~~~~~~~~~~~~~~~// + void processMcOmegacToOmegaKaWithDCAFitterNoCent(aod::HfCandToOmegaK const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToOmegaPiFT0c, "Run Omegac0 to omega pi MC process function - FT0C", false); - - void processMcOmegacToOmegaK(aod::HfCandToOmegaK const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsNoCents const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaKaWithDCAFitterNoCent, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Ka. No cents", false); + + void processMcOmegacToOmegaKaWithDCAFitterCentFT0C(aod::HfCandToOmegaK const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsFT0Cs const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToOmegaK, "Run Omegac0 to omega K MC process function - no centrality", false); - - void processMcOmegacToOmegaKFT0m(aod::HfCandToOmegaK const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - McCollisionsCentFT0Ms const& mcColls, - McCollisionsFT0Ms const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaKaWithDCAFitterCentFT0C, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Ka. Cents with FT0C", false); + + void processMcOmegacToOmegaKaWithDCAFitterCentFT0M(aod::HfCandToOmegaK const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Ms const& mcCollisions, + McCollisionsFT0Ms const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToOmegaKFT0m, "Run Omegac0 to omega K MC process function - FT0M", false); - - void processMcOmegacToOmegaKFT0c(aod::HfCandToOmegaK const& candidates, - MyTracksWMc const& tracks, - aod::McParticles const& mcParticles, - aod::McCollisions const& mcColls, - McCollisionsFT0Cs const& collsWithMcLabels, - BCsInfo const& bcs) + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcOmegacToOmegaKaWithDCAFitterCentFT0M, "Perform MC matching of DCAFitter reconstructed Omegac0 to Omega Ka. Cents with FT0M", false); + + ///////////////////////////////////////////////////// + /// /// + /// Process functions with KFParticle /// + /// /// + ///////////////////////////////////////////////////// + void processMcXicToXiPiWithKFParticleNoCent(aod::HfCandToXiPiKf const& candidates, + aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsNoCents const& collsWithMcLabels, + BCsInfo const& bcs) { - runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcColls, bcs); + runXic0Omegac0Mc(candidates, tracks, mcParticles, collsWithMcLabels, mcCollisions, bcs); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcOmegacToOmegaKFT0c, "Run Omegac0 to omega K MC process function - FT0C", false); - -}; // close struct + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0QaMc, processMcXicToXiPiWithKFParticleNoCent, "Perform MC matching of DCAFitter reconstructed Xic0 to Xi Pi. No cents", false); +}; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/PWGHF/TableProducer/candidateSelectorToXiPi.cxx b/PWGHF/TableProducer/candidateSelectorToXiPi.cxx index 4372e3cb40a..9209daed4b5 100644 --- a/PWGHF/TableProducer/candidateSelectorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorToXiPi.cxx @@ -9,10 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file candidateSelectorToXiPi.cxx -/// \brief Xic0 and Omegac0 → Xi Pi selection task -/// \author Federica Zanone , Heidelberg University - +/// \file candidateSelectorToXiPiQa.cxx +/// \brief Selection of Xic0 and Xicp candidates +/// +/// \author Jinhyun Park , Pusan National University +/// \author Krista Smith , Pusan National University + +#include "PWGHF/Core/HfMlResponseXic0ToXiPiKf.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" @@ -38,6 +42,10 @@ #include #include +#include +#include + +// Related to ML using namespace o2; using namespace o2::aod; @@ -52,48 +60,36 @@ enum PidInfoStored { }; /// Struct for applying Omegac0/Xic0 selection cuts -struct HfCandidateSelectorToXiPi { +struct HfCandidateSelectorToXiPiQa { + + // DCAFitter Produces hfSelToXiPi; + // KFParticle + Produces hfSelToXiPiKf; + Produces hfMlToXiPiKf; + + // cuts from SelectorCuts.h + Configurable> binsPt{"binsPt", std::vector{hf_cuts_to_xi_pi::vecBinsPt}, "pT bin limits"}; + Configurable> cuts{"cuts", {hf_cuts_to_xi_pi::Cuts[0], hf_cuts_to_xi_pi::NBinsPt, hf_cuts_to_xi_pi::NCutVars, hf_cuts_to_xi_pi::labelsPt, hf_cuts_to_xi_pi::labelsCutVar}, "Xic0 candidate selection per Pt Bin"}; + + // ML inference + Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; + Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + + // CCDB configuration + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTXic0ToXipiKf"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_Xic0ToXipiKf.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; // LF analysis selections - Configurable radiusCascMin{"radiusCascMin", 0.6, "Min cascade radius"}; - Configurable radiusV0Min{"radiusV0Min", 1.2, "Min V0 radius"}; - Configurable cosPAV0Min{"cosPAV0Min", 0.97, "Min valueCosPA V0"}; - Configurable cosPACascMin{"cosPACascMin", 0.97, "Min value CosPA cascade"}; - Configurable dcaCascDauMax{"dcaCascDauMax", 1.0, "Max DCA cascade daughters"}; - Configurable dcaV0DauMax{"dcaV0DauMax", 1.0, "Max DCA V0 daughters"}; - Configurable dcaBachToPvMin{"dcaBachToPvMin", 0.04, "DCA Bach To PV"}; - Configurable dcaNegToPvMin{"dcaNegToPvMin", 0.06, "DCA Neg To PV"}; - Configurable dcaPosToPvMin{"dcaPosToPvMin", 0.06, "DCA Pos To PV"}; - Configurable v0MassWindow{"v0MassWindow", 0.01, "V0 mass window"}; - Configurable cascadeMassWindow{"cascadeMassWindow", 0.01, "Cascade mass window"}; Configurable applyTrkSelLf{"applyTrkSelLf", true, "Apply track selection for LF daughters"}; - // limit charm baryon invariant mass spectrum - Configurable invMassCharmBaryonMin{"invMassCharmBaryonMin", 2.0, "Lower limit invariant mass spectrum charm baryon"}; // 2.4 Omegac0 only - Configurable invMassCharmBaryonMax{"invMassCharmBaryonMax", 3.1, "Upper limit invariant mass spectrum charm baryon"}; - - // kinematic selections - Configurable etaTrackCharmBachMax{"etaTrackCharmBachMax", 0.8, "Max absolute value of eta for charm baryon bachelor"}; - Configurable etaTrackLFDauMax{"etaTrackLFDauMax", 1.0, "Max absolute value of eta for V0 and cascade daughters"}; - Configurable ptPiFromCascMin{"ptPiFromCascMin", 0.15, "Min pT pi <- casc"}; - Configurable ptPiFromCharmBaryonMin{"ptPiFromCharmBaryonMin", 0.2, "Min pT pi <- charm baryon"}; - - Configurable impactParameterXYPiFromCharmBaryonMin{"impactParameterXYPiFromCharmBaryonMin", 0., "Min dcaxy pi from charm baryon track to PV"}; - Configurable impactParameterXYPiFromCharmBaryonMax{"impactParameterXYPiFromCharmBaryonMax", 10., "Max dcaxy pi from charm baryon track to PV"}; - Configurable impactParameterZPiFromCharmBaryonMin{"impactParameterZPiFromCharmBaryonMin", 0., "Min dcaz pi from charm baryon track to PV"}; - Configurable impactParameterZPiFromCharmBaryonMax{"impactParameterZPiFromCharmBaryonMax", 10., "Max dcaz pi from charm baryon track to PV"}; - - Configurable impactParameterXYCascMin{"impactParameterXYCascMin", 0., "Min dcaxy cascade track to PV"}; - Configurable impactParameterXYCascMax{"impactParameterXYCascMax", 10., "Max dcaxy cascade track to PV"}; - Configurable impactParameterZCascMin{"impactParameterZCascMin", 0., "Min dcaz cascade track to PV"}; - Configurable impactParameterZCascMax{"impactParameterZCascMax", 10., "Max dcaz cascade track to PV"}; - - Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; - Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; - - Configurable dcaCharmBaryonDauMax{"dcaCharmBaryonDauMax", 2.0, "Max DCA charm baryon daughters"}; - // PID options Configurable usePidTpcOnly{"usePidTpcOnly", false, "Perform PID using only TPC"}; Configurable usePidTpcTofCombined{"usePidTpcTofCombined", true, "Perform PID using TPC & TOF"}; @@ -129,16 +125,17 @@ struct HfCandidateSelectorToXiPi { Configurable nClustersItsInnBarrMin{"nClustersItsInnBarrMin", 1, "Minimum number of ITS clusters in inner barrel requirement for pi <- charm baryon"}; Configurable itsChi2PerClusterMax{"itsChi2PerClusterMax", 36, "Maximum value of chi2 fit over ITS clusters for pi <- charm baryon"}; + o2::analysis::HfMlResponseXic0ToXiPiKf hfMlResponse; + std::vector outputMlXic0ToXiPiKf = {}; + o2::ccdb::CcdbApi ccdbApi; + TrackSelectorPi selectorPion; TrackSelectorPr selectorProton; using TracksSel = soa::Join; - using TracksSelLf = soa::Join; HistogramRegistry registry{"registry"}; // for QA of selections - OutputObj hInvMassCharmBaryon{TH1F("hInvMassCharmBaryon", "Charm baryon invariant mass;inv mass;entries", 500, 2.2, 3.1)}; - void init(InitContext const&) { selectorPion.setRangePtTpc(ptPiPidTpcMin, ptPiPidTpcMax); @@ -189,13 +186,27 @@ struct HfCandidateSelectorToXiPi { registry.add("hSelMassCharmBaryon", "hSelMassCharmBaryon;status;entries", {HistType::kTH1F, {axisSel}}); registry.add("hSelDcaXYToPvV0Daughters", "hSelDcaXYToPvV0Daughters;status;entries", {HistType::kTH1F, {axisSel}}); registry.add("hSelDcaXYToPvPiFromCasc", "hSelDcaXYToPvPiFromCasc;status;entries", {HistType::kTH1F, {axisSel}}); + + // invarinat mass histograms + registry.add("hInvMassCharmBaryon", "Charm baryon invariant mass; int mass; entries", {HistType::kTH1F, {{1500, 1.5, 4.5}}}); + registry.add("hInvMassCharmBaryonBkg", "Charm baryon invariant mass, rejected; int mass; entries", {HistType::kTH1F, {{1500, 1.5, 4.5}}}); + + if (applyMl) { + hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } } - void process(aod::HfCandToXiPi const& candidates, - TracksSel const& tracks, - TracksSelLf const& lfTracks) + template + void runSelection(TCandTable const& candidates, TracksSel const&) { - double massLambdaFromPDG = o2::constants::physics::MassLambda0; double massXiFromPDG = o2::constants::physics::MassXiMinus; @@ -204,14 +215,10 @@ struct HfCandidateSelectorToXiPi { bool resultSelections = true; // True if the candidate passes all the selections, False otherwise - auto trackV0PosDauId = candidate.posTrackId(); // positive V0 daughter - auto trackV0NegDauId = candidate.negTrackId(); // negative V0 daughter - auto trackPiFromCascId = candidate.bachelorId(); // pion <- cascade - auto trackPiFromCharmId = candidate.bachelorFromCharmBaryonId(); // pion <- charm baryon - auto trackV0PosDau = lfTracks.rawIteratorAt(trackV0PosDauId); - auto trackV0NegDau = lfTracks.rawIteratorAt(trackV0NegDauId); - auto trackPiFromCasc = lfTracks.rawIteratorAt(trackPiFromCascId); - auto trackPiFromCharm = tracks.rawIteratorAt(trackPiFromCharmId); + auto trackV0PosDau = candidate.template posTrack_as(); + auto trackV0NegDau = candidate.template negTrack_as(); + auto trackPiFromCasc = candidate.template bachelor_as(); + auto trackPiFromCharm = candidate.template bachelorFromCharmBaryon_as(); auto trackPiFromLam = trackV0NegDau; auto trackPrFromLam = trackV0PosDau; @@ -226,30 +233,38 @@ struct HfCandidateSelectorToXiPi { registry.fill(HIST("hSelSignDec"), 0); // particle decay } + // pT selection + auto ptCandXic0 = RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()); + int pTBin = findBin(binsPt, ptCandXic0); + if (pTBin == -1) { + resultSelections = false; + continue; + } + // eta selection double etaV0PosDau = candidate.etaV0PosDau(); double etaV0NegDau = candidate.etaV0NegDau(); double etaPiFromCasc = candidate.etaBachFromCasc(); double etaPiFromCharmBaryon = candidate.etaBachFromCharmBaryon(); - if (std::abs(etaV0PosDau) > etaTrackLFDauMax) { + if (std::abs(etaV0PosDau) > cuts->get(pTBin, "etaTrackLFDauMax")) { resultSelections = false; registry.fill(HIST("hSelEtaPosV0Dau"), 0); } else { registry.fill(HIST("hSelEtaPosV0Dau"), 1); } - if (std::abs(etaV0NegDau) > etaTrackLFDauMax) { + if (std::abs(etaV0NegDau) > cuts->get(pTBin, "etaTrackLFDauMax")) { resultSelections = false; registry.fill(HIST("hSelEtaNegV0Dau"), 0); } else { registry.fill(HIST("hSelEtaNegV0Dau"), 1); } - if (std::abs(etaPiFromCasc) > etaTrackLFDauMax) { + if (std::abs(etaPiFromCasc) > cuts->get(pTBin, "etaTrackLFDauMax")) { resultSelections = false; registry.fill(HIST("hSelEtaPiFromCasc"), 0); } else { registry.fill(HIST("hSelEtaPiFromCasc"), 1); } - if (std::abs(etaPiFromCharmBaryon) > etaTrackCharmBachMax) { + if (std::abs(etaPiFromCharmBaryon) > cuts->get(pTBin, "etaTrackCharmBachMax")) { resultSelections = false; registry.fill(HIST("hSelEtaPiFromCharm"), 0); } else { @@ -257,13 +272,13 @@ struct HfCandidateSelectorToXiPi { } // minimum radius cut (LFcut) - if (RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxCascade(), candidate.yDecayVtxCascade()) < radiusCascMin) { + if (RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxCascade(), candidate.yDecayVtxCascade()) < cuts->get(pTBin, "radiusCascMin")) { resultSelections = false; registry.fill(HIST("hSelRadCasc"), 0); } else { registry.fill(HIST("hSelRadCasc"), 1); } - if (RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxV0(), candidate.yDecayVtxV0()) < radiusV0Min) { + if (RecoDecay::sqrtSumOfSquares(candidate.xDecayVtxV0(), candidate.yDecayVtxV0()) < cuts->get(pTBin, "radiusV0Min")) { resultSelections = false; registry.fill(HIST("hSelRadV0"), 0); } else { @@ -271,13 +286,13 @@ struct HfCandidateSelectorToXiPi { } // cosPA (LFcut) - if (candidate.cosPACasc() < cosPACascMin) { + if (candidate.cosPACasc() < cuts->get(pTBin, "cosPaCascMin")) { resultSelections = false; registry.fill(HIST("hSelCosPACasc"), 0); } else { registry.fill(HIST("hSelCosPACasc"), 1); } - if (candidate.cosPAV0() < cosPAV0Min) { + if (candidate.cosPAV0() < cuts->get(pTBin, "cosPaV0Min")) { resultSelections = false; registry.fill(HIST("hSelCosPAV0"), 0); } else { @@ -285,14 +300,14 @@ struct HfCandidateSelectorToXiPi { } // cascade and v0 daughters dca cut (LF cut) - if (candidate.dcaCascDau() > dcaCascDauMax) { + if (candidate.dcaCascDau() > cuts->get(pTBin, "dcaCascDauMax")) { resultSelections = false; registry.fill(HIST("hSelDCACascDau"), 0); } else { registry.fill(HIST("hSelDCACascDau"), 1); } - if (candidate.dcaV0Dau() > dcaV0DauMax) { + if (candidate.dcaV0Dau() > cuts->get(pTBin, "dcaV0DauMax")) { resultSelections = false; registry.fill(HIST("hSelDCAV0Dau"), 0); } else { @@ -300,7 +315,7 @@ struct HfCandidateSelectorToXiPi { } // dca charm baryon daughters cut - if (candidate.dcaCharmBaryonDau() > dcaCharmBaryonDauMax) { + if (candidate.dcaCharmBaryonDau() > cuts->get(pTBin, "dcaCharmBaryonDauMax")) { resultSelections = false; registry.fill(HIST("hSelDCACharmDau"), 0); } else { @@ -308,7 +323,7 @@ struct HfCandidateSelectorToXiPi { } // dcaXY v0 daughters to PV cut - if (std::abs(candidate.dcaXYToPvV0Dau0()) < dcaPosToPvMin || std::abs(candidate.dcaXYToPvV0Dau1()) < dcaNegToPvMin) { + if (std::abs(candidate.dcaXYToPvV0Dau0()) < cuts->get(pTBin, "dcaxyV0PosDauToPvMin") || std::abs(candidate.dcaXYToPvV0Dau1()) < cuts->get(pTBin, "dcaxyV0NegDauToPvMin")) { resultSelections = false; registry.fill(HIST("hSelDcaXYToPvV0Daughters"), 0); } else { @@ -316,51 +331,51 @@ struct HfCandidateSelectorToXiPi { } // dcaXY pi <-- cascade to PV cut - if (std::abs(candidate.dcaXYToPvCascDau()) < dcaBachToPvMin) { + if (std::abs(candidate.dcaXYToPvCascDau()) < cuts->get(pTBin, "dcaxyBachToPvMin")) { resultSelections = false; registry.fill(HIST("hSelDcaXYToPvPiFromCasc"), 0); } else { registry.fill(HIST("hSelDcaXYToPvPiFromCasc"), 1); } - // cut on charm bachelor pion dcaXY and dcaZ - if ((std::abs(candidate.impactParBachFromCharmBaryonXY()) < impactParameterXYPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonXY()) > impactParameterXYPiFromCharmBaryonMax)) { - resultSelections = false; - registry.fill(HIST("hSelDCAXYPrimPi"), 0); - } else { - registry.fill(HIST("hSelDCAXYPrimPi"), 1); - } - if ((std::abs(candidate.impactParBachFromCharmBaryonZ()) < impactParameterZPiFromCharmBaryonMin) || (std::abs(candidate.impactParBachFromCharmBaryonZ()) > impactParameterZPiFromCharmBaryonMax)) { - resultSelections = false; - registry.fill(HIST("hSelDCAZPrimPi"), 0); - } else { - registry.fill(HIST("hSelDCAZPrimPi"), 1); - } - - // cut on cascade dcaXY and dcaZ - if ((std::abs(candidate.impactParCascXY()) < impactParameterXYCascMin) || (std::abs(candidate.impactParCascXY()) > impactParameterXYCascMax)) { - resultSelections = false; - registry.fill(HIST("hSelDCAXYCasc"), 0); - } else { - registry.fill(HIST("hSelDCAXYCasc"), 1); - } - if ((std::abs(candidate.impactParCascZ()) < impactParameterZCascMin) || (std::abs(candidate.impactParCascZ()) > impactParameterZCascMax)) { - resultSelections = false; - registry.fill(HIST("hSelDCAZCasc"), 0); - } else { - registry.fill(HIST("hSelDCAZCasc"), 1); - } + // // cut on charm bachelor pion dcaXY and dcaZ + // if ((std::abs(candidate.impactParBachFromCharmBaryonXY()) < cuts->get(pTBin, "impactParXYCharmBachelorMin")) || (std::abs(candidate.impactParBachFromCharmBaryonXY()) > cuts->get(pTBin, "impactParXYCharmBachelorMax"))) { + // resultSelections = false; + // registry.fill(HIST("hSelDCAXYPrimPi"), 0); + // } else { + // registry.fill(HIST("hSelDCAXYPrimPi"), 1); + // } + // if ((std::abs(candidate.impactParBachFromCharmBaryonZ()) < cuts->get(pTBin, "impactParZCharmBachelorMin")) || (std::abs(candidate.impactParBachFromCharmBaryonZ()) > cuts->get(pTBin, "impactParZCharmBachelorMax"))) { + // resultSelections = false; + // registry.fill(HIST("hSelDCAZPrimPi"), 0); + // } else { + // registry.fill(HIST("hSelDCAZPrimPi"), 1); + // } + + // // cut on cascade dcaXY and dcaZ + // if ((std::abs(candidate.impactParCascXY()) < cuts->get(pTBin, "impactParXYCascMin")) || (std::abs(candidate.impactParCascXY()) > cuts->get(pTBin, "impactParXYCascMax"))) { + // resultSelections = false; + // registry.fill(HIST("hSelDCAXYCasc"), 0); + // } else { + // registry.fill(HIST("hSelDCAXYCasc"), 1); + // } + // if ((std::abs(candidate.impactParCascZ()) < cuts->get(pTBin, "impactParZCascMin")) || (std::abs(candidate.impactParCascZ()) > cuts->get(pTBin, "impactParZCascMax"))) { + // resultSelections = false; + // registry.fill(HIST("hSelDCAZCasc"), 0); + // } else { + // registry.fill(HIST("hSelDCAZCasc"), 1); + // } // pT selections double ptPiFromCasc = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCasc(), candidate.pyBachFromCasc()); double ptPiFromCharmBaryon = RecoDecay::sqrtSumOfSquares(candidate.pxBachFromCharmBaryon(), candidate.pyBachFromCharmBaryon()); - if (std::abs(ptPiFromCasc) < ptPiFromCascMin) { + if (std::abs(ptPiFromCasc) < cuts->get(pTBin, "ptBachelorMin")) { resultSelections = false; registry.fill(HIST("hSelPtPiFromCasc"), 0); } else { registry.fill(HIST("hSelPtPiFromCasc"), 1); } - if (std::abs(ptPiFromCharmBaryon) < ptPiFromCharmBaryonMin) { + if (std::abs(ptPiFromCharmBaryon) < cuts->get(pTBin, "ptCharmBachelorMin")) { resultSelections = false; registry.fill(HIST("hSelPtPiFromCharm"), 0); } else { @@ -489,7 +504,7 @@ struct HfCandidateSelectorToXiPi { double invMassCascade = candidate.invMassCascade(); double invMassCharmBaryon = candidate.invMassCharmBaryon(); - if (std::abs(invMassLambda - massLambdaFromPDG) < v0MassWindow) { + if (std::abs(invMassLambda - massLambdaFromPDG) < cuts->get(pTBin, "massWindowV0")) { statusInvMassLambda = true; registry.fill(HIST("hSelMassLam"), 1); if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && resultSelections) { @@ -499,7 +514,7 @@ struct HfCandidateSelectorToXiPi { registry.fill(HIST("hSelMassLam"), 0); } - if (std::abs(invMassCascade - massXiFromPDG) < cascadeMassWindow) { + if (std::abs(invMassCascade - massXiFromPDG) < cuts->get(pTBin, "massWindowCascade")) { statusInvMassCascade = true; registry.fill(HIST("hSelMassCasc"), 1); if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && resultSelections) { @@ -509,7 +524,7 @@ struct HfCandidateSelectorToXiPi { registry.fill(HIST("hSelMassCasc"), 0); } - if ((invMassCharmBaryon >= invMassCharmBaryonMin) && (invMassCharmBaryon <= invMassCharmBaryonMax)) { + if ((invMassCharmBaryon >= cuts->get(pTBin, "mCharmBaryonMin")) && (invMassCharmBaryon <= cuts->get(pTBin, "mCharmBaryonMax"))) { statusInvMassCharmBaryon = true; registry.fill(HIST("hSelMassCharmBaryon"), 1); if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && statusInvMassCascade && resultSelections) { @@ -519,9 +534,34 @@ struct HfCandidateSelectorToXiPi { registry.fill(HIST("hSelMassCharmBaryon"), 0); } - hfSelToXiPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, - trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), - trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); + // Fill in selection result + if constexpr (dokf == false) { + hfSelToXiPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, + trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), + trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); + } else { + // ML selections -> Currently, no Ml for DCAFitter result is implemented + if (applyMl) { + bool isSelectedMlXic0 = false; + std::vector inputFeaturesXic0 = hfMlResponse.getInputFeatures(candidate, trackPiFromLam, trackPiFromCasc, trackPiFromCharm); + isSelectedMlXic0 = hfMlResponse.isSelectedMl(inputFeaturesXic0, ptCandXic0, outputMlXic0ToXiPiKf); + if (!isSelectedMlXic0) { + continue; + } + hfMlToXiPiKf(outputMlXic0ToXiPiKf); + } + + // Set result of selection to false if one of the statusPID or statusInvMass is false + // This is required because selection table for KF does not store any information about statusPID or statusInvMass while DCAFitter does. + if (!(statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassCharmBaryon && statusInvMassCascade && statusInvMassLambda)) { + resultSelections = false; + } + + hfSelToXiPiKf(resultSelections, + // statusPidCharmBaryon, statusPidCascade, statusPidLambda, statusInvMassCharmBaryon, statusInvMassCascade, statusInvMassLambda, infoTpcStored, infoTofStored, + trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), + trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); + } if (resultSelections) { if (!statusPidLambda) { @@ -562,15 +602,38 @@ struct HfCandidateSelectorToXiPi { } } + // Fill in invariant mass histogram if (statusPidLambda && statusPidCascade && statusPidCharmBaryon && statusInvMassLambda && statusInvMassCascade && statusInvMassCharmBaryon && resultSelections) { - hInvMassCharmBaryon->Fill(invMassCharmBaryon); + registry.fill(HIST("hInvMassCharmBaryon"), invMassCharmBaryon); + } else { + registry.fill(HIST("hInvMassCharmBaryonBkg"), invMassCharmBaryon); } - } - } // end process + + } // end of candidate loop + } // end run fuction + + /////////////////////////////////// + /// Process with DCAFitter // + /////////////////////////////////// + void processSelectionDCAFitter(aod::HfCandToXiPi const& candidates, TracksSel const& tracks) + { + runSelection(candidates, tracks); + } + PROCESS_SWITCH(HfCandidateSelectorToXiPiQa, processSelectionDCAFitter, "Xic0 candidate selection with DCAFitter output", true); + + //////////////////////////////////// + /// Process with KFParticle // + //////////////////////////////////// + void processSelectionKFParticle(aod::HfCandToXiPiKf const& candidates, TracksSel const& tracks) + { + runSelection(candidates, tracks); + } + PROCESS_SWITCH(HfCandidateSelectorToXiPiQa, processSelectionKFParticle, "Xic0 candidate selection with KFParticle output", false); + }; // end struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGHF/TableProducer/treeCreatorToXiPi.cxx b/PWGHF/TableProducer/treeCreatorToXiPi.cxx index 01e40cfb2c8..6df52b8d01e 100644 --- a/PWGHF/TableProducer/treeCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorToXiPi.cxx @@ -9,11 +9,12 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file treeCreatorToXiPi.cxx +/// \file treeCreatorToXiPiQa.cxx /// \brief Writer of the omegac0 or xic0 to Xi Pi candidates in the form of flat tables to be stored in TTrees. /// In this file are defined and filled the output tables /// -/// \author Federica Zanone , Heidelberg University +/// \author Jinhyun Park , Pusan National University +/// \author Krista Smith , Pusan National University #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -133,10 +134,51 @@ DECLARE_SOA_COLUMN(NTpcRowsPion, nTpcRowsPion, int16_t); DECLARE_SOA_COLUMN(NTpcRowsPiFromCasc, nTpcRowsPiFromCasc, int16_t); DECLARE_SOA_COLUMN(NTpcRowsPosV0Dau, nTpcRowsPosV0Dau, int16_t); DECLARE_SOA_COLUMN(NTpcRowsNegV0Dau, nTpcRowsNegV0Dau, int16_t); +// from creator KF +DECLARE_SOA_COLUMN(KfDcaXYPiFromXic, kfDcaXYPiFromXic, float); +DECLARE_SOA_COLUMN(KfDcaXYCascToPv, kfDcaXYCascToPv, float); +DECLARE_SOA_COLUMN(Chi2GeoV0, chi2GeoV0, float); +DECLARE_SOA_COLUMN(Chi2GeoCasc, chi2GeoCasc, float); +DECLARE_SOA_COLUMN(Chi2GeoXic, chi2GeoXic, float); +DECLARE_SOA_COLUMN(Chi2MassV0, chi2MassV0, float); +DECLARE_SOA_COLUMN(Chi2MassCasc, chi2MassCasc, float); +DECLARE_SOA_COLUMN(V0ldl, v0ldl, float); +DECLARE_SOA_COLUMN(Cascldl, cascldl, float); +DECLARE_SOA_COLUMN(Xicldl, xicldl, float); +DECLARE_SOA_COLUMN(Chi2TopoV0ToPv, chi2TopoV0ToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoCascToPv, chi2TopoCascToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoPiFromXicToPv, chi2TopoPiFromXicToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoXicToPv, chi2TopoXicToPv, float); +DECLARE_SOA_COLUMN(Chi2TopoV0ToCasc, chi2TopoV0ToCasc, float); +DECLARE_SOA_COLUMN(Chi2TopoCascToXic, chi2TopoCascToXic, float); +DECLARE_SOA_COLUMN(DecayLenXYLambda, decayLenXYLambda, float); +DECLARE_SOA_COLUMN(DecayLenXYCasc, decayLenXYCasc, float); +DECLARE_SOA_COLUMN(DecayLenXYXic, decayLenXYXic, float); +DECLARE_SOA_COLUMN(CosPaV0ToCasc, cosPaV0ToCasc, float); +DECLARE_SOA_COLUMN(CosPaV0ToPv, cosPaV0ToPv, float); +DECLARE_SOA_COLUMN(CosPaCascToXic, cosPaCascToXic, float); +DECLARE_SOA_COLUMN(CosPaCascToPv, cosPaCascToPv, float); +DECLARE_SOA_COLUMN(CosPaXicToPv, cosPaXicToPv, float); +DECLARE_SOA_COLUMN(KfRapXic, kfRapXic, float); +DECLARE_SOA_COLUMN(KfptPiFromXic, kfptPiFromXic, float); +DECLARE_SOA_COLUMN(KfptXic, kfptXic, float); +DECLARE_SOA_COLUMN(CosThetaStarPiFromXic, cosThetaStarPiFromXic, float); +DECLARE_SOA_COLUMN(CtXic, ctXic, float); +DECLARE_SOA_COLUMN(EtaXic, etaXic, float); +DECLARE_SOA_COLUMN(V0Ndf, v0Ndf, float); +DECLARE_SOA_COLUMN(CascNdf, cascNdf, float); +DECLARE_SOA_COLUMN(XicNdf, xicNdf, float); +DECLARE_SOA_COLUMN(MassV0Ndf, massV0Ndf, float); +DECLARE_SOA_COLUMN(MassCascNdf, massCascNdf, float); +DECLARE_SOA_COLUMN(V0Chi2OverNdf, v0Chi2OverNdf, float); +DECLARE_SOA_COLUMN(CascChi2OverNdf, cascChi2OverNdf, float); +DECLARE_SOA_COLUMN(XicChi2OverNdf, xicChi2OverNdf, float); +DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); +DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); // from creator - MC DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level -DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); +DECLARE_SOA_COLUMN(OriginRec, originRec, int8_t); DECLARE_SOA_COLUMN(CollisionMatched, collisionMatched, bool); // from selector DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); @@ -156,7 +198,6 @@ DECLARE_SOA_COLUMN(TofNSigmaPiFromCharmBaryon, tofNSigmaPiFromCharmBaryon, float DECLARE_SOA_COLUMN(TofNSigmaPiFromCasc, tofNSigmaPiFromCasc, float); DECLARE_SOA_COLUMN(TofNSigmaPiFromLambda, tofNSigmaPiFromLambda, float); DECLARE_SOA_COLUMN(TofNSigmaPrFromLambda, tofNSigmaPrFromLambda, float); - } // namespace full DECLARE_SOA_TABLE(HfToXiPiEvs, "AOD", "HFTOXIPIEV", @@ -191,10 +232,11 @@ DECLARE_SOA_TABLE(HfToXiPiFulls, "AOD", "HFTOXIPIFULL", full::NormImpParCascade, full::NormImpParPiFromCharmBar, full::NormDecayLenCharmBar, full::IsPionGlbTrkWoDca, full::PionItsNCls, full::NTpcRowsPion, full::NTpcRowsPiFromCasc, full::NTpcRowsPosV0Dau, full::NTpcRowsNegV0Dau, full::StatusPidLambda, full::StatusPidCascade, full::StatusPidCharmBaryon, - full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, full::ResultSelections, full::PidTpcInfoStored, full::PidTofInfoStored, + full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, full::ResultSelections, + full::PidTpcInfoStored, full::PidTofInfoStored, full::TpcNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TpcNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCasc, full::TofNSigmaPiFromLambda, full::TofNSigmaPrFromLambda, - full::FlagMcMatchRec, full::DebugMcRec, full::OriginMcRec, full::CollisionMatched); + full::FlagMcMatchRec, full::DebugMcRec, full::OriginRec, full::CollisionMatched); DECLARE_SOA_TABLE(HfToXiPiLites, "AOD", "HFTOXIPILITE", full::XPv, full::YPv, full::ZPv, full::Centrality, collision::NumContrib, collision::Chi2, @@ -216,23 +258,50 @@ DECLARE_SOA_TABLE(HfToXiPiLites, "AOD", "HFTOXIPILITE", full::ErrorDecayLengthCharmBaryon, full::NormImpParCascade, full::NormImpParPiFromCharmBar, full::IsPionGlbTrkWoDca, full::PionItsNCls, full::NTpcRowsPion, full::NTpcRowsPiFromCasc, full::NTpcRowsPosV0Dau, full::NTpcRowsNegV0Dau, + full::StatusPidLambda, full::StatusPidCascade, full::StatusPidCharmBaryon, + full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, full::ResultSelections, full::PidTpcInfoStored, full::PidTofInfoStored, full::TpcNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TpcNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCasc, full::TofNSigmaPiFromLambda, full::TofNSigmaPrFromLambda, - full::FlagMcMatchRec, full::OriginMcRec, full::CollisionMatched); + full::FlagMcMatchRec, full::OriginRec, full::CollisionMatched); + +DECLARE_SOA_TABLE(HfKfXicFulls, "AOD", "HFKFXICFULL", + full::Centrality, + // full::StatusPidLambda, full::StatusPidCascade, full::StatusPidCharmBaryon, + // full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, + full::ResultSelections, + full::TpcNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TofNSigmaPiFromCasc, + full::TpcNSigmaPiFromLambda, full::TofNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPrFromLambda, + full::KfDcaXYPiFromXic, full::DcaCascDau, full::DcaCharmBaryonDau, full::KfDcaXYCascToPv, + full::DcaXYToPvV0Dau0, full::DcaXYToPvV0Dau1, full::DcaXYToPvCascDau, + full::Chi2GeoV0, full::Chi2GeoCasc, full::Chi2GeoXic, + full::Chi2MassV0, full::Chi2MassCasc, + full::V0ldl, full::Cascldl, // full::Xicldl, + full::Chi2TopoV0ToPv, full::Chi2TopoCascToPv, full::Chi2TopoPiFromXicToPv, full::Chi2TopoXicToPv, + full::Chi2TopoV0ToCasc, full::Chi2TopoCascToXic, + full::DecayLenXYLambda, full::DecayLenXYCasc, full::DecayLenXYXic, + full::CosPaV0ToCasc, full::CosPaV0ToPv, full::CosPaCascToXic, full::CosPaCascToPv, // full::CosPaXicToPv, + full::InvMassLambda, full::InvMassCascade, full::InvMassCharmBaryon, + full::KfRapXic, // full::KfptPiFromXic, full::KfptXic, + full::CosThetaStarPiFromXic, full::CtXic, full::EtaXic, + full::V0Ndf, full::CascNdf, full::XicNdf, + full::MassV0Ndf, full::MassCascNdf, + full::V0Chi2OverNdf, full::CascChi2OverNdf, full::XicChi2OverNdf, + full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, + full::FlagMcMatchRec, full::DebugMcRec, full::OriginRec, full::CollisionMatched); } // namespace o2::aod /// Writes the full information in an output TTree -struct HfTreeCreatorToXiPi { +struct HfTreeCreatorToXiPiQa { Produces rowCandidateFull; Produces rowCandidateLite; + Produces rowKfCandidate; Produces rowEv; Configurable zPvCut{"zPvCut", 10., "Cut on absolute value of primary vertex z coordinate"}; - using Cents = soa::Join; using MyTrackTable = soa::Join; using MyEventTable = soa::Join; using MyEventTableWithFT0C = soa::Join; @@ -246,17 +315,23 @@ struct HfTreeCreatorToXiPi { } } + ////////////////////////////////////////////////////// + // // + // Fill functions to fill in the tables // + // // + ////////////////////////////////////////////////////// + template void fillEvent(const T& collision, float cutZPv) { - rowEv( - collision.sel8(), std::abs(collision.posZ()) < cutZPv); + rowEv(collision.sel8(), std::abs(collision.posZ()) < cutZPv); } template void fillCandidate(const T& candidate, int8_t flagMc, int8_t debugMc, int8_t originMc, bool collisionMatched) { + // Save all candidate information float centrality = -999.f; if constexpr (useCentrality) { auto const& collision = candidate.template collision_as(); @@ -379,88 +454,182 @@ struct HfTreeCreatorToXiPi { template void fillCandidateLite(const T& candidate, int8_t flagMc, int8_t originMc, bool collisionMatched) { - if (candidate.resultSelections() && candidate.statusPidCharmBaryon() && candidate.statusInvMassLambda() && candidate.statusInvMassCascade() && candidate.statusInvMassCharmBaryon()) { - - float centrality = -999.f; - if constexpr (useCentrality) { - auto const& collision = candidate.template collision_as(); - centrality = o2::hf_centrality::getCentralityColl(collision); - } - - rowCandidateLite( - candidate.xPv(), - candidate.yPv(), - candidate.zPv(), - centrality, - candidate.template collision_as().numContrib(), - candidate.template collision_as().chi2(), - candidate.xDecayVtxCharmBaryon(), - candidate.yDecayVtxCharmBaryon(), - candidate.zDecayVtxCharmBaryon(), - candidate.xDecayVtxCascade(), - candidate.yDecayVtxCascade(), - candidate.zDecayVtxCascade(), - candidate.xDecayVtxV0(), - candidate.yDecayVtxV0(), - candidate.zDecayVtxV0(), - candidate.signDecay(), - candidate.pxCharmBaryon(), - candidate.pyCharmBaryon(), - candidate.pzCharmBaryon(), - candidate.pxBachFromCharmBaryon(), - candidate.pyBachFromCharmBaryon(), - candidate.pzBachFromCharmBaryon(), - candidate.pxBachFromCasc(), - candidate.pyBachFromCasc(), - candidate.pzBachFromCasc(), - candidate.pxPosV0Dau(), - candidate.pyPosV0Dau(), - candidate.pzPosV0Dau(), - candidate.pxNegV0Dau(), - candidate.pyNegV0Dau(), - candidate.pzNegV0Dau(), - candidate.impactParCascXY(), - candidate.impactParBachFromCharmBaryonXY(), - candidate.errImpactParCascXY(), - candidate.errImpactParBachFromCharmBaryonXY(), - candidate.invMassLambda(), - candidate.invMassCascade(), - candidate.invMassCharmBaryon(), - candidate.etaV0PosDau(), - candidate.etaV0NegDau(), - candidate.etaBachFromCasc(), - candidate.etaBachFromCharmBaryon(), - candidate.dcaXYToPvV0Dau0(), - candidate.dcaXYToPvV0Dau1(), - candidate.dcaXYToPvCascDau(), - candidate.dcaCascDau(), - candidate.dcaV0Dau(), - candidate.dcaCharmBaryonDau(), - candidate.errorDecayLengthCharmBaryon(), - candidate.impactParCascXY() / candidate.errImpactParCascXY(), - candidate.impactParBachFromCharmBaryonXY() / candidate.errImpactParBachFromCharmBaryonXY(), - candidate.template bachelorFromCharmBaryon_as().isGlobalTrackWoDCA(), - candidate.template bachelorFromCharmBaryon_as().itsNCls(), - candidate.template bachelorFromCharmBaryon_as().tpcNClsCrossedRows(), - candidate.template bachelor_as().tpcNClsCrossedRows(), - candidate.template posTrack_as().tpcNClsCrossedRows(), - candidate.template negTrack_as().tpcNClsCrossedRows(), - candidate.pidTpcInfoStored(), - candidate.pidTofInfoStored(), - candidate.tpcNSigmaPiFromCharmBaryon(), - candidate.tpcNSigmaPiFromCasc(), - candidate.tpcNSigmaPiFromLambda(), - candidate.tpcNSigmaPrFromLambda(), - candidate.tofNSigmaPiFromCharmBaryon(), - candidate.tofNSigmaPiFromCasc(), - candidate.tofNSigmaPiFromLambda(), - candidate.tofNSigmaPrFromLambda(), - flagMc, - originMc, - collisionMatched); + float centrality = -999.f; + if constexpr (useCentrality) { + auto const& collision = candidate.template collision_as(); + centrality = o2::hf_centrality::getCentralityColl(collision); } + + rowCandidateLite( + candidate.xPv(), + candidate.yPv(), + candidate.zPv(), + centrality, + candidate.template collision_as().numContrib(), + candidate.template collision_as().chi2(), + candidate.xDecayVtxCharmBaryon(), + candidate.yDecayVtxCharmBaryon(), + candidate.zDecayVtxCharmBaryon(), + candidate.xDecayVtxCascade(), + candidate.yDecayVtxCascade(), + candidate.zDecayVtxCascade(), + candidate.xDecayVtxV0(), + candidate.yDecayVtxV0(), + candidate.zDecayVtxV0(), + candidate.signDecay(), + candidate.pxCharmBaryon(), + candidate.pyCharmBaryon(), + candidate.pzCharmBaryon(), + candidate.pxBachFromCharmBaryon(), + candidate.pyBachFromCharmBaryon(), + candidate.pzBachFromCharmBaryon(), + candidate.pxBachFromCasc(), + candidate.pyBachFromCasc(), + candidate.pzBachFromCasc(), + candidate.pxPosV0Dau(), + candidate.pyPosV0Dau(), + candidate.pzPosV0Dau(), + candidate.pxNegV0Dau(), + candidate.pyNegV0Dau(), + candidate.pzNegV0Dau(), + candidate.impactParCascXY(), + candidate.impactParBachFromCharmBaryonXY(), + candidate.errImpactParCascXY(), + candidate.errImpactParBachFromCharmBaryonXY(), + candidate.invMassLambda(), + candidate.invMassCascade(), + candidate.invMassCharmBaryon(), + candidate.etaV0PosDau(), + candidate.etaV0NegDau(), + candidate.etaBachFromCasc(), + candidate.etaBachFromCharmBaryon(), + candidate.dcaXYToPvV0Dau0(), + candidate.dcaXYToPvV0Dau1(), + candidate.dcaXYToPvCascDau(), + candidate.dcaCascDau(), + candidate.dcaV0Dau(), + candidate.dcaCharmBaryonDau(), + candidate.errorDecayLengthCharmBaryon(), + candidate.impactParCascXY() / candidate.errImpactParCascXY(), + candidate.impactParBachFromCharmBaryonXY() / candidate.errImpactParBachFromCharmBaryonXY(), + candidate.template bachelorFromCharmBaryon_as().isGlobalTrackWoDCA(), + candidate.template bachelorFromCharmBaryon_as().itsNCls(), + candidate.template bachelorFromCharmBaryon_as().tpcNClsCrossedRows(), + candidate.template bachelor_as().tpcNClsCrossedRows(), + candidate.template posTrack_as().tpcNClsCrossedRows(), + candidate.template negTrack_as().tpcNClsCrossedRows(), + candidate.statusPidLambda(), + candidate.statusPidCascade(), + candidate.statusPidCharmBaryon(), + candidate.statusInvMassLambda(), + candidate.statusInvMassCascade(), + candidate.statusInvMassCharmBaryon(), + candidate.resultSelections(), + candidate.pidTpcInfoStored(), + candidate.pidTofInfoStored(), + candidate.tpcNSigmaPiFromCharmBaryon(), + candidate.tpcNSigmaPiFromCasc(), + candidate.tpcNSigmaPiFromLambda(), + candidate.tpcNSigmaPrFromLambda(), + candidate.tofNSigmaPiFromCharmBaryon(), + candidate.tofNSigmaPiFromCasc(), + candidate.tofNSigmaPiFromLambda(), + candidate.tofNSigmaPrFromLambda(), + flagMc, + originMc, + collisionMatched); } + template + void fillKfCandidate(const T& candidate, int8_t flagMc, int8_t debugMc, int8_t originMc, bool collisionMatched) + { + float centrality = -999.f; + if constexpr (useCentrality) { + auto const& collision = candidate.template collision_as(); + centrality = o2::hf_centrality::getCentralityColl(collision); + } + + rowKfCandidate( + centrality, + // candidate.statusPidLambda(), + // candidate.statusPidCascade(), + // candidate.statusPidCharmBaryon(), + // candidate.statusInvMassLambda(), + // candidate.statusInvMassCascade(), + // candidate.statusInvMassCharmBaryon(), + candidate.resultSelections(), + candidate.tpcNSigmaPiFromCharmBaryon(), + candidate.tofNSigmaPiFromCharmBaryon(), + candidate.tpcNSigmaPiFromCasc(), + candidate.tofNSigmaPiFromCasc(), + candidate.tpcNSigmaPiFromLambda(), + candidate.tofNSigmaPiFromLambda(), + candidate.tpcNSigmaPrFromLambda(), + candidate.tofNSigmaPrFromLambda(), + candidate.kfDcaXYPiFromXic(), + candidate.dcaCascDau(), + candidate.dcaCharmBaryonDau(), + candidate.kfDcaXYCascToPv(), + candidate.dcaXYToPvV0Dau0(), + candidate.dcaXYToPvV0Dau1(), + candidate.dcaXYToPvCascDau(), + candidate.chi2GeoV0(), + candidate.chi2GeoCasc(), + candidate.chi2GeoXic(), + candidate.chi2MassV0(), + candidate.chi2MassCasc(), + candidate.v0ldl(), + candidate.cascldl(), + // candidate.xicldl(), + candidate.chi2TopoV0ToPv(), + candidate.chi2TopoCascToPv(), + candidate.chi2TopoPiFromXicToPv(), + candidate.chi2TopoXicToPv(), + candidate.chi2TopoV0ToCasc(), + candidate.chi2TopoCascToXic(), + candidate.decayLenXYLambda(), + candidate.decayLenXYCasc(), + candidate.decayLenXYXic(), + candidate.cosPaV0ToCasc(), + candidate.cosPAV0(), + candidate.cosPaCascToXic(), + candidate.cosPACasc(), + // candidate.cosPACharmBaryon(), + candidate.invMassLambda(), + candidate.invMassCascade(), + candidate.invMassCharmBaryon(), + candidate.kfRapXic(), + // candidate.kfptPiFromXic(), + // candidate.kfptXic(), + candidate.cosThetaStarPiFromXic(), + candidate.cTauXic(), + candidate.etaCharmBaryon(), + candidate.v0Ndf(), + candidate.cascNdf(), + candidate.xicNdf(), + candidate.massV0Ndf(), + candidate.massCascNdf(), + candidate.v0Chi2OverNdf(), + candidate.cascChi2OverNdf(), + candidate.xicChi2OverNdf(), + candidate.massV0Chi2OverNdf(), + candidate.massCascChi2OverNdf(), + flagMc, + debugMc, + originMc, + collisionMatched); + } + + //////////////////////////////////// + // // + // Process functions // + // // + //////////////////////////////////// + + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + //*~~~~~~~Data with DCAFitter~~~~~~~~*// + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + void processDataFull(MyEventTable const& collisions, MyTrackTable const&, soa::Join const& candidates) { @@ -476,10 +645,9 @@ struct HfTreeCreatorToXiPi { fillCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processDataFull, "Process data with full information w/o centrality", true); - void processMcFullXic0(MyEventTable const& collisions, MyTrackTable const&, - soa::Join const& candidates) + void processDataLite(MyEventTable const& collisions, MyTrackTable const&, + soa::Join const& candidates) { // Filling event properties rowEv.reserve(collisions.size()); @@ -488,49 +656,46 @@ struct HfTreeCreatorToXiPi { } // Filling candidate properties - rowCandidateFull.reserve(candidates.size()); + rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcFullXic0, "Process MC with full information for xic0 w/o centrality", false); - void processMcFullOmegac0(MyEventTable const& collisions, MyTrackTable const&, - soa::Join const& candidates) + void processDataLiteWithFT0M(MyEventTableWithFT0M const& collisions, MyTrackTable const&, + soa::Join const& candidates) { // Filling event properties rowEv.reserve(collisions.size()); for (const auto& collision : collisions) { - fillEvent(collision, zPvCut); + fillEvent(collision, zPvCut); } // Filling candidate properties - rowCandidateFull.reserve(candidates.size()); + rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcFullOmegac0, "Process MC with full information for omegac0", false); - void processDataLite(MyEventTable const& collisions, MyTrackTable const&, - soa::Join const& candidates) + void processDataLiteWithFT0C(MyEventTableWithFT0C const& collisions, MyTrackTable const&, + soa::Join const& candidates) { // Filling event properties rowEv.reserve(collisions.size()); for (const auto& collision : collisions) { - fillEvent(collision, zPvCut); + fillEvent(collision, zPvCut); } // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); + fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processDataLite, "Process data and produce lite table version", false); - void processDataLiteWithFT0M(MyEventTableWithFT0M const& collisions, MyTrackTable const&, - soa::Join const& candidates) + void processDataLiteWithNTracksPV(MyEventTableWithNTracksPV const& collisions, MyTrackTable const&, + soa::Join const& candidates) { // Filling event properties rowEv.reserve(collisions.size()); @@ -541,13 +706,37 @@ struct HfTreeCreatorToXiPi { // Filling candidate properties rowCandidateLite.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); + fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processDataLiteWithFT0M, "Process data and produce lite table version with FT0M", false); - void processDataLiteWithFT0C(MyEventTableWithFT0C const& collisions, MyTrackTable const&, - soa::Join const& candidates) + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processDataFull, "Process data with full information w/o centrality", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processDataLite, "Process data and produce lite table version", true); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processDataLiteWithFT0M, "Process data and produce lite table version with FT0M", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processDataLiteWithFT0C, "Process data and produce lite table version with FT0C", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processDataLiteWithNTracksPV, "Process data and produce lite table version with NTracksPV", false); + + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + //*~~~~~~~Data with KFParticle~~~~~~~~*// + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + void processKfData(MyEventTable const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + + void processKfDataWithFT0M(MyEventTableWithFT0M const& collisions, MyTrackTable const&, + soa::Join const& candidates) { // Filling event properties rowEv.reserve(collisions.size()); @@ -556,15 +745,14 @@ struct HfTreeCreatorToXiPi { } // Filling candidate properties - rowCandidateLite.reserve(candidates.size()); + rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processDataLiteWithFT0C, "Process data and produce lite table version with FT0C", false); - void processDataLiteWithNTracksPV(MyEventTableWithNTracksPV const& collisions, MyTrackTable const&, - soa::Join const& candidates) + void processKfDataWithFT0C(MyEventTableWithFT0C const& collisions, MyTrackTable const&, + soa::Join const& candidates) { // Filling event properties rowEv.reserve(collisions.size()); @@ -573,12 +761,67 @@ struct HfTreeCreatorToXiPi { } // Filling candidate properties - rowCandidateLite.reserve(candidates.size()); + rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillCandidateLite(candidate, -7, RecoDecay::OriginType::None, false); + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + + void processKfDataWithNTracksPV(MyEventTableWithNTracksPV const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfData, "Process KF data, no cent", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfDataWithFT0M, "Process KF data, with FT0M", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfDataWithFT0C, "Process KF data, with FT0C", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfDataWithNTracksPV, "Process KF data, with NTracksPV", false); + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + //*~~~~~~~MC with DCAFitter~~~~~~~~*// + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + + void processMcFullXic0(MyEventTable const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowCandidateFull.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + } + } + + void processMcFullOmegac0(MyEventTable const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowCandidateFull.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processDataLiteWithNTracksPV, "Process data and produce lite table version with NTracksPV", false); void processMcLiteXic0(MyEventTable const& collisions, MyTrackTable const&, soa::Join const& candidates) @@ -595,7 +838,6 @@ struct HfTreeCreatorToXiPi { fillCandidateLite(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcLiteXic0, "Process MC and produce lite table version for xic0", false); void processMcLiteXic0WithFT0C(MyEventTableWithFT0C const& collisions, MyTrackTable const&, soa::Join const& candidates) @@ -612,7 +854,6 @@ struct HfTreeCreatorToXiPi { fillCandidateLite(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcLiteXic0WithFT0C, "Process MC and produce lite table version for Xic0 with FT0C", false); void processMcLiteXic0WithFT0M(MyEventTableWithFT0M const& collisions, MyTrackTable const&, soa::Join const& candidates) @@ -629,7 +870,6 @@ struct HfTreeCreatorToXiPi { fillCandidateLite(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcLiteXic0WithFT0M, "Process MC and produce lite table version for Xic0 with FT0M", false); void processMcLiteXic0WithNTracksPV(MyEventTableWithNTracksPV const& collisions, MyTrackTable const&, soa::Join const& candidates) @@ -646,7 +886,6 @@ struct HfTreeCreatorToXiPi { fillCandidateLite(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcLiteXic0WithNTracksPV, "Process MC and produce lite table version for Xic0 with NTracksPV", false); void processMcLiteOmegac0(MyEventTable const& collisions, MyTrackTable const&, soa::Join const& candidates) @@ -663,12 +902,89 @@ struct HfTreeCreatorToXiPi { fillCandidateLite(candidate, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.collisionMatched()); } } - PROCESS_SWITCH(HfTreeCreatorToXiPi, processMcLiteOmegac0, "Process MC and produce lite table version for omegac0", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcFullXic0, "Process MC with full information for xic0 w/o centrality", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcFullOmegac0, "Process MC with full information for omegac0", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcLiteXic0, "Process MC and produce lite table version for xic0", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcLiteXic0WithFT0C, "Process MC and produce lite table version for Xic0 with FT0C", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcLiteXic0WithFT0M, "Process MC and produce lite table version for Xic0 with FT0M", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcLiteXic0WithNTracksPV, "Process MC and produce lite table version for Xic0 with NTracksPV", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processMcLiteOmegac0, "Process MC and produce lite table version for omegac0", false); + + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + //*~~~~~~~MC with KFParticle~~~~~~~~*// + //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*// + void processKfMcXic0(MyEventTable const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + } + } + + void processKfMcXic0WithFT0C(MyEventTableWithFT0C const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + } + } + + void processKfMcXic0WithFT0M(MyEventTableWithFT0M const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate properties + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + } + } + + void processKfMcXic0WithNTracksPV(MyEventTableWithNTracksPV const& collisions, MyTrackTable const&, + soa::Join const& candidates) + { + // Filling event properties + rowEv.reserve(collisions.size()); + for (const auto& collision : collisions) { + fillEvent(collision, zPvCut); + } + + // Filling candidate table + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originMcRec(), candidate.collisionMatched()); + } + } + + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfMcXic0, "Process MC with information for xic0", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfMcXic0WithFT0C, "Process MC with information for xic0 at FT0C", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfMcXic0WithFT0M, "Process MC with information for xic0 at FT0M", false); + PROCESS_SWITCH(HfTreeCreatorToXiPiQa, processKfMcXic0WithNTracksPV, "Process MC with information for xic0 at Ntrack", false); }; // end of struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; }