diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 22e6d813f2f..041c273a643 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -90,10 +90,12 @@ namespace femtodreamparticle { /// Distinuishes the different particle types enum ParticleType { - kTrack, //! Track - kV0, //! V0 - kV0Child, //! Child track of a V0 - kCascade, //! Cascade + kTrack, //! Track + kV0, //! V0 + kV0Child, //! Child track of a V0 + kCascade, //! Cascade + kCascadeV0, + kCascadeV0Child, kCascadeBachelor, //! Bachelor track of a cascade kCharmHadron, //! Bachelor track of a cascade kNParticleTypes //! Number of particle types @@ -105,19 +107,20 @@ enum MomentumType { kPtpc //! momentum at the inner wall of the TPC (useful for PID plots) }; -static constexpr std::string_view ParticleTypeName[kNParticleTypes] = {"Tracks", "V0", "V0Child", "Cascade", "CascadeBachelor", "CharmHadron"}; //! Naming of the different particle types -static constexpr std::string_view TempFitVarName[kNParticleTypes] = {"/hDCAxy", "/hCPA", "/hDCAxy", "/hCPA", "/hDCAxy", "/hCPA"}; +static constexpr std::string_view ParticleTypeName[kNParticleTypes] = {"Tracks", "V0", "V0Child", "Cascade", "CascadeV0", "CascadeV0Child", "CascadeBachelor", "CharmHadron"}; //! Naming of the different particle types +static constexpr std::string_view TempFitVarName[kNParticleTypes] = {"/hDCAxy", "/hCPA", "/hDCAxy", "/hCPA", "/hCPA", "/hDCAxy", "/hDCAxy", "/hCPA"}; using cutContainerType = uint32_t; //! Definition of the data type for the bit-wise container for the different selection criteria enum TrackType { - kNoChild, //! Not a V0 child + kNoChild, //! Not any child kPosChild, //! Positive V0 child kNegChild, //! Negative V0 child + kBachelor, //! Bachelor Cascade child kNTrackTypes //! Number of child types }; -static constexpr std::string_view TrackTypeName[kNTrackTypes] = {"Trk", "Pos", "Neg"}; //! Naming of the different particle types +static constexpr std::string_view TrackTypeName[kNTrackTypes] = {"Trk", "Pos", "Neg", "Bach"}; //! Naming of the different particle types DECLARE_SOA_INDEX_COLUMN(FDCollision, fdCollision); DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c) diff --git a/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h b/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h new file mode 100644 index 00000000000..2826d545c19 --- /dev/null +++ b/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h @@ -0,0 +1,900 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoDreamCascadeSelection.h +/// \brief Definition of the femtoDreamCascadeSelection +/// \author Valentina Mantovani Sarti, TU München valentina.mantovani-sarti@tum.de +/// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +/// \author Luca Barioglio, TU München, luca.barioglio@cern.ch +/// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch +/// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch +/// \author Shirajum Monira, WUT Warsaw, shirajum.monira@cern.ch +/// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de + +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCASCADESELECTION_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMCASCADESELECTION_H_ + +#include +#include +#include + +#include // FIXME + +#include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" + +#include "Common/Core/RecoDecay.h" +#include "Framework/HistogramRegistry.h" +#include "ReconstructionDataFormats/PID.h" + +using namespace o2::framework; + +namespace o2::analysis::femtoDream +{ +namespace femtoDreamCascadeSelection +{ +/// The different selections this task is capable of doing +enum CascadeSel { + kCascadeSign, ///< +1 particle, -1 antiparticle + kCascadePtMin, + kCascadePtMax, + kCascadeEtaMax, + kCascadeDCADaughMax, + kCascadeCPAMin, + kCascadeTranRadMin, + kCascadeTranRadMax, + kCascadeDecVtxMax, + + kCascadeV0DCADaughMax, + kCascadeV0CPAMin, + kCascadeV0TranRadMin, + kCascadeV0TranRadMax, + kCascadeV0DCAtoPVMin, + kCascadeV0DCAtoPVMax + // kNcascadeSelection + // kCascadeV0MassMin, + // kCascadeV0MassMax +}; +/* +kCascadeDCAPosToPV, +kCascadeDCANegToPV, +kCascadeDCABachToPV, +*/ + +enum ChildTrackType { kPosTrack, + kNegTrack, + kBachTrack }; + +enum CascadeContainerPosition { + kCascade, + kPosCuts, + kPosPID, + kNegCuts, + kNegPID, + kBachCuts, + kBachPID, +}; /// Position in the full VO cut container (for cutculator) + +} // namespace femtoDreamCascadeSelection + +/// \class FemtoDreamCascadeSelection +/// \brief Cut class to contain and execute all cuts applied to Cascades +class FemtoDreamCascadeSelection + : public FemtoDreamObjectSelection +{ + public: + FemtoDreamCascadeSelection() + : nCascadePtMin(0), + nCascadePtMax(0), + nCascadeEtaMax(0), + nCascadeDCADaughMax(0), + nCascadeCPAMin(0), + nCascadeTranRadMin(0), + nCascadeTranRadMax(0), + nCascadeDecVtxMax(0), + /* + nCascadeDCAPosToPV(0), + nCascadeDCANegToPV(0), + nCascadeDCABachToPV(0), + */ + nCascadeV0DCADaughMax(0), + nCascadeV0CPAMin(0), + nCascadeV0TranRadMin(0), + nCascadeV0TranRadMax(0), + nCascadeV0DCAToPVMin(0), + nCascadeV0DCAToPVMax(0), + + fCascadePtMin(9999999), + fCascadePtMax(-9999999), + fCascadeEtaMax(-9999999), + fCascadeDCADaughMax(-9999999), + fCascadeCPAMin(9999999), + fCascadeTranRadMin(9999999), + fCascadeTranRadMax(-9999999), + fCascadeDecVtxMax(-9999999), + /* + fCascadeDCAPosToPV(9999999), + fCascadeDCANegToPV(9999999), + fCascadeDCABachToPV(9999999), + */ + fCascadeV0DCADaughMax(-9999999), + fCascadeV0CPAMin(9999999), + fCascadeV0TranRadMin(9999999), + fCascadeV0TranRadMax(-9999999), + fCascadeV0DCAToPVMin(9999999), + fCascadeV0DCAToPVMax(-9999999), + + fV0InvMassLowLimit(1.05), + fV0InvMassUpLimit(1.3), + fInvMassLowLimit(1.25), + fInvMassUpLimit(1.4), + fRejectCompetingMass(false), + fInvMassCompetingLowLimit(1.5), + fInvMassCompetingUpLimit(2.0), + isCascOmega(false) + /*,nSigmaPIDOffsetTPC(0.)*/ + { + } + + /// Initializes histograms for the task + template + void init(HistogramRegistry* QAregistry, HistogramRegistry* Registry, bool isSelectCascOmega = false); + + template + bool isSelectedMinimal(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack, Track const& bachTrack); + + template + void fillCascadeQA(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack); + + template + void fillQA(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack, Track const& bachTrack); + + // template + // std::array getCutContainer(Col const& col, Casc const& casc, V0 const& v0Daugh, Track const& posTrack, Track const& negTrack, Track const& bachTrack); + template + std::array getCutContainer(Col const& col, Casc const& casc, Track const& posTrack, Track const& negTrack, Track const& bachTrack); + + template + void setChildCuts(femtoDreamCascadeSelection::ChildTrackType child, + T1 selVal, + T2 selVar, + femtoDreamSelection::SelectionType selType) + { + if (child == femtoDreamCascadeSelection::kPosTrack) { + PosDaughTrack.setSelection(selVal, selVar, selType); + } else if (child == femtoDreamCascadeSelection::kNegTrack) { + NegDaughTrack.setSelection(selVal, selVar, selType); + } else if (child == femtoDreamCascadeSelection::kBachTrack) { + BachTrack.setSelection(selVal, selVar, selType); + } + } + + template + void setChildPIDSpecies(femtoDreamCascadeSelection::ChildTrackType child, + T& pids) + { + if (child == femtoDreamCascadeSelection::kPosTrack) { + PosDaughTrack.setPIDSpecies(pids); + } else if (child == femtoDreamCascadeSelection::kNegTrack) { + NegDaughTrack.setPIDSpecies(pids); + } else if (child == femtoDreamCascadeSelection::kBachTrack) { + BachTrack.setPIDSpecies(pids); + } + } + + /// Helper function to obtain the name of a given selection criterion for consistent naming of the configurables + /// \param iSel Track selection variable to be examined + /// \param prefix Additional prefix for the name of the configurable + /// \param suffix Additional suffix for the name of the configurable + static std::string getSelectionName(femtoDreamCascadeSelection::CascadeSel iSel, + std::string_view prefix = "", + std::string_view suffix = "") + { + std::string outString = static_cast(prefix); + outString += static_cast(mSelectionNames[iSel]); + outString += suffix; + return outString; + } + + /// Helper function to obtain the index of a given selection variable for consistent naming of the configurables + /// \param obs Cascade selection variable (together with prefix) got from file + /// \param prefix Additional prefix for the output of the configurable + static int findSelectionIndex(const std::string_view& obs, + std::string_view prefix = "") + { + for (int index = 0; index < kNcascadeSelection; index++) { + std::string comp = static_cast(prefix) + + static_cast(mSelectionNames[index]); + std::string_view cmp{comp}; + if (obs.compare(cmp) == 0) + return index; + } + LOGF(info, "Variable %s not found", obs); + return -1; + } + + /// Helper function to obtain the type of a given selection variable for consistent naming of the configurables + /// \param iSel Casc selection variable whose type is returned + static femtoDreamSelection::SelectionType getSelectionType(femtoDreamCascadeSelection::CascadeSel iSel) + { + return mSelectionTypes[iSel]; + } + + /// Helper function to obtain the helper string of a given selection criterion + /// for consistent description of the configurables + /// \param iSel Track selection variable to be examined + /// \param prefix Additional prefix for the output of the configurable + static std::string getSelectionHelper(femtoDreamCascadeSelection::CascadeSel iSel, + std::string_view prefix = "") + { + std::string outString = static_cast(prefix); + outString += static_cast(mSelectionHelper[iSel]); + return outString; + } + + /// Set limit for the selection on the invariant mass + /// \param lowLimit Lower limit for the invariant mass distribution + /// \param upLimit Upper limit for the invariant mass distribution + void setInvMassLimits(float lowLimit, float upLimit) + { + fInvMassLowLimit = lowLimit; + fInvMassUpLimit = upLimit; + } + + void setV0InvMassLimits(float lowLimit, float upLimit) + { + fV0InvMassLowLimit = lowLimit; + fV0InvMassUpLimit = upLimit; + } + + /// Set limit for the omega rejection on the invariant mass + /// \param lowLimit Lower limit for the invariant mass distribution + /// \param upLimit Upper limit for the invariant mass distribution + void setCompetingInvMassLimits(float lowLimit, float upLimit) + { + fRejectCompetingMass = true; + fInvMassCompetingLowLimit = lowLimit; + fInvMassCompetingUpLimit = upLimit; + } + + private: + int nCascadePtMin; + int nCascadePtMax; + int nCascadeEtaMax; + int nCascadeDCADaughMax; + int nCascadeCPAMin; + int nCascadeTranRadMin; + int nCascadeTranRadMax; + int nCascadeDecVtxMax; + /* + int nCascadeDCAPosToPV; + int nCascadeDCANegToPV; + int nCascadeDCABachToPV; + */ + int nCascadeV0DCADaughMax; + int nCascadeV0CPAMin; + int nCascadeV0TranRadMin; + int nCascadeV0TranRadMax; + int nCascadeV0DCAToPVMin; + int nCascadeV0DCAToPVMax; + + float fCascadePtMin; + float fCascadePtMax; + float fCascadeEtaMax; + float fCascadeDCADaughMax; + float fCascadeCPAMin; + float fCascadeTranRadMin; + float fCascadeTranRadMax; + float fCascadeDecVtxMax; + /* + float fCascadeDCAPosToPV; + float fCascadeDCANegToPV; + float fCascadeDCABachToPV; + */ + float fCascadeV0DCADaughMax; + float fCascadeV0CPAMin; + float fCascadeV0TranRadMin; + float fCascadeV0TranRadMax; + float fCascadeV0DCAToPVMin; + float fCascadeV0DCAToPVMax; + + float fV0InvMassLowLimit; + float fV0InvMassUpLimit; + + float fInvMassLowLimit; + float fInvMassUpLimit; + + float fRejectCompetingMass; + float fInvMassCompetingLowLimit; + float fInvMassCompetingUpLimit; + + bool isCascOmega; + + // float nSigmaPIDOffsetTPC; + + FemtoDreamTrackSelection PosDaughTrack; + FemtoDreamTrackSelection NegDaughTrack; + FemtoDreamTrackSelection BachTrack; + // FemtoDreamV0Selection V0DaughSel; + + static constexpr int kNcascadeSelection = 16; + + static constexpr std::string_view mSelectionNames[kNcascadeSelection] = { + "Sign", "PtMin", "PtMax", "EtaMax", "DCAcascDaugh", "CPAMin", "TranRadMin", "TranRadMax", "DecVtxMax", // Cascade Selections + "DCAv0daughMax", "v0CPAMin", "v0TranRadMin", "v0TranRadMax", "DCAV0ToPVMin", "DCAV0ToPVMax"}; // CascadeV0 selections + //"kV0MassMin", "V0MassMax"}; //CascadeV0 selections + // "DCAPosToPV", "DCANegToPV", "DCABachToPV", //Cascade daughter track selections + // }; //<< Name of the different selections + + static constexpr femtoDreamSelection::SelectionType + mSelectionTypes[kNcascadeSelection]{ + femtoDreamSelection::kEqual, // sign + femtoDreamSelection::kLowerLimit, // pt min + femtoDreamSelection::kUpperLimit, // pt max + femtoDreamSelection::kUpperLimit, // eta max + femtoDreamSelection::kUpperLimit, // DCA cascade daughters max + femtoDreamSelection::kLowerLimit, // cascade cos PA min + femtoDreamSelection::kLowerLimit, // cascade tran rad min + femtoDreamSelection::kUpperLimit, // cascade tran rad max + femtoDreamSelection::kUpperLimit, // cascade maximum distance of decay vertex to PV + + femtoDreamSelection::kUpperLimit, // v0 daughters DCA max + femtoDreamSelection::kLowerLimit, // v0 cos PA min + femtoDreamSelection::kLowerLimit, // v0 tran rad min + femtoDreamSelection::kUpperLimit, // v0 tran rad max + femtoDreamSelection::kLowerLimit, // v0 minimum distance of decay vertex to PV + femtoDreamSelection::kUpperLimit // v0 maximum distance of decay vertex to PV + // femtoDreamSelection::kLowerLimit, // v0 mass min + // femtoDreamSelection::kUpperLimit // v0 mass max + }; ///< Map to match a variable with + ///< its type + + /* + femtoDreamSelection::kLowerLimit, // DCA pos to PV max + femtoDreamSelection::kLowerLimit, // DCA neg to PV max + femtoDreamSelection::kLowerLimit, // DCA bach to PV max + */ + + static constexpr std::string_view mSelectionHelper[kNcascadeSelection] = { + "Cascade particle sign (+1 or -1)", + "Minimum pT (GeV/c)", + "Maximum pT (GeV/c)", + "Maximum |Eta|", + "Maximum DCA between cascade daughters (cm)", + "Minimum Cosine of Pointing Angle for cascade", + "Minimum cascade transverse radius (cm)", + "Maximum cascade transverse radius (cm)", + "Maximum distance of cascade from primary vertex", + + "Maximum DCA between v0 daughters (cm)", + "Minimum Cosine of Pointing Angle for v0", + "Minimum v0 transverse radius (cm)", + "Maximum v0 transverse radius (cm)", + "Minimum distance of v0 from primary vertex", + "Maximum distance of v0 from primary vertex" + //"Minimum V0 mass", + //"Maximum V0 mass" + }; ///< Helper information for the + ///< different selections + + /* + "Maximum DCA of positive track form primary vertex", + "Maximum DCA of negative track form primary vertex", + "Maximum DCA of bachelor track form primary vertex", + + }; ///< Helper information for the + ///< different selections ///< different selections + */ +}; // namespace femtoDream + +template +void FemtoDreamCascadeSelection::init(HistogramRegistry* QAregistry, HistogramRegistry* Registry, bool isSelectCascOmega) +{ + + if (QAregistry && Registry) { + mHistogramRegistry = Registry; + mQAHistogramRegistry = QAregistry; + // fillSelectionHistogram(); // cascade + // fillSelectionHistogram(); // pos, neg + // fillSelectionHistogram(); // bach + + AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec etaAxis = {100, -2.0f, 2.0f, "#it{#eta}"}; + AxisSpec phiAxis = {100, 0.0f, 6.0f, "#it{#phi}"}; + AxisSpec DCADaughAxis = {1000, 0.0f, 2.0f, "DCA (cm)"}; + AxisSpec CPAAxis = {1000, 0.95f, 1.0f, "#it{cos #theta_{p}}"}; + AxisSpec tranRadAxis = {1000, 0.0f, 100.0f, "#it{r}_{xy} (cm)"}; + AxisSpec decVtxAxis = {2000, 0, 200, "#it{Vtx}_{z} (cm)"}; + AxisSpec massAxisCascade = {2200, 1.25f, 1.8f, "m_{#Cascade} (GeV/#it{c}^{2})"}; + + AxisSpec DCAToPVAxis = {1000, -10.0f, 10.0f, "DCA to PV (cm)"}; + + AxisSpec massAxisV0 = {600, 0.0f, 3.0f, "m_{#V0} (GeV/#it{c}^{2})"}; + + /// \todo this should be an automatic check in the parent class, and the + /// return type should be templated + size_t nSelections = getNSelections(); + if (nSelections > 8 * sizeof(cutContainerType)) { + LOGF(info, "Number of selections %i", nSelections); + LOG(fatal) << "FemtoDreamCascadeCuts: Number of selections to large for your " + "container - quitting!"; + } + + std::string folderName = static_cast( + o2::aod::femtodreamparticle::ParticleTypeName[part]); + mQAHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{1000, 0, 10}}); + mQAHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{1000, -1, 1}}); + mQAHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{1000, 0, 2. * M_PI}}); + mQAHistogramRegistry->add((folderName + "/hDCADaugh").c_str(), "; daughters DCA; Entries", kTH1F, {DCADaughAxis}); + mQAHistogramRegistry->add((folderName + "/hCPA").c_str(), "; Cos PA; Entries", kTH1F, {CPAAxis}); + mQAHistogramRegistry->add((folderName + "/hTranRad").c_str(), "; Transverse Radius; Entries", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/hDecVtxX").c_str(), "; Decay vertex x position; Entries", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/hDecVtxY").c_str(), "; Decay vertex y position; Entries", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/hDecVtxZ").c_str(), "; Decay vertex z position; Entries", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/hInvMass").c_str(), "; Invariant mass; Entries", kTH1F, {tranRadAxis}); + + mQAHistogramRegistry->add((folderName + "/hV0DCADaugh").c_str(), "; V0-daughters DCA; Entries", kTH1F, {DCADaughAxis}); + mQAHistogramRegistry->add((folderName + "/hV0CPA").c_str(), "; V0 cos PA; Entries", kTH1F, {CPAAxis}); + mQAHistogramRegistry->add((folderName + "/hV0TranRad").c_str(), "; V0 transverse radius; Entries", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/hV0DCAToPV").c_str(), "; DCA of the V0 to the PV; Entries", kTH1F, {massAxisV0}); + mQAHistogramRegistry->add((folderName + "/hV0InvMass").c_str(), "; Invariant mass Cascade V0; Entries", kTH1F, {massAxisV0}); + + PosDaughTrack.init(mQAHistogramRegistry, mHistogramRegistry); + + NegDaughTrack.init(mQAHistogramRegistry, mHistogramRegistry); + + BachTrack.init(mQAHistogramRegistry, mHistogramRegistry); + + // Cascade (Xi, Omega) + mQAHistogramRegistry->add("CascadeQA/hCascadePt", "pT distribution", kTH1F, {ptAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeEta", "Eta distribution", kTH1F, {etaAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadePhi", "Phi distribution", kTH1F, {phiAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeDCADaugh", "Cascade-daughters DCA", kTH1F, {DCADaughAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeCPA", "Cos PA", kTH1F, {CPAAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeTranRad", "Transverse radius", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeDecVtxX", "Decay vertex x position", kTH1F, {decVtxAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeDecVtxY", "Decay vertex y position", kTH1F, {decVtxAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeDecVtxZ", "Decay vertex z position", kTH1F, {decVtxAxis}); + mQAHistogramRegistry->add("CascadeQA/hInvMassCascade", "Invariant mass Cascade", kTH1F, {massAxisCascade}); + // V0 (Lambda) + mQAHistogramRegistry->add("CascadeQA/hCascadeV0DCADaugh", "V0-daughters DCA", kTH1F, {DCADaughAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeV0CPA", "V0 cos PA", kTH1F, {CPAAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeV0TranRad", "V0 transverse radius", kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeV0DCAToPV", "DCA of the V0 to the PV", kTH1F, {massAxisV0}); + mQAHistogramRegistry->add("CascadeQA/hInvMassV0", "Invariant mass Cascade V0", kTH1F, {massAxisV0}); + + /* + // Dauchter Tracks + mQAHistogramRegistry->add("CascadeQA/hCascadeDCAPosToPV", "Pos V0 daughter DCA to primary vertex", kTH1F, {DCAToPVAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeDCANegToPV", "Neg V0 daughter DCA to primary vertex", kTH1F, {DCAToPVAxis}); + mQAHistogramRegistry->add("CascadeQA/hCascadeDCABachToPV", "Bachelor DCA to primary vertex", kTH1F, {DCAToPVAxis}); + */ + } + + /// check whether the most open cuts are fulfilled - most of this should have + /// already be done by the filters + nCascadePtMin = getNSelections(femtoDreamCascadeSelection::kCascadePtMin); + nCascadePtMax = getNSelections(femtoDreamCascadeSelection::kCascadePtMax); + nCascadeEtaMax = getNSelections(femtoDreamCascadeSelection::kCascadeEtaMax); + nCascadeDCADaughMax = getNSelections(femtoDreamCascadeSelection::kCascadeDCADaughMax); + nCascadeCPAMin = getNSelections(femtoDreamCascadeSelection::kCascadeCPAMin); + nCascadeTranRadMin = getNSelections(femtoDreamCascadeSelection::kCascadeTranRadMin); + nCascadeTranRadMax = getNSelections(femtoDreamCascadeSelection::kCascadeTranRadMax); + nCascadeDecVtxMax = getNSelections(femtoDreamCascadeSelection::kCascadeDecVtxMax); + + nCascadeV0DCADaughMax = getNSelections(femtoDreamCascadeSelection::kCascadeV0DCADaughMax); + nCascadeV0CPAMin = getNSelections(femtoDreamCascadeSelection::kCascadeV0CPAMin); + nCascadeV0TranRadMin = getNSelections(femtoDreamCascadeSelection::kCascadeV0TranRadMin); + nCascadeV0TranRadMax = getNSelections(femtoDreamCascadeSelection::kCascadeV0TranRadMax); + nCascadeV0DCAToPVMin = getNSelections(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin); + nCascadeV0DCAToPVMax = getNSelections(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax); + + /* + nCascadeDCAPosToPV = getNSelections(femtoDreamCascadeSelection::kCascadeDCAPosToPV); + nCascadeDCANegToPV = getNSelections(femtoDreamCascadeSelection::kCascadeDCANegToPV); + nCascadeDCABachToPV = getNSelections(femtoDreamCascadeSelection::kCascadeDCABachToPV); + */ + + fCascadePtMin = getMinimalSelection(femtoDreamCascadeSelection::kCascadePtMin, + femtoDreamSelection::kLowerLimit); + fCascadePtMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadePtMax, + femtoDreamSelection::kUpperLimit); + fCascadeEtaMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeEtaMax, + femtoDreamSelection::kAbsUpperLimit); + fCascadeDCADaughMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeDCADaughMax, + femtoDreamSelection::kUpperLimit); + fCascadeCPAMin = getMinimalSelection(femtoDreamCascadeSelection::kCascadeCPAMin, + femtoDreamSelection::kLowerLimit); + fCascadeTranRadMin = getMinimalSelection(femtoDreamCascadeSelection::kCascadeTranRadMin, + femtoDreamSelection::kLowerLimit); + fCascadeTranRadMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeTranRadMax, + femtoDreamSelection::kUpperLimit); + fCascadeDecVtxMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeDecVtxMax, + femtoDreamSelection::kAbsUpperLimit); + + fCascadeV0DCADaughMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0DCADaughMax, + femtoDreamSelection::kUpperLimit); + fCascadeV0CPAMin = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0CPAMin, + femtoDreamSelection::kLowerLimit); + fCascadeV0TranRadMin = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0TranRadMin, + femtoDreamSelection::kLowerLimit); + fCascadeV0TranRadMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0TranRadMax, + femtoDreamSelection::kUpperLimit); + fCascadeV0DCAToPVMin = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, + femtoDreamSelection::kLowerLimit); + fCascadeV0DCAToPVMax = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, + femtoDreamSelection::kUpperLimit); + // fV0InvMassLowLimit = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0MassMin, + // femtoDreamSelection::kLowerLimit); + // fV0InvMassUpLimit = getMinimalSelection(femtoDreamCascadeSelection::kCascadeV0MassMax, + // femtoDreamSelection::kUpperLimit); + + /* + fCascadeDCAPosToPV = getMinimalSelection(femtoDreamCascadeSelection::kCascadeDCAPosToPV, + femtoDreamSelection::kLowerLimit); + fCascadeDCANegToPV = getMinimalSelection(femtoDreamCascadeSelection::kCascadeDCANegToPV, + femtoDreamSelection::kLowerLimit); + fCascadeDCABachToPV = getMinimalSelection(femtoDreamCascadeSelection::kCascadeDCABachToPV, + femtoDreamSelection::kLowerLimit); + */ + isCascOmega = isSelectCascOmega; +} + +template +bool FemtoDreamCascadeSelection::isSelectedMinimal(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack, Track const& bachTrack) +{ + const auto signPos = posTrack.sign(); + const auto signNeg = negTrack.sign(); + + if (signPos < 0 || signNeg > 0) { + LOG(warn) << "Something wrong in isSelectedMinimal"; + LOG(warn) << "ERROR - Wrong sign for V0 daughters"; + } + + const std::vector decVtx = {cascade.x(), cascade.y(), cascade.z()}; + + const float cpav0 = cascade.v0cosPA(col.posX(), col.posY(), col.posZ()); + const float cpaCasc = cascade.casccosPA(col.posX(), col.posY(), col.posZ()); + const float dcav0topv = cascade.dcav0topv(col.posX(), col.posY(), col.posZ()); + const float invMassLambda = cascade.mLambda(); + // const float invMass = isCascOmega ? cascade.mOmega() : cascade.mXi(); + const float invMass = cascade.mXi(); + + if (invMassLambda < fV0InvMassLowLimit || invMassLambda > fV0InvMassUpLimit) { + return false; + } + // else{ + // mQAHistogramRegistry->fill(HIST("CascadeQA/hInvMassV0"), invMassLambda); + // } + + if (invMass < fInvMassLowLimit || invMass > fInvMassUpLimit) { + return false; + } + // else{ + // mQAHistogramRegistry->fill(HIST("CascadeQA/hInvMassCascade"), invMass); + // } + + /* + if (fRejectCompetingMass) { + const float invMassCompeting = isCascOmega ? cascade.mXi() : cascade.mOmega(); + if (invMassCompeting > fInvMassCompetingLowLimit && + invMassCompeting < fInvMassCompetingUpLimit) { + return false; + } + } + */ + + if (nCascadePtMin > 0 && cascade.pt() < fCascadePtMin) { + return false; + } + if (nCascadePtMax > 0 && cascade.pt() > fCascadePtMax) { + return false; + } + if (nCascadeEtaMax > 0 && std::abs(cascade.eta()) > fCascadeEtaMax) { + return false; + } + if (nCascadeDCADaughMax > 0 && cascade.dcacascdaughters() > fCascadeDCADaughMax) { + return false; + } + if (fCascadeCPAMin > 0 && cpaCasc < fCascadeCPAMin) { + return false; + } + if (nCascadeTranRadMin > 0 && cascade.cascradius() < fCascadeTranRadMin) { + return false; + } + if (nCascadeTranRadMax > 0 && cascade.cascradius() > fCascadeTranRadMax) { + return false; + } + for (size_t i = 0; i < decVtx.size(); i++) { + if (nCascadeDecVtxMax > 0 && decVtx.at(i) > fCascadeDecVtxMax) { + return false; + } + } + + // v0 criteria + if (nCascadeV0DCADaughMax > 0 && cascade.dcaV0daughters() > fCascadeV0DCADaughMax) { + return false; + } + if (nCascadeV0CPAMin > 0 && cpav0 < fCascadeV0CPAMin) { + return false; + } + if (nCascadeV0TranRadMin > 0 && cascade.v0radius() < fCascadeV0TranRadMin) { + return false; + } + if (nCascadeV0TranRadMax > 0 && cascade.v0radius() > fCascadeV0TranRadMax) { + return false; + } + if (nCascadeV0DCAToPVMin > 0 && abs(dcav0topv) < fCascadeV0DCAToPVMin) { + return false; + } + if (nCascadeV0DCAToPVMax > 0 && abs(dcav0topv) > fCascadeV0DCAToPVMax) { + return false; + } + // Chech the selection criteria for the tracks as well + if (!PosDaughTrack.isSelectedMinimal(posTrack)) { + return false; + } + if (!NegDaughTrack.isSelectedMinimal(negTrack)) { + return false; + } + if (!BachTrack.isSelectedMinimal(bachTrack)) { + return false; + } + + /* + if (nCascadeDCAPosToPV > 0 && abs(cascade.dcapostopv()) < fCascadeDCAPosToPV) { + return false; + } + if (nCascadeDCANegToPV > 0 && abs(cascade.dcanegtopv()) < fCascadeDCANegToPV) { + return false; + } + if (nCascadeDCABachToPV > 0 && abs(cascade.dcabachtopv()) < fCascadeDCABachToPV) { + return false; + } + */ + + return true; +} + +template +void FemtoDreamCascadeSelection::fillCascadeQA(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack) +{ + const auto signPos = posTrack.sign(); + const auto signNeg = negTrack.sign(); + if (signPos < 0 || signNeg > 0) { + LOG(warn) << "Something wrong in isSelectedMinimal"; + LOG(warn) << "ERROR - Wrong sign for V0 daughters"; + } + + const std::vector decVtx = {cascade.x(), cascade.y(), cascade.z()}; + const float cpaCasc = cascade.casccosPA(col.posX(), col.posY(), col.posZ()); + const float invMass = isCascOmega ? cascade.mOmega() : cascade.mXi(); + + const float cpav0 = cascade.v0cosPA(col.posX(), col.posY(), col.posZ()); + const float dcav0topv = cascade.dcav0topv(col.posX(), col.posY(), col.posZ()); + const float invMassLambda = cascade.mLambda(); + + // Cascade + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadePt"), cascade.pt()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeEta"), cascade.eta()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadePhi"), cascade.phi()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDCADaugh"), cascade.dcacascdaughters()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeCPA"), cpaCasc); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeTranRad"), cascade.cascradius()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDecVtxX"), decVtx.at(0)); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDecVtxY"), decVtx.at(1)); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDecVtxZ"), decVtx.at(2)); + mQAHistogramRegistry->fill(HIST("CascadeQA/hInvMassCascade"), invMass); + /* + // Daughter Tracks + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDCAPosToPV"), cascade.dcapostopv()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDCANegToPV"), cascade.dcanegtopv()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeDCABachToPV"), cascade.dcabachtopv()); + */ + // V0 (Lambda) + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeV0DCADaugh"), cascade.dcaV0daughters()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeV0CPA"), cpav0); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeV0TranRad"), cascade.v0radius()); + mQAHistogramRegistry->fill(HIST("CascadeQA/hCascadeV0DCAToPV"), dcav0topv); + mQAHistogramRegistry->fill(HIST("CascadeQA/hInvMassV0"), invMassLambda); + + // is this necessary + /* + bool write = true; + for (size_t i = 0; i < decVtx.size(); i++) { + write = write && (decVtx.at(i) < DecVtxMax); + } + if (write) { + mQAHistogramRegistry->fill(HIST("CAscadeQA/hInvMassCascadeDecVtxMax"), + cascade.mXi()); + } + */ +} + +// template +// std::array FemtoDreamCascadeSelection::getCutContainer(Col const& col, Casc const& casc, V0 const& v0Daugh, Track const& posTrack, Track const& negTrack, Track const& bachTrack) +template +std::array FemtoDreamCascadeSelection::getCutContainer(Col const& col, Casc const& casc, Track const& posTrack, Track const& negTrack, Track const& bachTrack) +{ + // Cut bit + // auto outputV0Daugh = V0DaughSel.getCutContainer(v0Daugh, posTrack, negTrack); + auto outputPosTrack = PosDaughTrack.getCutContainer(posTrack, casc.positivept(), casc.positiveeta(), casc.dcapostopv()); + auto outputNegTrack = NegDaughTrack.getCutContainer(negTrack, casc.negativept(), casc.negativeeta(), casc.dcanegtopv()); + auto outputBachTrack = BachTrack.getCutContainer(bachTrack, casc.bachelorpt(), casc.bacheloreta(), casc.dcabachtopv()); + cutContainerType output = 0; + size_t counter = 0; + + // auto xiMassNominal = o2::constants::physics::MassXiMinus; + // auto xiMassHypothesis = casc.mXi(); + // auto antiXiMassHypothesis = casc.mAntiXi(); + // auto diffXi = abs(xiMassNominal - xiMassHypothesis); + // auto diffAntiXi = abs(xiMassNominal - antiXiMassHypothesis); + + float sign = 0.; + int nSigmaPIDMax = PosDaughTrack.getSigmaPIDMax(); + + auto nSigmaPrNeg = negTrack.tpcNSigmaPr(); + auto nSigmaPiPos = posTrack.tpcNSigmaPi(); + auto nSigmaPiNeg = negTrack.tpcNSigmaPi(); + auto nSigmaPrPos = posTrack.tpcNSigmaPr(); + float nSigmaPIDOffsetTPC = 0.; + + // negative charge: Antiparticle (Xi+) + // positive charge: Particle (Xi-) + if (abs(nSigmaPrNeg - nSigmaPIDOffsetTPC) < nSigmaPIDMax && abs(nSigmaPiPos - nSigmaPIDOffsetTPC) < nSigmaPIDMax) { + sign = -1.; + } else if (abs(nSigmaPrPos - nSigmaPIDOffsetTPC) < nSigmaPIDMax && abs(nSigmaPiNeg - nSigmaPIDOffsetTPC) < nSigmaPIDMax) { + sign = 1.; + } + + const auto cpaCasc = casc.casccosPA(col.posX(), col.posY(), col.posZ()); + const std::vector decVtx = {casc.x(), casc.y(), casc.z()}; + const auto cpav0 = casc.v0cosPA(col.posX(), col.posY(), col.posZ()); + const auto dcav0topv = casc.dcav0topv(col.posX(), col.posY(), col.posZ()); + + float observable = 0.; + for (auto& sel : mSelections) { + + const auto selVariable = sel.getSelectionVariable(); + switch (selVariable) { + case (femtoDreamCascadeSelection::kCascadeSign): + observable = sign; + break; + case (femtoDreamCascadeSelection::kCascadePtMin): + observable = casc.pt(); + break; + case (femtoDreamCascadeSelection::kCascadePtMax): + observable = casc.pt(); + break; + case (femtoDreamCascadeSelection::kCascadeEtaMax): + observable = casc.eta(); + break; + case (femtoDreamCascadeSelection::kCascadeDCADaughMax): + observable = casc.dcacascdaughters(); + break; + case (femtoDreamCascadeSelection::kCascadeCPAMin): + observable = cpaCasc; + break; + case (femtoDreamCascadeSelection::kCascadeTranRadMin): + observable = casc.cascradius(); + break; + case (femtoDreamCascadeSelection::kCascadeTranRadMax): + observable = casc.cascradius(); + break; + // kCascadeDecVtxMax is done above + case (femtoDreamCascadeSelection::kCascadeDecVtxMax): + for (size_t i = 0; i < decVtx.size(); ++i) { + auto decVtxValue = decVtx.at(i); + sel.checkSelectionSetBit(decVtxValue, output, counter, nullptr); + } + continue; + break; + + case (femtoDreamCascadeSelection::kCascadeV0DCADaughMax): + observable = casc.dcaV0daughters(); + break; + case (femtoDreamCascadeSelection::kCascadeV0CPAMin): + observable = cpav0; + break; + case (femtoDreamCascadeSelection::kCascadeV0TranRadMin): + observable = casc.v0radius(); + break; + case (femtoDreamCascadeSelection::kCascadeV0TranRadMax): + observable = casc.v0radius(); + break; + case (femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin): + observable = dcav0topv; + break; + case (femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax): + observable = dcav0topv; + break; + // case (femtoDreamCascadeSelection::kCascadeV0MassMin): + // observable = casc.mLambda(); + // break; + // case (femtoDreamCascadeSelection::kCascadeV0MassMax): + // observable = casc.mLambda(); + // break; + + /* + case (femtoDreamCascadeSelection::kCascadeDCAPosToPV): + observable = casc.dcapostopv(); + break; + case (femtoDreamCascadeSelection::kCascadeDCANegToPV): + observable = casc.dcanegtopv(); + break; + case (femtoDreamCascadeSelection::kCascadeDCABachToPV): + observable = casc.dcabachtopv(); + break; + */ + + } // switch + sel.checkSelectionSetBit(observable, output, counter, nullptr); + //} + } // for loop + + return { + output, + outputPosTrack.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + outputPosTrack.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), + outputNegTrack.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + outputNegTrack.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), + outputBachTrack.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + outputBachTrack.at(femtoDreamTrackSelection::TrackContainerPosition::kPID)}; +} + +template +void FemtoDreamCascadeSelection::fillQA(Col const& col, Casc const& casc, Track const& posTrack, Track const& negTrack, Track const& bachTrack) +{ + + const std::vector decVtx = {casc.x(), casc.y(), casc.z()}; + const float cpaCasc = casc.casccosPA(col.posX(), col.posY(), col.posZ()); + const float cpav0 = casc.v0cosPA(col.posX(), col.posY(), col.posZ()); + const float dcav0topv = casc.dcav0topv(col.posX(), col.posY(), col.posZ()); + + if (mQAHistogramRegistry) { + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hPt"), casc.pt()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hEta"), casc.eta()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hPhi"), casc.phi()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hDCADaugh"), casc.dcacascdaughters()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hCPA"), cpaCasc); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hTranRad"), casc.cascradius()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hDecVtxX"), decVtx.at(0)); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hDecVtxY"), decVtx.at(1)); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hDecVtxZ"), decVtx.at(2)); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hInvMass"), casc.mXi()); + + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hV0DCADaugh"), casc.dcaV0daughters()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hV0CPA"), cpav0); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hV0TranRad"), casc.v0radius()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hV0DCAToPV"), dcav0topv); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/hV0InvMass"), casc.mLambda()); + } + PosDaughTrack.fillQA(posTrack); + NegDaughTrack.fillQA(negTrack); + BachTrack.fillQA(bachTrack); +} + +} // namespace o2::analysis::femtoDream + +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMCASCADESELECTION_H_ diff --git a/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h index 9d1e55aadf1..07e7d740d9a 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h +++ b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h @@ -64,7 +64,7 @@ class FemtoDreamDetaDphiStar radiiTPC = radiiTPCtoCut; fillQA = fillTHSparse; - if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kTrack) { + if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kTrack || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child)) { std::string dirName = static_cast(dirNames[0]); histdetadpi[0][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][0]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); histdetadpi[0][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][0]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); @@ -116,6 +116,24 @@ class FemtoDreamDetaDphiStar } } } + if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascade) { + for (int i = 0; i < 3; i++) { + std::string dirName = static_cast(dirNames[3]); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + if (plotForEveryRadii) { + for (int j = 0; j < 9; j++) { + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + } + } + if (fillQA) { + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + } + } + } } /// Check if pair is close or not template @@ -123,11 +141,12 @@ class FemtoDreamDetaDphiStar { magfield = lmagfield; - if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kTrack) { + if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kTrack || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child)) { /// Track-Track combination // check if provided particles are in agreement with the class instantiation - if (part1.partType() != o2::aod::femtodreamparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtodreamparticle::ParticleType::kTrack) { - LOG(fatal) << "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide kTrack,kTrack candidates."; + if (part1.partType() != o2::aod::femtodreamparticle::ParticleType::kTrack || !(part2.partType() == o2::aod::femtodreamparticle::ParticleType::kTrack || part2.partType() == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child)) { // hotfix to use the CPR + // LOG(fatal) << "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide kTrack,kTrack candidates."; + LOGF(fatal, "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide kTrack,kTrack candidates. Currently: %i", part2.partType()); return false; } auto deta = part1.eta() - part2.eta(); @@ -376,6 +395,85 @@ class FemtoDreamDetaDphiStar return pass; + } else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascade) { + /// Track-V0 combination + // check if provided particles are in agreement with the class instantiation + if (part1.partType() != o2::aod::femtodreamparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtodreamparticle::ParticleType::kCascade) { + LOG(fatal) << "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide kTrack,kV0 candidates."; + return false; + } + + bool pass = false; + for (int i = 0; i < 3; i++) { + int indexOfDaughter; + if (isMixedEventLambda) { + indexOfDaughter = part2.globalIndex() - 3 + i; + } else { + indexOfDaughter = part2.index() - 3 + i; + } + auto daughter = particles.begin() + indexOfDaughter; + auto deta = part1.eta() - daughter.eta(); + auto dphi_AT_PV = part1.phi() - daughter.phi(); + auto dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(part1, radiiTPC) - PhiAtSpecificRadiiTPC(daughter, radiiTPC); + bool sameCharge = false; + auto dphiAvg = AveragePhiStar(part1, *daughter, i, &sameCharge); + if (Q3 == 999) { + histdetadpi[i][0]->Fill(deta, dphiAvg); + histdetadpi[i][2]->Fill(deta, dphi_AT_PV); + if (fillQA) { + histdetadpi_eta[i]->Fill(deta, dphiAvg, part1.eta(), daughter.eta()); + histdetadpi_phi[i]->Fill(deta, dphiAvg, part1.phi(), daughter.phi()); + } + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[i][0]->Fill(deta, dphiAvg); + histdetadpi[i][2]->Fill(deta, dphi_AT_PV); + if (fillQA) { + histdetadpi_eta[i]->Fill(deta, dphiAvg, part1.eta(), daughter.eta()); + histdetadpi_phi[i]->Fill(deta, dphiAvg, part1.phi(), daughter.phi()); + } + } + if (sameCharge) { + if (atWhichRadiiToSelect == 1) { + if (pow(dphiAvg, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + if (Q3 == 999) { + histdetadpi[i][1]->Fill(deta, dphiAvg); + histdetadpi[i][3]->Fill(deta, dphi_AT_PV); + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[i][1]->Fill(deta, dphiAvg); + histdetadpi[i][3]->Fill(deta, dphi_AT_PV); + } + } + + } else if (atWhichRadiiToSelect == 0) { + if (pow(dphi_AT_PV, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + if (Q3 == 999) { + histdetadpi[i][1]->Fill(deta, dphiAvg); + histdetadpi[i][3]->Fill(deta, dphi_AT_PV); + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[i][1]->Fill(deta, dphiAvg); + histdetadpi[i][3]->Fill(deta, dphi_AT_PV); + } + } + } else if (atWhichRadiiToSelect == 2) { + if (pow(dphi_AT_SpecificRadii, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + if (Q3 == 999) { + histdetadpi[i][1]->Fill(deta, dphiAvg); + histdetadpi[i][3]->Fill(deta, dphi_AT_PV); + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[i][1]->Fill(deta, dphiAvg); + histdetadpi[i][3]->Fill(deta, dphi_AT_PV); + } + } + } + } + } + return pass; } else { LOG(fatal) << "FemtoDreamPairCleaner: Combination of objects not defined - quitting!"; return false; @@ -385,14 +483,14 @@ class FemtoDreamDetaDphiStar private: HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output - static constexpr std::string_view dirNames[3] = {"kTrack_kTrack/", "kTrack_kV0/", "kTrack_kCharmHadron/"}; + static constexpr std::string_view dirNames[4] = {"kTrack_kTrack/", "kTrack_kV0/", "kTrack_kCharmHadron/", "kTrack_kCascade/"}; static constexpr std::string_view histNameSEorME[3] = {"_SEandME", "_SE", "_ME"}; - static constexpr std::string_view histNames[2][3] = {{"detadphidetadphi0Before_0", "detadphidetadphi0Before_1", "detadphidetadphi0Before_2"}, - {"detadphidetadphi0After_0", "detadphidetadphi0After_1", "detadphidetadphi0After_2"}}; + static constexpr std::string_view histNames[2][4] = {{"detadphidetadphi0Before_0", "detadphidetadphi0Before_1", "detadphidetadphi0Before_2", "detadphidetadphi0Before_3"}, + {"detadphidetadphi0After_0", "detadphidetadphi0After_1", "detadphidetadphi0After_2", "detadphidetadphi0After_3"}}; - static constexpr std::string_view histNamesRadii[3][9] = { + static constexpr std::string_view histNamesRadii[4][9] = { {"detadphidetadphi0Before_0_0", "detadphidetadphi0Before_0_1", "detadphidetadphi0Before_0_2", "detadphidetadphi0Before_0_3", "detadphidetadphi0Before_0_4", "detadphidetadphi0Before_0_5", "detadphidetadphi0Before_0_6", "detadphidetadphi0Before_0_7", "detadphidetadphi0Before_0_8"}, @@ -401,7 +499,10 @@ class FemtoDreamDetaDphiStar "detadphidetadphi0Before_1_6", "detadphidetadphi0Before_1_7", "detadphidetadphi0Before_1_8"}, {"detadphidetadphi0Before_2_0", "detadphidetadphi0Before_2_1", "detadphidetadphi0Before_2_2", "detadphidetadphi0Before_2_3", "detadphidetadphi0Before_2_4", "detadphidetadphi0Before_2_5", - "detadphidetadphi0Before_2_6", "detadphidetadphi0Before_2_7", "detadphidetadphi0Before_2_8"}}; + "detadphidetadphi0Before_2_6", "detadphidetadphi0Before_2_7", "detadphidetadphi0Before_2_8"}, + {"detadphidetadphi0Before_3_0", "detadphidetadphi0Before_3_1", "detadphidetadphi0Before_3_2", + "detadphidetadphi0Before_3_3", "detadphidetadphi0Before_3_4", "detadphidetadphi0Before_3_5", + "detadphidetadphi0Before_3_6", "detadphidetadphi0Before_3_7", "detadphidetadphi0Before_3_8"}}; static constexpr o2::aod::femtodreamparticle::ParticleType mPartOneType = partOne; ///< Type of particle 1 static constexpr o2::aod::femtodreamparticle::ParticleType mPartTwoType = partTwo; ///< Type of particle 2 diff --git a/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h b/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h index 3cc1834de3f..5243f562fbe 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h +++ b/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h @@ -85,6 +85,19 @@ class FemtoDreamPairCleaner return true; } return false; + } else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascade) { + /// Track-Cascade combination + if (part2.partType() != o2::aod::femtodreamparticle::ParticleType::kCascade) { + LOG(fatal) << "FemtoDreamPairCleaner: passed arguments don't agree with FemtoDreamPairCleaner instantiation! Please provide second argument kCascade candidate."; + return false; + } + const auto& posChild = particles.iteratorAt(part2.index() - 3); + const auto& negChild = particles.iteratorAt(part2.index() - 2); + const auto& bachChild = particles.iteratorAt(part2.index() - 1); + if (part1.index() != posChild.childrenIds()[0] && part1.index() != negChild.childrenIds()[1] && part1.index() != bachChild.childrenIds()[2]) { + return true; + } + return false; } else { LOG(fatal) << "FemtoDreamPairCleaner: Combination of objects not defined - quitting!"; return false; diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index 0fa87ffdab3..0e6f4e81da6 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -61,13 +61,17 @@ class FemtoDreamParticleHisto if constexpr (o2::aod::femtodreamMCparticle::MCType::kRecon == mc) { mHistogramRegistry->add((folderName + folderSuffix + static_cast(o2::aod::femtodreamparticle::TempFitVarName[mParticleType])).c_str(), ("; #it{p}_{T} (GeV/#it{c}); " + tempFitVarAxisTitle).c_str(), kTH2F, {{pTAxis}, {tempFitVarAxis}}); } - if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 && mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { + if constexpr ((mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) && mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambda").c_str(), "; M_{#Lambda}; Entries", kTH1F, {InvMassAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassLambda").c_str(), "; p_{T} (GeV/#it{c{}); M_{#Lambda}", kTH2F, {pTAxis, InvMassAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", kTH1F, {InvMassAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", kTH2F, {pTAxis, InvMassAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaAntiLambda").c_str(), "; M_{#Lambda}; M_{#bar{#Lambda}}", kTH2F, {InvMassAxis, InvMassAxis}); } + if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCascade").c_str(), "; M_{Cascade}; Entries", kTH1F, {InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCascade").c_str(), "; p_{T} (GeV/#it{c{}); M_{Cascade}", kTH2F, {pTAxis, InvMassAxis}); + } } // comment @@ -81,7 +85,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hMomentumVsPhi").c_str(), "; #it{p} (GeV/#it{c}); #phi", kTH2F, {{500, 0, 10}, {360, 0., TMath::TwoPi()}}); mHistogramRegistry->add((folderName + folderSuffix + "/hEtaVsPhi").c_str(), "; #eta; #phi", kTH2F, {{300, -1.5, 1.5}, {360, 0., TMath::TwoPi()}}); - if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child) { + if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", kTH1F, {{5, -2.5, 2.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); @@ -128,7 +132,13 @@ class FemtoDreamParticleHisto if (correlatedPlots) { mHistogramRegistry->add((folderName + folderSuffix + "/HighDcorrelator").c_str(), "", kTHnSparseF, {multAxis, multPercentileAxis, pTAxis, etaAxis, phiAxis, tempFitVarAxis, dcazAxis, NsigmaTPCAxis, NsigmaTOFAxis}); } - } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0) { + } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) { + mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); + } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); @@ -158,7 +168,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", kTH2F, {{200, -1, 1}, {200, -1, 1}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPhi_DiffTruthReco").c_str(), "; #varphi^{truth}; #varphi^{reco} - #varphi^{truth}", kTH2F, {{720, 0, TMath::TwoPi()}, {200, -1, 1}}); - if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child) { + if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { /// Track histograms if (isDebug) { mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Primary").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); @@ -190,7 +200,7 @@ class FemtoDreamParticleHisto } // DCA plots - } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0) { + } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) { if (isDebug) { mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); @@ -238,10 +248,10 @@ class FemtoDreamParticleHisto mHistogramRegistry = registry; /// The folder names are defined by the type of the object and the suffix (if applicable) std::string tempFitVarAxisTitle; - if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child) { + if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { /// Track histograms tempFitVarAxisTitle = "DCA_{xy} (cm)"; - } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0) { + } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) { /// V0 histograms tempFitVarAxisTitle = "cos#alpha"; } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { @@ -294,13 +304,19 @@ class FemtoDreamParticleHisto if constexpr (mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST(o2::aod::femtodreamparticle::TempFitVarName[mParticleType]), part.pt(), part.tempFitVar()); } - if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 && mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { + if constexpr ((mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) && mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hInvMassLambda"), part.mLambda()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hpTInvMassLambda"), part.pt(), part.mLambda()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hInvMassAntiLambda"), part.mAntiLambda()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hpTInvMassAntiLambda"), part.pt(), part.mAntiLambda()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hInvMassLambdaAntiLambda"), part.mLambda(), part.mAntiLambda()); } + if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hInvMassCascade"), part.mLambda()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hpTInvMassCascade"), part.pt(), part.mLambda()); + // mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hInvMassCascade"), part.mLambda()); + // mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hpTInvMassCascade"), part.pt(), part.mLambda()); + } } template @@ -328,7 +344,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hEtaVsPhi"), part.eta(), part.phi()); // Histograms holding further debug information - if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child) { + if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hCharge"), part.sign()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hTPCfindable"), part.tpcNClsFindable()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hTPCfound"), part.tpcNClsFound()); @@ -421,7 +437,13 @@ class FemtoDreamParticleHisto pidTPC, pidTOF); } - } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0) { + } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) { + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hDaughDCA"), part.daughDCA()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hTransRadius"), part.transRadius()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hDecayVtxX"), part.decayVtxX()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hDecayVtxY"), part.decayVtxY()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hDecayVtxZ"), part.decayVtxZ()); + } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hDaughDCA"), part.daughDCA()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hTransRadius"), part.transRadius()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/hDecayVtxX"), part.decayVtxX()); @@ -657,11 +679,11 @@ class FemtoDreamParticleHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output - static constexpr o2::aod::femtodreamparticle::ParticleType mParticleType = particleType; ///< Type of the particle under analysis - static constexpr int mFolderSuffixType = suffixType; ///< Counter for the folder suffix specified below - static constexpr std::string_view mFolderSuffix[8] = {"", "_one", "_two", "_pos", "_neg", "_allSelected", "_allSelected_pos", "_allSelected_neg"}; ///< Suffix for the folder name in case of analyses of pairs of the same kind (T-T, V-V, C-C) - int mPDG = 0; ///< PDG code of the selected particle + HistogramRegistry* mHistogramRegistry; ///< For QA output + static constexpr o2::aod::femtodreamparticle::ParticleType mParticleType = particleType; ///< Type of the particle under analysis + static constexpr int mFolderSuffixType = suffixType; ///< Counter for the folder suffix specified below + static constexpr std::string_view mFolderSuffix[9] = {"", "_one", "_two", "_pos", "_neg", "_allSelected", "_allSelected_pos", "_allSelected_neg", "_bach"}; ///< Suffix for the folder name in case of analyses of pairs of the same kind (T-T, V-V, C-C) + int mPDG = 0; ///< PDG code of the selected particle }; } // namespace o2::analysis::femtoDream diff --git a/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h b/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h index ac2a04fa3e4..383740a87a3 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h @@ -284,7 +284,7 @@ class FemtoDreamTrackSelection : public FemtoDreamObjectSelection ConfEvtAddOfflineCheck{"ConfEvtAddOfflineCheck", false, "Evt sel: additional checks for offline selection (not part of sel8 yet)"}; Configurable ConfIsActivateV0{"ConfIsActivateV0", true, "Activate filling of V0 into femtodream tables"}; Configurable ConfIsActivateReso{"ConfIsActivateReso", false, "Activate filling of sl Resonances into femtodream tables"}; + Configurable ConfIsActivateCascade{"ConfIsActivateCascade", false, "Activate filling of Cascades into femtodream tables"}; Configurable ConfTrkRejectNotPropagated{"ConfTrkRejectNotPropagated", false, "True: reject not propagated tracks"}; // Configurable ConfRejectITSHitandTOFMissing{ "ConfRejectITSHitandTOFMissing", false, "True: reject if neither ITS hit nor TOF timing satisfied"}; @@ -170,6 +172,55 @@ struct femtoDreamProducerTask { Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{5.f, 4.f}, "V0 Child sel: Max. PID nSigma TPC"}; Configurable> ConfChildPIDspecies{"ConfChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "V0 Child sel: Particles species for PID"}; + FemtoDreamCascadeSelection cascadeCuts; + struct : o2::framework::ConfigurableGroup { + Configurable ConfCascadeInvMassLowLimit{"ConfCascadeInvMassLowLimit", 1.2, "Lower limit of the Cascade invariant mass"}; + Configurable ConfCascadeInvMassUpLimit{"ConfCascadeInvMassUpLimit", 1.5, "Upper limit of the Cascade invariant mass"}; + // Cascade + Configurable> ConfCascadeSign{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeSign, "ConfCascade"), std::vector{-1, 1}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeSign, "Cascade selection: ")}; + Configurable> ConfCascadePtMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadePtMin, "ConfCascade"), std::vector{0.3f, 0.4f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadePtMin, "Cascade selection: ")}; + Configurable> ConfCascadePtMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadePtMax, "ConfCascade"), std::vector{5.5f, 6.0f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadePtMax, "Cascade selection: ")}; + Configurable> ConfCascadeEtaMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeEtaMax, "ConfCascade"), std::vector{0.8f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeEtaMax, "Cascade selection: ")}; + Configurable> ConfCascadeDCADaughMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDCADaughMax, "ConfCascade"), std::vector{1.f, 1.2f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDCADaughMax, "Cascade selection: ")}; + Configurable> ConfCascadeCPAMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeCPAMin, "ConfCascade"), std::vector{0.99f, 0.95f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeCPAMin, "Cascade selection: ")}; + Configurable> ConfCascadeTranRadMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeTranRadMin, "ConfCascade"), std::vector{0.2f, 0.5f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeTranRadMin, "Cascade selection: ")}; + Configurable> ConfCascadeTranRadMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeTranRadMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeTranRadMax, "Cascade selection: ")}; + Configurable> ConfCascadeDecVtxMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDecVtxMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDecVtxMax, "Cascade selection: ")}; + // Cascade v0 daughters + Configurable> ConfCascadeV0DCADaughMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0DCADaughMax, "ConfCascade"), std::vector{1.2f, 1.5f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0DCADaughMax, "CascV0 selection: ")}; + Configurable> ConfCascadeV0CPAMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0CPAMin, "ConfCascade"), std::vector{0.99f, 0.995f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0CPAMin, "CascV0 selection: ")}; + Configurable> ConfCascadeV0TranRadMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0TranRadMin, "ConfCascade"), std::vector{0.2f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0TranRadMin, "CascV0 selection: ")}; + Configurable> ConfCascadeV0TranRadMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0TranRadMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0TranRadMax, "CascV0 selection: ")}; + Configurable> ConfCascadeV0DCAtoPVMin{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, "CascV0 selection: ")}; + Configurable> ConfCascadeV0DCAtoPVMax{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, "ConfCascade"), std::vector{100.f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, "CascV0 selection: ")}; + Configurable ConfCascadeV0InvMassLowLimit{"ConfCascadeV0InvMassLowLimit", 1.011461, "Lower limit of the Cascade invariant mass"}; + Configurable ConfCascadeV0InvMassUpLimit{"ConfCascadeV0InvMassUpLimit", 1.027461, "Upper limit of the Cascade invariant mass"}; + // Cascade Daughter Tracks + Configurable> ConfCascV0ChildCharge{"ConfCascV0ChildSign", std::vector{-1, 1}, "CascV0 Child sel: Charge"}; + Configurable> ConfCascV0ChildEtaMax{"ConfCascV0ChildEtaMax", std::vector{0.8f}, "CascV0 Child sel: max eta"}; + Configurable> ConfCascV0ChildTPCnClsMin{"ConfCascV0ChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "CascV0 Child sel: Min. nCls TPC"}; + Configurable> ConfCascV0ChildDCAMin{"ConfCascV0ChildDCAMin", std::vector{0.05f, 0.06f}, "CascV0 Child sel: Max. DCA Daugh to PV (cm)"}; + Configurable> ConfCascV0ChildPIDnSigmaMax{"ConfCascV0ChildPIDnSigmaMax", std::vector{5.f, 4.f}, "CascV0 Child sel: Max. PID nSigma TPC"}; + Configurable> ConfCascV0ChildPIDspecies{"ConfCascV0ChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "CascV0 Child sel: Particles species for PID"}; + // Cascade Bachelor Track + Configurable> ConfCascBachelorCharge{"ConfCascBachelorSign", std::vector{-1, 1}, "Cascade Bachelor sel: Charge"}; + Configurable> ConfCascBachelorEtaMax{"ConfCascBachelorEtaMax", std::vector{0.8f}, "Cascade Bachelor sel: max eta"}; + Configurable> ConfCascBachelorTPCnClsMin{"ConfCascBachelorTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "Cascade Bachelor sel: Min. nCls TPC"}; + Configurable> ConfCascBachelorDCAMin{"ConfCascBachelorDCAMin", std::vector{0.05f, 0.06f}, "Cascade Bachelor sel: Max. DCA Daugh to PV (cm)"}; + Configurable> ConfCascBachelorPIDnSigmaMax{"ConfCascBachelorPIDnSigmaMax", std::vector{5.f, 4.f}, "Cascade Bachelor sel: Max. PID nSigma TPC"}; + Configurable> ConfCascBachelorPIDspecies{"ConfCascBachelorPIDspecies", std::vector{o2::track::PID::Pion}, "Cascade Bachelor sel: Particles species for PID"}; + /* + Configurable> ConfCascadeDCAPosToPV{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDCAPosToPV, "ConfCascade"), std::vector{0.1f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDCAPosToPV, "Cascade selection: ")}; + Configurable> ConfCascadeDCANegToPV{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDCANegToPV, "ConfCascade"), std::vector{0.1f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDCANegToPV, "Cascade selection: ")}; + Configurable> ConfCascadeDCABachToPV{FemtoDreamCascadeSelection::getSelectionName(femtoDreamCascadeSelection::kCascadeDCABachToPV, "ConfCascade"), std::vector{0.1f}, FemtoDreamCascadeSelection::getSelectionHelper(femtoDreamCascadeSelection::kCascadeDCABachToPV, "Cascade selection: ")}; + + Configurable confCascRejectCompetingMass{"confCascRejectCompetingMass", false, "Switch on to reject Omegas (for Xi) or Xis (for Omegas)"}; + Configurable confCascInvCompetingMassLowLimit{"confCascInvCompetingMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for competing mass rejection"}; + Configurable confCascInvCompetingMassUpLimit{"confCascInvCompetingMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for competing mass rejection"}; + */ + } ConfCascSel; + + // Resonances Configurable ConfResoInvMassLowLimit{"ConfResoInvMassLowLimit", 1.011461, "Lower limit of the Reso invariant mass"}; Configurable ConfResoInvMassUpLimit{"ConfResoInvMassUpLimit", 1.027461, "Upper limit of the Reso invariant mass"}; Configurable> ConfDaughterCharge{"ConfDaughterCharge", std::vector{1, -1}, "Reso Daughter sel: Charge"}; @@ -197,6 +248,7 @@ struct femtoDreamProducerTask { HistogramRegistry TrackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry V0Registry{"V0", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry ResoRegistry{"Reso", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry CascadeRegistry{"Cascade", {}, OutputObjHandlingPolicy::AnalysisObject}; int mRunNumber; float mMagField; @@ -221,6 +273,7 @@ struct femtoDreamProducerTask { TrackRegistry.add("AnalysisQA/Mother", "; Bit; Entries", kTH1F, {{4000, -4000, 4000}}); TrackRegistry.add("AnalysisQA/Particle", "; Bit; Entries", kTH1F, {{4000, -4000, 4000}}); V0Registry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); + CascadeRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); ResoRegistry.add("AnalysisQA/Reso/InvMass", "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {{7000, 0.8, 1.5}}); ResoRegistry.add("AnalysisQA/Reso/InvMass_selected", "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {{7000, 0.8, 1.5}}); ResoRegistry.add("AnalysisQA/Reso/Daughter1/Pt", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); @@ -280,6 +333,7 @@ struct femtoDreamProducerTask { v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kAbsLowerLimit); v0Cuts.setChildCuts(femtoDreamV0Selection::kPosTrack, ConfChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); v0Cuts.setChildCuts(femtoDreamV0Selection::kNegTrack, ConfChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); @@ -301,6 +355,59 @@ struct femtoDreamProducerTask { v0Cuts.setKaonInvMassLimits(ConfV0InvKaonMassLowLimit, ConfV0InvKaonMassUpLimit); } } + if (ConfIsActivateCascade) { + // Cascades + cascadeCuts.setSelection(ConfCascSel.ConfCascadeSign, femtoDreamCascadeSelection::kCascadeSign, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeSign)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadePtMin, femtoDreamCascadeSelection::kCascadePtMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadePtMin)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadePtMax, femtoDreamCascadeSelection::kCascadePtMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadePtMax)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeEtaMax, femtoDreamCascadeSelection::kCascadeEtaMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeEtaMax)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeDCADaughMax, femtoDreamCascadeSelection::kCascadeDCADaughMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeDCADaughMax)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeCPAMin, femtoDreamCascadeSelection::kCascadeCPAMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeCPAMin)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeTranRadMin, femtoDreamCascadeSelection::kCascadeTranRadMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeTranRadMin)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeTranRadMax, femtoDreamCascadeSelection::kCascadeTranRadMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeTranRadMax)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeDecVtxMax, femtoDreamCascadeSelection::kCascadeDecVtxMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeDecVtxMax)); + // Cascade v0 + cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0DCADaughMax, femtoDreamCascadeSelection::kCascadeV0DCADaughMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0DCADaughMax)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0CPAMin, femtoDreamCascadeSelection::kCascadeV0CPAMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0CPAMin)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0TranRadMin, femtoDreamCascadeSelection::kCascadeV0TranRadMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0TranRadMin)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0TranRadMax, femtoDreamCascadeSelection::kCascadeV0TranRadMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0TranRadMax)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0DCAtoPVMin, femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMin)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeV0DCAtoPVMax, femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::kCascadeV0DCAtoPVMax)); + + // Cascade Daughter Tracks + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + cascadeCuts.setChildPIDSpecies(femtoDreamCascadeSelection::kPosTrack, ConfCascSel.ConfCascV0ChildPIDspecies); + + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + cascadeCuts.setChildPIDSpecies(femtoDreamCascadeSelection::kNegTrack, ConfCascSel.ConfCascV0ChildPIDspecies); + + // Cascade Bachelor Track + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorEtaMax, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorTPCnClsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorDCAMin, femtoDreamTrackSelection::kDCAMin, femtoDreamSelection::kLowerLimit); + cascadeCuts.setChildCuts(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + cascadeCuts.setChildPIDSpecies(femtoDreamCascadeSelection::kBachTrack, ConfCascSel.ConfCascBachelorPIDspecies); + + /* + //Cascade daughter tracks + cascadeCuts.setSelection(ConfCascSel.ConfCascadeDCAPosToPV, femtoDreamCascadeSelection::kCascadeDCAPosToPV, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::CascadeSel::kCascadeDCAPosToPV)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeDCANegToPV, femtoDreamCascadeSelection::kCascadeDCANegToPV, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::CascadeSel::kCascadeDCANegToPV)); + cascadeCuts.setSelection(ConfCascSel.ConfCascadeDCABachToPV, femtoDreamCascadeSelection::kCascadeDCABachToPV, FemtoDreamCascadeSelection::getSelectionType(femtoDreamCascadeSelection::CascadeSel::kCascadeDCABachToPV)); + */ + + cascadeCuts.init(&qaRegistry, &CascadeRegistry, false); + cascadeCuts.setInvMassLimits(ConfCascSel.ConfCascadeInvMassLowLimit, ConfCascSel.ConfCascadeInvMassUpLimit); + cascadeCuts.setV0InvMassLimits(ConfCascSel.ConfCascadeV0InvMassLowLimit, ConfCascSel.ConfCascadeV0InvMassUpLimit); + } mRunNumber = 0; mMagField = 0.0; @@ -439,6 +546,16 @@ struct femtoDreamProducerTask { } } + template + void fillDebugCascade(ParticleType) + { + outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999. - 999., -999., -999., -999., -999., -999.); // QA for Reso + } + template void fillMCParticle(CollisionType const& col, ParticleType const& particle, o2::aod::femtodreamparticle::ParticleType fdparttype) { @@ -512,8 +629,8 @@ struct femtoDreamProducerTask { outputCollsMCLabels(-1); } } - template - void fillCollisionsAndTracksAndV0(CollisionType const& col, TrackType const& tracks, TrackTypeWithItsPid const& tracksWithItsPid, V0Type const& fullV0s) + template + void fillCollisionsAndTracksAndV0AndCascade(CollisionType const& col, TrackType const& tracks, TrackTypeWithItsPid const& tracksWithItsPid, V0Type const& fullV0s, CascadeType const& fullCascades) { // If triggering is enabled, select only events which were triggered wit our triggers if (ConfEnableTriggerSelection) { @@ -550,6 +667,13 @@ struct femtoDreamProducerTask { if (!colCuts.isSelectedCollision(col)) { return; } + /* + if (ConfIsActivatecascade.value) { + if (colCuts.isEmptyCollision(col, tracks, trackCuts) && colCuts.isEmptyCollision(col, fullV0s, v0Cuts, tracks)) { + return; + } + } + */ if (ConfIsActivateV0.value) { if (colCuts.isEmptyCollision(col, tracks, trackCuts) && colCuts.isEmptyCollision(col, fullV0s, v0Cuts, tracks)) { return; @@ -565,8 +689,9 @@ struct femtoDreamProducerTask { fillMCCollision(col); } - std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children - std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index + std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children + std::vector cascadechildIDs = {0, 0, 0}; // these IDs are necessary to keep track of the children + std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index std::vector Daughter1, Daughter2; for (auto& track : tracksWithItsPid) { @@ -712,6 +837,117 @@ struct femtoDreamProducerTask { } } } + if (ConfIsActivateCascade.value) { + for (auto& casc : fullCascades) { + // get the daughter tracks + const auto& posTrackCasc = casc.template posTrack_as(); + const auto& negTrackCasc = casc.template negTrack_as(); + const auto& bachTrackCasc = casc.template bachelor_as(); + + // const auto& v0daughLink = casc.template v0_as(); + // get the daughter v0 + + // QA before the cuts + cascadeCuts.fillCascadeQA(col, casc, posTrackCasc, negTrackCasc); // TODO include the bachelor + + if (!cascadeCuts.isSelectedMinimal(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc)) { + continue; + } + cascadeCuts.fillQA(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc); + + // auto cutContainerCasc = cascadeCuts.getCutContainer(col, casc, v0daugh, posTrackCasc, negTrackCasc, bachTrackCasc); + auto cutContainerCasc = cascadeCuts.getCutContainer(col, casc, posTrackCasc, negTrackCasc, bachTrackCasc); + + // Fill positive child + int poscasctrackID = casc.posTrackId(); + int rowInPrimaryTrackTablePosCasc = -1; + rowInPrimaryTrackTablePosCasc = getRowDaughters(poscasctrackID, tmpIDtrack); + cascadechildIDs[0] = rowInPrimaryTrackTablePosCasc; + cascadechildIDs[1] = 0; + cascadechildIDs[2] = 0; + outputParts(outputCollision.lastIndex(), + casc.positivept(), + casc.positiveeta(), + casc.positivephi(), + aod::femtodreamparticle::ParticleType::kCascadeV0Child, + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kPosCuts), + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kPosPID), + posTrackCasc.dcaXY(), + cascadechildIDs, + 0, + 0); + const int rowOfPosCascadeTrack = outputParts.lastIndex(); + // TODO: include here MC filling + //------ + + // Fill negative child + int negcasctrackID = casc.negTrackId(); + int rowInPrimaryTrackTableNegCasc = -1; + rowInPrimaryTrackTableNegCasc = getRowDaughters(negcasctrackID, tmpIDtrack); + cascadechildIDs[0] = 0; + cascadechildIDs[1] = rowInPrimaryTrackTableNegCasc; + cascadechildIDs[2] = 0; + outputParts(outputCollision.lastIndex(), + casc.negativept(), + casc.negativeeta(), + casc.negativephi(), + aod::femtodreamparticle::ParticleType::kCascadeV0Child, + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kNegCuts), + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kNegPID), + negTrackCasc.dcaXY(), + cascadechildIDs, + 0, + 0); + const int rowOfNegCascadeTrack = outputParts.lastIndex(); + // TODO: include here MC filling + //------ + + // Fill bachelor child + int bachelorcasctrackID = casc.bachelorId(); + int rowInPrimaryTrackTableBachelorCasc = -1; + rowInPrimaryTrackTableBachelorCasc = getRowDaughters(bachelorcasctrackID, tmpIDtrack); + cascadechildIDs[0] = 0; + cascadechildIDs[1] = 0; + cascadechildIDs[2] = rowInPrimaryTrackTableBachelorCasc; + outputParts(outputCollision.lastIndex(), + casc.bachelorpt(), + casc.bacheloreta(), + casc.bachelorphi(), + aod::femtodreamparticle::ParticleType::kCascadeBachelor, + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kBachCuts), + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kBachPID), + bachTrackCasc.dcaXY(), + cascadechildIDs, + 0, + 0); + const int rowOfBachelorCascadeTrack = outputParts.lastIndex(); + // TODO: include here MC filling + //------ + + // Fill cascades + std::vector indexCascadeChildID = {rowOfPosCascadeTrack, rowOfNegCascadeTrack, rowOfBachelorCascadeTrack}; + outputParts(outputCollision.lastIndex(), + casc.pt(), + casc.eta(), + casc.phi(), + aod::femtodreamparticle::ParticleType::kCascade, + cutContainerCasc.at(femtoDreamCascadeSelection::CascadeContainerPosition::kCascade), + 0, + casc.casccosPA(col.posX(), col.posY(), col.posZ()), + indexCascadeChildID, + casc.mXi(), + casc.mLambda()); + // TODO: include here MC filling + //------ + + if (ConfIsDebug.value) { + fillDebugParticle(posTrackCasc); // QA for positive daughter + fillDebugParticle(negTrackCasc); // QA for negative daughter + fillDebugParticle(bachTrackCasc); // QA for negative daughter + fillDebugCascade(casc); // QA for Cascade + } + } + } if (ConfIsActivateReso.value) { for (std::size_t iDaug1 = 0; iDaug1 < Daughter1.size(); ++iDaug1) { @@ -783,7 +1019,9 @@ struct femtoDreamProducerTask { processData(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s) + o2::aod::V0Datas const& fullV0s, + o2::aod::V0sLinked const&, + o2::aod::CascDatas const& fullCascades) { // get magnetic field for run initCCDB_Mag_Trig(col.bc_as()); @@ -791,9 +1029,9 @@ struct femtoDreamProducerTask { auto tracksWithItsPid = soa::Attach(tracks); if (ConfUseItsPid.value) { - fillCollisionsAndTracksAndV0(col, tracks, tracksWithItsPid, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracksWithItsPid, fullV0s, fullCascades); } else { - fillCollisionsAndTracksAndV0(col, tracks, tracks, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } } PROCESS_SWITCH(femtoDreamProducerTask, processData, @@ -803,7 +1041,9 @@ struct femtoDreamProducerTask { processData_noCentrality(aod::FemtoFullCollision_noCent const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s) + o2::aod::V0Datas const& fullV0s, + o2::aod::V0sLinked const&, + o2::aod::CascDatas const& fullCascades) { // get magnetic field for run initCCDB_Mag_Trig(col.bc_as()); @@ -811,19 +1051,19 @@ struct femtoDreamProducerTask { auto tracksWithItsPid = soa::Attach(tracks); if (ConfUseItsPid.value) { - fillCollisionsAndTracksAndV0(col, tracks, tracksWithItsPid, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracksWithItsPid, fullV0s, fullCascades); } else { - fillCollisionsAndTracksAndV0(col, tracks, tracks, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } } PROCESS_SWITCH(femtoDreamProducerTask, processData_noCentrality, "Provide experimental data without centrality information", false); - void - processData_CentPbPb(aod::FemtoFullCollision_CentPbPb const& col, - aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks, - o2::aod::V0Datas const& fullV0s) + void processData_CentPbPb(aod::FemtoFullCollision_CentPbPb const& col, + aod::BCsWithTimestamps const&, + aod::FemtoFullTracks const& tracks, + o2::aod::V0Datas const& fullV0s, + o2::aod::CascDatas const& fullCascades) { // get magnetic field for run initCCDB_Mag_Trig(col.bc_as()); @@ -831,9 +1071,9 @@ struct femtoDreamProducerTask { auto tracksWithItsPid = soa::Attach(tracks); if (ConfUseItsPid.value) { - fillCollisionsAndTracksAndV0(col, tracks, tracksWithItsPid, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracksWithItsPid, fullV0s, fullCascades); } else { - fillCollisionsAndTracksAndV0(col, tracks, tracks, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } } PROCESS_SWITCH(femtoDreamProducerTask, processData_CentPbPb, @@ -844,12 +1084,13 @@ struct femtoDreamProducerTask { soa::Join const& tracks, aod::FemtoFullMCgenCollisions const&, aod::McParticles const&, - soa::Join const& fullV0s) /// \todo with FilteredFullV0s + soa::Join const& fullV0s, /// \todo with FilteredFullV0s + soa::Join const& fullCascades) { // get magnetic field for run initCCDB_Mag_Trig(col.bc_as()); // fill the tables - fillCollisionsAndTracksAndV0(col, tracks, tracks, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } PROCESS_SWITCH(femtoDreamProducerTask, processMC, "Provide MC data", false); @@ -858,12 +1099,13 @@ struct femtoDreamProducerTask { soa::Join const& tracks, aod::FemtoFullMCgenCollisions const&, aod::McParticles const&, - soa::Join const& fullV0s) /// \todo with FilteredFullV0s + soa::Join const& fullV0s, /// \todo with FilteredFullV0s + soa::Join const& fullCascades) { // get magnetic field for run initCCDB_Mag_Trig(col.bc_as()); // fill the tables - fillCollisionsAndTracksAndV0(col, tracks, tracks, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } PROCESS_SWITCH(femtoDreamProducerTask, processMC_noCentrality, "Provide MC data without requiring a centrality calibration", false); @@ -872,12 +1114,13 @@ struct femtoDreamProducerTask { soa::Join const& tracks, aod::FemtoFullMCgenCollisions const&, aod::McParticles const&, - soa::Join const& fullV0s) /// \todo with FilteredFullV0s + soa::Join const& fullV0s, /// \todo with FilteredFullV0s + soa::Join const& fullCascades) { // get magnetic field for run initCCDB_Mag_Trig(col.bc_as()); // fill the tables - fillCollisionsAndTracksAndV0(col, tracks, tracks, fullV0s); + fillCollisionsAndTracksAndV0AndCascade(col, tracks, tracks, fullV0s, fullCascades); } PROCESS_SWITCH(femtoDreamProducerTask, processMC_CentPbPb, "Provide MC data with centrality information for PbPb collisions", false); }; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx index b6ea6cd5f90..10e4c5c5254 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx @@ -51,6 +51,7 @@ struct femtoDreamProducerTaskForSpecificAnalysis { Configurable ConfNumberOfTracks{"ConfNumberOfTracks", 3, "Number of tracks"}; Configurable ConfNumberOfV0{"ConfNumberOfV0", 0, "Number of V0"}; + Configurable ConfNumberOfCascades{"ConfNumberOfCascades", 0, "Number of Cascades"}; /// Track selection Configurable ConfPIDthrMom{"ConfPIDthrMom", 1.f, "Momentum threshold from which TPC and TOF are required for PID"}; @@ -66,12 +67,18 @@ struct femtoDreamProducerTaskForSpecificAnalysis { Configurable Conf_maxInvMass_V0{"Conf_maxInvMass_V0", 1.15, "Maximum invariant mass of V0 (particle)"}; Configurable Conf_minInvMassAnti_V0{"Conf_minInvMassAnti_V0", 1.08, "Minimum invariant mass of V0 (antiparticle)"}; Configurable Conf_maxInvMassAnti_V0{"Conf_maxInvMassAnti_V0", 1.15, "Maximum invariant mass of V0 (antiparticle)"}; + /// Cascade selection + Configurable Conf_minInvMass_Cascade{"Conf_minInvMass_Cascade", 1.2, "Minimum invariant mass of Cascade (particle)"}; + Configurable Conf_maxInvMass_Cascade{"Conf_maxInvMass_Cascade", 1.5, "Maximum invariant mass of Cascade (particle)"}; // Partition for selected particles Partition SelectedV0s = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)); + Partition SelectedCascades = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kCascade)); HistogramRegistry EventRegistry{"EventRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + static constexpr uint32_t kSignPlusMask = 1 << 1; + template int getRowDaughters(int daughID, T const& vecID) { @@ -200,6 +207,139 @@ struct femtoDreamProducerTaskForSpecificAnalysis { createSpecifiedDerivedData(col, thegroupSelectedParts, thegroupSelectedV0s, parts); } PROCESS_SWITCH(femtoDreamProducerTaskForSpecificAnalysis, processCollisionsWithNTracksAndNV0, "Enable producing data with ppp collisions for data", true); + + /// This function stores accepted collisions in derived data + /// @tparam PartitionType + /// @tparam PartType + /// @tparam isMC: enables Monte Carlo truth specific histograms + /// @param groupSelectedTracks partition for the first particle passed by the process function + /// @param groupSelectedV0s partition for the second particle passed by the process function + /// @param parts femtoDreamParticles table + template + void createSpecifiedDerivedData_TrkCascade(o2::aod::FDCollision& col, PartitionType groupSelectedTracks, PartitionType groupSelectedCascades, PartType parts) + { + + /// check tracks + int tracksCount = 0; + int antitracksCount = 0; + for (auto& part : groupSelectedTracks) { + if (part.cut() & 1) { + antitracksCount++; + } else { + tracksCount++; + } + } + + /// check Cascades + int CascadeCount = 0; + int antiCascadeCount = 0; + for (auto& casc : groupSelectedCascades) { + if ((casc.cut() & kSignPlusMask) == kSignPlusMask) { + CascadeCount++; + } else { + antiCascadeCount++; + } + } + + std::vector tmpIDtrack; + + if ((CascadeCount >= ConfNumberOfCascades && tracksCount >= ConfNumberOfTracks) || (antiCascadeCount >= ConfNumberOfCascades && antitracksCount >= ConfNumberOfTracks)) { + EventRegistry.fill(HIST("hStatistiscs"), 1); + outputCollision(col.posZ(), col.multV0M(), col.multNtr(), col.sphericity(), col.magField()); + + for (auto& femtoParticle : parts) { + if (aod::femtodreamparticle::ParticleType::kTrack == femtoParticle.partType()) { + std::vector childIDs = {0, 0}; + outputParts(outputCollision.lastIndex(), + femtoParticle.pt(), + femtoParticle.eta(), + femtoParticle.phi(), + femtoParticle.partType(), + femtoParticle.cut(), + femtoParticle.pidcut(), + femtoParticle.tempFitVar(), + childIDs, + femtoParticle.mLambda(), + femtoParticle.mAntiLambda()); + tmpIDtrack.push_back(femtoParticle.index()); + } + if (aod::femtodreamparticle::ParticleType::kCascadeV0Child == femtoParticle.partType() || aod::femtodreamparticle::ParticleType::kCascadeBachelor == femtoParticle.partType()) { + std::vector childIDs = {0, 0, 0}; + const auto& children = femtoParticle.childrenIds(); + int childId = 0; + if (children[0] != 0) { + childId = children[0]; + } else if (children[1] != 0) { + childId = children[1]; + } else if (children[2] != 0) { + childId = children[2]; + } + + if (childId != -1) { + int rowInPrimaryTrackTable = getRowDaughters(childId, tmpIDtrack); + if (children[0] != 0) { + childIDs = std::vector{rowInPrimaryTrackTable, 0, 0}; + } else if (children[1] != 0) { + childIDs = std::vector{0, rowInPrimaryTrackTable, 0}; + } else if (children[2] != 0) { + childIDs = std::vector{0, 0, rowInPrimaryTrackTable}; + } + } else { + if (children[0] != 0) { + childIDs = std::vector{-1, 0, 0}; + } else if (children[1] != 0) { + childIDs = std::vector{0, -1, 0}; + } else if (children[2] != 0) { + childIDs = std::vector{0, 0, -1}; + } + } + outputParts(outputCollision.lastIndex(), + femtoParticle.pt(), + femtoParticle.eta(), + femtoParticle.phi(), + femtoParticle.partType(), + femtoParticle.cut(), + femtoParticle.pidcut(), + femtoParticle.tempFitVar(), + childIDs, + femtoParticle.mLambda(), + femtoParticle.mAntiLambda()); + } + if (aod::femtodreamparticle::ParticleType::kCascade == femtoParticle.partType()) { + // If the order in primary producer is changed of storing first pos, neg daughters and then V0 - this must be updated + const int rowOfLastTrack = outputParts.lastIndex(); + std::vector childIDs = {rowOfLastTrack - 2, rowOfLastTrack - 1, rowOfLastTrack}; + outputParts(outputCollision.lastIndex(), + femtoParticle.pt(), + femtoParticle.eta(), + femtoParticle.phi(), + femtoParticle.partType(), + femtoParticle.cut(), + femtoParticle.pidcut(), + femtoParticle.tempFitVar(), + childIDs, + femtoParticle.mLambda(), + femtoParticle.mAntiLambda()); + } + } + } else { + EventRegistry.fill(HIST("hStatistiscs"), 2); + } + } + + /// process function to create derived data with only collisions containing n tracks + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoDreamParticleTable + void processCollisionsWithNTracksAndNCascades(o2::aod::FDCollision& col, + o2::aod::FDParticles& parts) + { + EventRegistry.fill(HIST("hStatistiscs"), 0); + auto thegroupSelectedParts = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupSelectedCascades = SelectedCascades->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + + createSpecifiedDerivedData_TrkCascade(col, thegroupSelectedParts, thegroupSelectedCascades, parts); + } + PROCESS_SWITCH(femtoDreamProducerTaskForSpecificAnalysis, processCollisionsWithNTracksAndNCascades, "Enable producing data with tracks and Cascades collisions for data", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoDream/Tasks/CMakeLists.txt b/PWGCF/FemtoDream/Tasks/CMakeLists.txt index 58d9744c029..b0175157386 100644 --- a/PWGCF/FemtoDream/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoDream/Tasks/CMakeLists.txt @@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(femtodream-pair-track-v0 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femtodream-pair-track-cascade + SOURCES femtoDreamPairTaskTrackCascade.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femtodream-triplet-track-track-v0 SOURCES femtoDreamTripletTaskTrackTrackV0.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -39,6 +44,11 @@ o2physics_add_dpl_workflow(femtodream-debug-v0 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femtodream-debug-cascade + SOURCES femtoDreamDebugCascade.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femtodream-collision-masker SOURCES femtoDreamCollisionMasker.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx new file mode 100644 index 00000000000..c4c0485b6e9 --- /dev/null +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx @@ -0,0 +1,146 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoDreamDebugV0.cxx +/// \brief Tasks that reads the particle tables and fills QA histograms for V0s +/// \author Luca Barioglio, TU München, luca.barioglio@cern.ch +/// \author Georgios Mantzaridis, TU München, luca.barioglio@cern.ch + +#include +#include +#include +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "DataFormatsParameters/GRPObject.h" +#include "fairlogger/Logger.h" + +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" + +using namespace o2; +using namespace o2::analysis::femtoDream; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct femtoDreamDebugCascade { + SliceCache cache; + + Configurable ConfCascade_PDGCode{"ConfCascade_PDGCode", 3312, "Cascade - PDG code"}; + Configurable ConfCascade_ChildPos_PDGCode{"ConfCascade_PosChild_PDGCode", 2212, "Positive Child - PDG code"}; + Configurable ConfCascade_ChildNeg_PDGCode{"ConfCascade_NegChild_PDGCode", 211, "Negative Child- PDG code"}; + Configurable ConfCascade_Bach_PDGCode{"ConfCascade_Bach_PDGCode", 211, "Bachelor Child- PDG code"}; + + Configurable ConfCascade_CutBit{"ConfCascade_CutBit", 338, "Cascade - Selection bit from cutCulator"}; + ConfigurableAxis ConfCascadeTempFitVarBins{"ConfCascadeTempFitVarBins", {300, 0.95, 1.}, "Cascade: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfCascadeTempFitVarMomentumBins{"ConfCascadeTempFitVarMomentumBins", {20, 0.5, 4.05}, "Cascade: pT binning of the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfBinmult{"ConfBinmult", {1, 0, 1}, "multiplicity Binning"}; + ConfigurableAxis ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis for inv mass"}; + + Configurable ConfCascadeTempFitVarMomentum{"ConfCascadeTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; + + ConfigurableAxis ConfCascadeInvMassBins{"ConfCascadeInvMassBins", {200, 1.25, 1.45}, "Cascade: InvMass binning"}; + + ConfigurableAxis ConfCascadeChildTempFitVarMomentumBins{"ConfCascadeChildTempFitVarMomentumBins", {600, 0, 6}, "p binning for the p vs Nsigma TPC/TOF plot"}; + ConfigurableAxis ConfCascadeChildNsigmaTPCBins{"ConfCascadeChildNsigmaTPCBins", {1600, -8, 8}, "binning of Nsigma TPC plot"}; + ConfigurableAxis ConfCascadeChildNsigmaTOFBins{"ConfCascadeChildNsigmaTOFBins", {3000, -15, 15}, "binning of the Nsigma TOF plot"}; + ConfigurableAxis ConfCascadeChildNsigmaTPCTOFBins{"ConfCascadeChildNsigmaTPCTOFBins", {1000, 0, 10}, "binning of the Nsigma TPC+TOF plot"}; + + Configurable ConfCascade_ChildPos_CutBit{"ConfCascade_ChildPos_CutBit", 150, "Positive Child of Cascade - Selection bit from cutCulator"}; + Configurable ConfCascade_ChildPos_TPCBit{"ConfCascade_ChildPos_TPCBit", 4, "Positive Child of Cascade - PID bit from cutCulator"}; + Configurable ConfCascade_ChildNeg_CutBit{"ConfCascade_ChildNeg_CutBit", 149, "Negative Child of Cascade - PID bit from cutCulator"}; + Configurable ConfCascade_ChildNeg_TPCBit{"ConfCascade_ChildNeg_TPCBit", 8, "Negative Child of Cascade - PID bit from cutCulator"}; + Configurable ConfCascade_ChildBach_CutBit{"ConfCascade_ChildBach_CutBit", 149, "Bachelor Child of Cascade - PID bit from cutCulator"}; + Configurable ConfCascade_ChildBach_TPCBit{"ConfCascade_ChildBach_TPCBit", 8, "Bachelor Child of Cascade - PID bit from cutCulator"}; + Configurable ConfUseChildCuts{"ConfUseChildCuts", true, "Use cuts on the children of the Cascades additional to those of the selection of the cascade builder"}; + ConfigurableAxis ConfCascadeChildTempFitVarBins{"ConfCascadeChildTempFitVarBins", {300, -0.15, 0.15}, "Cascade child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfCascadeChildTempFitVarpTBins{"ConfCascadeChildTempFitVarpTBins", {20, 0.5, 4.05}, "Cascade child: pT binning of the pT vs. TempFitVar plot"}; + + using FemtoFullParticles = soa::Join; + Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kCascade)) && (ncheckbit(aod::femtodreamparticle::cut, ConfCascade_CutBit)); + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + + /// Histogramming + FemtoDreamEventHisto eventHisto; + FemtoDreamParticleHisto posChildHistos; + FemtoDreamParticleHisto negChildHistos; + FemtoDreamParticleHisto bachelorHistos; + FemtoDreamParticleHisto CascadeHistos; + + /// Histogram output + HistogramRegistry EventRegistry{"Event", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry CascadeRegistry{"FullCascQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext&) + { + eventHisto.init(&EventRegistry, false); + posChildHistos.init(&CascadeRegistry, ConfBinmult, ConfDummy, ConfCascadeChildTempFitVarMomentumBins, ConfDummy, ConfDummy, ConfCascadeChildTempFitVarBins, ConfCascadeChildNsigmaTPCBins, ConfCascadeChildNsigmaTOFBins, ConfCascadeChildNsigmaTPCTOFBins, ConfDummy, ConfCascadeInvMassBins, false, ConfCascade_ChildPos_PDGCode.value, true); + negChildHistos.init(&CascadeRegistry, ConfBinmult, ConfDummy, ConfCascadeChildTempFitVarMomentumBins, ConfDummy, ConfDummy, ConfCascadeChildTempFitVarBins, ConfCascadeChildNsigmaTPCBins, ConfCascadeChildNsigmaTOFBins, ConfCascadeChildNsigmaTPCTOFBins, ConfDummy, ConfCascadeInvMassBins, false, ConfCascade_ChildNeg_PDGCode.value, true); + bachelorHistos.init(&CascadeRegistry, ConfBinmult, ConfDummy, ConfCascadeChildTempFitVarMomentumBins, ConfDummy, ConfDummy, ConfCascadeChildTempFitVarBins, ConfCascadeChildNsigmaTPCBins, ConfCascadeChildNsigmaTOFBins, ConfCascadeChildNsigmaTPCTOFBins, ConfDummy, ConfCascadeInvMassBins, false, ConfCascade_Bach_PDGCode.value, true); + CascadeHistos.init(&CascadeRegistry, ConfBinmult, ConfDummy, ConfCascadeTempFitVarMomentumBins, ConfDummy, ConfDummy, ConfCascadeTempFitVarBins, ConfCascadeChildNsigmaTPCBins, ConfCascadeChildNsigmaTOFBins, ConfCascadeChildNsigmaTPCTOFBins, ConfDummy, ConfCascadeInvMassBins, false, ConfCascade_PDGCode.value, false); + } + + /// Porduce QA plots for V0 selection in FemtoDream framework + void process(o2::aod::FDCollision const& col, FemtoFullParticles const& parts) + { + auto groupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + eventHisto.fillQA(col); + for (auto& part : groupPartsOne) { + if (!part.has_children()) { + continue; + } + // check cut on v0 children + // TODO: check if this should be possible + // auto posChild = part.template children_as().front(); + // auto negChild = part.template children_as().back(); + const auto& posChild = parts.iteratorAt(part.index() - 3); + const auto& negChild = parts.iteratorAt(part.index() - 2); + const auto& bachChild = parts.iteratorAt(part.index() - 1); + if (posChild.globalIndex() != part.childrenIds()[0] || negChild.globalIndex() != part.childrenIds()[1] || bachChild.globalIndex() != part.childrenIds()[2]) { + LOG(warn) << "Indices of V0 children do not match"; + continue; + } + // check cuts on V0 children + if (posChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kCascadeV0Child) && + negChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kCascadeV0Child) && + bachChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kCascadeBachelor)) { + + if (ConfUseChildCuts && + !((posChild.cut() & ConfCascade_ChildPos_CutBit) == ConfCascade_ChildPos_CutBit && + (posChild.pidcut() & ConfCascade_ChildPos_TPCBit) == ConfCascade_ChildPos_TPCBit && + (negChild.cut() & ConfCascade_ChildNeg_CutBit) == ConfCascade_ChildNeg_CutBit && + (negChild.pidcut() & ConfCascade_ChildNeg_TPCBit) == ConfCascade_ChildNeg_TPCBit && + (bachChild.cut() & ConfCascade_ChildBach_CutBit) == ConfCascade_ChildBach_CutBit && + (bachChild.pidcut() & ConfCascade_ChildBach_TPCBit) == ConfCascade_ChildBach_TPCBit)) { + continue; + } + CascadeHistos.fillQA(part, static_cast(ConfCascadeTempFitVarMomentum.value), col.multNtr(), col.multV0M()); // set isDebug to true + posChildHistos.fillQA(posChild, static_cast(ConfCascadeTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + negChildHistos.fillQA(negChild, static_cast(ConfCascadeTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + bachelorHistos.fillQA(bachChild, static_cast(ConfCascadeTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + } + } + } +}; + +WorkflowSpec + defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx new file mode 100644 index 00000000000..57bda826deb --- /dev/null +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx @@ -0,0 +1,377 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// \file femtoDreamPairTaskTrackTrack.cxx +/// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks +/// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +#include +#include +#include +#include +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/Expressions.h" +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" +#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +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; +struct femtoDreamPairTaskTrackCascade { + SliceCache cache; + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + /// General options + struct : ConfigurableGroup { + std::string prefix = std::string("Option"); + Configurable IsMC{"IsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; + 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 ExtendedPlots{"ExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; + Configurable HighkstarCut{"HighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; + Configurable CPROn{"CPROn", true, "Close Pair Rejection"}; + Configurable CPROld{"CPROld", false, "Set to FALSE to use fixed version of CPR (for testing now, will be default soon)"}; + Configurable CPRPlotPerRadii{"CPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable CPRdeltaPhiMax{"CPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable CPRdeltaEtaMax{"CPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable DCACutPtDep{"DCACutPtDep", false, "Use pt dependent dca cut"}; + Configurable MixEventWithPairs{"MixEventWithPairs", false, "Only use events that contain particle 1 and partile 2 for the event mixing"}; + 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!"}; + ConfigurableAxis Dummy{"Dummy", {1, 0, 1}, "Dummy axis"}; + } Option; + /// Event selection + struct : ConfigurableGroup { + std::string prefix = std::string("EventSel"); + Configurable MultMin{"MultMin", 0, "Minimum Multiplicity (MultNtr)"}; + Configurable MultMax{"MultMax", 99999, "Maximum Multiplicity (MultNtr)"}; + Configurable MultPercentileMin{"MultPercentileMin", 0, "Minimum Multiplicity Percentile"}; + Configurable MultPercentileMax{"MultPercentileMax", 100, "Maximum Multiplicity Percentile"}; + } EventSel; + // Filter EventMultiplicity = aod::femtodreamcollision::multNtr >= EventSel.MultMin && aod::femtodreamcollision::multNtr <= EventSel.MultMax; + // Filter EventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= EventSel.MultPercentileMin && aod::femtodreamcollision::multV0M <= EventSel.MultPercentileMax; + /// Histogramming for Event + FemtoDreamEventHisto eventHisto; + // using FilteredCollisions = soa::Filtered; + using FilteredCollisions = FDCollisions; + using FilteredCollision = FilteredCollisions::iterator; + using FDMCParts = soa::Join; + using FDMCPart = FDMCParts::iterator; + femtodreamcollision::BitMaskType BitMask = 1; + /// Particle 1 (track) + struct : ConfigurableGroup { + std::string prefix = std::string("Track1"); + Configurable PDGCode{"PDGCode", 2212, "PDG code of Particle 1 (Track)"}; + Configurable CutBit{"CutBit", 5542474, "Particle 1 (Track) - Selection bit from cutCulator"}; + Configurable TPCBit{"TPCBit", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; + Configurable TPCBit_Reject{"TPCBit_Reject", 0, "Reject PID TPC bit from cutCulator for particle 1 (Track). Set to 0 to turn off"}; + Configurable TPCTOFBit{"TPCTOFBit", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; + Configurable PIDThres{"PIDThres", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; + Configurable PtMin{"PtMin", 0., "Minimum pT of partricle 1 (Track)"}; + Configurable PtMax{"PtMax", 999., "Maximum pT of partricle 1 (Track)"}; + Configurable EtaMin{"EtaMin", -10., "Minimum eta of partricle 1 (Track)"}; + Configurable EtaMax{"EtaMax", 10., "Maximum eta of partricle 1 (Track)"}; + Configurable TempFitVarMin{"TempFitVarMin", -10., "Minimum DCAxy of partricle 1 (Track)"}; + Configurable TempFitVarMax{"TempFitVarMax", 10., "Maximum DCAxy of partricle 1 (Track)"}; + } Track1; + /// Partition for particle 1 + Partition PartitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, Track1.CutBit)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= Track1.PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, Track1.TPCBit) && ((aod::femtodreamparticle::pidcut & Track1.TPCBit_Reject) == 0u), ncheckbit(aod::femtodreamparticle::pidcut, Track1.TPCTOFBit)) && + (aod::femtodreamparticle::pt > Track1.PtMin) && + (aod::femtodreamparticle::pt < Track1.PtMax) && + (aod::femtodreamparticle::eta > Track1.EtaMin) && + (aod::femtodreamparticle::eta < Track1.EtaMax) && + ifnode(Option.DCACutPtDep, (nabs(aod::femtodreamparticle::tempFitVar) <= 0.0105f + (0.035f / npow(aod::femtodreamparticle::pt, 1.1f))), + ((aod::femtodreamparticle::tempFitVar >= Track1.TempFitVarMin) && + (aod::femtodreamparticle::tempFitVar <= Track1.TempFitVarMax))); + /// Histogramming for particle 1 + FemtoDreamParticleHisto trackHistoPartOne; + /// Particle 2 (Cascade) + struct : ConfigurableGroup { + std::string prefix = std::string("Cascade2"); + Configurable PDGCode{"PDGCode", 3312, "PDG code of particle 2 (V0)"}; + Configurable CutBit{"CutBit", 32221874, "Selection bit for particle 2 (Cascade)"}; + Configurable ChildPos_CutBit{"ChildPos_CutBit", 278, "Selection bit for positive child of Cascade"}; + Configurable ChildPos_TPCBit{"ChildPos_TPCBit", 1024, "PID TPC bit for positive child of Cascade"}; + Configurable ChildNeg_CutBit{"ChildNeg_CutBit", 277, "Selection bit for negative child of Cascade"}; + Configurable ChildNeg_TPCBit{"ChildNeg_TPCBit", 4096, "PID TPC bit for negative child of Cascade"}; + Configurable ChildBach_CutBit{"ChildBach_CutBit", 277, "Selection bit for negative child of Cascade"}; + Configurable ChildBach_TPCBit{"ChildBach_TPCBit", 64, "PID TPC bit for bachelor child of Cascade"}; + Configurable InvMassMin{"InvMassMin", 1.2, "Minimum invariant mass of Partricle 2 (particle) (Cascade)"}; + Configurable InvMassMax{"InvMassMax", 1.4, "Maximum invariant mass of Partricle 2 (particle) (Cascade)"}; + Configurable InvMassV0DaughMin{"InvMassV0DaugMin", 0., "Minimum invariant mass of the V0 Daughter"}; + Configurable InvMassV0DaughMax{"InvMassV0DaugMax", 999., "Maximum invariant mass of the V0 Daughter"}; + Configurable PtMin{"PtMin", 0., "Minimum pT of Partricle 2 (V0)"}; + Configurable PtMax{"PtMax", 999., "Maximum pT of Partricle 2 (V0)"}; + Configurable EtaMin{"EtaMin", -10., "Minimum eta of Partricle 2 (V0)"}; + Configurable EtaMax{"EtaMax", 10., "Maximum eta of Partricle 2 (V0)"}; + Configurable UseChildCuts{"UseChildCuts", true, "Use cuts on the children of the Cascades additional to those of the selection of the cascade builder"}; + } Cascade2; + /// Partition for particle 2 + Partition PartitionCascade2 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kCascade)) && + ((aod::femtodreamparticle::cut & Cascade2.CutBit) == Cascade2.CutBit) && + (aod::femtodreamparticle::pt > Cascade2.PtMin) && + (aod::femtodreamparticle::pt < Cascade2.PtMax) && + (aod::femtodreamparticle::eta > Cascade2.EtaMin) && + (aod::femtodreamparticle::eta < Cascade2.EtaMax) && + (aod::femtodreamparticle::mLambda > Cascade2.InvMassMin) && + (aod::femtodreamparticle::mLambda < Cascade2.InvMassMax) && + (aod::femtodreamparticle::mAntiLambda > Cascade2.InvMassV0DaughMin) && + (aod::femtodreamparticle::mAntiLambda < Cascade2.InvMassV0DaughMax); + /// Histogramming for particle 2 + FemtoDreamParticleHisto trackHistoPartTwo; + FemtoDreamParticleHisto posChildHistos; + FemtoDreamParticleHisto negChildHistos; + FemtoDreamParticleHisto bachChildHistos; + /// Binning configurables + struct : ConfigurableGroup { + std::string prefix = std::string("Binning"); + ConfigurableAxis TempFitVarTrack{"TempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis TempFitVarCascade{"TempFitVarCascade", {300, 0.9, 1}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Cascade)"}; + ConfigurableAxis TempFitVarCascadeChild{"TempFitVarCascadeChild", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Cascade child)"}; + ConfigurableAxis InvMass{"InvMass", {200, 1.22, 1.42}, "InvMass binning"}; + ConfigurableAxis pTTrack{"pTTrack", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis pTCascade{"pTCascade", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (Cascade)"}; + ConfigurableAxis pTCascadeChild{"pTCascadeChild", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (Cascade)"}; + ConfigurableAxis pT{"pT", {20, 0.5, 4.05}, "pT binning"}; + ConfigurableAxis kstar{"kstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis kT{"kT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis mT{"mT", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis multTempFit{"multTempFit", {1, 0, 1}, "multiplicity for the TempFitVar plot"}; + } Binning; + struct : ConfigurableGroup { + std::string prefix = std::string("Binning4D"); + ConfigurableAxis kstar{"kstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis mT{"mT", {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 Mult{"mult", {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 multPercentile{"multPercentile", {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)"}; + } Binning4D; + // Mixing configurables + struct : ConfigurableGroup { + std::string prefix = std::string("Mixing"); + ConfigurableAxis BinMult{"BinMult", {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}, "bins - multiplicity"}; + ConfigurableAxis BinMultPercentile{"BinMultPercentile", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f}, "bins - multiplicity percentile"}; + ConfigurableAxis BinVztx{"BinVztx", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "bins - z-vertex"}; + Configurable Depth{"Depth", 5, "Number of events for mixing"}; + Configurable Policy{"BinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + } Mixing; + ColumnBinningPolicy colBinningMult{{Mixing.BinVztx, Mixing.BinMult}, true}; + ColumnBinningPolicy colBinningMultPercentile{{Mixing.BinVztx, Mixing.BinMultPercentile}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{Mixing.BinVztx, Mixing.BinMult, Mixing.BinMultPercentile}, true}; + FemtoDreamContainer sameEventCont; + FemtoDreamContainer mixedEventCont; + FemtoDreamPairCleaner pairCleaner; + FemtoDreamDetaDphiStar pairCloseRejectionSE; + FemtoDreamDetaDphiStar pairCloseRejectionME; + + static constexpr uint32_t kSignPlusMask = 1 << 1; + + /// Histogram output + HistogramRegistry Registry{"Output", {}, OutputObjHandlingPolicy::AnalysisObject}; + void init(InitContext&) + { + // setup binnnig policy for mixing + colBinningMult = {{Mixing.BinVztx, Mixing.BinMult}, true}; + colBinningMultPercentile = {{Mixing.BinVztx, Mixing.BinMultPercentile}, true}; + colBinningMultMultPercentile = {{Mixing.BinVztx, Mixing.BinMult, Mixing.BinMultPercentile}, true}; + eventHisto.init(&Registry, Option.IsMC); + trackHistoPartOne.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTTrack, Option.Dummy, Option.Dummy, Binning.TempFitVarTrack, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.IsMC, Track1.PDGCode); + trackHistoPartTwo.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTCascade, Option.Dummy, Option.Dummy, Binning.TempFitVarCascade, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Binning.InvMass, Option.IsMC, Cascade2.PDGCode); + posChildHistos.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTCascadeChild, Option.Dummy, Option.Dummy, Binning.TempFitVarCascadeChild, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, false, 0); + negChildHistos.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTCascadeChild, Option.Dummy, Option.Dummy, Binning.TempFitVarCascadeChild, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, false, 0); + bachChildHistos.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTCascadeChild, Option.Dummy, Option.Dummy, Binning.TempFitVarCascadeChild, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, false, 0); + sameEventCont.init(&Registry, + Binning.kstar, Binning.pT, Binning.kT, Binning.mT, Mixing.BinMult, Mixing.BinMultPercentile, + Binning4D.kstar, Binning4D.mT, Binning4D.Mult, Binning4D.multPercentile, + Option.IsMC, Option.Use4D, Option.ExtendedPlots, + Option.HighkstarCut, + Option.smearingByOrigin); + + sameEventCont.setPDGCodes(Track1.PDGCode, Cascade2.PDGCode); + + mixedEventCont.init(&Registry, + Binning.kstar, Binning.pT, Binning.kT, Binning.mT, Mixing.BinMult, Mixing.BinMultPercentile, + Binning4D.kstar, Binning4D.mT, Binning4D.Mult, Binning4D.multPercentile, + Option.IsMC, Option.Use4D, Option.ExtendedPlots, + Option.HighkstarCut, + Option.smearingByOrigin); + + mixedEventCont.setPDGCodes(Track1.PDGCode, Cascade2.PDGCode); + + pairCleaner.init(&Registry); + if (Option.CPROn.value) { + pairCloseRejectionSE.init(&Registry, &Registry, Option.CPRdeltaPhiMax.value, Option.CPRdeltaEtaMax.value, Option.CPRPlotPerRadii.value, 1, Option.CPROld.value); + pairCloseRejectionME.init(&Registry, &Registry, Option.CPRdeltaPhiMax.value, Option.CPRdeltaEtaMax.value, Option.CPRPlotPerRadii.value, 2, Option.CPROld.value, 99, true); + } + } + + /// This function processes the same event and takes care of all the histogramming + template + void doSameEvent(PartitionType& SliceTrk1, PartitionType& SliceCascade2, TableTracks const& parts, Collision const& col) + { + /// Histogramming same event + for (auto const& part : SliceTrk1) { + trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + } + for (auto& casc : SliceCascade2) { + const auto& posChild = parts.iteratorAt(casc.index() - 3); + const auto& negChild = parts.iteratorAt(casc.index() - 2); + const auto& bachChild = parts.iteratorAt(casc.index() - 1); + // This is how it is supposed to work but there seems to be an issue + // with partitions and accessing elements in tables that have been declared + // with an SELF_INDEX column. Under investigation. Maybe need to change + // femtdream dataformat to take special care of v0 candidates + // auto posChild = v0.template children_as().front(); + // auto negChild = v0.template children_as().back(); + // check cuts on V0 children + + if (Cascade2.UseChildCuts && + !(((posChild.cut() & Cascade2.ChildPos_CutBit) == Cascade2.ChildPos_CutBit) && + ((posChild.pidcut() & Cascade2.ChildPos_TPCBit) == Cascade2.ChildPos_TPCBit) && + ((negChild.cut() & Cascade2.ChildNeg_CutBit) == Cascade2.ChildNeg_CutBit) && + ((negChild.pidcut() & Cascade2.ChildNeg_TPCBit) == Cascade2.ChildNeg_TPCBit) && + ((bachChild.cut() & Cascade2.ChildBach_CutBit) == Cascade2.ChildBach_CutBit) && + ((bachChild.pidcut() & Cascade2.ChildBach_TPCBit) == Cascade2.ChildBach_TPCBit))) { + continue; + } // cutbit + trackHistoPartTwo.fillQA(casc, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + posChildHistos.fillQA(posChild, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + negChildHistos.fillQA(negChild, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + bachChildHistos.fillQA(bachChild, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + } + /// Now build particle combinations + for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceCascade2))) { + const auto& posChild = parts.iteratorAt(p2.index() - 3); + const auto& negChild = parts.iteratorAt(p2.index() - 2); + const auto& bachChild = parts.iteratorAt(p2.index() - 1); + // cuts on Cascade children still need to be applied + + if (Cascade2.UseChildCuts && + !(((posChild.cut() & Cascade2.ChildPos_CutBit) == Cascade2.ChildPos_CutBit) && + ((posChild.pidcut() & Cascade2.ChildPos_TPCBit) == Cascade2.ChildPos_TPCBit) && + ((negChild.cut() & Cascade2.ChildNeg_CutBit) == Cascade2.ChildNeg_CutBit) && + ((negChild.pidcut() & Cascade2.ChildNeg_TPCBit) == Cascade2.ChildNeg_TPCBit) && + ((bachChild.cut() & Cascade2.ChildBach_CutBit) == Cascade2.ChildBach_CutBit) && + ((bachChild.pidcut() & Cascade2.ChildBach_TPCBit) == Cascade2.ChildBach_TPCBit))) { + continue; + } + if (Option.CPROn.value) { + if ((p1.cut() & kSignPlusMask) == kSignPlusMask) { + if (pairCloseRejectionSE.isClosePair(p1, posChild, parts, col.magField())) { + continue; + } + } else { + if (pairCloseRejectionSE.isClosePair(p1, posChild, parts, col.magField())) { + continue; + } + } + } + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), Option.Use4D, Option.ExtendedPlots, Option.smearingByOrigin); + } + } + void processSameEvent(FilteredCollision const& col, FDParticles const& parts) + { + // if ((col.bitmaskTrackOne() & BitMask) != BitMask || (col.bitmaskTrackTwo() & BitMask) != BitMask) { + // return; + // } + eventHisto.fillQA(col); + auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceCascade2 = PartitionCascade2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(SliceTrk1, SliceCascade2, parts, col); + } + PROCESS_SWITCH(femtoDreamPairTaskTrackCascade, processSameEvent, "Enable processing same event", true); + + template + void doMixedEvent(CollisionType const& cols, PartType const& parts, PartitionType& part1, PartitionType& part2, BinningType policy) + { + // Partition PartitionMaskedCol = ncheckbit(aod::femtodreamcollision::bitmaskTrackOne, BitMask) && ncheckbit(aod::femtodreamcollision::bitmaskTrackTwo, BitMask);// && aod::femtodreamcollision::downsample == true; + // PartitionMaskedCol.bindTable(cols); + + // use *Partition.mFiltered when passing the partition to mixing object + // there is an issue when the partition is passed directly + // workaround for now, change back once it is fixed + for (auto const& [collision1, collision2] : soa::selfCombinations(policy, Mixing.Depth.value, -1, cols, cols)) { + // make sure that tracks in same events are not mixed + if (collision1.globalIndex() == collision2.globalIndex()) { + continue; + } + auto SliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceCasc2 = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceCasc2))) { + const auto& posChild = parts.iteratorAt(p2.index() - 3); + const auto& negChild = parts.iteratorAt(p2.index() - 2); + const auto& bachChild = parts.iteratorAt(p2.index() - 1); + // check cuts on Cascade children + if (Cascade2.UseChildCuts && + !(((posChild.cut() & Cascade2.ChildPos_CutBit) == Cascade2.ChildPos_CutBit) && + ((posChild.pidcut() & Cascade2.ChildPos_TPCBit) == Cascade2.ChildPos_TPCBit) && + ((negChild.cut() & Cascade2.ChildNeg_CutBit) == Cascade2.ChildNeg_CutBit) && + ((negChild.pidcut() & Cascade2.ChildNeg_TPCBit) == Cascade2.ChildNeg_TPCBit) && + ((bachChild.cut() & Cascade2.ChildBach_CutBit) == Cascade2.ChildBach_CutBit) && + ((bachChild.pidcut() & Cascade2.ChildBach_TPCBit) == Cascade2.ChildBach_TPCBit))) { + continue; + } + if (Option.CPROn.value) { + if ((p1.cut() & kSignPlusMask) == kSignPlusMask) { + if (pairCloseRejectionME.isClosePair(p1, posChild, parts, collision1.magField())) { + continue; + } + } else { + if (pairCloseRejectionME.isClosePair(p1, negChild, parts, collision1.magField())) { + continue; + } + } + } + // Pair cleaner not needed in the mixing + // if (!pairCleaner.isCleanPair(p1, p2, parts)) { + // continue; + //} + + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), Option.Use4D, Option.ExtendedPlots, Option.smearingByOrigin); + } + } + } + + void processMixedEvent(FilteredCollisions const& cols, FDParticles const& parts) + { + switch (Mixing.Policy.value) { + case femtodreamcollision::kMult: + doMixedEvent(cols, parts, PartitionTrk1, PartitionCascade2, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, parts, PartitionTrk1, PartitionCascade2, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, parts, PartitionTrk1, PartitionCascade2, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackCascade, processMixedEvent, "Enable processing mixed events", true); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx index 0096d6840e7..5794f81d7d9 100644 --- a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx +++ b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx @@ -13,9 +13,9 @@ /// \brief Executable that encodes physical selection criteria in a bit-wise /// selection \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#include #include #include +#include #include "PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" @@ -29,14 +29,14 @@ using namespace o2::analysis::femtoDream; int main(int /*argc*/, char* argv[]) { std::string configFileName(argv[1]); - std::filesystem::path configFile{configFileName}; + std::ifstream configFile(configFileName); - if (std::filesystem::exists(configFile)) { + if (configFile.is_open()) { FemtoDreamCutculator cut; cut.init(argv[1]); std::cout - << "Do you want to work with tracks or V0s (T/V)? >"; + << "Do you want to work with tracks or V0s or Cascades (T/V/C)? >"; std::string choice; std::cin >> choice; @@ -49,6 +49,24 @@ int main(int /*argc*/, char* argv[]) cut.setV0SelectionFromFile("ConfV0"); cut.setTrackSelectionFromFile("ConfChild"); cut.setPIDSelectionFromFile("ConfChild"); + } else if (choice == std::string("C")) { + std::cout << "Do you want to select cascades, V0-Daughter tracks of the cascades or the Bachelor track (C/V/B)? >"; + std::cin >> choice; + if (choice == std::string("C")) { + cut.setCascadeSelectionFromFile("ConfCascade"); + choice = "C"; + } else if (choice == std::string("V")) { + cut.setTrackSelectionFromFile("ConfCascV0Child"); + cut.setPIDSelectionFromFile("ConfCascV0Child"); + choice = "T"; + } else if (choice == std::string("B")) { + cut.setTrackSelectionFromFile("ConfCascBachelor"); + cut.setPIDSelectionFromFile("ConfCascBachelor"); + choice = "T"; + } else { + std::cout << "Option not recognized. Break..."; + return 2; + } } else { std::cout << "Option not recognized. Break..."; return 2; @@ -79,7 +97,8 @@ int main(int /*argc*/, char* argv[]) } else { std::cout << "The configuration file " << configFileName - << " could not be found."; + << " could not be found or could not be opened."; + return 1; } return 0; diff --git a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h index a0805c3446a..32aaa6599ec 100644 --- a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h +++ b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h @@ -32,6 +32,7 @@ #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" namespace o2::analysis::femtoDream { @@ -193,6 +194,44 @@ class FemtoDreamCutculator } } + /// Specialization of the setSelection function for Cascades + + /// The selection passed to the function is retrieved from the dpl-config.json + /// \param obs Observable of the track selection + /// \param type Type of the track selection + /// \param prefix Prefix which is added to the name of the Configurable + void setCascadeSelection(femtoDreamCascadeSelection::CascadeSel obs, + femtoDreamSelection::SelectionType type, + const char* prefix) + { + auto tmpVec = + setSelection(FemtoDreamCascadeSelection::getSelectionName(obs, prefix)); + if (tmpVec.size() > 0) { + mCascadeSel.setSelection(tmpVec, obs, type); + } + } + + /// Automatically retrieves V0 selections from the dpl-config.json + /// \param prefix Prefix which is added to the name of the Configurable + void setCascadeSelectionFromFile(const char* prefix) + { + for (const auto& sel : mConfigTree) { + std::string sel_name = sel.first; + femtoDreamCascadeSelection::CascadeSel obs; + if (sel_name.find(prefix) != std::string::npos) { + int index = FemtoDreamCascadeSelection::findSelectionIndex( + std::string_view(sel_name), prefix); + if (index >= 0) { + obs = femtoDreamCascadeSelection::CascadeSel(index); + } else { + continue; + } + setCascadeSelection(obs, FemtoDreamCascadeSelection::getSelectionType(obs), + prefix); + } + } + } + /// This function investigates a given selection criterion. The available /// options are displayed in the terminal and the bit-wise container is put /// together according to the user input \tparam T1 Selection class under @@ -319,6 +358,8 @@ class FemtoDreamCutculator output = iterateSelection(mTrackSel, SysChecks, sign); } else if (choice == std::string("V")) { output = iterateSelection(mV0Sel, SysChecks, sign); + } else if (choice == std::string("C")) { + output = iterateSelection(mCascadeSel, SysChecks, sign); } else { std::cout << "Option " << choice << " not recognized - available options are (T/V)" << std::endl; @@ -380,6 +421,7 @@ class FemtoDreamCutculator boost::property_tree::ptree mConfigTree; ///< the dpl-config.json buffered into a ptree FemtoDreamTrackSelection mTrackSel; ///< for setting up the bit-wise selection container for tracks FemtoDreamV0Selection mV0Sel; ///< for setting up the bit-wise selection container for V0s + FemtoDreamCascadeSelection mCascadeSel; ///< for setting up the bit-wise selection container for Cascades std::vector mPIDspecies; ///< list of particle species for which PID is stored std::vector mPIDValues; ///< list of nsigma values for which PID is stored };