From d0998e0699bfe750bd36092ea31217496356c9f1 Mon Sep 17 00:00:00 2001 From: FDUEnrich Date: Thu, 28 May 2026 14:56:44 +0800 Subject: [PATCH 01/17] =?UTF-8?q?Add=20=CE=9Ec=C2=B1=20=E2=86=92=20=CE=9E?= =?UTF-8?q?=CF=80=CF=80=20+=20track=20FemtoDream=20producer=20and=20task?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend FemtoDerived with FDHfCand3ProngXic for cascade-specific columns, register charm-cascade-hadrons-track-femto-dream workflows, and add XiC+ mass lookup in femtoDreamUtils. Co-authored-by: Cursor --- PWGCF/DataModel/FemtoDerived.h | 11 +- PWGCF/FemtoDream/Core/femtoDreamUtils.h | 3 + PWGHF/HFC/TableProducer/CMakeLists.txt | 5 + ...ucerCharmCascadeHadronsTrackFemtoDream.cxx | 706 ++++++++++++++++++ PWGHF/HFC/Tasks/CMakeLists.txt | 5 + ...taskCharmCascadeHadronsTrackFemtoDream.cxx | 693 +++++++++++++++++ 6 files changed, 1422 insertions(+), 1 deletion(-) create mode 100644 PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx create mode 100644 PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 4f15d00a342..29fb493c4ca 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -258,7 +258,10 @@ DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int); //! Selection o DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron -DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! To select MC particle among charm hadrons, { DplusToPiKPi = 1, LcToPKPi = 17, DsToKKPi = 6, XicToPKPi = 21, N3ProngD = 2ecays }; +DECLARE_SOA_COLUMN(InvMassCharm, invMassCharm, float); //! Reconstructed invariant mass of charm hadron (e.g. invMassXicPlus for Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! To select MC particle among charm hadrons, { DplusToPiKPi = 1, LcToPKPi = 17, DsToKKPi = 6, XicToPKPi = 21, XicToXiPiPi = 1, N3ProngD = 2ecays }; DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); //! flag for reconstruction level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int); //! flag for generator level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int); //! swapping of the prongs order (0 for Lc -> pkpi, 1 for Lc -> pikp) @@ -416,6 +419,12 @@ DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store th fdhf::Phi, fdhf::Pt); +DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFCAND3PRONGXIC", //! Extension table for Ξc± → Ξππ candidates (aligned rows with FDHfCand3Prong) + o2::soa::Index<>, + fdhf::InvMassCharm, + fdhf::CascPosTrackId, + fdhf::CascNegTrackId); + DECLARE_SOA_TABLE(FDHfCand2Prong, "AOD", "FDHFCAND2PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index efc075671c1..48a045fa5c1 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -74,6 +74,9 @@ inline float getMass(int pdgCode) case o2::constants::physics::Pdg::kLambdaCPlus: mass = o2::constants::physics::MassLambdaCPlus; break; + case o2::constants::physics::Pdg::kXiCPlus: + mass = o2::constants::physics::MassXiCPlus; + break; case o2::constants::physics::Pdg::kDeuteron: mass = o2::constants::physics::MassDeuteron; break; diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index cee79035d78..87ad53ed01d 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -89,6 +89,11 @@ o2physics_add_dpl_workflow(producer-charm-hadrons-track-femto-dream PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(producer-charm-cascade-hadrons-track-femto-dream + SOURCES producerCharmCascadeHadronsTrackFemtoDream.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(producer-charm-hadrons-v0-femto-dream SOURCES producerCharmHadronsV0FemtoDream.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::EventFilteringUtils diff --git a/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx new file mode 100644 index 00000000000..3622ddf4676 --- /dev/null +++ b/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx @@ -0,0 +1,706 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file producerCharmCascadeHadronsTrackFemtoDream.cxx +/// \brief FemtoDream producer for Ξc± → Ξ∓ π± π± + associated track (e.g. π) +/// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch + +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfMlResponseXicToXiPiPi.h" +#include "PWGHF/Core/DecayChannelsLegacy.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/AliasTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/ZorroSummary.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::analysis; +using namespace o2::framework::expressions; +using namespace o2::analysis::femtoDream; +using namespace o2::hf_evsel; +using namespace o2::hf_centrality; +using namespace o2::aod::hf_cand_xic_to_xi_pi_pi; + +enum Event : uint8_t { + All = 0, + RejEveSel, + RejNoTracksAndCharm, + TrackSelected, + CharmSelected, + PairSelected +}; + +enum MlMode : uint8_t { + NoMl = 0, + FillMlFromSelector, + FillMlFromNewBDT +}; + +struct HfProducerCharmCascadeHadronsTrackFemtoDream { + + Produces outputCollision; + Produces rowMasks; + Produces rowCandCharm3Prong; + Produces rowCandCharm3ProngXic; + Produces rowCandMcCharmHad; + Produces rowCandCharmHadGen; + Produces outputPartsIndex; + Produces outputPartsTime; + Produces outputMcCollision; + Produces outputCollsMcLabels; + Produces outputParts; + Produces outputPartsMc; + Produces outputDebugParts; + Produces outputPartsMcLabels; + Produces outputDebugPartsMc; + Produces outputPartsExtMcLabels; + + struct : ConfigurableGroup { + 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)"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTXicToXiPiPi"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_XicToXiPiPi.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"}; + } ccdbCfg; + + struct : ConfigurableGroup { + Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; + 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"}; + } mlCfg; + + struct : ConfigurableGroup { + Configurable pTrackMethod1Max{"pTrackMethod1Max", 0.85f, "Kaon PID Method1 (TPC-only): maximum p (GeV/c)"}; + Configurable pTrackExcludeMin{"pTrackExcludeMin", 0.50f, "Kaon PID Method1: excluded p window minimum (GeV/c)"}; + Configurable pTrackExcludeMax{"pTrackExcludeMax", 0.65f, "Kaon PID Method1: excluded p window maximum (GeV/c)"}; + Configurable pTrackPiRejMin{"pTrackPiRejMin", 0.50f, "Kaon PID Method1: pion rejection active for p > this (GeV/c)"}; + Configurable pTrackElRejMin{"pTrackElRejMin", 0.30f, "Kaon PID Method1: electron rejection active for p > this (GeV/c)"}; + Configurable pTrackTightMin{"pTrackTightMin", 1.20f, "Kaon PID Method2 (TPC+TOF): tighten cuts for p > this (GeV/c)"}; + Configurable nSigmaTpcKaMax{"nSigmaTpcKaMax", 3.f, "Kaon PID Method1: require |nSigmaTpcKa| < this"}; + Configurable nSigmaTpcPiMin{"nSigmaTpcPiMin", 3.f, "Kaon PID Method1: require |nSigmaTpcPi| > this (pion)"}; + Configurable nSigmaTpcElMin{"nSigmaTpcElMin", 3.f, "Kaon PID Method1: require |nSigmaTpcEl| > this (electron)"}; + Configurable nSigmaCombKaMax{"nSigmaCombKaMax", 3.f, "Kaon PID Method2: require |nSigmaCombKa| < this"}; + Configurable nSigmaCombKaTightMax{"nSigmaCombKaTightMax", 2.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombKa| < this"}; + Configurable nSigmaCombPiMax{"nSigmaCombPiMax", 6.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombPi| < this"}; + } kaonPidSel; + + Configurable isDebug{"isDebug", true, "Enable Debug tables"}; + Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection flag for Ξc± → Ξππ (same bit mask as hf_sel_candidate_xic::isSelXicToXiPiPi)"}; + Configurable useCent{"useCent", false, "Enable centrality for charm hadron"}; + + Configurable trkPDGCode{"trkPDGCode", kPiPlus, "PDG code of the associated track for MC truth and PID (default: π)"}; + Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; + Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; + Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; + Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; + Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; + Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; + Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; + Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; + Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; + Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.15f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; + Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; + Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; + Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; + Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; + Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; + Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; + + FemtoDreamTrackSelection trackCuts; + o2::analysis::HfMlResponseXicToXiPiPi hfMlResponseXic; + std::vector outputMlXic; + o2::ccdb::CcdbApi ccdbApi; + o2::hf_evsel::HfEventSelection hfEvSel; + Service ccdb{}; + o2::base::MatLayerCylSet* lut{}; + + float magField{}; + int runNumber{}; + + using CandidateXic = soa::Join; + using CandidateXicMc = soa::Join; + using CandidateXicKf = soa::Join; + using CandidateXicKfMc = soa::Join; + + using FemtoFullCollision = soa::Join::iterator; + using FemtoFullCollisionMc = soa::Join::iterator; + using FemtoHFTracks = soa::Join; + using FemtoHFMcTracks = soa::Join; + using GeneratedXicMc = soa::Join; + + Filter filterSelectCandidateXic = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= selectionFlagHadron; + + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; + OutputObj zorroSummary{"zorroSummary"}; + + void init(InitContext&) + { + std::array processes = {doprocessDataXicToXiPiPi, doprocessDataXicToXiPiPiKf, + doprocessDataXicToXiPiPiWithML, doprocessDataXicToXiPiPiWithMLKf, + doprocessMcXicToXiPiPi, doprocessMcXicToXiPiPiKf, + doprocessMcXicToXiPiPiWithML, doprocessMcXicToXiPiPiWithMLKf, + doprocessMcXicToXiPiPiGen}; + if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { + LOGP(fatal, "One and only one process function must be enabled at a time."); + } + + int const cutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); + trackRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{cutBits + 1, -0.5, cutBits + 0.5}}); + + constexpr int kEventTypes = PairSelected + 1; + std::string labels[kEventTypes]; + labels[Event::All] = "All events"; + labels[Event::RejEveSel] = "rejected by event selection"; + labels[Event::RejNoTracksAndCharm] = "rejected by no tracks and charm"; + labels[Event::TrackSelected] = "with tracks "; + labels[Event::CharmSelected] = "with charm hadrons "; + labels[Event::PairSelected] = "with pairs"; + + static const AxisSpec axisEvents = {kEventTypes, 0.5, kEventTypes + 0.5, ""}; + qaRegistry.add("hEventQA", "Events;;entries", HistType::kTH1F, {axisEvents}); + for (int iBin = 0; iBin < kEventTypes; iBin++) { + qaRegistry.get(HIST("hEventQA"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + + trackCuts.setSelection(trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + trackCuts.setSelection(trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setPIDSpecies(trkPIDspecies); + trackCuts.setnSigmaPIDOffset(trkPIDnSigmaOffsetTPC, trkPIDnSigmaOffsetTOF); + trackCuts.init(&qaRegistry, &trackRegistry); + + runNumber = 0; + magField = 0.f; + ccdb->setURL(ccdbCfg.ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + hfEvSel.init(qaRegistry, &zorroSummary); + + int64_t const now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + bool useXicMl = doprocessDataXicToXiPiPiWithML || doprocessMcXicToXiPiPiWithML || doprocessDataXicToXiPiPiWithMLKf || doprocessMcXicToXiPiPiWithMLKf; + if (mlCfg.applyMlMode == FillMlFromNewBDT && useXicMl) { + hfMlResponseXic.configure(mlCfg.binsPtMl, mlCfg.cutsMl, mlCfg.cutDirMl, mlCfg.nClassesMl); + hfMlResponseXic.cacheInputFeaturesIndices(mlCfg.namesInputFeatures); + if (ccdbCfg.loadModelsFromCCDB) { + ccdbApi.init(ccdbCfg.ccdbUrl); + hfMlResponseXic.setModelPathsCCDB(ccdbCfg.onnxFileNames, ccdbApi, ccdbCfg.modelPathsCCDB, ccdbCfg.timestampCCDB); + } else { + hfMlResponseXic.setModelPathsLocal(ccdbCfg.onnxFileNames); + } + hfMlResponseXic.init(); + } + } + + void getMagneticFieldTesla(const aod::BCsWithTimestamps::iterator& bc) + { + initCCDB(bc, runNumber, ccdb, !isRun3 ? ccdbCfg.ccdbPathGrp : ccdbCfg.ccdbPathGrpMag, lut, !isRun3); + } + + template + void fillDebugParticle(ParticleType const& particle) + { + outputDebugParts(particle.sign(), + (uint8_t)particle.tpcNClsFound(), + particle.tpcNClsFindable(), + (uint8_t)particle.tpcNClsCrossedRows(), + particle.tpcNClsShared(), + particle.tpcInnerParam(), + particle.itsNCls(), + particle.itsNClsInnerBarrel(), + particle.dcaXY(), + particle.dcaZ(), + particle.tpcSignal(), + -999., + particle.tpcNSigmaPi(), + particle.tpcNSigmaKa(), + particle.tpcNSigmaPr(), + particle.tpcNSigmaDe(), + -999., + -999., + -999., + particle.tofNSigmaPi(), + particle.tofNSigmaKa(), + particle.tofNSigmaPr(), + particle.tofNSigmaDe(), + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999.); + } + + template + void fillMcParticle(CollisionType const& col, ParticleType const& particle, o2::aod::femtodreamparticle::ParticleType fdparttype) + { + if (particle.has_mcParticle()) { + auto particleMc = particle.mcParticle(); + auto pdgCode = particleMc.pdgCode(); + int particleOrigin = 99; + int pdgCodeMother = -1; + constexpr int GenFromTransport = -1; + auto motherparticlesMc = particleMc.template mothers_as(); + if (std::abs(pdgCode) == std::abs(trkPDGCode.value)) { + if ((col.has_mcCollision() && (particleMc.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { + particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kWrongCollision; + } else if (particleMc.isPhysicalPrimary()) { + particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; + } else if (particleMc.getProcess() == TMCProcess::kPDecay && particleMc.getGenStatusCode() == GenFromTransport && !motherparticlesMc.empty()) { + auto motherparticleMc = motherparticlesMc.front(); + pdgCodeMother = motherparticleMc.pdgCode(); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + } else if (particleMc.getProcess() == TMCProcess::kPHInhelastic && particleMc.getGenStatusCode() == GenFromTransport) { + particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; + } else { + particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kElse; + } + } else { + particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; + } + + outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); + outputPartsMcLabels(outputPartsMc.lastIndex()); + if (isDebug) { + outputPartsExtMcLabels(outputPartsMc.lastIndex()); + outputDebugPartsMc(pdgCodeMother); + } + } else { + outputPartsMcLabels(-1); + if (isDebug) { + outputPartsExtMcLabels(-1); + } + } + } + + template + bool isTrackKaonPidSelected(const TrackType& track) + { + const float pTrack = track.p(); + + bool isTrackKaonPidMethod1 = true; + if (pTrack >= kaonPidSel.pTrackMethod1Max) { + isTrackKaonPidMethod1 = false; + } + if (std::abs(track.tpcNSigmaKa()) >= kaonPidSel.nSigmaTpcKaMax) { + isTrackKaonPidMethod1 = false; + } + if (pTrack >= kaonPidSel.pTrackExcludeMin && pTrack <= kaonPidSel.pTrackExcludeMax) { + isTrackKaonPidMethod1 = false; + } + if (pTrack > kaonPidSel.pTrackPiRejMin && std::abs(track.tpcNSigmaPi()) <= kaonPidSel.nSigmaTpcPiMin) { + isTrackKaonPidMethod1 = false; + } + if (pTrack > kaonPidSel.pTrackElRejMin && std::abs(track.tpcNSigmaEl()) <= kaonPidSel.nSigmaTpcElMin) { + isTrackKaonPidMethod1 = false; + } + + bool isTrackKaonPidMethod2 = true; + if (pTrack > kaonPidSel.pTrackMethod1Max && !track.hasTOF()) { + isTrackKaonPidMethod2 = false; + } + + const float nSigmaCombKa = std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa()); + const float nSigmaCombPi = std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi()); + + if (std::abs(nSigmaCombKa) >= kaonPidSel.nSigmaCombKaMax) { + isTrackKaonPidMethod2 = false; + } + + if (pTrack > kaonPidSel.pTrackTightMin) { + if (std::abs(nSigmaCombKa) >= kaonPidSel.nSigmaCombKaTightMax) { + isTrackKaonPidMethod2 = false; + } + if (std::abs(nSigmaCombPi) <= kaonPidSel.nSigmaCombPiMax) { + isTrackKaonPidMethod2 = false; + } + } + + return isTrackKaonPidMethod1 || isTrackKaonPidMethod2; + } + + template + void fillMcCollision(CollisionType const& col) + { + if (col.has_mcCollision()) { + outputCollsMcLabels(outputMcCollision.lastIndex()); + } else { + outputCollsMcLabels(-1); + } + } + + template + bool fillTracksForCharmHadron(CollisionType const& col, TrackType const& tracks) + { + std::vector const childIDs = {0, 0}; + bool fIsTrackFilled = false; + + for (const auto& track : tracks) { + if (!trackCuts.isSelectedMinimal(track)) { + continue; + } + + trackCuts.fillQA(track); + auto cutContainer = trackCuts.getCutContainer(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f))); + auto bc = col.template bc_as(); + int64_t timeStamp = bc.timestamp(); + outputPartsIndex(track.globalIndex()); + outputPartsTime(timeStamp); + + if (trkPDGCode == kKPlus) { + const auto pidTrackPassBit = static_cast(isTrackKaonPidSelected(track)); + + outputParts(outputCollision.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + pidTrackPassBit, + track.dcaXY(), childIDs, 0, 0); + } else { + outputParts(outputCollision.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), + track.dcaXY(), childIDs, 0, 0); + } + + fIsTrackFilled = true; + if (isDebug.value) { + fillDebugParticle(track); + } + + if constexpr (IsMc) { + fillMcParticle(col, track, o2::aod::femtodreamparticle::ParticleType::kTrack); + } + } + return fIsTrackFilled; + } + + template + bool isNoSelectedTracks(C const& /*col*/, T const& tracks, TC& cuts) + { + for (auto const& track : tracks) { + if (cuts.isSelectedMinimal(track)) { + return false; + } + } + return true; + } + + template + void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) + { + const auto vtxZ = col.posZ(); + const auto sizeCand = candidates.size(); + const auto spher = 2.f; + float mult = 0; + int multNtr = 0; + if (isRun3) { + mult = useCent ? col.centFT0M() : 0.f; + multNtr = col.multNTracksPV(); + } else { + mult = 1.f; + multNtr = col.multTracklets(); + } + + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(col, mult, ccdb, qaRegistry); + qaRegistry.fill(HIST("hEventQA"), 1 + Event::All); + hfEvSel.fillHistograms(col, rejectionMask, mult); + if (rejectionMask != 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejEveSel); + return; + } + + if (isNoSelectedTracks(col, tracks, trackCuts) && sizeCand <= 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejNoTracksAndCharm); + return; + } + + outputCollision(vtxZ, mult, multNtr, spher, magField); + if constexpr (IsMc) { + fillMcCollision(col); + } + + rowCandCharm3Prong.reserve(sizeCand); + rowCandCharm3ProngXic.reserve(sizeCand); + bool isTrackFilled = false; + int nSelectedXic = 0; + + for (const auto& candidate : candidates) { + if (candidate.isSelXicToXiPiPi() < selectionFlagHadron) { + continue; + } + + outputMlXic = {-1.f, -1.f, -1.f}; + bool isSelectedMlXicToXiPiPi = true; + if constexpr (UseCharmMl) { + if (mlCfg.applyMlMode == FillMlFromSelector) { + if (candidate.mlProbXicToXiPiPi().size() > 0) { + outputMlXic.at(0) = candidate.mlProbXicToXiPiPi()[0]; + outputMlXic.at(1) = candidate.mlProbXicToXiPiPi()[1]; + outputMlXic.at(2) = candidate.mlProbXicToXiPiPi()[2]; + } + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { + isSelectedMlXicToXiPiPi = false; + if (candidate.mlProbXicToXiPiPi().size() > 0) { + std::vector inputFeaturesXicToXiPiPi = hfMlResponseXic.getInputFeatures(candidate); + isSelectedMlXicToXiPiPi = hfMlResponseXic.isSelectedMl(inputFeaturesXicToXiPiPi, candidate.pt(), outputMlXic); + } + if (!isSelectedMlXicToXiPiPi) { + continue; + } + } else { + LOGF(fatal, "Please check your ML configuration."); + } + } + + auto bc = col.template bc_as(); + int64_t timeStamp = bc.timestamp(); + const auto eta0 = static_cast(RecoDecay::eta(std::array{candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()})); + const auto eta1 = static_cast(RecoDecay::eta(std::array{candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()})); + const auto eta2 = static_cast(RecoDecay::eta(std::array{candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()})); + const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); + const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); + const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); + + rowCandCharm3Prong( + outputCollision.lastIndex(), + timeStamp, + candidate.sign(), + candidate.pi0Id(), + candidate.pi1Id(), + candidate.bachelorId(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + eta0, + eta1, + eta2, + phi0, + phi1, + phi2, + 1 << 0, + outputMlXic.at(0), + outputMlXic.at(1), + outputMlXic.at(2)); + + rowCandCharm3ProngXic( + candidate.invMassXicPlus(), + candidate.posTrackId(), + candidate.negTrackId()); + + ++nSelectedXic; + if constexpr (IsMc) { + rowCandMcCharmHad( + candidate.flagMcMatchRec(), + candidate.originMcRec()); + } + } + + isTrackFilled = fillTracksForCharmHadron(col, tracks); + + aod::femtodreamcollision::BitMaskType bitTrack = 0; + if (isTrackFilled) { + bitTrack |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::TrackSelected); + } + + aod::femtodreamcollision::BitMaskType bitCand = 0; + if (nSelectedXic > 0) { + bitCand |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::CharmSelected); + } + + if (isTrackFilled && nSelectedXic > 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); + } + + rowMasks(bitTrack, bitCand, 0); + } + + void fillXicMcGen(GeneratedXicMc const& particles) + { + rowCandCharmHadGen.reserve(particles.size()); + for (const auto& particle : particles) { + const int absFlag = std::abs(static_cast(particle.flagMcMatchGen())); + if (absFlag == (1 << DecayType::XicToXiPiPi) || absFlag == (1 << DecayType::XicToXiResPiToXiPiPi)) { + rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + } + } + + void processDataXicToXiPiPi(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPi, "Data for XicToXiPiPi femto (DCAFitter; no HFCANDXICKF)", false); + + void processDataXicToXiPiPiKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPiKf, "Data for XicToXiPiPi femto (KFParticle; requires HFCANDXICKF)", false); + + void processDataXicToXiPiPiWithML(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPiWithML, "Data for XicToXiPiPi femto with ML (DCAFitter)", false); + + void processDataXicToXiPiPiWithMLKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPiWithMLKf, "Data for XicToXiPiPi femto with ML (KFParticle)", false); + + void processMcXicToXiPiPi(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); + + void processMcXicToXiPiPiKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); + + void processMcXicToXiPiPiWithML(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); + + void processMcXicToXiPiPiWithMLKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false); + + void processMcXicToXiPiPiGen(GeneratedXicMc const& particles) + { + fillXicMcGen(particles); + } + PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiGen, "MC generated XicToXiPiPi", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/Tasks/CMakeLists.txt b/PWGHF/HFC/Tasks/CMakeLists.txt index 4fa2b6cd959..1c9e6f3b294 100644 --- a/PWGHF/HFC/Tasks/CMakeLists.txt +++ b/PWGHF/HFC/Tasks/CMakeLists.txt @@ -14,6 +14,11 @@ o2physics_add_dpl_workflow(task-charm-hadrons-track-femto-dream PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-charm-cascade-hadrons-track-femto-dream + SOURCES taskCharmCascadeHadronsTrackFemtoDream.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-charm-hadrons-v0-femto-dream SOURCES taskCharmHadronsV0FemtoDream.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx new file mode 100644 index 00000000000..41629751ca4 --- /dev/null +++ b/PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx @@ -0,0 +1,693 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskCharmCascadeHadronsTrackFemtoDream.cxx +/// \brief FemtoDream task for Ξc± → Ξ∓ π± π± + associated track (e.g. π) +/// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch + +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" +#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" + +#include "Common/Core/RecoDecay.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis::femtoDream; +using namespace o2::constants::physics; + +inline o2::framework::expressions::Node coshEta(o2::framework::expressions::Node&& eta) +{ + auto e1 = std::move(eta); + auto e2 = e1; + + return (nexp(std::move(e1)) + nexp(std::move(e2) * (-1.0f))) * 0.5f; +} + +struct HfTaskCharmCascadeHadronsTrackFemtoDream { + + enum TrackCharge { + PositiveCharge = 1, + NegativeCharge = -1 + }; + + enum PairSign { + PairNotDefined = 0, + LikeSignPair = 1, + UnLikeSignPair = 2, + ReflectedPair = 3 + }; + + enum DecayChannel { XicToXiPiPi = 0 }; + + constexpr static int OriginRecPrompt = 1; + constexpr static int OriginRecFD = 2; + constexpr static int CutBitChargePositive = 2; + constexpr static uint32_t PidTrackPass = 1u; + + Produces rowFemtoResultPairs; + Produces rowFemtoResultCharm3Prong; + Produces rowFemtoResultTrk; + Produces rowFemtoResultColl; + + Configurable confTempFitVarMomentum{"confTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; + + struct : ConfigurableGroup { + Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; + Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron (bit mask, 1 for XicToXiPiPi)"}; + Configurable charmHadMcSel{"charmHadMcSel", 1, "MC charm hadron selection: 1 << XicToXiPiPi = 1"}; + Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; + Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; + Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.55, "Maximum invariant mass of Ξc± (particle 2)"}; + Configurable charmHadMinInvMass{"charmHadMinInvMass", 2.35, "Minimum invariant mass of Ξc± (particle 2)"}; + Configurable charmHadMinPt{"charmHadMinPt", 0., "Minimum pT of Charm Hadron (particle 2)"}; + Configurable charmHadMaxPt{"charmHadMaxPt", 999., "Maximum pT of Charm Hadron (particle 2)"}; + Configurable charmHadPDGCode{"charmHadPDGCode", 4232, "PDG code of particle 2 (Ξc+)"}; + Configurable charmHadPromptBDTmin{"charmHadPromptBDTmin", 0., "Minimum prompt bdt score Charm Hadron (particle 2)"}; + Configurable charmHadPromptBDTmax{"charmHadPromptBDTmax", 1., "Maximum prompt bdt score Charm Hadron (particle 2)"}; + } charmSel; + + struct : ConfigurableGroup { + Configurable cprDeltaEtaMax{"cprDeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable cprDeltaPhiMax{"cprDeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable cprPlotPerRadii{"cprPlotPerRadii", false, "Plot CPR per radii"}; + Configurable extendedPlots{"extendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; + Configurable use4D{"use4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; + Configurable useCPR{"useCPR", false, "Close Pair Rejection"}; + } pairQASetting; + + Configurable highkstarCut{"highkstarCut", 100000., "Set a cut for high k*, above which the pairs are rejected"}; + Configurable isMc{"isMc", false, "Set true in the case of a MonteCarlo Run"}; + Configurable smearingByOrigin{"smearingByOrigin", false, "Obtain the smearing matrix differential in the MC origin of particle 1 and particle 2. High memory consumption. Use with care!"}; + Configurable fillTableWithCharm{"fillTableWithCharm", true, "Write charm/tracks/collision table only if >=1 charm hadron in this collision"}; + + struct : ConfigurableGroup { + Configurable doMixEvent{"doMixEvent", false, "choose do mix-event online"}; + Configurable mixingBinPolicy{"mixingBinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + Configurable mixingDepth{"mixingDepth", 5, "Number of events for mixing"}; + } mixSetting; + + struct : ConfigurableGroup { + std::string prefix = "eventSel"; + Configurable multMin{"multMin", 0, "Minimum Multiplicity (MultNtr)"}; + Configurable multMax{"multMax", 99999, "Maximum Multiplicity (MultNtr)"}; + Configurable multPercentileMin{"multPercentileMin", 0, "Maximum Multiplicity Percentile"}; + Configurable multPercentileMax{"multPercentileMax", 100, "Minimum Multiplicity Percentile"}; + } eventSel; + + struct : ConfigurableGroup { + Configurable cutBitTrack1{"cutBitTrack1", 8188, "Particle 1 (Track) - Selection bit from cutCulator"}; + Configurable pdgCodeTrack1{"pdgCodeTrack1", 211, "PDG code of Particle 1 (Track)"}; + Configurable pidThresTrack1{"pidThresTrack1", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; + Configurable tpcBitTrack1{"tpcBitTrack1", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; + Configurable tpcTofBitTrack1{"tpcTofBitTrack1", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; + Configurable etaTrack1Max{"etaTrack1Max", 10., "Maximum eta of partricle 1 (Track)"}; + Configurable ptTrack1Max{"ptTrack1Max", 999., "Maximum pT of partricle 1 (Track)"}; + Configurable etaTrack1Min{"etaTrack1Min", -10., "Minimum eta of partricle 1 (Track)"}; + Configurable ptTrack1Min{"ptTrack1Min", 0., "Minimum pT of partricle 1 (Track)"}; + } trackSel; + + SliceCache cache; + + using FilteredCharmCand3Prongs = soa::Filtered>; + using FilteredCharmCand3Prong = FilteredCharmCand3Prongs::iterator; + + using FilteredCharmMcCand3Prongs = soa::Filtered>; + using FilteredCharmMcCand3Prong = FilteredCharmMcCand3Prongs::iterator; + + using FilteredCollisions = soa::Filtered>; + using FilteredCollision = FilteredCollisions::iterator; + + using FilteredMcColisions = soa::Filtered>; + using FilteredMcColision = FilteredMcColisions::iterator; + + using FilteredFDMcParts = soa::Filtered>; + using FilteredFDMcPart = FilteredFDMcParts::iterator; + + using FilteredFDParticles = soa::Filtered>; + using FilteredFDParticle = FilteredFDParticles::iterator; + + Filter eventMultiplicity = aod::femtodreamcollision::multNtr >= eventSel.multMin && aod::femtodreamcollision::multNtr <= eventSel.multMax; + Filter eventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax; + Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= charmSel.charmHadCandSel; + Filter hfMcSelFilter = (nabs(aod::fdhf::flagMc) == charmSel.charmHadMcSel); + Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < trackSel.etaTrack1Max, true); + Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > trackSel.etaTrack1Min, true); + Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < trackSel.ptTrack1Max, true); + Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > trackSel.ptTrack1Min, true); + + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; + + Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); + Partition partitionTrk1Ka = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && (aod::femtodreamparticle::pidcut == PidTrackPass); + + Partition partitionMcTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && + ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); + + Partition partitionMcTrk1Ka = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && (aod::femtodreamparticle::pidcut == PidTrackPass); + + Partition partitionCharmHadron3Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; + + Partition partitionMcCharmHadron3Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; + + ConfigurableAxis dummy{"dummy", {1, 0, 1}, "dummy axis"}; + ConfigurableAxis bin4Dkstar{"bin4Dkstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentil vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DMult{"bin4DMult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DmT{"bin4DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DmultPercentile{"bin4DmultPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis binInvMass{"binInvMass", {400, 2.10, 2.80}, "InvMass binning for Ξc±"}; + ConfigurableAxis binpTCharm{"binpTCharm", {360, 0, 36}, "pT binning of charm hadron"}; + ConfigurableAxis binTempFitVarTrack{"binTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis binmT{"binmT", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis binmultTempFit{"binmultTempFit", {1, 0, 1}, "multiplicity Binning for the TempFitVar plot"}; + ConfigurableAxis binMulPercentile{"binMulPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning"}; + ConfigurableAxis binpTTrack{"binpTTrack", {50, 0.5, 10.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis binEta{"binEta", {{200, -1.5, 1.5}}, "eta binning"}; + ConfigurableAxis binPhi{"binPhi", {{200, 0, o2::constants::math::TwoPI}}, "phi binning"}; + ConfigurableAxis binkT{"binkT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis binkstar{"binkstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis binNSigmaTPC{"binNSigmaTPC", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; + ConfigurableAxis binNSigmaTOF{"binNSigmaTOF", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; + ConfigurableAxis binNSigmaTPCTOF{"binNSigmaTPCTOF", {3000, -15, 15}, "Binning of the Nsigma TPC+TOF plot"}; + ConfigurableAxis binTPCClusters{"binTPCClusters", {163, -0.5, 162.5}, "Binning of TPC found clusters plot"}; + ConfigurableAxis mixingBinMult{"mixingBinMult", {VARIABLE_WIDTH, 0.0f, 20.0f, 60.0f, 200.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis mixingBinMultPercentile{"mixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 100.f}, "Mixing bins - multiplicity percentile"}; + ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.0f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; + + ColumnBinningPolicy colBinningMult{{mixingBinVztx, mixingBinMult}, true}; + ColumnBinningPolicy colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; + + FemtoDreamContainer sameEventCont; + FemtoDreamContainer mixedEventCont; + FemtoDreamPairCleaner pairCleaner3Prong; + FemtoDreamDetaDphiStar pairCloseRejectionSE3Prong; + FemtoDreamDetaDphiStar pairCloseRejectionME3Prong; + + femtodreamcollision::BitMaskType bitMask = 1 << 0; + + FemtoDreamParticleHisto allTrackHisto; + FemtoDreamParticleHisto selectedTrackHisto; + FemtoDreamEventHisto eventHisto; + + HistogramRegistry registry{"CorrelationsAndQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry registryMixQa{"registryMixQa"}; + HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; + + float massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1); + float massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode); + int64_t processType = 0; + + void init(InitContext& /*context*/) + { + std::array processes = {doprocessDataXicTrk, doprocessMcXicTrk}; + if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { + LOGP(fatal, "One and only one process function must be enabled at a time."); + } + + colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; + colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; + colBinningMultMultPercentile = {{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; + eventHisto.init(®istry); + allTrackHisto.init(®istry, binmultTempFit, binMulPercentile, binpTTrack, binEta, binPhi, binTempFitVarTrack, binNSigmaTPC, binNSigmaTOF, binNSigmaTPCTOF, binTPCClusters, dummy, dummy, isMc, trackSel.pdgCodeTrack1, true); + selectedTrackHisto.init(®istry, binmultTempFit, binMulPercentile, binpTTrack, binEta, binPhi, binTempFitVarTrack, binNSigmaTPC, binNSigmaTOF, binNSigmaTPCTOF, binTPCClusters, dummy, dummy, isMc, trackSel.pdgCodeTrack1, true); + + sameEventCont.init(®istry, + binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, + bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, + isMc, pairQASetting.use4D, pairQASetting.extendedPlots, + highkstarCut, + smearingByOrigin, binInvMass); + + sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + mixedEventCont.init(®istry, + binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, + bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, + isMc, pairQASetting.use4D, pairQASetting.extendedPlots, + highkstarCut, + smearingByOrigin, binInvMass); + + mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + registryMixQa.add("MixingQA/hSECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); + registryMixQa.add("MixingQA/hSECollisionPool", "; Vz (cm); Mul", kTH2F, {{100, -10, 10}, {200, 0, 200}}); + registryMixQa.add("MixingQA/hMECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); + registryCharmHadronQa.add("CharmHadronQA/hPtVsMass", "; #it{p}_{T} (GeV/#it{c}); inv. mass (GeV/#it{c}^{2})", kTH2F, {binpTCharm, binInvMass}); + + if (pairQASetting.useCPR.value) { + pairCleaner3Prong.init(®istry); + pairCloseRejectionSE3Prong.init(®istry, ®istry, pairQASetting.cprDeltaPhiMax.value, pairQASetting.cprDeltaEtaMax.value, pairQASetting.cprPlotPerRadii.value, 1); + pairCloseRejectionME3Prong.init(®istry, ®istry, pairQASetting.cprDeltaPhiMax.value, pairQASetting.cprDeltaEtaMax.value, pairQASetting.cprPlotPerRadii.value, 2); + } + } + + template + void fillCollision(CollisionType const& col) + { + registryMixQa.fill(HIST("MixingQA/hSECollisionBins"), colBinningMult.getBin({col.posZ(), col.multNtr()})); + registryMixQa.fill(HIST("MixingQA/hSECollisionPool"), col.posZ(), col.multNtr()); + } + + template + float getCharmHadronMass(const Candidate& cand) + { + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + return cand.invMassCharm(); + } + return 0.f; + } + + template + float getCharmHadronTrackMass(const Candidate& cand, + const Track& trk, + int trkPDGCode) + { + auto pVecProng0 = RecoDecayPtEtaPhi::pVector(cand.prong0Pt(), cand.prong0Eta(), cand.prong0Phi()); + auto pVecProng1 = RecoDecayPtEtaPhi::pVector(cand.prong1Pt(), cand.prong1Eta(), cand.prong1Phi()); + auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); + auto pVecTrack = RecoDecayPtEtaPhi::pVector(trk.pt(), trk.eta(), trk.phi()); + + double trackMassHyp = 0.; + switch (trkPDGCode) { + case kProton: + trackMassHyp = MassProton; + break; + case kPiPlus: + trackMassHyp = MassPiPlus; + break; + case kKPlus: + trackMassHyp = MassKPlus; + break; + case kDeuteron: + trackMassHyp = MassDeuteron; + break; + default: + LOG(fatal) << "Invalid PDG code for track mass hypothesis: " << trkPDGCode; + } + + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; + const std::array massCharmTrk{MassXiMinus, MassPiPlus, MassPiPlus, trackMassHyp}; + return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); + } + return -1.f; + } + + template + void doSameEvent(CandType& sliceCharmHad, PartitionType& sliceTrk1, TableTracks const& parts, Collision const& col) + { + fillCollision(col); + processType = 1; + for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { + + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || + p1.trackId() == p2.cascPosTrackId() || p1.trackId() == p2.cascNegTrackId()) { + continue; + } + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionSE3Prong.isClosePair(p1, p2, parts, col.magField())) { + continue; + } + } + if (!pairCleaner3Prong.isCleanPair(p1, p2, parts)) { + continue; + } + } + + float kstar = FemtoDreamMath::getkstar(p1, massOne, p2, massTwo); + if (kstar > highkstarCut) { + continue; + } + float invMass = getCharmHadronMass(p2); + + if (invMass < charmSel.charmHadMinInvMass || invMass > charmSel.charmHadMaxInvMass) { + continue; + } + + if (p2.pt() < charmSel.charmHadMinPt || p2.pt() > charmSel.charmHadMaxPt) { + continue; + } + + float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; + + float chargeTrack = 0.f; + if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { + chargeTrack = PositiveCharge; + } else { + chargeTrack = NegativeCharge; + } + int pairSign = 0; + if (chargeTrack == p2.charge()) { + pairSign = LikeSignPair; + } else if (chargeTrack == -p2.charge()) { + pairSign = UnLikeSignPair; + } else { + pairSign = ReflectedPair; + } + + selectedTrackHisto.fillQA(p1, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + + int charmHadMc = 0; + int originType = 0; + if constexpr (IsMc) { + charmHadMc = p2.flagMc(); + originType = p2.originMcRec(); + } + + rowFemtoResultPairs( + invMass, + p2.pt(), + p1.pt(), + p2.bdtBkg(), + p2.bdtPrompt(), + p2.bdtFD(), + kstar, + FemtoDreamMath::getkT(p1, massOne, p2, massTwo), + FemtoDreamMath::getmT(p1, massOne, p2, massTwo), + col.multNtr(), + col.multV0M(), + p2.charge(), + pairSign, + deltaInvMassPair, + processType, + charmHadMc, + originType); + + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), pairQASetting.use4D, pairQASetting.extendedPlots, smearingByOrigin); + } + } + + template + void doMixedEvent(CollisionType const& cols, PartitionType1& charms, PartitionType2& trks, TableTracks const& parts, BinningType policy) + { + processType = 2; + Partition partitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; + partitionMaskedCol1.bindTable(cols); + + Partition partitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & bitMask) == bitMask; + partitionMaskedCol2.bindTable(cols); + + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy(policy, mixSetting.mixingDepth, -1, *partitionMaskedCol1.mFiltered, *partitionMaskedCol2.mFiltered))) { + if (collision1.globalIndex() == collision2.globalIndex()) { + continue; + } + + const int multiplicityCol = collision1.multNtr(); + registryMixQa.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), multiplicityCol})); + + auto sliceTrk1 = trks->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto sliceCharmHad = charms->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { + + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + if (!pairCleaner3Prong.isCleanPair(p1, p2, parts)) { + continue; + } + } + + float kstar = FemtoDreamMath::getkstar(p1, massOne, p2, massTwo); + if (kstar > highkstarCut) { + continue; + } + float invMass = getCharmHadronMass(p2); + + if (invMass < charmSel.charmHadMinInvMass || invMass > charmSel.charmHadMaxInvMass) { + continue; + } + + if (p2.pt() < charmSel.charmHadMinPt || p2.pt() > charmSel.charmHadMaxPt) { + continue; + } + + float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; + + float chargeTrack = 0.f; + if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { + chargeTrack = PositiveCharge; + } else { + chargeTrack = NegativeCharge; + } + int pairSign = 0; + if (chargeTrack == p2.charge()) { + pairSign = LikeSignPair; + } else if (chargeTrack == -p2.charge()) { + pairSign = UnLikeSignPair; + } else { + pairSign = ReflectedPair; + } + + int charmHadMc = 0; + int originType = 0; + if constexpr (IsMc) { + charmHadMc = p2.flagMc(); + originType = p2.originMcRec(); + } + + rowFemtoResultPairs( + invMass, + p2.pt(), + p1.pt(), + p2.bdtBkg(), + p2.bdtPrompt(), + p2.bdtFD(), + kstar, + FemtoDreamMath::getkT(p1, massOne, p2, massTwo), + FemtoDreamMath::getmT(p1, massOne, p2, massTwo), + collision1.multNtr(), + collision1.multV0M(), + p2.charge(), + pairSign, + deltaInvMassPair, + processType, + charmHadMc, + originType); + + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), pairQASetting.use4D, pairQASetting.extendedPlots, smearingByOrigin); + } + } + } + + template + void fillTables(const CollType& col, + const TrackType& sliceTrk1, + const CandType& sliceCharmHad) + { + int64_t timeStamp = -999; + + for (auto const& part : sliceCharmHad) { + float invMass = getCharmHadronMass(part); + registryCharmHadronQa.fill( + HIST("CharmHadronQA/hPtVsMass"), + part.pt(), invMass); + + timeStamp = part.timeStamp(); + + rowFemtoResultCharm3Prong( + col.globalIndex(), + timeStamp, + invMass, + part.pt(), + part.eta(), + part.phi(), + part.prong0Id(), + part.prong1Id(), + part.prong2Id(), + part.charge(), + part.bdtBkg(), + part.bdtPrompt(), + part.bdtFD()); + } + + for (auto const& part : sliceTrk1) { + allTrackHisto.fillQA( + part, + static_cast(confTempFitVarMomentum.value), + col.multNtr(), + col.multV0M()); + + float chargeTrack = ((part.cut() & CutBitChargePositive) == CutBitChargePositive) + ? PositiveCharge + : NegativeCharge; + + timeStamp = part.timeStamp(); + float tpcNSigma = 999.f; + float tofNSigma = 999.f; + switch (trackSel.pdgCodeTrack1.value) { + case kProton: + tpcNSigma = part.tpcNSigmaPr(); + tofNSigma = part.tofNSigmaPr(); + break; + case kPiPlus: + tpcNSigma = part.tpcNSigmaPi(); + tofNSigma = part.tofNSigmaPi(); + break; + case kKPlus: + tpcNSigma = part.tpcNSigmaKa(); + tofNSigma = part.tofNSigmaKa(); + break; + case kDeuteron: + tpcNSigma = part.tpcNSigmaDe(); + tofNSigma = part.tofNSigmaDe(); + break; + default: + LOG(fatal) << "Invalid PDG code for track PID QA: " << trackSel.pdgCodeTrack1.value; + } + + rowFemtoResultTrk( + col.globalIndex(), + timeStamp, + part.pt(), + part.eta(), + part.phi(), + part.trackId(), + chargeTrack, + part.tpcNClsFound(), + part.tpcNClsFindable(), + part.tpcNClsCrossedRows(), + tpcNSigma, + tofNSigma); + } + + if (sliceCharmHad.size() > 0 || sliceTrk1.size() > 0) { + rowFemtoResultColl( + col.globalIndex(), + timeStamp, + col.posZ(), + col.multNtr()); + } + } + + void processDataXicTrk(FilteredCollisions const& cols, + FilteredFDParticles const& parts, + FilteredCharmCand3Prongs const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + auto sliceTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceCharmHad = partitionCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (fillTableWithCharm.value && sliceCharmHad.size() == 0) { + continue; + } else { + fillTables(col, sliceTrk1, sliceCharmHad); + } + if (sliceCharmHad.size() > 0 && sliceTrk1.size() > 0) { + doSameEvent(sliceCharmHad, sliceTrk1, parts, col); + } + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmCascadeHadronsTrackFemtoDream, processDataXicTrk, "Enable processing XicToXiPiPi and Tracks correlation", false); + + void processMcXicTrk(FilteredMcColisions const& cols, + FilteredFDMcParts const& parts, + o2::aod::FDMCParticles const&, + o2::aod::FDExtMCParticles const&, + FilteredCharmMcCand3Prongs const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + auto sliceMcTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceMcCharmHad = partitionMcCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { + continue; + } + doSameEvent(sliceMcCharmHad, sliceMcTrk1, parts, col); + } + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionMcCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(HfTaskCharmCascadeHadronsTrackFemtoDream, processMcXicTrk, "Enable processing XicToXiPiPi and Tracks correlation for Monte Carlo", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 519e2e7b2af60f458f18415b85694803ad3b3644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Sat, 13 Jun 2026 09:24:40 +0200 Subject: [PATCH 02/17] Add Xic track femto task and kaon MC sources --- PWGCF/DataModel/FemtoDerived.h | 37 +- .../FemtoDream/Core/femtoDreamParticleHisto.h | 110 ++- PWGCF/FemtoDream/Core/femtoDreamUtils.h | 82 ++- .../femtoDreamProducerReducedTask.cxx | 2 +- .../TableProducer/femtoDreamProducerTask.cxx | 2 +- .../femtoDreamProducerTaskReso.cxx | 2 +- .../Core/FemtoUniverseEfficiencyCorrection.h | 8 + .../Core/FemtoUniverseParticleHisto.h | 80 ++ PWGCF/FemtoUniverse/Core/femtoUtils.h | 48 +- PWGCF/FemtoUniverse/DataModel/FemtoDerived.h | 36 +- .../femtoUniverseProducerMCTruthTask.cxx | 2 +- .../femtoUniverseProducerReducedTask.cxx | 2 +- .../femtoUniverseProducerTask.cxx | 6 +- .../Tasks/femtoUniverseEfficiencyBase.cxx | 4 +- ...ucerCharmCascadeHadronsTrackFemtoDream.cxx | 2 +- .../producerCharmHadronsTrackFemtoDream.cxx | 2 +- .../producerCharmHadronsV0FemtoDream.cxx | 2 +- PWGHF/HFC/Tasks/CMakeLists.txt | 5 - ...taskCharmCascadeHadronsTrackFemtoDream.cxx | 693 ------------------ .../Tasks/taskCharmHadronsTrackFemtoDream.cxx | 162 +++- 20 files changed, 541 insertions(+), 746 deletions(-) delete mode 100644 PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 29fb493c4ca..36d123b1d5e 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -674,11 +674,16 @@ enum ParticleOriginMCTruth { kSecondaryDaughterLambda, //! Daughter from a Lambda decay kSecondaryDaughterSigmaplus, //! Daughter from a Sigma^plus decay kSecondaryDaughterSigma0, //! Daughter from a Sigma^0 decay + kSecondaryDaughterSigmaminus, //! Daughter from a Sigma^- decay kSecondaryDaughterXiMinus, //! Daughter from a Xi^- decay kSecondaryDaughterXi0, //! Daughter from a Xi^0 decay kSecondaryDaughterOmegaMinus, //! Daughter from a Omega^- decay kSecondaryDaughterXistar0, //! Daughter from a Xi*^0 decay kSecondaryDaughterXistarMinus, //! Daughter from a Xi*^- decay + kSecondaryDaughterK0Long, //! Daughter from a K0 long decay + kSecondaryDaughterK0Short, //! Daughter from a K0 short decay + kSecondaryDaughterKCharged, //! Daughter from a charged kaon decay + kSecondaryDaughterPionCharged, //! Daughter from a charged pion decay kElse, //! none of the above; (NOTE: used to catch bugs. will be removed once MC usage is properly validated) kNOriginMCTruthTypes }; @@ -690,8 +695,38 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_Material", "_NotPrimary", "_Fake", + "_WrongCollision", "_SecondaryDaughterLambda", - "_SecondaryDaughterSigmaPlus"}; + "_SecondaryDaughterSigmaplus", + "_SecondaryDaughterSigma0", + "_SecondaryDaughterSigmaminus", + "_SecondaryDaughterXiMinus", + "_SecondaryDaughterXi0", + "_SecondaryDaughterOmegaMinus", + "_SecondaryDaughterXistar0", + "_SecondaryDaughterXistarMinus", + "_SecondaryDaughterK0Long", + "_SecondaryDaughterK0Short", + "_SecondaryDaughterKCharged", + "_SecondaryDaughterPionCharged", + "_Else"}; + +inline constexpr bool isSecondaryOrigin(uint8_t origin) +{ + return origin == kSecondary || origin == kSecondaryDaughterLambda || + origin == kSecondaryDaughterSigmaplus || + origin == kSecondaryDaughterSigma0 || + origin == kSecondaryDaughterSigmaminus || + origin == kSecondaryDaughterXiMinus || + origin == kSecondaryDaughterXi0 || + origin == kSecondaryDaughterOmegaMinus || + origin == kSecondaryDaughterXistar0 || + origin == kSecondaryDaughterXistarMinus || + origin == kSecondaryDaughterK0Long || + origin == kSecondaryDaughterK0Short || + origin == kSecondaryDaughterKCharged || + origin == kSecondaryDaughterPionCharged; +} /// Distinguished between reconstructed and truth enum MCType { diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index 8371f683515..24b018cc108 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -212,7 +212,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::HistType::kTH1F, {{240, 0, 6}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{7, -0.5, 6.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes), -0.5, static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes) - 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", o2::framework::HistType::kTH1I, {{1, -0.5, 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_DiffTruthReco").c_str(), "; p^{truth}_{T}; (p^{reco}_{T} - p^{truth}_{T}) / p^{truth}_{T}", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, {200, -1, 1}}); mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", o2::framework::HistType::kTH2F, {{200, -1, 1}, {200, -1, 1}}); @@ -229,6 +229,15 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigma0").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaminus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterXiMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterXi0").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterOmegaMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterK0Long").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterK0Short").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterKCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterPionCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); @@ -237,6 +246,15 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXiMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXi0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); } else { mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -246,6 +264,15 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXiMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXi0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } @@ -616,6 +643,51 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar(), part.dcaZ(), mult); break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigma0): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterSigma0"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigma0"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigmaminus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterSigmaminus"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaminus"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXiMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterXiMinus"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXiMinus"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXi0): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterXi0"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXi0"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterOmegaMinus"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Long): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterK0Long"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Long"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Short): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterK0Short"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Short"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterKCharged): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterKCharged"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterKCharged"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterPionCharged): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterPionCharged"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterPionCharged"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_Else"), part.fdExtMCParticle().motherPDG()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), @@ -654,6 +726,42 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar()); break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigma0): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigma0"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigmaminus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaminus"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXiMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXiMinus"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXi0): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXi0"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Long): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Long"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Short): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Short"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterKCharged): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterKCharged"), + part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterPionCharged): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterPionCharged"), + part.pt(), part.tempFitVar()); + break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index 48a045fa5c1..f1c39526336 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -102,23 +102,68 @@ inline float getMass(int pdgCode) return mass; } -inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG) +inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG, int daughterPDG = 0) { int partOrigin = 0; + const auto absMotherPDG = std::abs(motherPDG); + const auto absDaughterPDG = std::abs(daughterPDG); + const bool isTrackLike = partType == o2::aod::femtodreamparticle::ParticleType::kTrack || + partType == o2::aod::femtodreamparticle::ParticleType::kV0Child || + partType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || + partType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor; + + if (absDaughterPDG == kKPlus && isTrackLike) { + switch (absMotherPDG) { + case kOmegaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; + break; + default: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; + } + return partOrigin; + } + if (partType == o2::aod::femtodreamparticle::ParticleType::kTrack) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kLambda0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterLambda; break; case kSigmaPlus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaplus; break; + case kSigma0: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; + break; + case kSigmaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaminus; + break; + case kXiMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXiMinus; + break; + case o2::constants::physics::Pdg::kXi0: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXi0; + break; + case kOmegaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; + break; + case kK0Long: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Long; + break; + case kK0Short: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Short; + break; + case kKPlus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterKCharged; + break; + case kPiPlus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterPionCharged; + break; default: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; } // switch } else if (partType == o2::aod::femtodreamparticle::ParticleType::kV0) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kSigma0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; break; @@ -133,19 +178,46 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } } else if (partType == o2::aod::femtodreamparticle::ParticleType::kV0Child || partType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || partType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { - switch (abs(motherPDG)) { + switch (absMotherPDG) { case kLambda0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterLambda; break; case kSigmaPlus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaplus; break; + case kSigma0: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; + break; + case kSigmaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaminus; + break; + case kXiMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXiMinus; + break; + case o2::constants::physics::Pdg::kXi0: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXi0; + break; + case kOmegaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; + break; + case kK0Long: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Long; + break; + case kK0Short: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Short; + break; + case kKPlus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterKCharged; + break; + case kPiPlus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterPionCharged; + break; default: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; } // switch } else if (partType == o2::aod::femtodreamparticle::ParticleType::kCascade) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kOmegaMinus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; break; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx index 8d2a80b00c4..a35faf8c8a7 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx @@ -214,7 +214,7 @@ struct femtoDreamProducerReducedTask { } else if (particleMC.isPhysicalPrimary()) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; } else if (motherparticleMC.isPhysicalPrimary() && particleMC.getProcess() == 4) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); } else if (particleMC.getGenStatusCode() == -1) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; } else { diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index 9f47d915620..bb88a135cb2 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -672,7 +672,7 @@ struct femtoDreamProducerTask { auto motherparticleMC = motherparticlesMC.front(); pdgCodeMother = motherparticleMC.pdgCode(); TrackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx index 9b0f753ef9c..03779b09ed9 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx @@ -928,7 +928,7 @@ struct FemtoDreamProducerTaskReso { auto motherparticleMC = motherparticlesMC.front(); pdgCodeMother = motherparticleMC.pdgCode(); trackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h index 23506574426..1d8ef2aef5a 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h @@ -167,6 +167,14 @@ class EfficiencyCorrection case (o2::aod::femtouniverse_mc_particle::kDaughter): case (o2::aod::femtouniverse_mc_particle::kDaughterLambda): case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaplus): + case (o2::aod::femtouniverse_mc_particle::kDaughterSigma0): + case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaminus): + case (o2::aod::femtouniverse_mc_particle::kDaughterXi): + case (o2::aod::femtouniverse_mc_particle::kDaughterOmega): + case (o2::aod::femtouniverse_mc_particle::kDaughterK0Long): + case (o2::aod::femtouniverse_mc_particle::kDaughterK0Short): + case (o2::aod::femtouniverse_mc_particle::kDaughterKCharged): + case (o2::aod::femtouniverse_mc_particle::kDaughterPionCharged): histRegistry->fill(HIST(histDirectory) + HIST("/") + HIST(histSuffix[N - 1]) + HIST("/hSecondary"), mcParticle.pt(), mcParticle.eta(), diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h index 02f5a330340..db684ef8219 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h @@ -171,6 +171,14 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigma0").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigmaminus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterXi").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterOmega").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterK0Long").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterK0Short").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterKCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterPionCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Daughter").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -180,6 +188,14 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterXi").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterOmega").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_NoMCTruthOrigin").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hMisidentification").c_str(), "; #it{p}_{T} (GeV/#it{c}); Particle; Particle", o2::framework::HistType::kTH3F, {{4, 0, 4}, {4, 0, 4}, tempFitVarpTAxis}); @@ -195,6 +211,14 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterXi").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterOmega").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0) { @@ -407,6 +431,38 @@ class FemtoUniverseParticleHisto // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterSigmaplus"), part.fdMCParticle().motherPDG()); mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaplus"), part.pt(), part.tempFitVar()); break; + case (o2::aod::femtouniverse_mc_particle::kDaughterSigma0): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterSigma0"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigma0"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaminus): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterSigmaminus"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaminus"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterXi): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterXi"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterXi"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterOmega): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterOmega"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterOmega"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterK0Long): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterK0Long"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Long"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterK0Short): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterK0Short"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Short"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterKCharged): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterKCharged"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterKCharged"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterPionCharged): + // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterPionCharged"), part.fdMCParticle().motherPDG()); + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterPionCharged"), part.pt(), part.tempFitVar()); + break; case (o2::aod::femtouniverse_mc_particle::kElse): // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_Else"), part.fdMCParticle().motherPDG()); mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); @@ -438,6 +494,30 @@ class FemtoUniverseParticleHisto case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaplus): mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaplus"), part.pt(), part.tempFitVar()); break; + case (o2::aod::femtouniverse_mc_particle::kDaughterSigma0): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigma0"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaminus): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaminus"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterXi): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterXi"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterOmega): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterOmega"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterK0Long): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Long"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterK0Short): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Short"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterKCharged): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterKCharged"), part.pt(), part.tempFitVar()); + break; + case (o2::aod::femtouniverse_mc_particle::kDaughterPionCharged): + mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterPionCharged"), part.pt(), part.tempFitVar()); + break; case (o2::aod::femtouniverse_mc_particle::kElse): mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); break; diff --git a/PWGCF/FemtoUniverse/Core/femtoUtils.h b/PWGCF/FemtoUniverse/Core/femtoUtils.h index daeef089442..a3cd3804b2d 100644 --- a/PWGCF/FemtoUniverse/Core/femtoUtils.h +++ b/PWGCF/FemtoUniverse/Core/femtoUtils.h @@ -27,6 +27,8 @@ #include #include +#include + namespace o2::analysis::femto_universe { @@ -100,18 +102,56 @@ bool isFullPIDSelected(aod::femtouniverseparticle::CutContainerType const& pidCu return pidSelection; }; -int checkDaughterType(o2::aod::femtouniverseparticle::ParticleType partType, int motherPDG) +int checkDaughterType(o2::aod::femtouniverseparticle::ParticleType partType, int motherPDG, int daughterPDG = 0) { int partOrigin = 0; + const auto absMotherPDG = std::abs(motherPDG); + const auto absDaughterPDG = std::abs(daughterPDG); + + if (absDaughterPDG == kKPlus && partType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { + switch (absMotherPDG) { + case kOmegaMinus: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterOmega; + break; + default: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter; + } + return partOrigin; + } + if (partType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { - switch (std::abs(motherPDG)) { - case 3122: + switch (absMotherPDG) { + case kLambda0: partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterLambda; break; - case 3222: + case kSigmaPlus: partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaplus; break; + case kSigma0: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigma0; + break; + case kSigmaMinus: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaminus; + break; + case kXiMinus: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterXi; + break; + case kOmegaMinus: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterOmega; + break; + case kK0Long: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterK0Long; + break; + case kK0Short: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterK0Short; + break; + case kKPlus: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterKCharged; + break; + case kPiPlus: + partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterPionCharged; + break; default: partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter; } // switch diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index 71a3a3acdeb..22102903217 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -269,10 +269,18 @@ enum ParticleOriginMCTruth { kMaterial, //! Particle from a material kNotPrimary, //! Not primary particles (kept for compatibility reasons with the FullProducer task. will be removed, since we look at "non primaries" more differentially now) kFake, //! Particle, that has NOT the PDG code of the current analysed particle - kDaughterLambda, //! Daughter from a Lambda decay - kDaughterSigmaplus, //! Daughter from a Sigma^plus decay - kPrompt, //! Origin for D0/D0bar mesons - kNonPrompt, //! Origin for D0/D0bar mesons + kDaughterLambda, //! Daughter from a Lambda decay + kDaughterSigmaplus, //! Daughter from a Sigma^plus decay + kDaughterSigma0, //! Daughter from a Sigma^0 decay + kDaughterSigmaminus, //! Daughter from a Sigma^- decay + kDaughterXi, //! Daughter from a Xi decay + kDaughterOmega, //! Daughter from an Omega decay + kDaughterK0Long, //! Daughter from a K0 long decay + kDaughterK0Short, //! Daughter from a K0 short decay + kDaughterKCharged, //! Daughter from a charged kaon decay + kDaughterPionCharged, //! Daughter from a charged pion decay + kPrompt, //! Origin for D0/D0bar mesons + kNonPrompt, //! Origin for D0/D0bar mesons kNOriginMCTruthTypes, kElse, kWrongCollision //! Origin for the wrong collision @@ -286,10 +294,28 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_NotPrimary", "_Fake", "_DaughterLambda", - "DaughterSigmaPlus", + "_DaughterSigmaplus", + "_DaughterSigma0", + "_DaughterSigmaminus", + "_DaughterXi", + "_DaughterOmega", + "_DaughterK0Long", + "_DaughterK0Short", + "_DaughterKCharged", + "_DaughterPionCharged", "_Prompt", "_NonPrompt"}; +inline constexpr bool isDaughterOrigin(uint8_t origin) +{ + return origin == kDaughter || origin == kDaughterLambda || + origin == kDaughterSigmaplus || origin == kDaughterSigma0 || + origin == kDaughterSigmaminus || origin == kDaughterXi || + origin == kDaughterOmega || origin == kDaughterK0Long || + origin == kDaughterK0Short || origin == kDaughterKCharged || + origin == kDaughterPionCharged; +} + /// Distinguished between reconstructed and truth enum MCType { kRecon, //! Reconstructed in case of MC and used as default in case of data diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index 3f94d573ee9..816f35e4cef 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -90,7 +90,7 @@ struct FemtoUniverseProducerMCTruthTask { Configurable confIsRun3{"confIsRun3", false, "Running on Run3 or pilot"}; Configurable confIsMC{"confIsMC", false, "Running on MC; implemented only for Run3"}; Configurable confIsForceGRP{"confIsForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; - Configurable> confPDGCodes{"confPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; + Configurable> confPDGCodes{"confPDGCodes", std::vector{kPiPlus, -kPiPlus, kKPlus, kKMinus, kProton, -kProton, Pdg::kPhi}, "PDG of particles to be stored"}; Configurable confAnalysisWithPID{"confAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles"}; /// Event cuts diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx index a0eb1fe69d1..eab5b5226c4 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx @@ -214,7 +214,7 @@ struct femtoUniverseProducerReducedTask { if (particleMC.isPhysicalPrimary()) { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary; } else if (motherparticleMC.producedByGenerator()) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); } else { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial; } diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index a112f5f4768..952a29d0f73 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -176,7 +176,7 @@ struct FemtoUniverseProducerTask { Configurable confIsActivatePhi{"confIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; Configurable confIsActiveD0{"confIsActiveD0", false, "Activate filling FU tables for D0/D0bar mesons"}; Configurable confMCTruthAnalysisWithPID{"confMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; - Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; + Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{kPiPlus, -kPiPlus, kKPlus, kKMinus, kProton, -kProton, Pdg::kPhi}, "PDG of particles to be stored"}; Configurable confCentFT0Min{"confCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; Configurable confCentFT0Max{"confCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; Configurable confEvIsGoodZvtxFT0vsPV{"confEvIsGoodZvtxFT0vsPV", true, "Require kIsGoodZvtxFT0vsPV selection on Events."}; @@ -946,7 +946,7 @@ struct FemtoUniverseProducerTask { } else if (!motherparticlesMC.empty()) { auto motherparticleMC = motherparticlesMC.front(); if (motherparticleMC.producedByGenerator()) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); } else { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial; } @@ -979,7 +979,7 @@ struct FemtoUniverseProducerTask { if (!mothers.empty()) { auto mother = mothers.front(); if (mother.producedByGenerator()) { - particleOrigin = checkDaughterType(fdparttype, mother.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, mother.pdgCode(), pdgCode); } else { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index f8c99fb90d7..34bff602357 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -700,7 +700,7 @@ struct FemtoUniverseEfficiencyBase { if (fillSecTrkContHistos) { if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { registrySecTrkCont.fill(HIST("part1/hDCAxy_Primary"), part.pt(), part.tempFitVar()); - } else if ((mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterLambda) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaplus)) { + } else if (aod::femtouniverse_mc_particle::isDaughterOrigin(mcParticle.partOriginMCTruth())) { registrySecTrkCont.fill(HIST("part1/hDCAxy_Daughter"), part.pt(), part.tempFitVar()); } else if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial) { registrySecTrkCont.fill(HIST("part1/hDCAxy_Material"), part.pt(), part.tempFitVar()); @@ -790,7 +790,7 @@ struct FemtoUniverseEfficiencyBase { if (fillSecTrkContHistos) { if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { registrySecTrkCont.fill(HIST("part2/hDCAxy_Primary"), part.pt(), part.tempFitVar()); - } else if ((mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterLambda) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaplus)) { + } else if (aod::femtouniverse_mc_particle::isDaughterOrigin(mcParticle.partOriginMCTruth())) { registrySecTrkCont.fill(HIST("part2/hDCAxy_Daughter"), part.pt(), part.tempFitVar()); } else if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial) { registrySecTrkCont.fill(HIST("part2/hDCAxy_Material"), part.pt(), part.tempFitVar()); diff --git a/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx index 3622ddf4676..0db94d38a0e 100644 --- a/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx @@ -321,7 +321,7 @@ struct HfProducerCharmCascadeHadronsTrackFemtoDream { } else if (particleMc.getProcess() == TMCProcess::kPDecay && particleMc.getGenStatusCode() == GenFromTransport && !motherparticlesMc.empty()) { auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); } else if (particleMc.getProcess() == TMCProcess::kPHInhelastic && particleMc.getGenStatusCode() == GenFromTransport) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; } else { diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index e2e0ab680d4..4e65027b2c9 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -470,7 +470,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { // get direct mother auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx index fa7304877ff..a28c94bb485 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx @@ -524,7 +524,7 @@ struct HfProducerCharmHadronsV0FemtoDream { // get direct mother auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGHF/HFC/Tasks/CMakeLists.txt b/PWGHF/HFC/Tasks/CMakeLists.txt index 1c9e6f3b294..4fa2b6cd959 100644 --- a/PWGHF/HFC/Tasks/CMakeLists.txt +++ b/PWGHF/HFC/Tasks/CMakeLists.txt @@ -14,11 +14,6 @@ o2physics_add_dpl_workflow(task-charm-hadrons-track-femto-dream PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(task-charm-cascade-hadrons-track-femto-dream - SOURCES taskCharmCascadeHadronsTrackFemtoDream.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(task-charm-hadrons-v0-femto-dream SOURCES taskCharmHadronsV0FemtoDream.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx deleted file mode 100644 index 41629751ca4..00000000000 --- a/PWGHF/HFC/Tasks/taskCharmCascadeHadronsTrackFemtoDream.cxx +++ /dev/null @@ -1,693 +0,0 @@ -// Copyright 2019-2025 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file taskCharmCascadeHadronsTrackFemtoDream.cxx -/// \brief FemtoDream task for Ξc± → Ξ∓ π± π± + associated track (e.g. π) -/// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch - -#include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" -#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" -#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" -#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" - -#include "Common/Core/RecoDecay.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::analysis::femtoDream; -using namespace o2::constants::physics; - -inline o2::framework::expressions::Node coshEta(o2::framework::expressions::Node&& eta) -{ - auto e1 = std::move(eta); - auto e2 = e1; - - return (nexp(std::move(e1)) + nexp(std::move(e2) * (-1.0f))) * 0.5f; -} - -struct HfTaskCharmCascadeHadronsTrackFemtoDream { - - enum TrackCharge { - PositiveCharge = 1, - NegativeCharge = -1 - }; - - enum PairSign { - PairNotDefined = 0, - LikeSignPair = 1, - UnLikeSignPair = 2, - ReflectedPair = 3 - }; - - enum DecayChannel { XicToXiPiPi = 0 }; - - constexpr static int OriginRecPrompt = 1; - constexpr static int OriginRecFD = 2; - constexpr static int CutBitChargePositive = 2; - constexpr static uint32_t PidTrackPass = 1u; - - Produces rowFemtoResultPairs; - Produces rowFemtoResultCharm3Prong; - Produces rowFemtoResultTrk; - Produces rowFemtoResultColl; - - Configurable confTempFitVarMomentum{"confTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; - - struct : ConfigurableGroup { - Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; - Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron (bit mask, 1 for XicToXiPiPi)"}; - Configurable charmHadMcSel{"charmHadMcSel", 1, "MC charm hadron selection: 1 << XicToXiPiPi = 1"}; - Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; - Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; - Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.55, "Maximum invariant mass of Ξc± (particle 2)"}; - Configurable charmHadMinInvMass{"charmHadMinInvMass", 2.35, "Minimum invariant mass of Ξc± (particle 2)"}; - Configurable charmHadMinPt{"charmHadMinPt", 0., "Minimum pT of Charm Hadron (particle 2)"}; - Configurable charmHadMaxPt{"charmHadMaxPt", 999., "Maximum pT of Charm Hadron (particle 2)"}; - Configurable charmHadPDGCode{"charmHadPDGCode", 4232, "PDG code of particle 2 (Ξc+)"}; - Configurable charmHadPromptBDTmin{"charmHadPromptBDTmin", 0., "Minimum prompt bdt score Charm Hadron (particle 2)"}; - Configurable charmHadPromptBDTmax{"charmHadPromptBDTmax", 1., "Maximum prompt bdt score Charm Hadron (particle 2)"}; - } charmSel; - - struct : ConfigurableGroup { - Configurable cprDeltaEtaMax{"cprDeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; - Configurable cprDeltaPhiMax{"cprDeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; - Configurable cprPlotPerRadii{"cprPlotPerRadii", false, "Plot CPR per radii"}; - Configurable extendedPlots{"extendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; - Configurable use4D{"use4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; - Configurable useCPR{"useCPR", false, "Close Pair Rejection"}; - } pairQASetting; - - Configurable highkstarCut{"highkstarCut", 100000., "Set a cut for high k*, above which the pairs are rejected"}; - Configurable isMc{"isMc", false, "Set true in the case of a MonteCarlo Run"}; - Configurable smearingByOrigin{"smearingByOrigin", false, "Obtain the smearing matrix differential in the MC origin of particle 1 and particle 2. High memory consumption. Use with care!"}; - Configurable fillTableWithCharm{"fillTableWithCharm", true, "Write charm/tracks/collision table only if >=1 charm hadron in this collision"}; - - struct : ConfigurableGroup { - Configurable doMixEvent{"doMixEvent", false, "choose do mix-event online"}; - Configurable mixingBinPolicy{"mixingBinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; - Configurable mixingDepth{"mixingDepth", 5, "Number of events for mixing"}; - } mixSetting; - - struct : ConfigurableGroup { - std::string prefix = "eventSel"; - Configurable multMin{"multMin", 0, "Minimum Multiplicity (MultNtr)"}; - Configurable multMax{"multMax", 99999, "Maximum Multiplicity (MultNtr)"}; - Configurable multPercentileMin{"multPercentileMin", 0, "Maximum Multiplicity Percentile"}; - Configurable multPercentileMax{"multPercentileMax", 100, "Minimum Multiplicity Percentile"}; - } eventSel; - - struct : ConfigurableGroup { - Configurable cutBitTrack1{"cutBitTrack1", 8188, "Particle 1 (Track) - Selection bit from cutCulator"}; - Configurable pdgCodeTrack1{"pdgCodeTrack1", 211, "PDG code of Particle 1 (Track)"}; - Configurable pidThresTrack1{"pidThresTrack1", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; - Configurable tpcBitTrack1{"tpcBitTrack1", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; - Configurable tpcTofBitTrack1{"tpcTofBitTrack1", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; - Configurable etaTrack1Max{"etaTrack1Max", 10., "Maximum eta of partricle 1 (Track)"}; - Configurable ptTrack1Max{"ptTrack1Max", 999., "Maximum pT of partricle 1 (Track)"}; - Configurable etaTrack1Min{"etaTrack1Min", -10., "Minimum eta of partricle 1 (Track)"}; - Configurable ptTrack1Min{"ptTrack1Min", 0., "Minimum pT of partricle 1 (Track)"}; - } trackSel; - - SliceCache cache; - - using FilteredCharmCand3Prongs = soa::Filtered>; - using FilteredCharmCand3Prong = FilteredCharmCand3Prongs::iterator; - - using FilteredCharmMcCand3Prongs = soa::Filtered>; - using FilteredCharmMcCand3Prong = FilteredCharmMcCand3Prongs::iterator; - - using FilteredCollisions = soa::Filtered>; - using FilteredCollision = FilteredCollisions::iterator; - - using FilteredMcColisions = soa::Filtered>; - using FilteredMcColision = FilteredMcColisions::iterator; - - using FilteredFDMcParts = soa::Filtered>; - using FilteredFDMcPart = FilteredFDMcParts::iterator; - - using FilteredFDParticles = soa::Filtered>; - using FilteredFDParticle = FilteredFDParticles::iterator; - - Filter eventMultiplicity = aod::femtodreamcollision::multNtr >= eventSel.multMin && aod::femtodreamcollision::multNtr <= eventSel.multMax; - Filter eventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax; - Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= charmSel.charmHadCandSel; - Filter hfMcSelFilter = (nabs(aod::fdhf::flagMc) == charmSel.charmHadMcSel); - Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < trackSel.etaTrack1Max, true); - Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > trackSel.etaTrack1Min, true); - Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < trackSel.ptTrack1Max, true); - Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > trackSel.ptTrack1Min, true); - - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; - - Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); - Partition partitionTrk1Ka = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && (aod::femtodreamparticle::pidcut == PidTrackPass); - - Partition partitionMcTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && - ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); - - Partition partitionMcTrk1Ka = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && (aod::femtodreamparticle::pidcut == PidTrackPass); - - Partition partitionCharmHadron3Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; - - Partition partitionMcCharmHadron3Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; - - ConfigurableAxis dummy{"dummy", {1, 0, 1}, "dummy axis"}; - ConfigurableAxis bin4Dkstar{"bin4Dkstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentil vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DMult{"bin4DMult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DmT{"bin4DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DmultPercentile{"bin4DmultPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis binInvMass{"binInvMass", {400, 2.10, 2.80}, "InvMass binning for Ξc±"}; - ConfigurableAxis binpTCharm{"binpTCharm", {360, 0, 36}, "pT binning of charm hadron"}; - ConfigurableAxis binTempFitVarTrack{"binTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; - ConfigurableAxis binmT{"binmT", {225, 0., 7.5}, "binning mT"}; - ConfigurableAxis binmultTempFit{"binmultTempFit", {1, 0, 1}, "multiplicity Binning for the TempFitVar plot"}; - ConfigurableAxis binMulPercentile{"binMulPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning"}; - ConfigurableAxis binpTTrack{"binpTTrack", {50, 0.5, 10.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; - ConfigurableAxis binEta{"binEta", {{200, -1.5, 1.5}}, "eta binning"}; - ConfigurableAxis binPhi{"binPhi", {{200, 0, o2::constants::math::TwoPI}}, "phi binning"}; - ConfigurableAxis binkT{"binkT", {150, 0., 9.}, "binning kT"}; - ConfigurableAxis binkstar{"binkstar", {1500, 0., 6.}, "binning kstar"}; - ConfigurableAxis binNSigmaTPC{"binNSigmaTPC", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; - ConfigurableAxis binNSigmaTOF{"binNSigmaTOF", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; - ConfigurableAxis binNSigmaTPCTOF{"binNSigmaTPCTOF", {3000, -15, 15}, "Binning of the Nsigma TPC+TOF plot"}; - ConfigurableAxis binTPCClusters{"binTPCClusters", {163, -0.5, 162.5}, "Binning of TPC found clusters plot"}; - ConfigurableAxis mixingBinMult{"mixingBinMult", {VARIABLE_WIDTH, 0.0f, 20.0f, 60.0f, 200.0f}, "Mixing bins - multiplicity"}; - ConfigurableAxis mixingBinMultPercentile{"mixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 100.f}, "Mixing bins - multiplicity percentile"}; - ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.0f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; - - ColumnBinningPolicy colBinningMult{{mixingBinVztx, mixingBinMult}, true}; - ColumnBinningPolicy colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; - ColumnBinningPolicy colBinningMultMultPercentile{{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; - - FemtoDreamContainer sameEventCont; - FemtoDreamContainer mixedEventCont; - FemtoDreamPairCleaner pairCleaner3Prong; - FemtoDreamDetaDphiStar pairCloseRejectionSE3Prong; - FemtoDreamDetaDphiStar pairCloseRejectionME3Prong; - - femtodreamcollision::BitMaskType bitMask = 1 << 0; - - FemtoDreamParticleHisto allTrackHisto; - FemtoDreamParticleHisto selectedTrackHisto; - FemtoDreamEventHisto eventHisto; - - HistogramRegistry registry{"CorrelationsAndQA", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry registryMixQa{"registryMixQa"}; - HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; - - float massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1); - float massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode); - int64_t processType = 0; - - void init(InitContext& /*context*/) - { - std::array processes = {doprocessDataXicTrk, doprocessMcXicTrk}; - if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { - LOGP(fatal, "One and only one process function must be enabled at a time."); - } - - colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; - colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; - colBinningMultMultPercentile = {{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; - eventHisto.init(®istry); - allTrackHisto.init(®istry, binmultTempFit, binMulPercentile, binpTTrack, binEta, binPhi, binTempFitVarTrack, binNSigmaTPC, binNSigmaTOF, binNSigmaTPCTOF, binTPCClusters, dummy, dummy, isMc, trackSel.pdgCodeTrack1, true); - selectedTrackHisto.init(®istry, binmultTempFit, binMulPercentile, binpTTrack, binEta, binPhi, binTempFitVarTrack, binNSigmaTPC, binNSigmaTOF, binNSigmaTPCTOF, binTPCClusters, dummy, dummy, isMc, trackSel.pdgCodeTrack1, true); - - sameEventCont.init(®istry, - binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, - bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, - isMc, pairQASetting.use4D, pairQASetting.extendedPlots, - highkstarCut, - smearingByOrigin, binInvMass); - - sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); - mixedEventCont.init(®istry, - binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, - bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, - isMc, pairQASetting.use4D, pairQASetting.extendedPlots, - highkstarCut, - smearingByOrigin, binInvMass); - - mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); - registryMixQa.add("MixingQA/hSECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); - registryMixQa.add("MixingQA/hSECollisionPool", "; Vz (cm); Mul", kTH2F, {{100, -10, 10}, {200, 0, 200}}); - registryMixQa.add("MixingQA/hMECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); - registryCharmHadronQa.add("CharmHadronQA/hPtVsMass", "; #it{p}_{T} (GeV/#it{c}); inv. mass (GeV/#it{c}^{2})", kTH2F, {binpTCharm, binInvMass}); - - if (pairQASetting.useCPR.value) { - pairCleaner3Prong.init(®istry); - pairCloseRejectionSE3Prong.init(®istry, ®istry, pairQASetting.cprDeltaPhiMax.value, pairQASetting.cprDeltaEtaMax.value, pairQASetting.cprPlotPerRadii.value, 1); - pairCloseRejectionME3Prong.init(®istry, ®istry, pairQASetting.cprDeltaPhiMax.value, pairQASetting.cprDeltaEtaMax.value, pairQASetting.cprPlotPerRadii.value, 2); - } - } - - template - void fillCollision(CollisionType const& col) - { - registryMixQa.fill(HIST("MixingQA/hSECollisionBins"), colBinningMult.getBin({col.posZ(), col.multNtr()})); - registryMixQa.fill(HIST("MixingQA/hSECollisionPool"), col.posZ(), col.multNtr()); - } - - template - float getCharmHadronMass(const Candidate& cand) - { - if constexpr (Channel == DecayChannel::XicToXiPiPi) { - return cand.invMassCharm(); - } - return 0.f; - } - - template - float getCharmHadronTrackMass(const Candidate& cand, - const Track& trk, - int trkPDGCode) - { - auto pVecProng0 = RecoDecayPtEtaPhi::pVector(cand.prong0Pt(), cand.prong0Eta(), cand.prong0Phi()); - auto pVecProng1 = RecoDecayPtEtaPhi::pVector(cand.prong1Pt(), cand.prong1Eta(), cand.prong1Phi()); - auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); - auto pVecTrack = RecoDecayPtEtaPhi::pVector(trk.pt(), trk.eta(), trk.phi()); - - double trackMassHyp = 0.; - switch (trkPDGCode) { - case kProton: - trackMassHyp = MassProton; - break; - case kPiPlus: - trackMassHyp = MassPiPlus; - break; - case kKPlus: - trackMassHyp = MassKPlus; - break; - case kDeuteron: - trackMassHyp = MassDeuteron; - break; - default: - LOG(fatal) << "Invalid PDG code for track mass hypothesis: " << trkPDGCode; - } - - if constexpr (Channel == DecayChannel::XicToXiPiPi) { - const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; - const std::array massCharmTrk{MassXiMinus, MassPiPlus, MassPiPlus, trackMassHyp}; - return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); - } - return -1.f; - } - - template - void doSameEvent(CandType& sliceCharmHad, PartitionType& sliceTrk1, TableTracks const& parts, Collision const& col) - { - fillCollision(col); - processType = 1; - for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { - - if constexpr (Channel == DecayChannel::XicToXiPiPi) { - if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || - p1.trackId() == p2.cascPosTrackId() || p1.trackId() == p2.cascNegTrackId()) { - continue; - } - if (pairQASetting.useCPR.value) { - if (pairCloseRejectionSE3Prong.isClosePair(p1, p2, parts, col.magField())) { - continue; - } - } - if (!pairCleaner3Prong.isCleanPair(p1, p2, parts)) { - continue; - } - } - - float kstar = FemtoDreamMath::getkstar(p1, massOne, p2, massTwo); - if (kstar > highkstarCut) { - continue; - } - float invMass = getCharmHadronMass(p2); - - if (invMass < charmSel.charmHadMinInvMass || invMass > charmSel.charmHadMaxInvMass) { - continue; - } - - if (p2.pt() < charmSel.charmHadMinPt || p2.pt() > charmSel.charmHadMaxPt) { - continue; - } - - float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - - float chargeTrack = 0.f; - if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { - chargeTrack = PositiveCharge; - } else { - chargeTrack = NegativeCharge; - } - int pairSign = 0; - if (chargeTrack == p2.charge()) { - pairSign = LikeSignPair; - } else if (chargeTrack == -p2.charge()) { - pairSign = UnLikeSignPair; - } else { - pairSign = ReflectedPair; - } - - selectedTrackHisto.fillQA(p1, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); - - int charmHadMc = 0; - int originType = 0; - if constexpr (IsMc) { - charmHadMc = p2.flagMc(); - originType = p2.originMcRec(); - } - - rowFemtoResultPairs( - invMass, - p2.pt(), - p1.pt(), - p2.bdtBkg(), - p2.bdtPrompt(), - p2.bdtFD(), - kstar, - FemtoDreamMath::getkT(p1, massOne, p2, massTwo), - FemtoDreamMath::getmT(p1, massOne, p2, massTwo), - col.multNtr(), - col.multV0M(), - p2.charge(), - pairSign, - deltaInvMassPair, - processType, - charmHadMc, - originType); - - sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), pairQASetting.use4D, pairQASetting.extendedPlots, smearingByOrigin); - } - } - - template - void doMixedEvent(CollisionType const& cols, PartitionType1& charms, PartitionType2& trks, TableTracks const& parts, BinningType policy) - { - processType = 2; - Partition partitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; - partitionMaskedCol1.bindTable(cols); - - Partition partitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & bitMask) == bitMask; - partitionMaskedCol2.bindTable(cols); - - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy(policy, mixSetting.mixingDepth, -1, *partitionMaskedCol1.mFiltered, *partitionMaskedCol2.mFiltered))) { - if (collision1.globalIndex() == collision2.globalIndex()) { - continue; - } - - const int multiplicityCol = collision1.multNtr(); - registryMixQa.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), multiplicityCol})); - - auto sliceTrk1 = trks->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto sliceCharmHad = charms->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { - - if constexpr (Channel == DecayChannel::XicToXiPiPi) { - if (pairQASetting.useCPR.value) { - if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { - continue; - } - } - if (!pairCleaner3Prong.isCleanPair(p1, p2, parts)) { - continue; - } - } - - float kstar = FemtoDreamMath::getkstar(p1, massOne, p2, massTwo); - if (kstar > highkstarCut) { - continue; - } - float invMass = getCharmHadronMass(p2); - - if (invMass < charmSel.charmHadMinInvMass || invMass > charmSel.charmHadMaxInvMass) { - continue; - } - - if (p2.pt() < charmSel.charmHadMinPt || p2.pt() > charmSel.charmHadMaxPt) { - continue; - } - - float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - - float chargeTrack = 0.f; - if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { - chargeTrack = PositiveCharge; - } else { - chargeTrack = NegativeCharge; - } - int pairSign = 0; - if (chargeTrack == p2.charge()) { - pairSign = LikeSignPair; - } else if (chargeTrack == -p2.charge()) { - pairSign = UnLikeSignPair; - } else { - pairSign = ReflectedPair; - } - - int charmHadMc = 0; - int originType = 0; - if constexpr (IsMc) { - charmHadMc = p2.flagMc(); - originType = p2.originMcRec(); - } - - rowFemtoResultPairs( - invMass, - p2.pt(), - p1.pt(), - p2.bdtBkg(), - p2.bdtPrompt(), - p2.bdtFD(), - kstar, - FemtoDreamMath::getkT(p1, massOne, p2, massTwo), - FemtoDreamMath::getmT(p1, massOne, p2, massTwo), - collision1.multNtr(), - collision1.multV0M(), - p2.charge(), - pairSign, - deltaInvMassPair, - processType, - charmHadMc, - originType); - - mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), pairQASetting.use4D, pairQASetting.extendedPlots, smearingByOrigin); - } - } - } - - template - void fillTables(const CollType& col, - const TrackType& sliceTrk1, - const CandType& sliceCharmHad) - { - int64_t timeStamp = -999; - - for (auto const& part : sliceCharmHad) { - float invMass = getCharmHadronMass(part); - registryCharmHadronQa.fill( - HIST("CharmHadronQA/hPtVsMass"), - part.pt(), invMass); - - timeStamp = part.timeStamp(); - - rowFemtoResultCharm3Prong( - col.globalIndex(), - timeStamp, - invMass, - part.pt(), - part.eta(), - part.phi(), - part.prong0Id(), - part.prong1Id(), - part.prong2Id(), - part.charge(), - part.bdtBkg(), - part.bdtPrompt(), - part.bdtFD()); - } - - for (auto const& part : sliceTrk1) { - allTrackHisto.fillQA( - part, - static_cast(confTempFitVarMomentum.value), - col.multNtr(), - col.multV0M()); - - float chargeTrack = ((part.cut() & CutBitChargePositive) == CutBitChargePositive) - ? PositiveCharge - : NegativeCharge; - - timeStamp = part.timeStamp(); - float tpcNSigma = 999.f; - float tofNSigma = 999.f; - switch (trackSel.pdgCodeTrack1.value) { - case kProton: - tpcNSigma = part.tpcNSigmaPr(); - tofNSigma = part.tofNSigmaPr(); - break; - case kPiPlus: - tpcNSigma = part.tpcNSigmaPi(); - tofNSigma = part.tofNSigmaPi(); - break; - case kKPlus: - tpcNSigma = part.tpcNSigmaKa(); - tofNSigma = part.tofNSigmaKa(); - break; - case kDeuteron: - tpcNSigma = part.tpcNSigmaDe(); - tofNSigma = part.tofNSigmaDe(); - break; - default: - LOG(fatal) << "Invalid PDG code for track PID QA: " << trackSel.pdgCodeTrack1.value; - } - - rowFemtoResultTrk( - col.globalIndex(), - timeStamp, - part.pt(), - part.eta(), - part.phi(), - part.trackId(), - chargeTrack, - part.tpcNClsFound(), - part.tpcNClsFindable(), - part.tpcNClsCrossedRows(), - tpcNSigma, - tofNSigma); - } - - if (sliceCharmHad.size() > 0 || sliceTrk1.size() > 0) { - rowFemtoResultColl( - col.globalIndex(), - timeStamp, - col.posZ(), - col.multNtr()); - } - } - - void processDataXicTrk(FilteredCollisions const& cols, - FilteredFDParticles const& parts, - FilteredCharmCand3Prongs const&) - { - for (const auto& col : cols) { - eventHisto.fillQA(col); - auto* partitionTrk1Selected = &partitionTrk1; - if (trackSel.pdgCodeTrack1.value == kKPlus) { - partitionTrk1Selected = &partitionTrk1Ka; - } - auto sliceTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto sliceCharmHad = partitionCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - if (fillTableWithCharm.value && sliceCharmHad.size() == 0) { - continue; - } else { - fillTables(col, sliceTrk1, sliceCharmHad); - } - if (sliceCharmHad.size() > 0 && sliceTrk1.size() > 0) { - doSameEvent(sliceCharmHad, sliceTrk1, parts, col); - } - } - if (mixSetting.doMixEvent) { - auto* partitionTrk1Selected = &partitionTrk1; - if (trackSel.pdgCodeTrack1.value == kKPlus) { - partitionTrk1Selected = &partitionTrk1Ka; - } - switch (mixSetting.mixingBinPolicy) { - case femtodreamcollision::kMult: - doMixedEvent(cols, partitionCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMult); - break; - case femtodreamcollision::kMultPercentile: - doMixedEvent(cols, partitionCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultPercentile); - break; - case femtodreamcollision::kMultMultPercentile: - doMixedEvent(cols, partitionCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultMultPercentile); - break; - default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; - } - } - } - PROCESS_SWITCH(HfTaskCharmCascadeHadronsTrackFemtoDream, processDataXicTrk, "Enable processing XicToXiPiPi and Tracks correlation", false); - - void processMcXicTrk(FilteredMcColisions const& cols, - FilteredFDMcParts const& parts, - o2::aod::FDMCParticles const&, - o2::aod::FDExtMCParticles const&, - FilteredCharmMcCand3Prongs const&) - { - for (const auto& col : cols) { - eventHisto.fillQA(col); - auto* partitionTrk1Selected = &partitionMcTrk1; - if (trackSel.pdgCodeTrack1.value == kKPlus) { - partitionTrk1Selected = &partitionMcTrk1Ka; - } - auto sliceMcTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto sliceMcCharmHad = partitionMcCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { - continue; - } - doSameEvent(sliceMcCharmHad, sliceMcTrk1, parts, col); - } - auto* partitionTrk1Selected = &partitionMcTrk1; - if (trackSel.pdgCodeTrack1.value == kKPlus) { - partitionTrk1Selected = &partitionMcTrk1Ka; - } - switch (mixSetting.mixingBinPolicy) { - case femtodreamcollision::kMult: - doMixedEvent(cols, partitionMcCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMult); - break; - case femtodreamcollision::kMultPercentile: - doMixedEvent(cols, partitionMcCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultPercentile); - break; - case femtodreamcollision::kMultMultPercentile: - doMixedEvent(cols, partitionMcCharmHadron3Prong, *partitionTrk1Selected, parts, colBinningMultMultPercentile); - break; - default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; - } - } - PROCESS_SWITCH(HfTaskCharmCascadeHadronsTrackFemtoDream, processMcXicTrk, "Enable processing XicToXiPiPi and Tracks correlation for Monte Carlo", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index a0b6b1aed76..386b99b91d7 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -86,7 +86,8 @@ struct HfTaskCharmHadronsTrackFemtoDream { enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, D0ToPiK, - DstarToD0Pi + DstarToD0Pi, + XicToXiPiPi }; constexpr static int OriginRecPrompt = 1; @@ -107,14 +108,14 @@ struct HfTaskCharmHadronsTrackFemtoDream { struct : ConfigurableGroup { Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron"}; - Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "charm hadron selection for mc, DplusToPiKPi = 1, LcToPKPi = 17"}; + Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "charm hadron selection for mc, DplusToPiKPi = 1, XicToXiPiPi = 1, LcToPKPi = 17"}; Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.45, "Maximum invariant mass of Charm Hadron (particle 2)"}; Configurable charmHadMinInvMass{"charmHadMinInvMass", 2.15, "Minimum invariant mass of Charm Hadron (particle 2)"}; Configurable charmHadMinPt{"charmHadMinPt", 0., "Minimum pT of Charm Hadron (particle 2)"}; Configurable charmHadMaxPt{"charmHadMaxPt", 999., "Maximum pT of Charm Hadron (particle 2)"}; - Configurable charmHadPDGCode{"charmHadPDGCode", 4122, "PDG code of particle 2 Charm Hadron"}; + Configurable charmHadPDGCode{"charmHadPDGCode", Pdg::kLambdaCPlus, "PDG code of particle 2 Charm Hadron"}; Configurable charmHadPromptBDTmin{"charmHadPromptBDTmin", 0., "Minimum prompt bdt score Charm Hadron (particle 2)"}; Configurable charmHadPromptBDTmax{"charmHadPromptBDTmax", 1., "Maximum prompt bdt score Charm Hadron (particle 2)"}; } charmSel; @@ -150,7 +151,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { /// Particle 1 (track) struct : ConfigurableGroup { Configurable cutBitTrack1{"cutBitTrack1", 8188, "Particle 1 (Track) - Selection bit from cutCulator"}; - Configurable pdgCodeTrack1{"pdgCodeTrack1", 2212, "PDG code of Particle 1 (Track)"}; + Configurable pdgCodeTrack1{"pdgCodeTrack1", kProton, "PDG code of Particle 1 (Track)"}; Configurable pidThresTrack1{"pidThresTrack1", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; Configurable tpcBitTrack1{"tpcBitTrack1", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; Configurable tpcTofBitTrack1{"tpcTofBitTrack1", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; @@ -164,6 +165,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmCand3Prongs = soa::Filtered; using FilteredCharmCand3Prong = FilteredCharmCand3Prongs::iterator; + using FilteredCharmCand3ProngsXic = soa::Filtered>; + using FilteredCharmCand3ProngXic = FilteredCharmCand3ProngsXic::iterator; + using FilteredCharmCand2Prongs = soa::Filtered; using FilteredCharmCand2Prong = FilteredCharmCand2Prongs::iterator; @@ -173,6 +177,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmMcCand3Prongs = soa::Filtered>; using FilteredCharmMcCand3Prong = FilteredCharmMcCand3Prongs::iterator; + using FilteredCharmMcCand3ProngsXic = soa::Filtered>; + using FilteredCharmMcCand3ProngXic = FilteredCharmMcCand3ProngsXic::iterator; + using FilteredCharmMcCand2Prongs = soa::Filtered>; using FilteredCharmMcCand2Prong = FilteredCharmMcCand2Prongs::iterator; @@ -200,10 +207,13 @@ struct HfTaskCharmHadronsTrackFemtoDream { Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < trackSel.ptTrack1Max, true); Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > trackSel.ptTrack1Min, true); - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; + struct : PresliceGroup { + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngXicByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; + } preslices; /// Partition for particle 1 Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); @@ -217,10 +227,12 @@ struct HfTaskCharmHadronsTrackFemtoDream { /// Partition for particle 2 Partition partitionCharmHadron3Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; + Partition partitionCharmHadron3ProngXic = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadron2Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadronDstar = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionMcCharmHadron3Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; + Partition partitionMcCharmHadron3ProngXic = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; Partition partitionMcCharmHadron2Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; Partition partitionMcCharmHadronDstar = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; @@ -282,21 +294,23 @@ struct HfTaskCharmHadronsTrackFemtoDream { HistogramRegistry registryMixQa{"registryMixQa"}; HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; - float massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1); - float massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode); - int8_t partSign = 0; + float massOne = 0.f; + float massTwo = 0.f; int64_t processType = 0; void init(InitContext& /*context*/) { - std::array processes = {doprocessDataLcTrk, doprocessDataDplusTrk, doprocessDataD0Trk, doprocessDataDstarTrk, doprocessMcLcTrk, doprocessMcDplusTrk, doprocessMcD0Trk, doprocessMcDstarTrk}; + std::array processes = {doprocessDataLcTrk, doprocessDataDplusTrk, doprocessDataD0Trk, doprocessDataDstarTrk, doprocessDataXicTrk, doprocessMcLcTrk, doprocessMcDplusTrk, doprocessMcD0Trk, doprocessMcDstarTrk, doprocessMcXicTrk}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } - bool process3Prong = doprocessDataLcTrk || doprocessDataDplusTrk || doprocessMcLcTrk || doprocessMcDplusTrk; + bool process3Prong = doprocessDataLcTrk || doprocessDataDplusTrk || doprocessDataXicTrk || doprocessMcLcTrk || doprocessMcDplusTrk || doprocessMcXicTrk; bool process2Prong = doprocessDataD0Trk || doprocessMcD0Trk; bool processDstar = doprocessDataDstarTrk || doprocessMcDstarTrk; + massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1.value); + massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode.value); + // setup columnpolicy for binning colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; @@ -312,7 +326,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { highkstarCut, smearingByOrigin, binInvMass); - sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1.value, charmSel.charmHadPDGCode.value); mixedEventCont.init(®istry, binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, @@ -320,7 +334,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { highkstarCut, smearingByOrigin, binInvMass); - mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1.value, charmSel.charmHadPDGCode.value); registryMixQa.add("MixingQA/hSECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); registryMixQa.add("MixingQA/hSECollisionPool", "; Vz (cm); Mul", kTH2F, {{100, -10, 10}, {200, 0, 200}}); registryMixQa.add("MixingQA/hMECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); @@ -349,7 +363,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { } /// Compute the charm hadron candidates mass with the daughter masses - /// assumes the candidate is either a D+ or Λc+ or D0 or Dstar + /// assumes the candidate is either a D+ or Lc+ or D0 or Dstar or Xic+ template float getCharmHadronMass(const Candidate& cand, bool ReturnDaughMass = false) { @@ -387,6 +401,8 @@ struct HfTaskCharmHadronsTrackFemtoDream { } else { return mDstar - mD0; } + } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { + return cand.invMassCharm(); } // Add more channels as needed return 0.f; @@ -433,7 +449,15 @@ struct HfTaskCharmHadronsTrackFemtoDream { return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); } - // 3-prong:Λc → p K π, D+ → π K π + track + // Xic+ -> Xi pi pi + track + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); + const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; + const std::array massCharmTrk{MassXiMinus, MassPiPlus, MassPiPlus, trackMassHyp}; + return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); + } + + // 3-prong: Lc -> p K pi, D+ -> pi K pi, D* -> D0 pi + track if constexpr (Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::DstarToD0Pi) { auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; @@ -502,6 +526,22 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || + p1.trackId() == p2.cascPosTrackId() || p1.trackId() == p2.cascNegTrackId()) { + continue; + } + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionSE3Prong.isClosePair(p1, p2, parts, col.magField())) { + continue; + } + } + + if (!pairCleaner3Prong.isCleanPair(p1, p2, parts)) { + continue; + } + } + if constexpr (Channel == DecayChannel::DstarToD0Pi) { if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id()) { continue; @@ -619,7 +659,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } - if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { + if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::XicToXiPiPi) { if (pairQASetting.useCPR.value) { if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { @@ -724,7 +764,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { timeStamp = part.timeStamp(); - if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { + if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::XicToXiPiPi) { rowFemtoResultCharm3Prong( col.globalIndex(), @@ -992,6 +1032,49 @@ struct HfTaskCharmHadronsTrackFemtoDream { } PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processDataDstarTrk, "Enable processing DstarToD0Pi and Tracks correlation", false); + void processDataXicTrk(FilteredCollisions const& cols, + FilteredFDParticles const& parts, + FilteredCharmCand3ProngsXic const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + auto sliceTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceCharmHad = partitionCharmHadron3ProngXic->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (fillTableWithCharm.value && sliceCharmHad.size() == 0) { + continue; + } else { + fillTables(col, sliceTrk1, sliceCharmHad); + } + if (sliceCharmHad.size() > 0 && sliceTrk1.size() > 0) { + doSameEvent(sliceCharmHad, sliceTrk1, parts, col); + } + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processDataXicTrk, "Enable processing XicToXiPiPi and Tracks correlation", false); + void processMcLcTrk(FilteredMcColisions const& cols, FilteredFDMcParts const& parts, o2::aod::FDMCParticles const&, @@ -1131,6 +1214,47 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processMcDstarTrk, "Enable processing DstarToD0Pi and Tracks correlation for Monte Carlo", false); + + void processMcXicTrk(FilteredMcColisions const& cols, + FilteredFDMcParts const& parts, + o2::aod::FDMCParticles const&, + o2::aod::FDExtMCParticles const&, + FilteredCharmMcCand3ProngsXic const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + auto sliceMcTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceMcCharmHad = partitionMcCharmHadron3ProngXic->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { + continue; + } + doSameEvent(sliceMcCharmHad, sliceMcTrk1, parts, col); + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processMcXicTrk, "Enable processing XicToXiPiPi and Tracks correlation for Monte Carlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From bf0a17b812d9179b9c8e9afc8f04e7c4477aad2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Tue, 16 Jun 2026 08:33:00 +0200 Subject: [PATCH 03/17] Limit kaon source classification to Omega --- PWGCF/DataModel/FemtoDerived.h | 37 +------ .../FemtoDream/Core/femtoDreamParticleHisto.h | 99 +------------------ PWGCF/FemtoDream/Core/femtoDreamUtils.h | 54 ---------- .../Core/FemtoUniverseEfficiencyCorrection.h | 8 -- .../Core/FemtoUniverseParticleHisto.h | 80 --------------- PWGCF/FemtoUniverse/Core/femtoUtils.h | 48 +-------- PWGCF/FemtoUniverse/DataModel/FemtoDerived.h | 36 +------ .../femtoUniverseProducerMCTruthTask.cxx | 2 +- .../femtoUniverseProducerReducedTask.cxx | 2 +- .../femtoUniverseProducerTask.cxx | 6 +- .../Tasks/femtoUniverseEfficiencyBase.cxx | 4 +- 11 files changed, 19 insertions(+), 357 deletions(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 36d123b1d5e..29fb493c4ca 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -674,16 +674,11 @@ enum ParticleOriginMCTruth { kSecondaryDaughterLambda, //! Daughter from a Lambda decay kSecondaryDaughterSigmaplus, //! Daughter from a Sigma^plus decay kSecondaryDaughterSigma0, //! Daughter from a Sigma^0 decay - kSecondaryDaughterSigmaminus, //! Daughter from a Sigma^- decay kSecondaryDaughterXiMinus, //! Daughter from a Xi^- decay kSecondaryDaughterXi0, //! Daughter from a Xi^0 decay kSecondaryDaughterOmegaMinus, //! Daughter from a Omega^- decay kSecondaryDaughterXistar0, //! Daughter from a Xi*^0 decay kSecondaryDaughterXistarMinus, //! Daughter from a Xi*^- decay - kSecondaryDaughterK0Long, //! Daughter from a K0 long decay - kSecondaryDaughterK0Short, //! Daughter from a K0 short decay - kSecondaryDaughterKCharged, //! Daughter from a charged kaon decay - kSecondaryDaughterPionCharged, //! Daughter from a charged pion decay kElse, //! none of the above; (NOTE: used to catch bugs. will be removed once MC usage is properly validated) kNOriginMCTruthTypes }; @@ -695,38 +690,8 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_Material", "_NotPrimary", "_Fake", - "_WrongCollision", "_SecondaryDaughterLambda", - "_SecondaryDaughterSigmaplus", - "_SecondaryDaughterSigma0", - "_SecondaryDaughterSigmaminus", - "_SecondaryDaughterXiMinus", - "_SecondaryDaughterXi0", - "_SecondaryDaughterOmegaMinus", - "_SecondaryDaughterXistar0", - "_SecondaryDaughterXistarMinus", - "_SecondaryDaughterK0Long", - "_SecondaryDaughterK0Short", - "_SecondaryDaughterKCharged", - "_SecondaryDaughterPionCharged", - "_Else"}; - -inline constexpr bool isSecondaryOrigin(uint8_t origin) -{ - return origin == kSecondary || origin == kSecondaryDaughterLambda || - origin == kSecondaryDaughterSigmaplus || - origin == kSecondaryDaughterSigma0 || - origin == kSecondaryDaughterSigmaminus || - origin == kSecondaryDaughterXiMinus || - origin == kSecondaryDaughterXi0 || - origin == kSecondaryDaughterOmegaMinus || - origin == kSecondaryDaughterXistar0 || - origin == kSecondaryDaughterXistarMinus || - origin == kSecondaryDaughterK0Long || - origin == kSecondaryDaughterK0Short || - origin == kSecondaryDaughterKCharged || - origin == kSecondaryDaughterPionCharged; -} + "_SecondaryDaughterSigmaPlus"}; /// Distinguished between reconstructed and truth enum MCType { diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index 24b018cc108..ae3e12e9f69 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -209,10 +209,11 @@ class FemtoDreamParticleHisto { /// Particle-type specific histograms std::string folderSuffix = static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]).c_str(); + const auto nMcOriginTypes = static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::HistType::kTH1F, {{240, 0, 6}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes), -0.5, static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes) - 0.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{nMcOriginTypes, -0.5, static_cast(nMcOriginTypes) - 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", o2::framework::HistType::kTH1I, {{1, -0.5, 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_DiffTruthReco").c_str(), "; p^{truth}_{T}; (p^{reco}_{T} - p^{truth}_{T}) / p^{truth}_{T}", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, {200, -1, 1}}); mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", o2::framework::HistType::kTH2F, {{200, -1, 1}, {200, -1, 1}}); @@ -229,15 +230,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigma0").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaminus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterXiMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterXi0").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterOmegaMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterK0Long").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterK0Short").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterKCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterPionCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); @@ -246,15 +239,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXiMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXi0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); } else { mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -264,15 +249,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXiMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterXi0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } @@ -643,51 +620,11 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar(), part.dcaZ(), mult); break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigma0): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterSigma0"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigma0"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigmaminus): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterSigmaminus"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaminus"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXiMinus): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterXiMinus"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXiMinus"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXi0): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterXi0"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXi0"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterOmegaMinus"), part.fdExtMCParticle().motherPDG()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), part.pt(), part.tempFitVar(), part.dcaZ(), mult); break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Long): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterK0Long"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Long"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Short): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterK0Short"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Short"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterKCharged): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterKCharged"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterKCharged"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterPionCharged): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterPionCharged"), part.fdExtMCParticle().motherPDG()); - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterPionCharged"), - part.pt(), part.tempFitVar(), part.dcaZ(), mult); - break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_Else"), part.fdExtMCParticle().motherPDG()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), @@ -726,42 +663,10 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar()); break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigma0): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigma0"), - part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterSigmaminus): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaminus"), - part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXiMinus): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXiMinus"), - part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterXi0): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterXi0"), - part.pt(), part.tempFitVar()); - break; case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), part.pt(), part.tempFitVar()); break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Long): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Long"), - part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterK0Short): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterK0Short"), - part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterKCharged): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterKCharged"), - part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtodreamMCparticle::kSecondaryDaughterPionCharged): - mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterPionCharged"), - part.pt(), part.tempFitVar()); - break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index f1c39526336..fde124f5db4 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -131,33 +131,6 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, case kSigmaPlus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaplus; break; - case kSigma0: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; - break; - case kSigmaMinus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaminus; - break; - case kXiMinus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXiMinus; - break; - case o2::constants::physics::Pdg::kXi0: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXi0; - break; - case kOmegaMinus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; - break; - case kK0Long: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Long; - break; - case kK0Short: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Short; - break; - case kKPlus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterKCharged; - break; - case kPiPlus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterPionCharged; - break; default: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; } // switch @@ -185,33 +158,6 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, case kSigmaPlus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaplus; break; - case kSigma0: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; - break; - case kSigmaMinus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigmaminus; - break; - case kXiMinus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXiMinus; - break; - case o2::constants::physics::Pdg::kXi0: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterXi0; - break; - case kOmegaMinus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; - break; - case kK0Long: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Long; - break; - case kK0Short: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterK0Short; - break; - case kKPlus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterKCharged; - break; - case kPiPlus: - partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterPionCharged; - break; default: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; } // switch diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h index 1d8ef2aef5a..23506574426 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h @@ -167,14 +167,6 @@ class EfficiencyCorrection case (o2::aod::femtouniverse_mc_particle::kDaughter): case (o2::aod::femtouniverse_mc_particle::kDaughterLambda): case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaplus): - case (o2::aod::femtouniverse_mc_particle::kDaughterSigma0): - case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaminus): - case (o2::aod::femtouniverse_mc_particle::kDaughterXi): - case (o2::aod::femtouniverse_mc_particle::kDaughterOmega): - case (o2::aod::femtouniverse_mc_particle::kDaughterK0Long): - case (o2::aod::femtouniverse_mc_particle::kDaughterK0Short): - case (o2::aod::femtouniverse_mc_particle::kDaughterKCharged): - case (o2::aod::femtouniverse_mc_particle::kDaughterPionCharged): histRegistry->fill(HIST(histDirectory) + HIST("/") + HIST(histSuffix[N - 1]) + HIST("/hSecondary"), mcParticle.pt(), mcParticle.eta(), diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h index db684ef8219..02f5a330340 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h @@ -171,14 +171,6 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigma0").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigmaminus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterXi").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterOmega").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterK0Long").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterK0Short").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterKCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterPionCharged").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Daughter").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -188,14 +180,6 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterXi").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterOmega").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_NoMCTruthOrigin").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hMisidentification").c_str(), "; #it{p}_{T} (GeV/#it{c}); Particle; Particle", o2::framework::HistType::kTH3F, {{4, 0, 4}, {4, 0, 4}, tempFitVarpTAxis}); @@ -211,14 +195,6 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigma0").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaminus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterXi").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterOmega").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Long").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterK0Short").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterKCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterPionCharged").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0) { @@ -431,38 +407,6 @@ class FemtoUniverseParticleHisto // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterSigmaplus"), part.fdMCParticle().motherPDG()); mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaplus"), part.pt(), part.tempFitVar()); break; - case (o2::aod::femtouniverse_mc_particle::kDaughterSigma0): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterSigma0"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigma0"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaminus): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterSigmaminus"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaminus"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterXi): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterXi"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterXi"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterOmega): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterOmega"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterOmega"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterK0Long): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterK0Long"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Long"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterK0Short): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterK0Short"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Short"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterKCharged): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterKCharged"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterKCharged"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterPionCharged): - // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_DaughterPionCharged"), part.fdMCParticle().motherPDG()); - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterPionCharged"), part.pt(), part.tempFitVar()); - break; case (o2::aod::femtouniverse_mc_particle::kElse): // mHistogramRegistry->fill(histFolder + HIST("_MC/Debug/hPDGmother_Else"), part.fdMCParticle().motherPDG()); mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); @@ -494,30 +438,6 @@ class FemtoUniverseParticleHisto case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaplus): mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaplus"), part.pt(), part.tempFitVar()); break; - case (o2::aod::femtouniverse_mc_particle::kDaughterSigma0): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigma0"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterSigmaminus): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterSigmaminus"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterXi): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterXi"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterOmega): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterOmega"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterK0Long): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Long"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterK0Short): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterK0Short"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterKCharged): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterKCharged"), part.pt(), part.tempFitVar()); - break; - case (o2::aod::femtouniverse_mc_particle::kDaughterPionCharged): - mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_DaughterPionCharged"), part.pt(), part.tempFitVar()); - break; case (o2::aod::femtouniverse_mc_particle::kElse): mHistogramRegistry->fill(histFolder + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); break; diff --git a/PWGCF/FemtoUniverse/Core/femtoUtils.h b/PWGCF/FemtoUniverse/Core/femtoUtils.h index a3cd3804b2d..daeef089442 100644 --- a/PWGCF/FemtoUniverse/Core/femtoUtils.h +++ b/PWGCF/FemtoUniverse/Core/femtoUtils.h @@ -27,8 +27,6 @@ #include #include -#include - namespace o2::analysis::femto_universe { @@ -102,56 +100,18 @@ bool isFullPIDSelected(aod::femtouniverseparticle::CutContainerType const& pidCu return pidSelection; }; -int checkDaughterType(o2::aod::femtouniverseparticle::ParticleType partType, int motherPDG, int daughterPDG = 0) +int checkDaughterType(o2::aod::femtouniverseparticle::ParticleType partType, int motherPDG) { int partOrigin = 0; - const auto absMotherPDG = std::abs(motherPDG); - const auto absDaughterPDG = std::abs(daughterPDG); - - if (absDaughterPDG == kKPlus && partType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { - switch (absMotherPDG) { - case kOmegaMinus: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterOmega; - break; - default: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter; - } - return partOrigin; - } - if (partType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { - switch (absMotherPDG) { - case kLambda0: + switch (std::abs(motherPDG)) { + case 3122: partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterLambda; break; - case kSigmaPlus: + case 3222: partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaplus; break; - case kSigma0: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigma0; - break; - case kSigmaMinus: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaminus; - break; - case kXiMinus: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterXi; - break; - case kOmegaMinus: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterOmega; - break; - case kK0Long: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterK0Long; - break; - case kK0Short: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterK0Short; - break; - case kKPlus: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterKCharged; - break; - case kPiPlus: - partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterPionCharged; - break; default: partOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter; } // switch diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index 22102903217..71a3a3acdeb 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -269,18 +269,10 @@ enum ParticleOriginMCTruth { kMaterial, //! Particle from a material kNotPrimary, //! Not primary particles (kept for compatibility reasons with the FullProducer task. will be removed, since we look at "non primaries" more differentially now) kFake, //! Particle, that has NOT the PDG code of the current analysed particle - kDaughterLambda, //! Daughter from a Lambda decay - kDaughterSigmaplus, //! Daughter from a Sigma^plus decay - kDaughterSigma0, //! Daughter from a Sigma^0 decay - kDaughterSigmaminus, //! Daughter from a Sigma^- decay - kDaughterXi, //! Daughter from a Xi decay - kDaughterOmega, //! Daughter from an Omega decay - kDaughterK0Long, //! Daughter from a K0 long decay - kDaughterK0Short, //! Daughter from a K0 short decay - kDaughterKCharged, //! Daughter from a charged kaon decay - kDaughterPionCharged, //! Daughter from a charged pion decay - kPrompt, //! Origin for D0/D0bar mesons - kNonPrompt, //! Origin for D0/D0bar mesons + kDaughterLambda, //! Daughter from a Lambda decay + kDaughterSigmaplus, //! Daughter from a Sigma^plus decay + kPrompt, //! Origin for D0/D0bar mesons + kNonPrompt, //! Origin for D0/D0bar mesons kNOriginMCTruthTypes, kElse, kWrongCollision //! Origin for the wrong collision @@ -294,28 +286,10 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_NotPrimary", "_Fake", "_DaughterLambda", - "_DaughterSigmaplus", - "_DaughterSigma0", - "_DaughterSigmaminus", - "_DaughterXi", - "_DaughterOmega", - "_DaughterK0Long", - "_DaughterK0Short", - "_DaughterKCharged", - "_DaughterPionCharged", + "DaughterSigmaPlus", "_Prompt", "_NonPrompt"}; -inline constexpr bool isDaughterOrigin(uint8_t origin) -{ - return origin == kDaughter || origin == kDaughterLambda || - origin == kDaughterSigmaplus || origin == kDaughterSigma0 || - origin == kDaughterSigmaminus || origin == kDaughterXi || - origin == kDaughterOmega || origin == kDaughterK0Long || - origin == kDaughterK0Short || origin == kDaughterKCharged || - origin == kDaughterPionCharged; -} - /// Distinguished between reconstructed and truth enum MCType { kRecon, //! Reconstructed in case of MC and used as default in case of data diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index 816f35e4cef..3f94d573ee9 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -90,7 +90,7 @@ struct FemtoUniverseProducerMCTruthTask { Configurable confIsRun3{"confIsRun3", false, "Running on Run3 or pilot"}; Configurable confIsMC{"confIsMC", false, "Running on MC; implemented only for Run3"}; Configurable confIsForceGRP{"confIsForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; - Configurable> confPDGCodes{"confPDGCodes", std::vector{kPiPlus, -kPiPlus, kKPlus, kKMinus, kProton, -kProton, Pdg::kPhi}, "PDG of particles to be stored"}; + Configurable> confPDGCodes{"confPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; Configurable confAnalysisWithPID{"confAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles"}; /// Event cuts diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx index eab5b5226c4..a0eb1fe69d1 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx @@ -214,7 +214,7 @@ struct femtoUniverseProducerReducedTask { if (particleMC.isPhysicalPrimary()) { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary; } else if (motherparticleMC.producedByGenerator()) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); } else { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial; } diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 952a29d0f73..a112f5f4768 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -176,7 +176,7 @@ struct FemtoUniverseProducerTask { Configurable confIsActivatePhi{"confIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; Configurable confIsActiveD0{"confIsActiveD0", false, "Activate filling FU tables for D0/D0bar mesons"}; Configurable confMCTruthAnalysisWithPID{"confMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; - Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{kPiPlus, -kPiPlus, kKPlus, kKMinus, kProton, -kProton, Pdg::kPhi}, "PDG of particles to be stored"}; + Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; Configurable confCentFT0Min{"confCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; Configurable confCentFT0Max{"confCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; Configurable confEvIsGoodZvtxFT0vsPV{"confEvIsGoodZvtxFT0vsPV", true, "Require kIsGoodZvtxFT0vsPV selection on Events."}; @@ -946,7 +946,7 @@ struct FemtoUniverseProducerTask { } else if (!motherparticlesMC.empty()) { auto motherparticleMC = motherparticlesMC.front(); if (motherparticleMC.producedByGenerator()) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); } else { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial; } @@ -979,7 +979,7 @@ struct FemtoUniverseProducerTask { if (!mothers.empty()) { auto mother = mothers.front(); if (mother.producedByGenerator()) { - particleOrigin = checkDaughterType(fdparttype, mother.pdgCode(), pdgCode); + particleOrigin = checkDaughterType(fdparttype, mother.pdgCode()); } else { particleOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index 34bff602357..f8c99fb90d7 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -700,7 +700,7 @@ struct FemtoUniverseEfficiencyBase { if (fillSecTrkContHistos) { if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { registrySecTrkCont.fill(HIST("part1/hDCAxy_Primary"), part.pt(), part.tempFitVar()); - } else if (aod::femtouniverse_mc_particle::isDaughterOrigin(mcParticle.partOriginMCTruth())) { + } else if ((mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterLambda) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaplus)) { registrySecTrkCont.fill(HIST("part1/hDCAxy_Daughter"), part.pt(), part.tempFitVar()); } else if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial) { registrySecTrkCont.fill(HIST("part1/hDCAxy_Material"), part.pt(), part.tempFitVar()); @@ -790,7 +790,7 @@ struct FemtoUniverseEfficiencyBase { if (fillSecTrkContHistos) { if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { registrySecTrkCont.fill(HIST("part2/hDCAxy_Primary"), part.pt(), part.tempFitVar()); - } else if (aod::femtouniverse_mc_particle::isDaughterOrigin(mcParticle.partOriginMCTruth())) { + } else if ((mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughter) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterLambda) || (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kDaughterSigmaplus)) { registrySecTrkCont.fill(HIST("part2/hDCAxy_Daughter"), part.pt(), part.tempFitVar()); } else if (mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kMaterial) { registrySecTrkCont.fill(HIST("part2/hDCAxy_Material"), part.pt(), part.tempFitVar()); From c8b855c91ce2574b683b7e8638db7ad4ef91b847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Tue, 16 Jun 2026 17:09:30 +0200 Subject: [PATCH 04/17] Refactor charm-track femto producer for Xic --- PWGHF/HFC/TableProducer/CMakeLists.txt | 5 - ...ucerCharmCascadeHadronsTrackFemtoDream.cxx | 706 ------------------ .../producerCharmHadronsTrackFemtoDream.cxx | 532 +++++++++---- 3 files changed, 398 insertions(+), 845 deletions(-) delete mode 100644 PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 9fbd484933a..d0c1fb800ff 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -94,11 +94,6 @@ o2physics_add_dpl_workflow(producer-charm-hadrons-track-femto-dream PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(producer-charm-cascade-hadrons-track-femto-dream - SOURCES producerCharmCascadeHadronsTrackFemtoDream.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::EventFilteringUtils - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(producer-charm-hadrons-v0-femto-dream SOURCES producerCharmHadronsV0FemtoDream.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::EventFilteringUtils diff --git a/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx deleted file mode 100644 index 0db94d38a0e..00000000000 --- a/PWGHF/HFC/TableProducer/producerCharmCascadeHadronsTrackFemtoDream.cxx +++ /dev/null @@ -1,706 +0,0 @@ -// Copyright 2019-2025 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file producerCharmCascadeHadronsTrackFemtoDream.cxx -/// \brief FemtoDream producer for Ξc± → Ξ∓ π± π± + associated track (e.g. π) -/// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch - -#include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/HfMlResponseXicToXiPiPi.h" -#include "PWGHF/Core/DecayChannelsLegacy.h" -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/DataModel/AliasTables.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" - -#include "Common/Core/RecoDecay.h" -#include "Common/Core/ZorroSummary.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::analysis; -using namespace o2::framework::expressions; -using namespace o2::analysis::femtoDream; -using namespace o2::hf_evsel; -using namespace o2::hf_centrality; -using namespace o2::aod::hf_cand_xic_to_xi_pi_pi; - -enum Event : uint8_t { - All = 0, - RejEveSel, - RejNoTracksAndCharm, - TrackSelected, - CharmSelected, - PairSelected -}; - -enum MlMode : uint8_t { - NoMl = 0, - FillMlFromSelector, - FillMlFromNewBDT -}; - -struct HfProducerCharmCascadeHadronsTrackFemtoDream { - - Produces outputCollision; - Produces rowMasks; - Produces rowCandCharm3Prong; - Produces rowCandCharm3ProngXic; - Produces rowCandMcCharmHad; - Produces rowCandCharmHadGen; - Produces outputPartsIndex; - Produces outputPartsTime; - Produces outputMcCollision; - Produces outputCollsMcLabels; - Produces outputParts; - Produces outputPartsMc; - Produces outputDebugParts; - Produces outputPartsMcLabels; - Produces outputDebugPartsMc; - Produces outputPartsExtMcLabels; - - struct : ConfigurableGroup { - 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)"}; - Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTXicToXiPiPi"}, "Paths of models on CCDB"}; - Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_XicToXiPiPi.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"}; - } ccdbCfg; - - struct : ConfigurableGroup { - Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; - 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"}; - } mlCfg; - - struct : ConfigurableGroup { - Configurable pTrackMethod1Max{"pTrackMethod1Max", 0.85f, "Kaon PID Method1 (TPC-only): maximum p (GeV/c)"}; - Configurable pTrackExcludeMin{"pTrackExcludeMin", 0.50f, "Kaon PID Method1: excluded p window minimum (GeV/c)"}; - Configurable pTrackExcludeMax{"pTrackExcludeMax", 0.65f, "Kaon PID Method1: excluded p window maximum (GeV/c)"}; - Configurable pTrackPiRejMin{"pTrackPiRejMin", 0.50f, "Kaon PID Method1: pion rejection active for p > this (GeV/c)"}; - Configurable pTrackElRejMin{"pTrackElRejMin", 0.30f, "Kaon PID Method1: electron rejection active for p > this (GeV/c)"}; - Configurable pTrackTightMin{"pTrackTightMin", 1.20f, "Kaon PID Method2 (TPC+TOF): tighten cuts for p > this (GeV/c)"}; - Configurable nSigmaTpcKaMax{"nSigmaTpcKaMax", 3.f, "Kaon PID Method1: require |nSigmaTpcKa| < this"}; - Configurable nSigmaTpcPiMin{"nSigmaTpcPiMin", 3.f, "Kaon PID Method1: require |nSigmaTpcPi| > this (pion)"}; - Configurable nSigmaTpcElMin{"nSigmaTpcElMin", 3.f, "Kaon PID Method1: require |nSigmaTpcEl| > this (electron)"}; - Configurable nSigmaCombKaMax{"nSigmaCombKaMax", 3.f, "Kaon PID Method2: require |nSigmaCombKa| < this"}; - Configurable nSigmaCombKaTightMax{"nSigmaCombKaTightMax", 2.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombKa| < this"}; - Configurable nSigmaCombPiMax{"nSigmaCombPiMax", 6.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombPi| < this"}; - } kaonPidSel; - - Configurable isDebug{"isDebug", true, "Enable Debug tables"}; - Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection flag for Ξc± → Ξππ (same bit mask as hf_sel_candidate_xic::isSelXicToXiPiPi)"}; - Configurable useCent{"useCent", false, "Enable centrality for charm hadron"}; - - Configurable trkPDGCode{"trkPDGCode", kPiPlus, "PDG code of the associated track for MC truth and PID (default: π)"}; - Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; - Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; - Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; - Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; - Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; - Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; - Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; - Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.15f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; - Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; - Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; - Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; - Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; - Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; - Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; - - FemtoDreamTrackSelection trackCuts; - o2::analysis::HfMlResponseXicToXiPiPi hfMlResponseXic; - std::vector outputMlXic; - o2::ccdb::CcdbApi ccdbApi; - o2::hf_evsel::HfEventSelection hfEvSel; - Service ccdb{}; - o2::base::MatLayerCylSet* lut{}; - - float magField{}; - int runNumber{}; - - using CandidateXic = soa::Join; - using CandidateXicMc = soa::Join; - using CandidateXicKf = soa::Join; - using CandidateXicKfMc = soa::Join; - - using FemtoFullCollision = soa::Join::iterator; - using FemtoFullCollisionMc = soa::Join::iterator; - using FemtoHFTracks = soa::Join; - using FemtoHFMcTracks = soa::Join; - using GeneratedXicMc = soa::Join; - - Filter filterSelectCandidateXic = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= selectionFlagHadron; - - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; - OutputObj zorroSummary{"zorroSummary"}; - - void init(InitContext&) - { - std::array processes = {doprocessDataXicToXiPiPi, doprocessDataXicToXiPiPiKf, - doprocessDataXicToXiPiPiWithML, doprocessDataXicToXiPiPiWithMLKf, - doprocessMcXicToXiPiPi, doprocessMcXicToXiPiPiKf, - doprocessMcXicToXiPiPiWithML, doprocessMcXicToXiPiPiWithMLKf, - doprocessMcXicToXiPiPiGen}; - if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { - LOGP(fatal, "One and only one process function must be enabled at a time."); - } - - int const cutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); - trackRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{cutBits + 1, -0.5, cutBits + 0.5}}); - - constexpr int kEventTypes = PairSelected + 1; - std::string labels[kEventTypes]; - labels[Event::All] = "All events"; - labels[Event::RejEveSel] = "rejected by event selection"; - labels[Event::RejNoTracksAndCharm] = "rejected by no tracks and charm"; - labels[Event::TrackSelected] = "with tracks "; - labels[Event::CharmSelected] = "with charm hadrons "; - labels[Event::PairSelected] = "with pairs"; - - static const AxisSpec axisEvents = {kEventTypes, 0.5, kEventTypes + 0.5, ""}; - qaRegistry.add("hEventQA", "Events;;entries", HistType::kTH1F, {axisEvents}); - for (int iBin = 0; iBin < kEventTypes; iBin++) { - qaRegistry.get(HIST("hEventQA"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); - } - - trackCuts.setSelection(trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - trackCuts.setSelection(trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setPIDSpecies(trkPIDspecies); - trackCuts.setnSigmaPIDOffset(trkPIDnSigmaOffsetTPC, trkPIDnSigmaOffsetTOF); - trackCuts.init(&qaRegistry, &trackRegistry); - - runNumber = 0; - magField = 0.f; - ccdb->setURL(ccdbCfg.ccdbUrl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - hfEvSel.init(qaRegistry, &zorroSummary); - - int64_t const now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - ccdb->setCreatedNotAfter(now); - - bool useXicMl = doprocessDataXicToXiPiPiWithML || doprocessMcXicToXiPiPiWithML || doprocessDataXicToXiPiPiWithMLKf || doprocessMcXicToXiPiPiWithMLKf; - if (mlCfg.applyMlMode == FillMlFromNewBDT && useXicMl) { - hfMlResponseXic.configure(mlCfg.binsPtMl, mlCfg.cutsMl, mlCfg.cutDirMl, mlCfg.nClassesMl); - hfMlResponseXic.cacheInputFeaturesIndices(mlCfg.namesInputFeatures); - if (ccdbCfg.loadModelsFromCCDB) { - ccdbApi.init(ccdbCfg.ccdbUrl); - hfMlResponseXic.setModelPathsCCDB(ccdbCfg.onnxFileNames, ccdbApi, ccdbCfg.modelPathsCCDB, ccdbCfg.timestampCCDB); - } else { - hfMlResponseXic.setModelPathsLocal(ccdbCfg.onnxFileNames); - } - hfMlResponseXic.init(); - } - } - - void getMagneticFieldTesla(const aod::BCsWithTimestamps::iterator& bc) - { - initCCDB(bc, runNumber, ccdb, !isRun3 ? ccdbCfg.ccdbPathGrp : ccdbCfg.ccdbPathGrpMag, lut, !isRun3); - } - - template - void fillDebugParticle(ParticleType const& particle) - { - outputDebugParts(particle.sign(), - (uint8_t)particle.tpcNClsFound(), - particle.tpcNClsFindable(), - (uint8_t)particle.tpcNClsCrossedRows(), - particle.tpcNClsShared(), - particle.tpcInnerParam(), - particle.itsNCls(), - particle.itsNClsInnerBarrel(), - particle.dcaXY(), - particle.dcaZ(), - particle.tpcSignal(), - -999., - particle.tpcNSigmaPi(), - particle.tpcNSigmaKa(), - particle.tpcNSigmaPr(), - particle.tpcNSigmaDe(), - -999., - -999., - -999., - particle.tofNSigmaPi(), - particle.tofNSigmaKa(), - particle.tofNSigmaPr(), - particle.tofNSigmaDe(), - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999.); - } - - template - void fillMcParticle(CollisionType const& col, ParticleType const& particle, o2::aod::femtodreamparticle::ParticleType fdparttype) - { - if (particle.has_mcParticle()) { - auto particleMc = particle.mcParticle(); - auto pdgCode = particleMc.pdgCode(); - int particleOrigin = 99; - int pdgCodeMother = -1; - constexpr int GenFromTransport = -1; - auto motherparticlesMc = particleMc.template mothers_as(); - if (std::abs(pdgCode) == std::abs(trkPDGCode.value)) { - if ((col.has_mcCollision() && (particleMc.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kWrongCollision; - } else if (particleMc.isPhysicalPrimary()) { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; - } else if (particleMc.getProcess() == TMCProcess::kPDecay && particleMc.getGenStatusCode() == GenFromTransport && !motherparticlesMc.empty()) { - auto motherparticleMc = motherparticlesMc.front(); - pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); - } else if (particleMc.getProcess() == TMCProcess::kPHInhelastic && particleMc.getGenStatusCode() == GenFromTransport) { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; - } else { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kElse; - } - } else { - particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; - } - - outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); - outputPartsMcLabels(outputPartsMc.lastIndex()); - if (isDebug) { - outputPartsExtMcLabels(outputPartsMc.lastIndex()); - outputDebugPartsMc(pdgCodeMother); - } - } else { - outputPartsMcLabels(-1); - if (isDebug) { - outputPartsExtMcLabels(-1); - } - } - } - - template - bool isTrackKaonPidSelected(const TrackType& track) - { - const float pTrack = track.p(); - - bool isTrackKaonPidMethod1 = true; - if (pTrack >= kaonPidSel.pTrackMethod1Max) { - isTrackKaonPidMethod1 = false; - } - if (std::abs(track.tpcNSigmaKa()) >= kaonPidSel.nSigmaTpcKaMax) { - isTrackKaonPidMethod1 = false; - } - if (pTrack >= kaonPidSel.pTrackExcludeMin && pTrack <= kaonPidSel.pTrackExcludeMax) { - isTrackKaonPidMethod1 = false; - } - if (pTrack > kaonPidSel.pTrackPiRejMin && std::abs(track.tpcNSigmaPi()) <= kaonPidSel.nSigmaTpcPiMin) { - isTrackKaonPidMethod1 = false; - } - if (pTrack > kaonPidSel.pTrackElRejMin && std::abs(track.tpcNSigmaEl()) <= kaonPidSel.nSigmaTpcElMin) { - isTrackKaonPidMethod1 = false; - } - - bool isTrackKaonPidMethod2 = true; - if (pTrack > kaonPidSel.pTrackMethod1Max && !track.hasTOF()) { - isTrackKaonPidMethod2 = false; - } - - const float nSigmaCombKa = std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa()); - const float nSigmaCombPi = std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi()); - - if (std::abs(nSigmaCombKa) >= kaonPidSel.nSigmaCombKaMax) { - isTrackKaonPidMethod2 = false; - } - - if (pTrack > kaonPidSel.pTrackTightMin) { - if (std::abs(nSigmaCombKa) >= kaonPidSel.nSigmaCombKaTightMax) { - isTrackKaonPidMethod2 = false; - } - if (std::abs(nSigmaCombPi) <= kaonPidSel.nSigmaCombPiMax) { - isTrackKaonPidMethod2 = false; - } - } - - return isTrackKaonPidMethod1 || isTrackKaonPidMethod2; - } - - template - void fillMcCollision(CollisionType const& col) - { - if (col.has_mcCollision()) { - outputCollsMcLabels(outputMcCollision.lastIndex()); - } else { - outputCollsMcLabels(-1); - } - } - - template - bool fillTracksForCharmHadron(CollisionType const& col, TrackType const& tracks) - { - std::vector const childIDs = {0, 0}; - bool fIsTrackFilled = false; - - for (const auto& track : tracks) { - if (!trackCuts.isSelectedMinimal(track)) { - continue; - } - - trackCuts.fillQA(track); - auto cutContainer = trackCuts.getCutContainer(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f))); - auto bc = col.template bc_as(); - int64_t timeStamp = bc.timestamp(); - outputPartsIndex(track.globalIndex()); - outputPartsTime(timeStamp); - - if (trkPDGCode == kKPlus) { - const auto pidTrackPassBit = static_cast(isTrackKaonPidSelected(track)); - - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - pidTrackPassBit, - track.dcaXY(), childIDs, 0, 0); - } else { - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), - track.dcaXY(), childIDs, 0, 0); - } - - fIsTrackFilled = true; - if (isDebug.value) { - fillDebugParticle(track); - } - - if constexpr (IsMc) { - fillMcParticle(col, track, o2::aod::femtodreamparticle::ParticleType::kTrack); - } - } - return fIsTrackFilled; - } - - template - bool isNoSelectedTracks(C const& /*col*/, T const& tracks, TC& cuts) - { - for (auto const& track : tracks) { - if (cuts.isSelectedMinimal(track)) { - return false; - } - } - return true; - } - - template - void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) - { - const auto vtxZ = col.posZ(); - const auto sizeCand = candidates.size(); - const auto spher = 2.f; - float mult = 0; - int multNtr = 0; - if (isRun3) { - mult = useCent ? col.centFT0M() : 0.f; - multNtr = col.multNTracksPV(); - } else { - mult = 1.f; - multNtr = col.multTracklets(); - } - - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(col, mult, ccdb, qaRegistry); - qaRegistry.fill(HIST("hEventQA"), 1 + Event::All); - hfEvSel.fillHistograms(col, rejectionMask, mult); - if (rejectionMask != 0) { - qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejEveSel); - return; - } - - if (isNoSelectedTracks(col, tracks, trackCuts) && sizeCand <= 0) { - qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejNoTracksAndCharm); - return; - } - - outputCollision(vtxZ, mult, multNtr, spher, magField); - if constexpr (IsMc) { - fillMcCollision(col); - } - - rowCandCharm3Prong.reserve(sizeCand); - rowCandCharm3ProngXic.reserve(sizeCand); - bool isTrackFilled = false; - int nSelectedXic = 0; - - for (const auto& candidate : candidates) { - if (candidate.isSelXicToXiPiPi() < selectionFlagHadron) { - continue; - } - - outputMlXic = {-1.f, -1.f, -1.f}; - bool isSelectedMlXicToXiPiPi = true; - if constexpr (UseCharmMl) { - if (mlCfg.applyMlMode == FillMlFromSelector) { - if (candidate.mlProbXicToXiPiPi().size() > 0) { - outputMlXic.at(0) = candidate.mlProbXicToXiPiPi()[0]; - outputMlXic.at(1) = candidate.mlProbXicToXiPiPi()[1]; - outputMlXic.at(2) = candidate.mlProbXicToXiPiPi()[2]; - } - } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { - isSelectedMlXicToXiPiPi = false; - if (candidate.mlProbXicToXiPiPi().size() > 0) { - std::vector inputFeaturesXicToXiPiPi = hfMlResponseXic.getInputFeatures(candidate); - isSelectedMlXicToXiPiPi = hfMlResponseXic.isSelectedMl(inputFeaturesXicToXiPiPi, candidate.pt(), outputMlXic); - } - if (!isSelectedMlXicToXiPiPi) { - continue; - } - } else { - LOGF(fatal, "Please check your ML configuration."); - } - } - - auto bc = col.template bc_as(); - int64_t timeStamp = bc.timestamp(); - const auto eta0 = static_cast(RecoDecay::eta(std::array{candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()})); - const auto eta1 = static_cast(RecoDecay::eta(std::array{candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()})); - const auto eta2 = static_cast(RecoDecay::eta(std::array{candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()})); - const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); - const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); - const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); - - rowCandCharm3Prong( - outputCollision.lastIndex(), - timeStamp, - candidate.sign(), - candidate.pi0Id(), - candidate.pi1Id(), - candidate.bachelorId(), - candidate.ptProng0(), - candidate.ptProng1(), - candidate.ptProng2(), - eta0, - eta1, - eta2, - phi0, - phi1, - phi2, - 1 << 0, - outputMlXic.at(0), - outputMlXic.at(1), - outputMlXic.at(2)); - - rowCandCharm3ProngXic( - candidate.invMassXicPlus(), - candidate.posTrackId(), - candidate.negTrackId()); - - ++nSelectedXic; - if constexpr (IsMc) { - rowCandMcCharmHad( - candidate.flagMcMatchRec(), - candidate.originMcRec()); - } - } - - isTrackFilled = fillTracksForCharmHadron(col, tracks); - - aod::femtodreamcollision::BitMaskType bitTrack = 0; - if (isTrackFilled) { - bitTrack |= 1 << 0; - qaRegistry.fill(HIST("hEventQA"), 1 + Event::TrackSelected); - } - - aod::femtodreamcollision::BitMaskType bitCand = 0; - if (nSelectedXic > 0) { - bitCand |= 1 << 0; - qaRegistry.fill(HIST("hEventQA"), 1 + Event::CharmSelected); - } - - if (isTrackFilled && nSelectedXic > 0) { - qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); - } - - rowMasks(bitTrack, bitCand, 0); - } - - void fillXicMcGen(GeneratedXicMc const& particles) - { - rowCandCharmHadGen.reserve(particles.size()); - for (const auto& particle : particles) { - const int absFlag = std::abs(static_cast(particle.flagMcMatchGen())); - if (absFlag == (1 << DecayType::XicToXiPiPi) || absFlag == (1 << DecayType::XicToXiResPiToXiPiPi)) { - rowCandCharmHadGen( - particle.mcCollisionId(), - particle.flagMcMatchGen(), - particle.originMcGen()); - } - } - } - - void processDataXicToXiPiPi(FemtoFullCollision const& col, - aod::BCsWithTimestamps const&, - FemtoHFTracks const& tracks, - soa::Filtered const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPi, "Data for XicToXiPiPi femto (DCAFitter; no HFCANDXICKF)", false); - - void processDataXicToXiPiPiKf(FemtoFullCollision const& col, - aod::BCsWithTimestamps const&, - FemtoHFTracks const& tracks, - soa::Filtered const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPiKf, "Data for XicToXiPiPi femto (KFParticle; requires HFCANDXICKF)", false); - - void processDataXicToXiPiPiWithML(FemtoFullCollision const& col, - aod::BCsWithTimestamps const&, - FemtoHFTracks const& tracks, - soa::Filtered> const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPiWithML, "Data for XicToXiPiPi femto with ML (DCAFitter)", false); - - void processDataXicToXiPiPiWithMLKf(FemtoFullCollision const& col, - aod::BCsWithTimestamps const&, - FemtoHFTracks const& tracks, - soa::Filtered> const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processDataXicToXiPiPiWithMLKf, "Data for XicToXiPiPi femto with ML (KFParticle)", false); - - void processMcXicToXiPiPi(FemtoFullCollisionMc const& col, - aod::BCsWithTimestamps const&, - FemtoHFMcTracks const& tracks, - aod::McParticles const&, - soa::Filtered const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); - - void processMcXicToXiPiPiKf(FemtoFullCollisionMc const& col, - aod::BCsWithTimestamps const&, - FemtoHFMcTracks const& tracks, - aod::McParticles const&, - soa::Filtered const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); - - void processMcXicToXiPiPiWithML(FemtoFullCollisionMc const& col, - aod::BCsWithTimestamps const&, - FemtoHFMcTracks const& tracks, - aod::McParticles const&, - soa::Filtered> const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); - - void processMcXicToXiPiPiWithMLKf(FemtoFullCollisionMc const& col, - aod::BCsWithTimestamps const&, - FemtoHFMcTracks const& tracks, - aod::McParticles const&, - soa::Filtered> const& candidates) - { - getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false); - - void processMcXicToXiPiPiGen(GeneratedXicMc const& particles) - { - fillXicMcGen(particles); - } - PROCESS_SWITCH(HfProducerCharmCascadeHadronsTrackFemtoDream, processMcXicToXiPiPiGen, "MC generated XicToXiPiPi", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index 4e65027b2c9..28083a268b1 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -21,10 +21,12 @@ #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/DecayChannelsLegacy.h" #include "PWGHF/Core/HfMlResponseD0ToKPi.h" #include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" #include "PWGHF/Core/HfMlResponseDstarToD0Pi.h" #include "PWGHF/Core/HfMlResponseLcToPKPi.h" +#include "PWGHF/Core/HfMlResponseXicToXiPiPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -32,6 +34,7 @@ #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/ZorroSummary.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -98,7 +101,8 @@ enum MlMode : uint8_t { enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, D0ToPiK, - DstarToD0Pi + DstarToD0Pi, + XicToXiPiPi }; enum class D0CandFlag : uint8_t { @@ -109,33 +113,37 @@ enum class D0CandFlag : uint8_t { struct HfProducerCharmHadronsTrackFemtoDream { - Produces outputCollision; - Produces rowMasks; - Produces rowCandCharm3Prong; - Produces rowCandCharm2Prong; - Produces rowCandCharmDstar; - Produces rowCandMcCharmHad; - Produces rowCandCharmHadGen; - Produces outputPartsIndex; - Produces outputPartsTime; - Produces outputMcCollision; - Produces outputCollsMcLabels; - Produces outputParts; - Produces outputPartsMc; - Produces outputDebugParts; - Produces outputPartsMcLabels; - Produces outputDebugPartsMc; - Produces outputPartsExtMcLabels; - - 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)"}; - - Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; - Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.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"}; + struct : ProducesGroup { + Produces outputCollision; + Produces rowMasks; + Produces rowCandCharm3Prong; + Produces rowCandCharm3ProngXic; + Produces rowCandCharm2Prong; + Produces rowCandCharmDstar; + Produces rowCandMcCharmHad; + Produces rowCandCharmHadGen; + Produces outputPartsIndex; + Produces outputPartsTime; + Produces outputMcCollision; + Produces outputCollsMcLabels; + Produces outputParts; + Produces outputPartsMc; + Produces outputDebugParts; + Produces outputPartsMcLabels; + Produces outputDebugPartsMc; + Produces outputPartsExtMcLabels; + } tables; + + struct : ConfigurableGroup { + 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)"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.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"}; + } ccdbCfg; // Configurable isForceGRP{"isForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; @@ -157,37 +165,41 @@ struct HfProducerCharmHadronsTrackFemtoDream { Configurable nSigmaCombPiMax{"nSigmaCombPiMax", 6.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombPi| < this"}; } kaonPidSel; - Configurable isDebug{"isDebug", true, "Enable Debug tables"}; - Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - - /// Charm hadron table - Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; - Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; - - Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; - Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; - Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; - Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; - Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; - Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; - Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; - Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; - Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; - Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; - Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; - Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; - Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; - Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; - Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; - // ML inference - Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; - 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"}; + struct : ConfigurableGroup { + Configurable isDebug{"isDebug", true, "Enable Debug tables"}; + Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; + Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; + } generalCfg; + + struct : ConfigurableGroup { + Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; + Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; + Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; + Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; + Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; + Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; + Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; + Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; + Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; + Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; + Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; + Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; + Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; + Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; + Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; + Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; + Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; + } trackCfg; + + struct : ConfigurableGroup { + Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; + 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"}; + } mlCfg; FemtoDreamTrackSelection trackCuts; @@ -195,6 +207,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { o2::analysis::HfMlResponseDplusToPiKPi hfMlResponseDplus; o2::analysis::HfMlResponseD0ToKPi hfMlResponseD0; o2::analysis::HfMlResponseDstarToD0Pi hfMlResponseDstar; + o2::analysis::HfMlResponseXicToXiPiPi hfMlResponseXic; std::vector outputMlD0; std::vector outputMlD0bar; @@ -202,11 +215,12 @@ struct HfProducerCharmHadronsTrackFemtoDream { std::vector outputMlDplus; std::vector outputMlPKPi; std::vector outputMlPiKP; + std::vector outputMlXic; o2::ccdb::CcdbApi ccdbApi; o2::hf_evsel::HfEventSelection hfEvSel; Service ccdb{}; /// Accessing the CCDB o2::base::MatLayerCylSet* lut{}; - // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut));} //! may be it useful, will check later + // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbCfg.ccdbPathLut));} //! may be it useful, will check later float magField{}; int runNumber{}; @@ -218,6 +232,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { using CandidateDplusMc = soa::Join; using CandidateLc = soa::Join; using CandidateLcMc = soa::Join; + using CandidateXic = soa::Join; + using CandidateXicMc = soa::Join; + using CandidateXicKf = soa::Join; + using CandidateXicKfMc = soa::Join; using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollisionMc = soa::Join::iterator; @@ -231,11 +249,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { using Generated3ProngMc = soa::Join; using Generated2ProngMc = soa::Join; using GeneratedDstarMc = soa::Join; + using GeneratedXicMc = soa::Join; - Filter filterSelectCandidateD0 = (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagHadron || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagHadron); + Filter filterSelectCandidateD0 = (aod::hf_sel_candidate_d0::isSelD0 >= generalCfg.selectionFlagHadron || aod::hf_sel_candidate_d0::isSelD0bar >= generalCfg.selectionFlagHadron); Filter filterSelectCandidateDstar = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; - Filter filterSelectCandidateDplus = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron; - Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagHadron); + Filter filterSelectCandidateDplus = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= generalCfg.selectionFlagHadron; + Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= generalCfg.selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= generalCfg.selectionFlagHadron); + Filter filterSelectCandidateXic = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= generalCfg.selectionFlagHadron; HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -243,8 +263,12 @@ struct HfProducerCharmHadronsTrackFemtoDream { void init(InitContext&) { - std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, - doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen, doprocessDataD0ToPiK, doprocessMcD0ToPiK, doprocessDataD0ToPiKWithML, doprocessMcD0ToPiKWithML, doprocessMcD0ToPiKGen, doprocessDataDstarToD0Pi, doprocessMcDstarToD0Pi, doprocessDataDstarToD0PiWithML, doprocessMcDstarToD0PiWithML, doprocessMcDstarToD0PiGen}; + std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, + doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen, + doprocessDataD0ToPiK, doprocessMcD0ToPiK, doprocessDataD0ToPiKWithML, doprocessMcD0ToPiKWithML, doprocessMcD0ToPiKGen, + doprocessDataDstarToD0Pi, doprocessMcDstarToD0Pi, doprocessDataDstarToD0PiWithML, doprocessMcDstarToD0PiWithML, doprocessMcDstarToD0PiGen, + doprocessDataXicToXiPiPi, doprocessDataXicToXiPiPiKf, doprocessDataXicToXiPiPiWithML, doprocessDataXicToXiPiPiWithMLKf, + doprocessMcXicToXiPiPi, doprocessMcXicToXiPiPiKf, doprocessMcXicToXiPiPiWithML, doprocessMcXicToXiPiPiWithMLKf, doprocessMcXicToXiPiPiGen}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } @@ -268,27 +292,27 @@ struct HfProducerCharmHadronsTrackFemtoDream { qaRegistry.get(HIST("hEventQA"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } - trackCuts.setSelection(trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - trackCuts.setSelection(trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setPIDSpecies(trkPIDspecies); - trackCuts.setnSigmaPIDOffset(trkPIDnSigmaOffsetTPC, trkPIDnSigmaOffsetTOF); + trackCuts.setSelection(trackCfg.trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + trackCuts.setSelection(trackCfg.trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trackCfg.trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trackCfg.trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setPIDSpecies(trackCfg.trkPIDspecies); + trackCuts.setnSigmaPIDOffset(trackCfg.trkPIDnSigmaOffsetTPC, trackCfg.trkPIDnSigmaOffsetTOF); trackCuts.init(&qaRegistry, &trackRegistry); runNumber = 0; magField = 0.0; /// Initializing CCDB - ccdb->setURL(ccdbUrl); + ccdb->setURL(ccdbCfg.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -301,25 +325,27 @@ struct HfProducerCharmHadronsTrackFemtoDream { bool useDplusMl = doprocessDataDplusToPiKPiWithML || doprocessMcDplusToPiKPiWithML; bool useD0Ml = doprocessDataD0ToPiKWithML || doprocessMcD0ToPiKWithML; bool useDstarMl = doprocessDataDstarToD0PiWithML || doprocessMcDstarToD0PiWithML; + bool useXicMl = doprocessDataXicToXiPiPiWithML || doprocessMcXicToXiPiPiWithML || doprocessDataXicToXiPiPiWithMLKf || doprocessMcXicToXiPiPiWithMLKf; - if (applyMlMode == FillMlFromNewBDT) { + if (mlCfg.applyMlMode == FillMlFromNewBDT) { auto setupFeatures = [&](auto& hfResponse, bool useMlFlag) { if (!useMlFlag) { return; } - hfResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); - hfResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfResponse.configure(mlCfg.binsPtMl, mlCfg.cutsMl, mlCfg.cutDirMl, mlCfg.nClassesMl); + hfResponse.cacheInputFeaturesIndices(mlCfg.namesInputFeatures); }; setupFeatures(hfMlResponseLc, useLcMl); setupFeatures(hfMlResponseDplus, useDplusMl); setupFeatures(hfMlResponseD0, useD0Ml); setupFeatures(hfMlResponseDstar, useDstarMl); + setupFeatures(hfMlResponseXic, useXicMl); - const bool useAnyMl = useLcMl || useDplusMl || useD0Ml || useDstarMl; - if (loadModelsFromCCDB && useAnyMl) { - ccdbApi.init(ccdbUrl); + const bool useAnyMl = useLcMl || useDplusMl || useD0Ml || useDstarMl || useXicMl; + if (ccdbCfg.loadModelsFromCCDB && useAnyMl) { + ccdbApi.init(ccdbCfg.ccdbUrl); } auto initModel = [&](auto& hfResponse, bool useMlFlag) { @@ -327,10 +353,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { return; } - if (loadModelsFromCCDB) { - hfResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + if (ccdbCfg.loadModelsFromCCDB) { + hfResponse.setModelPathsCCDB(ccdbCfg.onnxFileNames, ccdbApi, ccdbCfg.modelPathsCCDB, ccdbCfg.timestampCCDB); } else { - hfResponse.setModelPathsLocal(onnxFileNames); + hfResponse.setModelPathsLocal(ccdbCfg.onnxFileNames); } hfResponse.init(); }; @@ -339,6 +365,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { initModel(hfMlResponseDplus, useDplusMl); initModel(hfMlResponseD0, useD0Ml); initModel(hfMlResponseDstar, useDstarMl); + initModel(hfMlResponseXic, useXicMl); } } @@ -403,13 +430,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { /// Function to retrieve the nominal magnetic field in kG (0.1T) and convert it directly to T void getMagneticFieldTesla(const aod::BCsWithTimestamps::iterator& bc) { - initCCDB(bc, runNumber, ccdb, !isRun3 ? ccdbPathGrp : ccdbPathGrpMag, lut, !isRun3); + initCCDB(bc, runNumber, ccdb, !generalCfg.isRun3 ? ccdbCfg.ccdbPathGrp : ccdbCfg.ccdbPathGrpMag, lut, !generalCfg.isRun3); } template void fillDebugParticle(ParticleType const& particle) { - outputDebugParts(particle.sign(), + tables.outputDebugParts(particle.sign(), (uint8_t)particle.tpcNClsFound(), particle.tpcNClsFindable(), (uint8_t)particle.tpcNClsCrossedRows(), @@ -454,7 +481,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { auto motherparticlesMc = particleMc.template mothers_as(); // check pdg code // if this fails, the particle is a fake - if (std::abs(pdgCode) == std::abs(trkPDGCode.value)) { + if (std::abs(pdgCode) == std::abs(trackCfg.trkPDGCode.value)) { // check first if particle is from pile up // check if the collision associated with the particle is the same as the analyzed collision by checking their Ids if ((col.has_mcCollision() && (particleMc.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { @@ -485,16 +512,16 @@ struct HfProducerCharmHadronsTrackFemtoDream { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; } - outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); - outputPartsMcLabels(outputPartsMc.lastIndex()); - if (isDebug) { - outputPartsExtMcLabels(outputPartsMc.lastIndex()); - outputDebugPartsMc(pdgCodeMother); + tables.outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); + tables.outputPartsMcLabels(tables.outputPartsMc.lastIndex()); + if (generalCfg.isDebug) { + tables.outputPartsExtMcLabels(tables.outputPartsMc.lastIndex()); + tables.outputDebugPartsMc(pdgCodeMother); } } else { - outputPartsMcLabels(-1); - if (isDebug) { - outputPartsExtMcLabels(-1); + tables.outputPartsMcLabels(-1); + if (generalCfg.isDebug) { + tables.outputPartsExtMcLabels(-1); } } } @@ -504,10 +531,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { { if (col.has_mcCollision()) { // auto genMCcol = col.template mcCollision_as(); - // outputMcCollision(genMCcol.multMCNParticlesEta08()); - outputCollsMcLabels(outputMcCollision.lastIndex()); + // tables.outputMcCollision(genMCcol.multMCNParticlesEta08()); + tables.outputCollsMcLabels(tables.outputMcCollision.lastIndex()); } else { - outputCollsMcLabels(-1); + tables.outputCollsMcLabels(-1); } } @@ -532,14 +559,14 @@ struct HfProducerCharmHadronsTrackFemtoDream { auto bc = col.template bc_as(); int64_t timeStamp = bc.timestamp(); // track global index - outputPartsIndex(track.globalIndex()); - outputPartsTime(timeStamp); + tables.outputPartsIndex(track.globalIndex()); + tables.outputPartsTime(timeStamp); // now the table is filled - if (trkPDGCode == kKPlus) { + if (trackCfg.trkPDGCode == kKPlus) { const auto pidTrackPassBit = static_cast(isTrackKaonPidSelected(track)); - outputParts(outputCollision.lastIndex(), + tables.outputParts(tables.outputCollision.lastIndex(), track.pt(), track.eta(), track.phi(), @@ -548,7 +575,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { pidTrackPassBit, track.dcaXY(), childIDs, 0, 0); } else { - outputParts(outputCollision.lastIndex(), + tables.outputParts(tables.outputCollision.lastIndex(), track.pt(), track.eta(), track.phi(), @@ -560,7 +587,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { fIsTrackFilled = true; // tmpIDtrack.push_back(track.globalIndex()); - if (isDebug.value) { + if (generalCfg.isDebug.value) { fillDebugParticle(track); } @@ -579,8 +606,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { const auto spher = 2.; // dummy value for the moment float mult = 0; int multNtr = 0; - if (isRun3) { - if (useCent) { + if (generalCfg.isRun3) { + if (generalCfg.useCent) { mult = col.centFT0M(); } else { mult = 0; @@ -608,7 +635,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { return; } - outputCollision(vtxZ, mult, multNtr, spher, magField); + tables.outputCollision(vtxZ, mult, multNtr, spher, magField); if constexpr (IsMc) { fillMcCollision(col); } @@ -642,8 +669,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { if (functionSelection >= 1) { if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { auto trackPos2 = candidate.template prong2_as(); - rowCandCharm3Prong( - outputCollision.lastIndex(), + tables.rowCandCharm3Prong( + tables.outputCollision.lastIndex(), timeStamp, trackPos1.sign() + trackNeg.sign() + trackPos2.sign(), trackPos1.globalIndex(), @@ -674,8 +701,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else { LOG(error) << "Unexpected candFlag = " << candFlag; } - rowCandCharm2Prong( - outputCollision.lastIndex(), + tables.rowCandCharm2Prong( + tables.outputCollision.lastIndex(), timeStamp, signD0, trackPos1.globalIndex(), @@ -692,8 +719,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { bdtScoreFd); } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { auto trackPos2 = candidate.template prongPi_as(); - rowCandCharmDstar( - outputCollision.lastIndex(), + tables.rowCandCharmDstar( + tables.outputCollision.lastIndex(), timeStamp, candidate.template prongPi_as().sign(), trackPos1.globalIndex(), @@ -715,7 +742,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } if constexpr (IsMc) { - rowCandMcCharmHad( + tables.rowCandMcCharmHad( candidate.flagMcMatchRec(), candidate.originMcRec()); } @@ -726,13 +753,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbDplusToPiKPi().size() > 0) { outputMlDplus.at(0) = candidate.mlProbDplusToPiKPi()[0]; /// bkg score outputMlDplus.at(1) = candidate.mlProbDplusToPiKPi()[1]; /// prompt score outputMlDplus.at(2) = candidate.mlProbDplusToPiKPi()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlDplusToPiKPi = false; if (candidate.mlProbDplusToPiKPi().size() > 0) { std::vector inputFeaturesDplusToPiKPi = hfMlResponseDplus.getInputFeatures(candidate); @@ -751,7 +778,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbLcToPKPi().size() > 0) { outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score @@ -762,7 +789,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlLcToPKPi = false; isSelectedMlLcToPiKP = false; if (candidate.mlProbLcToPKPi().size() > 0) { @@ -787,7 +814,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbD0().size() > 0) { outputMlD0.at(0) = candidate.mlProbD0()[0]; /// bkg score outputMlD0.at(1) = candidate.mlProbD0()[1]; /// prompt score @@ -799,7 +826,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlD0bar.at(2) = candidate.mlProbD0bar()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlD0ToPiK = false; isSelectedMlD0barToKPi = false; @@ -829,13 +856,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbDstarToD0Pi().size() > 0) { outputMlDstar.at(0) = candidate.mlProbDstarToD0Pi()[0]; /// bkg score outputMlDstar.at(1) = candidate.mlProbDstarToD0Pi()[1]; /// prompt score outputMlDstar.at(2) = candidate.mlProbDstarToD0Pi()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlDstarToD0Pi = false; if (candidate.mlProbDstarToD0Pi().size() > 0) { std::vector inputFeaturesDstarToD0Pi = hfMlResponseDstar.getInputFeatures(candidate, false); @@ -869,11 +896,142 @@ struct HfProducerCharmHadronsTrackFemtoDream { qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); } - rowMasks(bitTrack, + tables.rowMasks(bitTrack, bitCand, 0); } + template + void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) + { + const auto vtxZ = col.posZ(); + const auto sizeCand = candidates.size(); + const auto spher = 2.f; + float mult = 0; + int multNtr = 0; + if (generalCfg.isRun3) { + mult = generalCfg.useCent ? col.centFT0M() : 0.f; + multNtr = col.multNTracksPV(); + } else { + mult = 1.f; + multNtr = col.multTracklets(); + } + + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(col, mult, ccdb, qaRegistry); + qaRegistry.fill(HIST("hEventQA"), 1 + Event::All); + hfEvSel.fillHistograms(col, rejectionMask, mult); + if (rejectionMask != 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejEveSel); + return; + } + + if (isNoSelectedTracks(col, tracks, trackCuts) && sizeCand <= 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejNoTracksAndCharm); + return; + } + + tables.outputCollision(vtxZ, mult, multNtr, spher, magField); + if constexpr (IsMc) { + fillMcCollision(col); + } + + tables.rowCandCharm3Prong.reserve(sizeCand); + tables.rowCandCharm3ProngXic.reserve(sizeCand); + bool isTrackFilled = false; + int nSelectedXic = 0; + + for (const auto& candidate : candidates) { + if (candidate.isSelXicToXiPiPi() < generalCfg.selectionFlagHadron) { + continue; + } + + outputMlXic = {-1.f, -1.f, -1.f}; + bool isSelectedMlXicToXiPiPi = true; + if constexpr (UseCharmMl) { + if (mlCfg.applyMlMode == FillMlFromSelector) { + if (candidate.mlProbXicToXiPiPi().size() > 0) { + outputMlXic.at(0) = candidate.mlProbXicToXiPiPi()[0]; + outputMlXic.at(1) = candidate.mlProbXicToXiPiPi()[1]; + outputMlXic.at(2) = candidate.mlProbXicToXiPiPi()[2]; + } + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { + isSelectedMlXicToXiPiPi = false; + if (candidate.mlProbXicToXiPiPi().size() > 0) { + std::vector inputFeaturesXicToXiPiPi = hfMlResponseXic.getInputFeatures(candidate); + isSelectedMlXicToXiPiPi = hfMlResponseXic.isSelectedMl(inputFeaturesXicToXiPiPi, candidate.pt(), outputMlXic); + } + if (!isSelectedMlXicToXiPiPi) { + continue; + } + } else { + LOGF(fatal, "Please check your ML configuration."); + } + } + + auto bc = col.template bc_as(); + int64_t timeStamp = bc.timestamp(); + const auto eta0 = static_cast(RecoDecay::eta(std::array{candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()})); + const auto eta1 = static_cast(RecoDecay::eta(std::array{candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()})); + const auto eta2 = static_cast(RecoDecay::eta(std::array{candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()})); + const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); + const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); + const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); + + tables.rowCandCharm3Prong( + tables.outputCollision.lastIndex(), + timeStamp, + candidate.sign(), + candidate.pi0Id(), + candidate.pi1Id(), + candidate.bachelorId(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + eta0, + eta1, + eta2, + phi0, + phi1, + phi2, + 1 << 0, + outputMlXic.at(0), + outputMlXic.at(1), + outputMlXic.at(2)); + + tables.rowCandCharm3ProngXic( + candidate.invMassXicPlus(), + candidate.posTrackId(), + candidate.negTrackId()); + + ++nSelectedXic; + if constexpr (IsMc) { + tables.rowCandMcCharmHad( + candidate.flagMcMatchRec(), + candidate.originMcRec()); + } + } + + isTrackFilled = fillTracksForCharmHadron(col, tracks); + + aod::femtodreamcollision::BitMaskType bitTrack = 0; + if (isTrackFilled) { + bitTrack |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::TrackSelected); + } + + aod::femtodreamcollision::BitMaskType bitCand = 0; + if (nSelectedXic > 0) { + bitCand |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::CharmSelected); + } + + if (isTrackFilled && nSelectedXic > 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); + } + + tables.rowMasks(bitTrack, bitCand, 0); + } + // check if there is no selected track /// \param C type of the collision /// \param T type of the tracks @@ -894,11 +1052,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { void fillCharmHadMcGen(ParticleType particles) { // Filling particle properties - rowCandCharmHadGen.reserve(particles.size()); + tables.rowCandCharmHadGen.reserve(particles.size()); if constexpr (Channel == DecayChannel::DplusToPiKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -907,7 +1065,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::LcToPKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -916,7 +1074,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::D0ToPiK) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -925,7 +1083,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -934,6 +1092,21 @@ struct HfProducerCharmHadronsTrackFemtoDream { } } + void fillXicMcGen(GeneratedXicMc const& particles) + { + tables.rowCandCharmHadGen.reserve(particles.size()); + for (const auto& particle : particles) { + const int absFlag = std::abs(static_cast(particle.flagMcMatchGen())); + if (absFlag == (1 << o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi) || + absFlag == (1 << o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiResPiToXiPiPi)) { + tables.rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + } + } + /// D0ToPiK void processDataD0ToPiK(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, @@ -1158,6 +1331,97 @@ struct HfProducerCharmHadronsTrackFemtoDream { fillCharmHadMcGen(particles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcLcToPKPiGen, "Provide Mc Generated lctopkpi", false); + + /// XicToXiPiPi + void processDataXicToXiPiPi(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPi, "Data for XicToXiPiPi femto (DCAFitter; no HFCANDXICKF)", false); + + void processDataXicToXiPiPiKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiKf, "Data for XicToXiPiPi femto (KFParticle; requires HFCANDXICKF)", false); + + void processDataXicToXiPiPiWithML(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithML, "Data for XicToXiPiPi femto with ML (DCAFitter)", false); + + void processDataXicToXiPiPiWithMLKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithMLKf, "Data for XicToXiPiPi femto with ML (KFParticle)", false); + + void processMcXicToXiPiPi(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); + + void processMcXicToXiPiPiKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); + + void processMcXicToXiPiPiWithML(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); + + void processMcXicToXiPiPiWithMLKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false); + + void processMcXicToXiPiPiGen(GeneratedXicMc const& particles) + { + fillXicMcGen(particles); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiGen, "MC generated XicToXiPiPi", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 7d89b374c799b28cf201b47556c95c39d65e6330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Wed, 17 Jun 2026 08:52:17 +0200 Subject: [PATCH 05/17] Add Xic femto QA daughter table --- PWGCF/DataModel/FemtoDerived.h | 65 +++++++++++++++++-- .../producerCharmHadronsTrackFemtoDream.cxx | 25 +++++-- .../Tasks/taskCharmHadronsTrackFemtoDream.cxx | 41 +++++++++--- 3 files changed, 110 insertions(+), 21 deletions(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 29fb493c4ca..ee057b4c146 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -245,6 +245,7 @@ DECLARE_SOA_COLUMN(Charge, charge, int8_t); //! Charge of c DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Track id of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Track id of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Track id of charm hadron prong2 +DECLARE_SOA_COLUMN(XiProngId, xiProngId, int); //! Cascade id of the Xi prong in Xic -> Xi pi pi candidates DECLARE_SOA_COLUMN(Prong0Pt, prong0Pt, float); //! Track pT of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Pt, prong1Pt, float); //! Track pT of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Pt, prong2Pt, float); //! Track pT of charm hadron prong2 @@ -258,9 +259,18 @@ DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int); //! Selection o DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron -DECLARE_SOA_COLUMN(InvMassCharm, invMassCharm, float); //! Reconstructed invariant mass of charm hadron (e.g. invMassXicPlus for Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Xi cascade (Xic -> Xi pi pi) DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Λ in Ξ cascade (Ξc± → Ξππ) DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPt, cascPosPt, float); //! pT of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPhi, cascPosPhi, float); //! phi of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosEta, cascPosEta, float); //! eta of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPt, cascNegPt, float); //! pT of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPhi, cascNegPhi, float); //! phi of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegEta, cascNegEta, float); //! eta of the negative Lambda daughter track from the Xi cascade DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! To select MC particle among charm hadrons, { DplusToPiKPi = 1, LcToPKPi = 17, DsToKKPi = 6, XicToPKPi = 21, XicToXiPiPi = 1, N3ProngD = 2ecays }; DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); //! flag for reconstruction level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int); //! flag for generator level matching (1 for prompt, 2 for non-prompt) @@ -391,6 +401,16 @@ DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2))); }); //! Eta distribution of charm hadron } // namespace fdhf_dstar +namespace fdhf_xic +{ +DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! + [](float pt0, float phi0, float eta0, float pt1, float phi1, float eta1, float pt2, float phi2, float eta2) -> float { return RecoDecay::y(RecoDecay::pVec( + RecoDecayPtEtaPhi::pVector(pt0, eta0, phi0), + RecoDecayPtEtaPhi::pVector(pt1, eta1, phi1), + RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2)), + o2::constants::physics::MassXiCPlus); }); //! Rapidity distribution of Xic candidates +} // namespace fdhf_xic + DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, @@ -419,11 +439,48 @@ DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store th fdhf::Phi, fdhf::Pt); -DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFCAND3PRONGXIC", //! Extension table for Ξc± → Ξππ candidates (aligned rows with FDHfCand3Prong) +DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFCAND3PRONGXIC", //! Table to store the derived data for Xic -> Xi pi pi candidates o2::soa::Index<>, - fdhf::InvMassCharm, + femtodreamparticle::FDCollisionId, + fdhf::TimeStamp, + fdhf::Charge, + fdhf::XiProngId, + fdhf::Prong1Id, + fdhf::Prong2Id, + fdhf::CascBachelorTrackId, fdhf::CascPosTrackId, - fdhf::CascNegTrackId); + fdhf::CascNegTrackId, + fdhf::Prong0Pt, + fdhf::Prong1Pt, + fdhf::Prong2Pt, + fdhf::Prong0Eta, + fdhf::Prong1Eta, + fdhf::Prong2Eta, + fdhf::Prong0Phi, + fdhf::Prong1Phi, + fdhf::Prong2Phi, + fdhf::CandidateSelFlag, + fdhf::BDTBkg, + fdhf::BDTPrompt, + fdhf::BDTFD, + fdhf::M, + fdhf::P, + fdhf_xic::Y, + fdhf::Eta, + fdhf::Phi, + fdhf::Pt); + +DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFCAND3PXICQA", //! QA extension table for Xi daughters in Xic -> Xi pi pi candidates + o2::soa::Index<>, + fdhf::CascBachelorPt, + fdhf::CascBachelorPhi, + fdhf::CascBachelorEta, + fdhf::CascPosPt, + fdhf::CascPosPhi, + fdhf::CascPosEta, + fdhf::CascNegPt, + fdhf::CascNegPhi, + fdhf::CascNegEta); DECLARE_SOA_TABLE(FDHfCand2Prong, "AOD", "FDHFCAND2PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index 28083a268b1..0378473585b 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -118,6 +118,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { Produces rowMasks; Produces rowCandCharm3Prong; Produces rowCandCharm3ProngXic; + Produces rowCandCharm3ProngXicQa; Produces rowCandCharm2Prong; Produces rowCandCharmDstar; Produces rowCandMcCharmHad; @@ -935,8 +936,6 @@ struct HfProducerCharmHadronsTrackFemtoDream { fillMcCollision(col); } - tables.rowCandCharm3Prong.reserve(sizeCand); - tables.rowCandCharm3ProngXic.reserve(sizeCand); bool isTrackFilled = false; int nSelectedXic = 0; @@ -976,14 +975,20 @@ struct HfProducerCharmHadronsTrackFemtoDream { const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); + const auto cascBachelorTrack = tracks.rawIteratorAt(candidate.bachelorId()); + const auto cascPosTrack = tracks.rawIteratorAt(candidate.posTrackId()); + const auto cascNegTrack = tracks.rawIteratorAt(candidate.negTrackId()); - tables.rowCandCharm3Prong( + tables.rowCandCharm3ProngXic( tables.outputCollision.lastIndex(), timeStamp, candidate.sign(), + candidate.cascadeId(), candidate.pi0Id(), candidate.pi1Id(), candidate.bachelorId(), + candidate.posTrackId(), + candidate.negTrackId(), candidate.ptProng0(), candidate.ptProng1(), candidate.ptProng2(), @@ -998,10 +1003,16 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlXic.at(1), outputMlXic.at(2)); - tables.rowCandCharm3ProngXic( - candidate.invMassXicPlus(), - candidate.posTrackId(), - candidate.negTrackId()); + tables.rowCandCharm3ProngXicQa( + cascBachelorTrack.pt(), + cascBachelorTrack.phi(), + cascBachelorTrack.eta(), + cascPosTrack.pt(), + cascPosTrack.phi(), + cascPosTrack.eta(), + cascNegTrack.pt(), + cascNegTrack.phi(), + cascNegTrack.eta()); ++nSelectedXic; if constexpr (IsMc) { diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index 386b99b91d7..0eebc245c89 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -165,7 +165,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmCand3Prongs = soa::Filtered; using FilteredCharmCand3Prong = FilteredCharmCand3Prongs::iterator; - using FilteredCharmCand3ProngsXic = soa::Filtered>; + using FilteredCharmCand3ProngsXic = soa::Filtered; using FilteredCharmCand3ProngXic = FilteredCharmCand3ProngsXic::iterator; using FilteredCharmCand2Prongs = soa::Filtered; @@ -177,7 +177,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmMcCand3Prongs = soa::Filtered>; using FilteredCharmMcCand3Prong = FilteredCharmMcCand3Prongs::iterator; - using FilteredCharmMcCand3ProngsXic = soa::Filtered>; + using FilteredCharmMcCand3ProngsXic = soa::Filtered>; using FilteredCharmMcCand3ProngXic = FilteredCharmMcCand3ProngsXic::iterator; using FilteredCharmMcCand2Prongs = soa::Filtered>; @@ -402,7 +402,8 @@ struct HfTaskCharmHadronsTrackFemtoDream { return mDstar - mD0; } } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { - return cand.invMassCharm(); + invMass = cand.m(std::array{MassXiMinus, MassPiPlus, MassPiPlus}); + return invMass; } // Add more channels as needed return 0.f; @@ -527,7 +528,8 @@ struct HfTaskCharmHadronsTrackFemtoDream { } if constexpr (Channel == DecayChannel::XicToXiPiPi) { - if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || + if (p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || + p1.trackId() == p2.cascBachelorTrackId() || p1.trackId() == p2.cascPosTrackId() || p1.trackId() == p2.cascNegTrackId()) { continue; } @@ -536,10 +538,6 @@ struct HfTaskCharmHadronsTrackFemtoDream { continue; } } - - if (!pairCleaner3Prong.isCleanPair(p1, p2, parts)) { - continue; - } } if constexpr (Channel == DecayChannel::DstarToD0Pi) { @@ -659,7 +657,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } - if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::XicToXiPiPi) { + if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { if (pairQASetting.useCPR.value) { if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { @@ -672,6 +670,14 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + } + if constexpr (Channel == DecayChannel::DstarToD0Pi) { if (pairQASetting.useCPR.value) { @@ -764,7 +770,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { timeStamp = part.timeStamp(); - if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::XicToXiPiPi) { + if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { rowFemtoResultCharm3Prong( col.globalIndex(), @@ -780,6 +786,21 @@ struct HfTaskCharmHadronsTrackFemtoDream { part.bdtBkg(), part.bdtPrompt(), part.bdtFD()); + } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { + rowFemtoResultCharm3Prong( + col.globalIndex(), + timeStamp, + invMass, + part.pt(), + part.eta(), + part.phi(), + part.xiProngId(), + part.prong1Id(), + part.prong2Id(), + part.charge(), + part.bdtBkg(), + part.bdtPrompt(), + part.bdtFD()); } else if constexpr (Channel == DecayChannel::D0ToPiK) { rowFemtoResultCharm2Prong( col.globalIndex(), From 4e7d8b1245e939cddd54bf9abc212a0e2233572b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Wed, 17 Jun 2026 10:58:38 +0200 Subject: [PATCH 06/17] Reserve Xic femto producer tables --- .../HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index 0378473585b..1cb46fdebe1 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -936,6 +936,9 @@ struct HfProducerCharmHadronsTrackFemtoDream { fillMcCollision(col); } + tables.rowCandCharm3ProngXic.reserve(tables.rowCandCharm3ProngXic.lastIndex() + sizeCand + 1); + tables.rowCandCharm3ProngXicQa.reserve(tables.rowCandCharm3ProngXicQa.lastIndex() + sizeCand + 1); + bool isTrackFilled = false; int nSelectedXic = 0; From 27f2cc1d21c9a26818328cf77a6d5441a0350a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Thu, 18 Jun 2026 15:58:31 +0200 Subject: [PATCH 07/17] Fix Xic femto QA daughter track lookup --- .../producerCharmHadronsTrackFemtoDream.cxx | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index 429abad0cbc..bbb3a8394f4 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -910,8 +910,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { 0); } - template - void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) + template + void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates, DaughterTrackType const&) { const auto vtxZ = col.posZ(); const auto sizeCand = candidates.size(); @@ -986,9 +986,9 @@ struct HfProducerCharmHadronsTrackFemtoDream { const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); - const auto cascBachelorTrack = tracks.rawIteratorAt(candidate.bachelorId()); - const auto cascPosTrack = tracks.rawIteratorAt(candidate.posTrackId()); - const auto cascNegTrack = tracks.rawIteratorAt(candidate.negTrackId()); + const auto cascBachelorTrack = candidate.template bachelor_as(); + const auto cascPosTrack = candidate.template posTrack_as(); + const auto cascNegTrack = candidate.template negTrack_as(); tables.rowCandCharm3ProngXic( tables.outputCollision.lastIndex(), @@ -1358,84 +1358,92 @@ struct HfProducerCharmHadronsTrackFemtoDream { void processDataXicToXiPiPi(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, soa::Filtered const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPi, "Data for XicToXiPiPi femto (DCAFitter; no HFCANDXICKF)", false); void processDataXicToXiPiPiKf(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, soa::Filtered const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiKf, "Data for XicToXiPiPi femto (KFParticle; requires HFCANDXICKF)", false); void processDataXicToXiPiPiWithML(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, soa::Filtered> const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithML, "Data for XicToXiPiPi femto with ML (DCAFitter)", false); void processDataXicToXiPiPiWithMLKf(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, soa::Filtered> const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithMLKf, "Data for XicToXiPiPi femto with ML (KFParticle)", false); void processMcXicToXiPiPi(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, aod::McParticles const&, soa::Filtered const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); void processMcXicToXiPiPiKf(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, aod::McParticles const&, soa::Filtered const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); void processMcXicToXiPiPiWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, aod::McParticles const&, soa::Filtered> const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); void processMcXicToXiPiPiWithMLKf(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, aod::McParticles const&, soa::Filtered> const& candidates) { getMagneticFieldTesla(col.bc_as()); - fillXicHadronTable(col, tracks, candidates); + fillXicHadronTable(col, tracks, candidates, daughterTracks); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false); From 9cfe66b77146d474db781105fc706c5f67ec847a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Thu, 18 Jun 2026 17:27:11 +0200 Subject: [PATCH 08/17] Polish Xic femto comments for HF guidelines --- PWGCF/DataModel/FemtoDerived.h | 10 +++++----- .../producerCharmHadronsTrackFemtoDream.cxx | 5 +---- .../Tasks/taskCharmHadronsTrackFemtoDream.cxx | 20 +++++++++---------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index ee057b4c146..1dc20429093 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -260,8 +260,8 @@ DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Xi cascade (Xic -> Xi pi pi) -DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Λ in Ξ cascade (Ξc± → Ξππ) -DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Lambda in Xi cascade (Xic -> Xi pi pi) +DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Lambda in Xi cascade (Xic -> Xi pi pi) DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade @@ -271,7 +271,7 @@ DECLARE_SOA_COLUMN(CascPosEta, cascPosEta, float); //! eta of the DECLARE_SOA_COLUMN(CascNegPt, cascNegPt, float); //! pT of the negative Lambda daughter track from the Xi cascade DECLARE_SOA_COLUMN(CascNegPhi, cascNegPhi, float); //! phi of the negative Lambda daughter track from the Xi cascade DECLARE_SOA_COLUMN(CascNegEta, cascNegEta, float); //! eta of the negative Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! To select MC particle among charm hadrons, { DplusToPiKPi = 1, LcToPKPi = 17, DsToKKPi = 6, XicToPKPi = 21, XicToXiPiPi = 1, N3ProngD = 2ecays }; +DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! MC matching flag for the selected charm hadron decay channel DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); //! flag for reconstruction level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int); //! flag for generator level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int); //! swapping of the prongs order (0 for Lc -> pkpi, 1 for Lc -> pikp) @@ -283,12 +283,12 @@ DECLARE_SOA_COLUMN(KT, kT, float); //! kT distribu DECLARE_SOA_COLUMN(MT, mT, float); //! Transverse mass distribution DECLARE_SOA_COLUMN(CharmM, charmM, float); //! Charm hadron mass DECLARE_SOA_COLUMN(CharmDaughM, charmDaughM, float); //! Charm hadron daughter mass -DECLARE_SOA_COLUMN(CharmTrkM, charmtrkM, float); //! Charm hadron track mass +DECLARE_SOA_COLUMN(CharmTrkM, charmtrkM, float); //! Invariant-mass difference of the charm-track pair DECLARE_SOA_COLUMN(CharmPt, charmPt, float); //! Transverse momentum of charm hadron for result task DECLARE_SOA_COLUMN(CharmEta, charmEta, float); //! Eta of charm hadron for result task DECLARE_SOA_COLUMN(CharmPhi, charmPhi, float); //! Phi of charm hadron for result task DECLARE_SOA_COLUMN(Mult, mult, int); //! Charge particle multiplicity -DECLARE_SOA_COLUMN(MultPercentile, multPercentile, float); //! Multiplicity precentile +DECLARE_SOA_COLUMN(MultPercentile, multPercentile, float); //! Multiplicity percentile DECLARE_SOA_COLUMN(PairSign, pairSign, int8_t); //! Selection between like sign (1) and unlike sign pair (2) DECLARE_SOA_COLUMN(ProcessType, processType, int64_t); //! Selection between same-event (1), and mixed-event (2) DECLARE_SOA_DYNAMIC_COLUMN(M, m, //! diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index bbb3a8394f4..37f11806e90 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -146,8 +146,6 @@ struct HfProducerCharmHadronsTrackFemtoDream { Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; } ccdbCfg; - // Configurable isForceGRP{"isForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; - // ------------------------- // Kaon PID cut parameters // ------------------------- @@ -169,7 +167,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { struct : ConfigurableGroup { Configurable isDebug{"isDebug", true, "Enable Debug tables"}; Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection flag for charm hadrons; applied to D0, Dplus, Lc and Xic selector decisions"}; Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; } generalCfg; @@ -221,7 +219,6 @@ struct HfProducerCharmHadronsTrackFemtoDream { o2::hf_evsel::HfEventSelection hfEvSel; Service ccdb{}; /// Accessing the CCDB o2::base::MatLayerCylSet* lut{}; - // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbCfg.ccdbPathLut));} //! may be it useful, will check later float magField{}; int runNumber{}; diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index a54298a9a83..849280739dd 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -108,7 +108,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { struct : ConfigurableGroup { Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron"}; - Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "charm hadron selection for mc, DplusToPiKPi = 1, XicToXiPiPi = 1, LcToPKPi = 17"}; + Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "MC matching flag for the selected charm hadron decay channel"}; Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.45, "Maximum invariant mass of Charm Hadron (particle 2)"}; @@ -375,10 +375,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { } invMass = cand.m(std::array{MassPiPlus, MassKPlus, MassProton}); return invMass; - } else if constexpr (Channel == DecayChannel::DplusToPiKPi) { // D+ → π K π (PDG: 411) + } else if constexpr (Channel == DecayChannel::DplusToPiKPi) { // D+ -> pi K pi invMass = cand.m(std::array{MassPiPlus, MassKPlus, MassPiPlus}); return invMass; - } else if constexpr (Channel == DecayChannel::D0ToPiK) { // D0 → π K (PDG: 421) + } else if constexpr (Channel == DecayChannel::D0ToPiK) { // D0 -> pi K if (cand.candidateSelFlag() == 1) { invMass = cand.m(std::array{MassPiPlus, MassKPlus}); return invMass; @@ -386,7 +386,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { invMass = cand.m(std::array{MassKPlus, MassPiPlus}); return invMass; } - } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { // D* → D0π (PDG: 413) + } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { // D* -> D0 pi float mDstar = 0.f; float mD0 = 0.f; if (cand.charge() > 0.f) { @@ -436,7 +436,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { LOG(fatal) << "Invalid PDG code for track mass hypothesis: " << trkPDGCode; } - // D0 → K π + track (2-prong) + // D0 -> K pi + track (2-prong) if constexpr (Channel == DecayChannel::D0ToPiK) { const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecTrack}; std::array massCharmTrk{}; @@ -465,17 +465,17 @@ struct HfTaskCharmHadronsTrackFemtoDream { std::array massCharmTrk{}; if constexpr (Channel == DecayChannel::LcToPKPi) { - // Λc⁺ → p K π + // Lc+ -> p K pi if (cand.candidateSelFlag() == 1) { massCharmTrk = {MassProton, MassKPlus, MassPiPlus, trackMassHyp}; } else { massCharmTrk = {MassPiPlus, MassKPlus, MassProton, trackMassHyp}; } } else if constexpr (Channel == DecayChannel::DplusToPiKPi) { - // D⁺ → π K π + // D+ -> pi K pi massCharmTrk = {MassPiPlus, MassKPlus, MassPiPlus, trackMassHyp}; } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { - // D* → D0π + // D* -> D0 pi if (cand.candidateSelFlag() == 1) { massCharmTrk = {MassPiPlus, MassKPlus, MassPiPlus, trackMassHyp}; } else { @@ -571,7 +571,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - // proton track charge + // associated track charge float chargeTrack = 0.; if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; @@ -708,7 +708,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - // proton track charge + // associated track charge float chargeTrack = 0.; if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; From 7ee2c9407b756884d9d4b27166246133bbb31cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Thu, 18 Jun 2026 20:34:09 +0200 Subject: [PATCH 09/17] Use shorter Xic femto derived table names --- PWGCF/DataModel/FemtoDerived.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 1dc20429093..632fda6ad18 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -439,7 +439,7 @@ DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store th fdhf::Phi, fdhf::Pt); -DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFCAND3PRONGXIC", //! Table to store the derived data for Xic -> Xi pi pi candidates +DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store the derived data for Xic -> Xi pi pi candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, fdhf::TimeStamp, @@ -470,7 +470,7 @@ DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFCAND3PRONGXIC", //! Table to st fdhf::Phi, fdhf::Pt); -DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFCAND3PXICQA", //! QA extension table for Xi daughters in Xic -> Xi pi pi candidates +DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFXIC3PQA", //! QA extension table for Xi daughters in Xic -> Xi pi pi candidates o2::soa::Index<>, fdhf::CascBachelorPt, fdhf::CascBachelorPhi, From 004b42cbd6369d9ddaf81f45697206a23653ed1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Thu, 18 Jun 2026 20:46:12 +0200 Subject: [PATCH 10/17] Complete FemtoDream MC origin names --- PWGCF/DataModel/FemtoDerived.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 632fda6ad18..ad719388c23 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -747,8 +747,16 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_Material", "_NotPrimary", "_Fake", + "_WrongCollision", "_SecondaryDaughterLambda", - "_SecondaryDaughterSigmaPlus"}; + "_SecondaryDaughterSigmaPlus", + "_SecondaryDaughterSigma0", + "_SecondaryDaughterXiMinus", + "_SecondaryDaughterXi0", + "_SecondaryDaughterOmegaMinus", + "_SecondaryDaughterXistar0", + "_SecondaryDaughterXistarMinus", + "_Else"}; /// Distinguished between reconstructed and truth enum MCType { From af85e1a19fb9f31e34f6b9fae21b314245691e14 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Thu, 18 Jun 2026 20:55:57 +0000 Subject: [PATCH 11/17] Please consider the following formatting changes --- PWGCF/DataModel/FemtoDerived.h | 32 +++---- .../producerCharmHadronsTrackFemtoDream.cxx | 88 +++++++++---------- .../Tasks/taskCharmHadronsTrackFemtoDream.cxx | 2 +- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index ad719388c23..a2f0f2eaac6 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -260,18 +260,18 @@ DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Xi cascade (Xic -> Xi pi pi) -DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Lambda in Xi cascade (Xic -> Xi pi pi) -DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Lambda in Xi cascade (Xic -> Xi pi pi) -DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade -DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade -DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade -DECLARE_SOA_COLUMN(CascPosPt, cascPosPt, float); //! pT of the positive Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(CascPosPhi, cascPosPhi, float); //! phi of the positive Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(CascPosEta, cascPosEta, float); //! eta of the positive Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(CascNegPt, cascNegPt, float); //! pT of the negative Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(CascNegPhi, cascNegPhi, float); //! phi of the negative Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(CascNegEta, cascNegEta, float); //! eta of the negative Lambda daughter track from the Xi cascade -DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! MC matching flag for the selected charm hadron decay channel +DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Lambda in Xi cascade (Xic -> Xi pi pi) +DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Lambda in Xi cascade (Xic -> Xi pi pi) +DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPt, cascPosPt, float); //! pT of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPhi, cascPosPhi, float); //! phi of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosEta, cascPosEta, float); //! eta of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPt, cascNegPt, float); //! pT of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPhi, cascNegPhi, float); //! phi of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegEta, cascNegEta, float); //! eta of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! MC matching flag for the selected charm hadron decay channel DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); //! flag for reconstruction level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int); //! flag for generator level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int); //! swapping of the prongs order (0 for Lc -> pkpi, 1 for Lc -> pikp) @@ -405,10 +405,10 @@ namespace fdhf_xic { DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! [](float pt0, float phi0, float eta0, float pt1, float phi1, float eta1, float pt2, float phi2, float eta2) -> float { return RecoDecay::y(RecoDecay::pVec( - RecoDecayPtEtaPhi::pVector(pt0, eta0, phi0), - RecoDecayPtEtaPhi::pVector(pt1, eta1, phi1), - RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2)), - o2::constants::physics::MassXiCPlus); }); //! Rapidity distribution of Xic candidates + RecoDecayPtEtaPhi::pVector(pt0, eta0, phi0), + RecoDecayPtEtaPhi::pVector(pt1, eta1, phi1), + RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2)), + o2::constants::physics::MassXiCPlus); }); //! Rapidity distribution of Xic candidates } // namespace fdhf_xic DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store the derived data for charm 3prong candidates diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index 37f11806e90..d128f50fafb 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -435,34 +435,34 @@ struct HfProducerCharmHadronsTrackFemtoDream { void fillDebugParticle(ParticleType const& particle) { tables.outputDebugParts(particle.sign(), - (uint8_t)particle.tpcNClsFound(), - particle.tpcNClsFindable(), - (uint8_t)particle.tpcNClsCrossedRows(), - particle.tpcNClsShared(), - particle.tpcInnerParam(), - particle.itsNCls(), - particle.itsNClsInnerBarrel(), - particle.dcaXY(), - particle.dcaZ(), - particle.tpcSignal(), - -999., - particle.tpcNSigmaPi(), - particle.tpcNSigmaKa(), - particle.tpcNSigmaPr(), - particle.tpcNSigmaDe(), - -999., - -999., - -999., - particle.tofNSigmaPi(), - particle.tofNSigmaKa(), - particle.tofNSigmaPr(), - particle.tofNSigmaDe(), - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999.); + (uint8_t)particle.tpcNClsFound(), + particle.tpcNClsFindable(), + (uint8_t)particle.tpcNClsCrossedRows(), + particle.tpcNClsShared(), + particle.tpcInnerParam(), + particle.itsNCls(), + particle.itsNClsInnerBarrel(), + particle.dcaXY(), + particle.dcaZ(), + particle.tpcSignal(), + -999., + particle.tpcNSigmaPi(), + particle.tpcNSigmaKa(), + particle.tpcNSigmaPr(), + particle.tpcNSigmaDe(), + -999., + -999., + -999., + particle.tofNSigmaPi(), + particle.tofNSigmaKa(), + particle.tofNSigmaPr(), + particle.tofNSigmaDe(), + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999.); } template @@ -565,22 +565,22 @@ struct HfProducerCharmHadronsTrackFemtoDream { const auto pidTrackPassBit = static_cast(isTrackKaonPidSelected(track)); tables.outputParts(tables.outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - pidTrackPassBit, - track.dcaXY(), childIDs, 0, 0); + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + pidTrackPassBit, + track.dcaXY(), childIDs, 0, 0); } else { tables.outputParts(tables.outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), - track.dcaXY(), childIDs, 0, 0); + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), + track.dcaXY(), childIDs, 0, 0); } fIsTrackFilled = true; @@ -903,8 +903,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { } tables.rowMasks(bitTrack, - bitCand, - 0); + bitCand, + 0); } template diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index 849280739dd..354eb0cf50e 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -436,7 +436,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { LOG(fatal) << "Invalid PDG code for track mass hypothesis: " << trkPDGCode; } - // D0 -> K pi + track (2-prong) + // D0 -> K pi + track (2-prong) if constexpr (Channel == DecayChannel::D0ToPiK) { const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecTrack}; std::array massCharmTrk{}; From 491b4424b38fe5729a805de3bcb1d4d52bf0e660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Thu, 18 Jun 2026 23:21:37 +0200 Subject: [PATCH 12/17] Restore Lc decay notation in comment --- PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index 354eb0cf50e..eb297963313 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -465,7 +465,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { std::array massCharmTrk{}; if constexpr (Channel == DecayChannel::LcToPKPi) { - // Lc+ -> p K pi + // Λc⁺ → p K π if (cand.candidateSelFlag() == 1) { massCharmTrk = {MassProton, MassKPlus, MassPiPlus, trackMassHyp}; } else { From 0c8947c002387896ed1aea94aff246cd25ec86f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Fri, 19 Jun 2026 10:26:37 +0200 Subject: [PATCH 13/17] Restore physics notation in femto comments --- PWGCF/DataModel/FemtoDerived.h | 12 ++++++------ .../Tasks/taskCharmHadronsTrackFemtoDream.cxx | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index a2f0f2eaac6..2a5bda2c00f 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -245,7 +245,7 @@ DECLARE_SOA_COLUMN(Charge, charge, int8_t); //! Charge of c DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Track id of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Track id of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Track id of charm hadron prong2 -DECLARE_SOA_COLUMN(XiProngId, xiProngId, int); //! Cascade id of the Xi prong in Xic -> Xi pi pi candidates +DECLARE_SOA_COLUMN(XiProngId, xiProngId, int); //! Cascade id of the Ξ prong in Ξc → Ξππ candidates DECLARE_SOA_COLUMN(Prong0Pt, prong0Pt, float); //! Track pT of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Pt, prong1Pt, float); //! Track pT of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Pt, prong2Pt, float); //! Track pT of charm hadron prong2 @@ -259,9 +259,9 @@ DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int); //! Selection o DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron -DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Xi cascade (Xic -> Xi pi pi) -DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Lambda in Xi cascade (Xic -> Xi pi pi) -DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Lambda in Xi cascade (Xic -> Xi pi pi) +DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Λ in Ξ cascade (Ξc± → Ξππ) DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade @@ -439,7 +439,7 @@ DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store th fdhf::Phi, fdhf::Pt); -DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store the derived data for Xic -> Xi pi pi candidates +DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store the derived data for Ξc → Ξππ candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, fdhf::TimeStamp, @@ -470,7 +470,7 @@ DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store fdhf::Phi, fdhf::Pt); -DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFXIC3PQA", //! QA extension table for Xi daughters in Xic -> Xi pi pi candidates +DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFXIC3PQA", //! QA extension table for Ξ daughters in Ξc → Ξππ candidates o2::soa::Index<>, fdhf::CascBachelorPt, fdhf::CascBachelorPhi, diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index eb297963313..76adf7d2aab 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -363,7 +363,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { } /// Compute the charm hadron candidates mass with the daughter masses - /// assumes the candidate is either a D+ or Lc+ or D0 or Dstar or Xic+ + /// assumes the candidate is either a D+ or Λc+ or D0 or Dstar or Ξc+ template float getCharmHadronMass(const Candidate& cand, bool ReturnDaughMass = false) { @@ -375,10 +375,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { } invMass = cand.m(std::array{MassPiPlus, MassKPlus, MassProton}); return invMass; - } else if constexpr (Channel == DecayChannel::DplusToPiKPi) { // D+ -> pi K pi + } else if constexpr (Channel == DecayChannel::DplusToPiKPi) { // D+ → π K π (PDG: 411) invMass = cand.m(std::array{MassPiPlus, MassKPlus, MassPiPlus}); return invMass; - } else if constexpr (Channel == DecayChannel::D0ToPiK) { // D0 -> pi K + } else if constexpr (Channel == DecayChannel::D0ToPiK) { // D0 → π K (PDG: 421) if (cand.candidateSelFlag() == 1) { invMass = cand.m(std::array{MassPiPlus, MassKPlus}); return invMass; @@ -386,7 +386,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { invMass = cand.m(std::array{MassKPlus, MassPiPlus}); return invMass; } - } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { // D* -> D0 pi + } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { // D* → D0π (PDG: 413) float mDstar = 0.f; float mD0 = 0.f; if (cand.charge() > 0.f) { @@ -436,7 +436,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { LOG(fatal) << "Invalid PDG code for track mass hypothesis: " << trkPDGCode; } - // D0 -> K pi + track (2-prong) + // D0 → K π + track (2-prong) if constexpr (Channel == DecayChannel::D0ToPiK) { const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecTrack}; std::array massCharmTrk{}; @@ -450,7 +450,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); } - // Xic+ -> Xi pi pi + track + // Ξc⁺ → Ξ π π + track if constexpr (Channel == DecayChannel::XicToXiPiPi) { auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; @@ -458,7 +458,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); } - // 3-prong: Lc -> p K pi, D+ -> pi K pi, D* -> D0 pi + track + // 3-prong: Λc → p K π, D+ → π K π, D* → D0π + track if constexpr (Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::DstarToD0Pi) { auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; @@ -472,10 +472,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { massCharmTrk = {MassPiPlus, MassKPlus, MassProton, trackMassHyp}; } } else if constexpr (Channel == DecayChannel::DplusToPiKPi) { - // D+ -> pi K pi + // D⁺ → π K π massCharmTrk = {MassPiPlus, MassKPlus, MassPiPlus, trackMassHyp}; } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { - // D* -> D0 pi + // D* → D0π if (cand.candidateSelFlag() == 1) { massCharmTrk = {MassPiPlus, MassKPlus, MassPiPlus, trackMassHyp}; } else { From cb4896d31caa02662a8c82f1a45549647acfebbc Mon Sep 17 00:00:00 2001 From: RuiqiYin <25110190115@m.fudan.edu.cn> Date: Fri, 19 Jun 2026 10:32:29 +0200 Subject: [PATCH 14/17] Update PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx Co-authored-by: Fabrizio --- PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index 76adf7d2aab..e7f10007cfa 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -794,7 +794,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { part.pt(), part.eta(), part.phi(), - part.xiProngId(), + part.cascId(), part.prong1Id(), part.prong2Id(), part.charge(), From 77eb72f09faa05d0d2b4badc1303a722fb4bd9a9 Mon Sep 17 00:00:00 2001 From: RuiqiYin <25110190115@m.fudan.edu.cn> Date: Fri, 19 Jun 2026 10:32:53 +0200 Subject: [PATCH 15/17] Update PWGCF/DataModel/FemtoDerived.h Co-authored-by: Fabrizio --- PWGCF/DataModel/FemtoDerived.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 2a5bda2c00f..630f9392495 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -444,7 +444,7 @@ DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store femtodreamparticle::FDCollisionId, fdhf::TimeStamp, fdhf::Charge, - fdhf::XiProngId, + fdhf::CascId, fdhf::Prong1Id, fdhf::Prong2Id, fdhf::CascBachelorTrackId, From dbec2982be41836897ea3d3656df093f981fdadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Fri, 19 Jun 2026 10:39:11 +0200 Subject: [PATCH 16/17] Fix Xic femto cascade id column --- PWGCF/DataModel/FemtoDerived.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 630f9392495..a4d00d6d416 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -245,7 +245,7 @@ DECLARE_SOA_COLUMN(Charge, charge, int8_t); //! Charge of c DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Track id of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Track id of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Track id of charm hadron prong2 -DECLARE_SOA_COLUMN(XiProngId, xiProngId, int); //! Cascade id of the Ξ prong in Ξc → Ξππ candidates +DECLARE_SOA_COLUMN(CascId, cascId, int); //! Cascade id of the Ξ prong in Ξc → Ξππ candidates DECLARE_SOA_COLUMN(Prong0Pt, prong0Pt, float); //! Track pT of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Pt, prong1Pt, float); //! Track pT of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Pt, prong2Pt, float); //! Track pT of charm hadron prong2 From 4b2c1e893432b57c4ece97044726a989777f2dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRuiqi?= <23210190047@m.fudan.edu.cn> Date: Fri, 19 Jun 2026 11:36:52 +0200 Subject: [PATCH 17/17] Trigger CI rerun