diff --git a/PWGCF/Femto/Core/kinkBuilder.h b/PWGCF/Femto/Core/kinkBuilder.h index c884e325420..34728fbdcec 100644 --- a/PWGCF/Femto/Core/kinkBuilder.h +++ b/PWGCF/Femto/Core/kinkBuilder.h @@ -57,6 +57,9 @@ struct ConfKinkFilters : o2::framework::ConfigurableGroup { o2::framework::Configurable massMaxSigma{"massMaxSigma", 1.3f, "Maximum mass for Sigma hypothesis"}; o2::framework::Configurable massMinSigmaPlus{"massMinSigmaPlus", 1.1f, "Minimum mass for SigmaPlus hypothesis"}; o2::framework::Configurable massMaxSigmaPlus{"massMaxSigmaPlus", 1.3f, "Maximum mass for SigmaPlus hypothesis"}; + o2::framework::Configurable massMinSigmaPlusPcm{"massMinSigmaPlusPcm", 1.1f, "Minimum mass for SigmaPlus (PCM) hypothesis"}; + o2::framework::Configurable massMaxSigmaPlusPcm{"massMaxSigmaPlusPcm", 1.3f, "Maximum mass for SigmaPlus (PCM) hypothesis"}; + o2::framework::Configurable mlScoreMinSigmaPlusPcm{"mlScoreMinSigmaPlusPcm", -1.f, "Minimum BDT score for SigmaPlus (PCM) (-1: no cut)"}; }; // selections bits for all kinks @@ -98,6 +101,20 @@ struct ConfSigmaPlusBits : o2::framework::ConfigurableGroup { #undef KINK_DEFAULT_BITS +// selection bits for sigma plus reconstructed with a PCM photon +struct ConfSigmaPlusPcmBits : o2::framework::ConfigurableGroup { + std::string prefix = std::string("SigmaPlusPcmBits"); + o2::framework::Configurable passThrough{"passThrough", false, "If true, all SigmaPlusPcm are passed through. Bits for all selections are stored."}; + o2::framework::Configurable> flightDirTiltMax{"flightDirTiltMax", {0.05f}, "Maximum tilt of the flight direction (rad)"}; + o2::framework::Configurable> mothDcaPvMax{"mothDcaPvMax", {1.0f}, "Maximum DCA of mother from primary vertex (cm)"}; + o2::framework::Configurable> chaDauDcaZMax{"chaDauDcaZMax", {0.3f}, "Maximum |DCAz| of charged daughter from primary vertex (cm)"}; + o2::framework::Configurable> photonDcaZMax{"photonDcaZMax", {2.0f}, "Maximum |DCAz| of the photon from primary vertex (cm)"}; + o2::framework::Configurable> chaDauTpcProton{"chaDauTpcProton", {3.f}, "Maximum |nsigma_Proton| TPC for charged daughter tracks"}; + o2::framework::Configurable> chaDauTofProton{"chaDauTofProton", {}, "Maximum |nsigma_Proton| TOF for charged daughter tracks"}; + o2::framework::Configurable requireTof{"requireTof", false, "If true, TOF PID is a minimal selection. If false, TOF PID is optional"}; + o2::framework::Configurable keepTracksWithoutTof{"keepTracksWithoutTof", true, "If true, the bit mask for the TOF selection will be true for all limits if the daughter track has no TOF"}; +}; + // base selection for analysis task for kinks // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define KINK_DEFAULT_SELECTIONS(defaultMassMin, defaultMassMax, defaultPdgCode) \ @@ -128,6 +145,15 @@ struct ConfSigmaPlusSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable sign{"sign", 1, "Sign of the Sigma mother track (e.g. +1 for Sigma+ or -1 for AntiSigma+)"}; }; +// base selection for analysis task for sigma plus reconstructed with a PCM photon +template +struct ConfSigmaPlusPcmSelection : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + KINK_DEFAULT_SELECTIONS(1.1, 1.3, 3222) + o2::framework::Configurable sign{"sign", 1, "Sign of the Sigma candidate (e.g. +1 for Sigma+ or -1 for AntiSigma+)"}; + o2::framework::Configurable mlScoreMin{"mlScoreMin", -1.f, "Minimum BDT score (-1: no cut)"}; +}; + #undef KINK_DEFAULT_SELECTIONS constexpr const char PrefixSigmaSelection1[] = "SigmaSelection1"; @@ -138,6 +164,10 @@ constexpr const char PrefixSigmaPlusSelection1[] = "SigmaPlusSelection1"; constexpr const char PrefixSigmaPlusSelection2[] = "SigmaPlusSelection2"; using ConfSigmaPlusSelection1 = ConfSigmaPlusSelection; using ConfSigmaPlusSelection2 = ConfSigmaPlusSelection; +constexpr const char PrefixSigmaPlusPcmSelection1[] = "SigmaPlusPcmSelection1"; +constexpr const char PrefixSigmaPlusPcmSelection2[] = "SigmaPlusPcmSelection2"; +using ConfSigmaPlusPcmSelection1 = ConfSigmaPlusPcmSelection; +using ConfSigmaPlusPcmSelection2 = ConfSigmaPlusPcmSelection; /// The different selections for kinks enum KinkSeles { @@ -162,11 +192,16 @@ enum KinkSeles { kPtOriginalMin, kPtOriginalMax, + kFlightDirTiltMax, + kChaDauDcaZMax, + kPhotonDcaZMax, + kKinkSelsMax }; constexpr char SigmaSelHistName[] = "hSigmaSelection"; constexpr char SigmaPlusSelHistName[] = "hSigmaPlusSelection"; +constexpr char SigmaPlusPcmSelHistName[] = "hSigmaPlusPcmSelection"; const char kinkSelsName[] = "Kink selection object"; const std::unordered_map kinkSelectionNames = { {kKinkTopoDcaMax, "kinkTopoDcaMax"}, @@ -184,7 +219,10 @@ const std::unordered_map kinkSelectionNames = { {kQtAPMax, "qtAPMax"}, {kCosPointingAngleMin, "cosPointingAngleMin"}, {kPtOriginalMin, "ptOriginalMin"}, - {kPtOriginalMax, "ptOriginalMax"}}; + {kPtOriginalMax, "ptOriginalMax"}, + {kFlightDirTiltMax, "flightDirTiltMax"}, + {kChaDauDcaZMax, "chaDauDcaZMax"}, + {kPhotonDcaZMax, "photonDcaZMax"}}; /// enum for all kink pre-filters (evaluated in checkFilters, before the selection bitmask) enum KinkFilters { @@ -196,11 +234,13 @@ enum KinkFilters { kPhiMax, kMassMin, kMassMax, + kMlScoreMin, kKinkFiltersMax }; constexpr char SigmaFilterHistName[] = "hSigmaFilters"; constexpr char SigmaPlusFilterHistName[] = "hSigmaPlusFilters"; +constexpr char SigmaPlusPcmFilterHistName[] = "hSigmaPlusPcmFilters"; const std::unordered_map kinkFilterNames = { {kPtMin, "ptMin"}, {kPtMax, "ptMax"}, @@ -209,7 +249,8 @@ const std::unordered_map kinkFilterNames = { {kPhiMin, "phiMin"}, {kPhiMax, "phiMax"}, {kMassMin, "massMin"}, - {kMassMax, "massMax"}}; + {kMassMax, "massMax"}, + {kMlScoreMin, "mlScoreMin"}}; /// \class KinkCuts /// \brief Cut class to contain and execute all cuts applied to kinks @@ -501,6 +542,11 @@ struct KinkBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedLiteSigmaPlus; o2::framework::Produces producedSigmaPlusMasks; o2::framework::Produces producedSigmaPlusExtras; + o2::framework::Produces producedSigmaPlusPcm; + o2::framework::Produces producedLiteSigmaPlusPcm; + o2::framework::Produces producedSigmaPlusPcmMasks; + o2::framework::Produces producedSigmaPlusPcmMlScores; + o2::framework::Produces producedSigmaPlusPcmExtras; }; struct ConfKinkTables : o2::framework::ConfigurableGroup { @@ -513,6 +559,11 @@ struct ConfKinkTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceLiteSigmaPlus{"produceLiteSigmaPlus", -1, "Produce LiteSigmaPlus (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceSigmaPlusMasks{"produceSigmaPlusMasks", -1, "Produce SigmaPlusMasks (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceSigmaPlusExtras{"produceSigmaPlusExtras", -1, "Produce SigmaPlusExtras (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlusPcm{"produceSigmaPlusPcm", -1, "Produce SigmaPlusPcm (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceLiteSigmaPlusPcm{"produceLiteSigmaPlusPcm", -1, "Produce LiteSigmaPlusPcm (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlusPcmMasks{"produceSigmaPlusPcmMasks", -1, "Produce SigmaPlusPcmMasks (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlusPcmMlScores{"produceSigmaPlusPcmMlScores", -1, "Produce SigmaPlusPcmMlScores (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable produceSigmaPlusPcmExtras{"produceSigmaPlusPcmExtras", -1, "Produce SigmaPlusPcmExtras (-1: auto; 0 off; 1 on)"}; }; template @@ -756,10 +807,320 @@ class KinkBuilder bool mProduceSigmaPlusExtras = false; }; +/// \class SigmaPlusPcmSelection +/// \brief Cut class to contain and execute all cuts applied to sigma plus reconstructed with a PCM photon +template +class SigmaPlusPcmSelection : public baseselection::BaseSelection +{ + public: + SigmaPlusPcmSelection() = default; + ~SigmaPlusPcmSelection() override = default; + + template + void configure(o2::framework::HistogramRegistry* registry, T1& config, T2& filter) + { + this->init(config.passThrough.value); + + mPtMin = filter.ptMin.value; + mPtMax = filter.ptMax.value; + mEtaMin = filter.etaMin.value; + mEtaMax = filter.etaMax.value; + mPhiMin = filter.phiMin.value; + mPhiMax = filter.phiMax.value; + mMassLowerLimit = filter.massMinSigmaPlusPcm.value; + mMassUpperLimit = filter.massMaxSigmaPlusPcm.value; + mMlScoreMin = filter.mlScoreMinSigmaPlusPcm.value; + mKeepTracksWithoutTof = config.keepTracksWithoutTof.value; + + this->addSelection(kFlightDirTiltMax, kinkSelectionNames.at(kFlightDirTiltMax), config.flightDirTiltMax.value, limits::kUpperLimit, true, true, false); + this->addSelection(kMothDcaPvMax, kinkSelectionNames.at(kMothDcaPvMax), config.mothDcaPvMax.value, limits::kUpperLimit, true, true, false); + this->addSelection(kChaDauDcaZMax, kinkSelectionNames.at(kChaDauDcaZMax), config.chaDauDcaZMax.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kPhotonDcaZMax, kinkSelectionNames.at(kPhotonDcaZMax), config.photonDcaZMax.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kChaDaughTpcProton, kinkSelectionNames.at(kChaDaughTpcProton), config.chaDauTpcProton.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kChaDaughTofProton, kinkSelectionNames.at(kChaDaughTofProton), config.chaDauTofProton.value, limits::kAbsUpperLimit, true, config.requireTof.value, false); + this->addComments(kChaDaughTofProton, "requireTof = " + std::to_string(config.requireTof.value) + "; keepTracksWithoutTof = " + std::to_string(mKeepTracksWithoutTof)); + + this->setupSelectionHistogram(registry); + this->template setupFilterHistogram( + registry, + { + {kinkFilterNames.at(kPtMin), mPtMin}, + {kinkFilterNames.at(kPtMax), mPtMax}, + {kinkFilterNames.at(kEtaMin), mEtaMin}, + {kinkFilterNames.at(kEtaMax), mEtaMax}, + {kinkFilterNames.at(kPhiMin), mPhiMin}, + {kinkFilterNames.at(kPhiMax), mPhiMax}, + {kinkFilterNames.at(kMassMin), mMassLowerLimit}, + {kinkFilterNames.at(kMassMax), mMassUpperLimit}, + {kinkFilterNames.at(kMlScoreMin), mMlScoreMin}, + }); + }; + + template + void computeKinematics(T const& sigmaPlusPcmCand) + { + std::array momMother = {sigmaPlusPcmCand.pxSigmaPlus(), sigmaPlusPcmCand.pySigmaPlus(), sigmaPlusPcmCand.pzSigmaPlus()}; + mPt = RecoDecay::pt(momMother); + mEta = RecoDecay::eta(momMother); + mPhi = RecoDecay::phi(momMother); + mMass = sigmaPlusPcmCand.massSigmaPlus(); + mMlScore = sigmaPlusPcmCand.mlScore(); + } + + template + bool checkFilters(T const& /*sigmaPlusPcmCand*/) const + { + bool pass = true; + bool p = false; + + p = mPt > mPtMin; + this->template fillFilter(kPtMin, p); + pass &= p; + + p = mPt < mPtMax; + this->template fillFilter(kPtMax, p); + pass &= p; + + p = mEta > mEtaMin; + this->template fillFilter(kEtaMin, p); + pass &= p; + + p = mEta < mEtaMax; + this->template fillFilter(kEtaMax, p); + pass &= p; + + p = mPhi > mPhiMin; + this->template fillFilter(kPhiMin, p); + pass &= p; + + p = mPhi < mPhiMax; + this->template fillFilter(kPhiMax, p); + pass &= p; + + p = mMass > mMassLowerLimit; + this->template fillFilter(kMassMin, p); + pass &= p; + + p = mMass < mMassUpperLimit; + this->template fillFilter(kMassMax, p); + pass &= p; + + p = mMlScore >= mMlScoreMin; + this->template fillFilter(kMlScoreMin, p); + pass &= p; + + this->template fillFilterSummary(pass); + + return this->isPassThrough() || pass; + } + + template + void applySelections(T1 const& sigmaPlusPcmCand, T2 const& /*tracks*/) + { + this->reset(); + this->evaluateObservable(kFlightDirTiltMax, sigmaPlusPcmCand.flightDirTilt()); + this->evaluateObservable(kMothDcaPvMax, sigmaPlusPcmCand.candDcaToPV()); + this->evaluateObservable(kChaDauDcaZMax, sigmaPlusPcmCand.protonDcaZ()); + this->evaluateObservable(kPhotonDcaZMax, sigmaPlusPcmCand.photonDcaZToPV()); + + auto chaDaughter = sigmaPlusPcmCand.template protonTrack_as(); + this->evaluateObservable(kChaDaughTpcProton, chaDaughter.tpcNSigmaPr()); + if (chaDaughter.hasTOF()) { + this->evaluateObservable(kChaDaughTofProton, chaDaughter.tofNSigmaPr()); + } else { + this->evaluateObservable(kChaDaughTofProton, mKeepTracksWithoutTof ? 0.f : 999.f); + } + + this->assembleBitmask(); + }; + + [[nodiscard]] float getPt() const { return mPt; } + [[nodiscard]] float getEta() const { return mEta; } + [[nodiscard]] float getPhi() const { return mPhi; } + [[nodiscard]] float getMass() const { return mMass; } + + private: + float mMassLowerLimit = 1.1f; + float mMassUpperLimit = 1.3f; + float mMlScoreMin = -1.f; + bool mKeepTracksWithoutTof = true; + + // kinematic filters + float mPtMin = 0.f; + float mPtMax = 6.f; + float mEtaMin = -1.f; + float mEtaMax = 1.f; + float mPhiMin = 0.f; + float mPhiMax = o2::constants::math::TwoPI; + + // mother kinematic + float mPt = 0.f; + float mEta = 0.f; + float mPhi = 0.f; + float mMass = 0.f; + float mMlScore = 0.f; +}; + +template +class SigmaPlusPcmBuilder +{ + public: + SigmaPlusPcmBuilder() = default; + ~SigmaPlusPcmBuilder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, T1& config, T2& filter, T3& table, T4& initContext, T5& trackBuilder) + { + LOG(info) << "Initialize femto SigmaPlusPcm builder..."; + mProduceSigmaPlusPcm = utils::enableTable("FSigmaPlusPcm_001", table.produceSigmaPlusPcm.value, initContext); + mProduceLiteSigmaPlusPcm = utils::enableTable("FLiteSigmaPlusPcm_001", table.produceLiteSigmaPlusPcm.value, initContext); + mProduceSigmaPlusPcmMasks = utils::enableTable("FSigmaPlusPcmMasks_001", table.produceSigmaPlusPcmMasks.value, initContext); + mProduceSigmaPlusPcmMlScores = utils::enableTable("FSigmaPlusPcmMlScores_001", table.produceSigmaPlusPcmMlScores.value, initContext); + mProduceSigmaPlusPcmExtras = utils::enableTable("FSigmaPlusPcmExtras_001", table.produceSigmaPlusPcmExtras.value, initContext); + + if (mProduceSigmaPlusPcm && mProduceLiteSigmaPlusPcm) { + LOG(fatal) << "FSigmaPlusPcm and FLiteSigmaPlusPcm are mutually exclusive -- enable only one. " + << "FLiteSigmaPlusPcm is meant to replace FSigmaPlusPcm at the producer stage (for better compression in derived data); " + << "use the dedicated converter task to reconstruct FSigmaPlusPcm from FLiteSigmaPlusPcm downstream."; + } + if (mProduceSigmaPlusPcm && !trackBuilder.producingTracks()) { + LOG(fatal) << "FSigmaPlusPcm is enabled, but the track builder is not producing FTracks (full precision). " + << "FSigmaPlusPcm stores the daughter index into FTracks -- enable TrackTables.produceTracks, " + << "or switch to FLiteSigmaPlusPcm if TrackTables.produceLiteTracks is enabled instead."; + } + if (mProduceLiteSigmaPlusPcm && !trackBuilder.producingLiteTracks()) { + LOG(fatal) << "FLiteSigmaPlusPcm is enabled, but the track builder is not producing FLiteTracks. " + << "FLiteSigmaPlusPcm stores the daughter index into FLiteTracks -- enable TrackTables.produceLiteTracks, " + << "or switch to FSigmaPlusPcm if TrackTables.produceTracks is enabled instead."; + } + + if (mProduceSigmaPlusPcm || mProduceLiteSigmaPlusPcm || mProduceSigmaPlusPcmMasks || mProduceSigmaPlusPcmMlScores || mProduceSigmaPlusPcmExtras) { + mFillAnyTable = true; + } else { + LOG(info) << "No tables configured, Selection object will not be configured..."; + LOG(info) << "Initialization done..."; + return; + } + mSigmaPlusPcmSelection.configure(registry, config, filter); + mSigmaPlusPcmSelection.printSelections(kinkSelsName); + LOG(info) << "Initialization done..."; + } + + template + void fillSigmaPlusPcms(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4& trackProducts, T5& kinkProducts, T6 const& sigmaPlusPcms, T7 const& tracks, T8& trackBuilder) + { + if (!mFillAnyTable) { + return; + } + int64_t daughterIndex = 0; + + for (const auto& sigmaPlusPcm : sigmaPlusPcms) { + mSigmaPlusPcmSelection.computeKinematics(sigmaPlusPcm); + if (!mSigmaPlusPcmSelection.checkFilters(sigmaPlusPcm)) { + continue; + } + mSigmaPlusPcmSelection.applySelections(sigmaPlusPcm, tracks); + if (!mSigmaPlusPcmSelection.passesAllRequiredSelections()) { + continue; + } + + collisionBuilder.template fillCollision(collisionProducts, col); + + auto daughter = sigmaPlusPcm.template protonTrack_as(); + daughterIndex = trackBuilder.template getDaughterIndex(daughter, trackProducts, collisionBuilder); + fillSigmaPlusPcm(collisionBuilder, kinkProducts, sigmaPlusPcm, daughterIndex); + } + } + + template + void fillMcSigmaPlusPcms(T1 const& col, T2& collisionBuilder, T3& collisionProducts, T4 const& mcCols, T5& trackProducts, T6& kinkProducts, T7 const& sigmaPlusPcms, T8 const& tracks, T9& trackBuilder, T10 const& mcParticles, T11& mcBuilder, T12& mcProducts) + { + if (!mFillAnyTable) { + return; + } + int64_t daughterIndex = 0; + + for (const auto& sigmaPlusPcm : sigmaPlusPcms) { + mSigmaPlusPcmSelection.computeKinematics(sigmaPlusPcm); + if (!mSigmaPlusPcmSelection.checkFilters(sigmaPlusPcm)) { + continue; + } + mSigmaPlusPcmSelection.applySelections(sigmaPlusPcm, tracks); + if (!mSigmaPlusPcmSelection.passesAllRequiredSelections()) { + continue; + } + + collisionBuilder.template fillMcCollision(collisionProducts, col, mcCols, mcProducts, mcBuilder); + + auto daughter = sigmaPlusPcm.template protonTrack_as(); + daughterIndex = trackBuilder.template getDaughterIndex(daughter, trackProducts, mcCols, collisionBuilder, mcParticles, mcBuilder, mcProducts); + fillSigmaPlusPcm(collisionBuilder, kinkProducts, sigmaPlusPcm, daughterIndex); + mcBuilder.template fillMcSigmaPlusPcmWithLabel(sigmaPlusPcm, daughter, mcParticles, mcCols, mcProducts); + } + } + + template + void fillSigmaPlusPcm(T1& collisionBuilder, T2& kinkProducts, T3 const& sigmaPlusPcm, int64_t daughterIndex) + { + float signedPt = sigmaPlusPcm.protonSign() * mSigmaPlusPcmSelection.getPt(); + if (mProduceSigmaPlusPcm) { + kinkProducts.producedSigmaPlusPcm(collisionBuilder.collisionIndex(), + signedPt, + mSigmaPlusPcmSelection.getEta(), + mSigmaPlusPcmSelection.getPhi(), + mSigmaPlusPcmSelection.getMass(), + daughterIndex); + } + if (mProduceLiteSigmaPlusPcm) { + kinkProducts.producedLiteSigmaPlusPcm(collisionBuilder.collisionIndex(), + o2::aod::femtobase::lite::binSignedPt(signedPt), + o2::aod::femtobase::lite::binEta(mSigmaPlusPcmSelection.getEta()), + o2::aod::femtobase::lite::binPhi(mSigmaPlusPcmSelection.getPhi()), + o2::aod::femtokinks::lite::binSigmaMass(mSigmaPlusPcmSelection.getMass()), + daughterIndex); + } + if (mProduceSigmaPlusPcmMasks) { + kinkProducts.producedSigmaPlusPcmMasks(mSigmaPlusPcmSelection.getBitmask()); + } + if (mProduceSigmaPlusPcmMlScores) { + kinkProducts.producedSigmaPlusPcmMlScores(sigmaPlusPcm.mlScore()); + } + if (mProduceSigmaPlusPcmExtras) { + kinkProducts.producedSigmaPlusPcmExtras( + sigmaPlusPcm.flightDirTilt(), + sigmaPlusPcm.candDcaToPV(), + sigmaPlusPcm.protonDcaXY(), + sigmaPlusPcm.protonDcaZ(), + sigmaPlusPcm.nSigmaTPCProton(), + sigmaPlusPcm.nSigmaTOFProton(), + sigmaPlusPcm.photonDcaXYToPV(), + sigmaPlusPcm.photonDcaZToPV(), + sigmaPlusPcm.photonCosPAToPV(), + sigmaPlusPcm.photonConvRadius(), + sigmaPlusPcm.antiSigmaPointingAngle(), + sigmaPlusPcm.dcaProtonGamma(), + sigmaPlusPcm.radius()); + } + } + + [[nodiscard]] bool fillAnyTable() const { return mFillAnyTable; } + [[nodiscard]] bool isPassThrough() const { return mSigmaPlusPcmSelection.isPassThrough(); } + + private: + SigmaPlusPcmSelection mSigmaPlusPcmSelection; + bool mFillAnyTable = false; + bool mProduceSigmaPlusPcm = false; + bool mProduceLiteSigmaPlusPcm = false; + bool mProduceSigmaPlusPcmMasks = false; + bool mProduceSigmaPlusPcmMlScores = false; + bool mProduceSigmaPlusPcmExtras = false; +}; + struct ConfKinkTablesDerivedToDerived : o2::framework::ConfigurableGroup { std::string prefix = std::string("KinkTables"); o2::framework::Configurable limitSigma{"limitSigma", 1, "Require at least this many Sigmas in the collision. Set to 0 to skip Sigmas entirely (not written to output)."}; o2::framework::Configurable limitSigmaPlus{"limitSigmaPlus", 0, "Require at least this many SigmaPlus in the collision. Set to 0 to skip SigmaPlus entirely (not written to output)."}; + o2::framework::Configurable limitSigmaPlusPcm{"limitSigmaPlusPcm", 0, "Require at least this many SigmaPlusPcm in the collision. Set to 0 to skip SigmaPlusPcm entirely (not written to output)."}; }; struct KinkBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup { @@ -768,6 +1129,10 @@ struct KinkBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup { o2::framework::Produces producedSigmaPluses; o2::framework::Produces producedSigmaPlusMasks; o2::framework::Produces producedSigmaPlusExtras; + o2::framework::Produces producedSigmaPlusPcms; + o2::framework::Produces producedSigmaPlusPcmMasks; + o2::framework::Produces producedSigmaPlusPcmMlScores; + o2::framework::Produces producedSigmaPlusPcmExtras; }; class KinkBuilderDerivedToDerived @@ -778,12 +1143,13 @@ class KinkBuilderDerivedToDerived { mLimitSigma = config.limitSigma.value; mLimitSigmaPlus = config.limitSigmaPlus.value; + mLimitSigmaPlusPcm = config.limitSigmaPlusPcm.value; - if (mLimitSigma < 0 || mLimitSigmaPlus < 0) { - LOG(fatal) << "Kink limits must be non-negative (got " << mLimitSigma << " and " << mLimitSigmaPlus << "). Breaking..."; + if (mLimitSigma < 0 || mLimitSigmaPlus < 0 || mLimitSigmaPlusPcm < 0) { + LOG(fatal) << "Kink limits must be non-negative (got " << mLimitSigma << ", " << mLimitSigmaPlus << " and " << mLimitSigmaPlusPcm << "). Breaking..."; } - if (mLimitSigma == 0 && mLimitSigmaPlus == 0) { - LOG(fatal) << "Both sigma limit and sigmaplus limit are 0. Breaking..."; + if (mLimitSigma == 0 && mLimitSigmaPlus == 0 && mLimitSigmaPlusPcm == 0) { + LOG(fatal) << "Sigma, sigmaplus and sigmapluspcm limits are all 0. Breaking..."; } } @@ -807,6 +1173,16 @@ class KinkBuilderDerivedToDerived return sigmaPlusSlice.size() < static_cast(mLimitSigmaPlus); } + template + bool collisionHasTooFewSigmaPlusPcm(T1 const& col, T2 const& /*sigmaPlusPcmTable*/, T3& partitionSigmaPlusPcm, T4& cache) + { + if (mLimitSigmaPlusPcm == 0) { // sigma pluses (PCM) disabled, cannot reject on them + return false; + } + auto sigmaPlusPcmSlice = partitionSigmaPlusPcm->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + return sigmaPlusPcmSlice.size() < static_cast(mLimitSigmaPlusPcm); + } + template void processSigma(T1 const& col, T2 const& /*sigmaTable*/, T3 const& oldTrackTable, T4& partitionSigma, T5& trackBuilder, T6& cache, T7& newSigmaTable, T8& newTrackTable, T9& newCollisionTable) { @@ -909,6 +1285,58 @@ class KinkBuilderDerivedToDerived } } + template + void processSigmaPlusPcm(T1 const& col, T2 const& /*sigmaPlusPcmTable*/, T3 const& oldTrackTable, T4& partitionSigmaPlusPcm, T5& trackBuilder, T6& cache, T7& newSigmaPlusPcmTable, T8& newTrackTable, T9& newCollisionTable) + { + if (mLimitSigmaPlusPcm == 0) { // sigma pluses (PCM) disabled + return; + } + + auto sigmaPlusPcmSlice = partitionSigmaPlusPcm->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + + for (auto const& sigmaPlusPcm : sigmaPlusPcmSlice) { + auto chaDaughter = oldTrackTable.rawIteratorAt(utils::daughterRow(sigmaPlusPcm.chaDauId(), oldTrackTable)); + + int64_t chaDaughterIndex = trackBuilder.getDaughterIndex(chaDaughter, newTrackTable, newCollisionTable); + + newSigmaPlusPcmTable.producedSigmaPlusPcms(newCollisionTable.producedCollision.lastIndex(), + sigmaPlusPcm.signedPt(), + sigmaPlusPcm.eta(), + sigmaPlusPcm.phi(), + sigmaPlusPcm.mass(), + chaDaughterIndex); + newSigmaPlusPcmTable.producedSigmaPlusPcmMasks(sigmaPlusPcm.mask()); + fillSigmaPlusPcmExtensions(sigmaPlusPcm, newSigmaPlusPcmTable); + } + } + + template + void processSigmaPlusPcmWithMc(T1 const& col, T2 const& /*sigmaPlusPcmTable*/, T3 const& oldTrackTable, T4& partitionSigmaPlusPcm, T5& trackBuilder, T6& cache, T7& newSigmaPlusPcmTable, T8& newTrackTable, T9& newCollisionTable, + T10& mcBuilder, T11 const& mcCols, T12 const& mcParticles, T13 const& mcMothers, T14 const& mcPartonicMothers, T15& mcProducts) + { + if (mLimitSigmaPlusPcm == 0) { + return; + } + + auto sigmaPlusPcmSlice = partitionSigmaPlusPcm->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + + for (auto const& sigmaPlusPcm : sigmaPlusPcmSlice) { + auto chaDaughter = oldTrackTable.rawIteratorAt(utils::daughterRow(sigmaPlusPcm.chaDauId(), oldTrackTable)); + + int64_t chaDaughterIndex = trackBuilder.getDaughterIndex(chaDaughter, newTrackTable, newCollisionTable, mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcProducts); + + newSigmaPlusPcmTable.producedSigmaPlusPcms(newCollisionTable.producedCollision.lastIndex(), + sigmaPlusPcm.signedPt(), + sigmaPlusPcm.eta(), + sigmaPlusPcm.phi(), + sigmaPlusPcm.mass(), + chaDaughterIndex); + newSigmaPlusPcmTable.producedSigmaPlusPcmMasks(sigmaPlusPcm.mask()); + fillSigmaPlusPcmExtensions(sigmaPlusPcm, newSigmaPlusPcmTable); + mcBuilder.fillSigmaPlusPcmWithLabel(sigmaPlusPcm, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcProducts); + } + } + private: template void fillSigmaPlusExtensions(T1 const& sigmaPlus, T2& newSigmaPlusTable) @@ -930,8 +1358,32 @@ class KinkBuilderDerivedToDerived } } + template + void fillSigmaPlusPcmExtensions(T1 const& sigmaPlusPcm, T2& newSigmaPlusPcmTable) + { + if constexpr (requires(T1 t) { t.mlScore(); }) { + newSigmaPlusPcmTable.producedSigmaPlusPcmMlScores(sigmaPlusPcm.mlScore()); + } + if constexpr (requires(T1 t) { t.photonConvRadius(); }) { + newSigmaPlusPcmTable.producedSigmaPlusPcmExtras(sigmaPlusPcm.flightDirTilt(), + sigmaPlusPcm.dcaMothToPV(), + sigmaPlusPcm.dauDcaXY(), + sigmaPlusPcm.dauDcaZ(), + sigmaPlusPcm.dauTpcNSigmaPr(), + sigmaPlusPcm.dauTofNSigmaPr(), + sigmaPlusPcm.photonDcaXYToPV(), + sigmaPlusPcm.photonDcaZToPV(), + sigmaPlusPcm.photonCosPAToPV(), + sigmaPlusPcm.photonConvRadius(), + sigmaPlusPcm.antiSigmaPointingAngle(), + sigmaPlusPcm.dcaDauPhoton(), + sigmaPlusPcm.transRadius()); + } + } + int mLimitSigma = 0; int mLimitSigmaPlus = 0; + int mLimitSigmaPlusPcm = 0; }; } // namespace o2::analysis::femto::kinkbuilder #endif // PWGCF_FEMTO_CORE_KINKBUILDER_H_ diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index abebfda31f4..2d9eed98b87 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -105,6 +105,11 @@ struct ConfSigmaPlusBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_BINNING(1.1, 1.3) }; +template +struct ConfSigmaPlusPcmBinning : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + KINK_DEFAULT_BINNING(1.1, 1.3) +}; #undef KINK_DEFAULT_BINNING @@ -114,6 +119,9 @@ using ConfSigmaBinning1 = ConfSigmaBinning; constexpr const char PrefixSigmaPlusBinning1[] = "SigmaPlusBinning1"; using ConfSigmaPlusBinning1 = ConfSigmaPlusBinning; +constexpr const char PrefixSigmaPlusPcmBinning1[] = "SigmaPlusPcmBinning1"; +using ConfSigmaPlusPcmBinning1 = ConfSigmaPlusPcmBinning; + template struct ConfKinkQaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; @@ -262,6 +270,8 @@ constexpr char PrefixSigmaPlusQa[] = "SigmaPlusQA/"; constexpr char PrefixSigmaPlus1Se[] = "SigmaPlus1/SE/"; constexpr char PrefixSigmaPlus1Me[] = "SigmaPlus1/ME/"; constexpr char PrefixSigmaPlus2[] = "SigmaPlus2/"; +constexpr char PrefixSigmaPlusPcm1Se[] = "SigmaPlusPcm1/SE/"; +constexpr char PrefixSigmaPlusPcm1Me[] = "SigmaPlusPcm1/ME/"; constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; @@ -508,7 +518,7 @@ class KinkHistManager mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(AnalysisDir) + HIST(getHistName(kPhi, HistTable)), kinkcandidate.phi()); mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(AnalysisDir) + HIST(getHistName(kMass, HistTable)), kinkcandidate.mass()); - if constexpr (isEqual(kink, modes::Kink::kSigma) || isEqual(kink, modes::Kink::kSigmaPlus)) { + if constexpr (isEqual(kink, modes::Kink::kSigma) || isEqual(kink, modes::Kink::kSigmaPlus) || isEqual(kink, modes::Kink::kSigmaPlusPcm)) { mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(AnalysisDir) + HIST(getHistName(kSign, HistTable)), kinkcandidate.sign()); } } diff --git a/PWGCF/Femto/Core/mcBuilder.h b/PWGCF/Femto/Core/mcBuilder.h index d05820904a2..8062322c13b 100644 --- a/PWGCF/Femto/Core/mcBuilder.h +++ b/PWGCF/Femto/Core/mcBuilder.h @@ -66,6 +66,7 @@ struct McBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedLcLabels; o2::framework::Produces producedSigmaLabels; o2::framework::Produces producedSigmaPlusLabels; + o2::framework::Produces producedSigmaPlusPcmLabels; o2::framework::Produces producedXiLabels; o2::framework::Produces producedOmegaLabels; }; @@ -86,6 +87,7 @@ struct ConfMcTables : o2::framework::ConfigurableGroup { o2::framework::Configurable producedLcLabels{"producedLcLabels", -1, "Produce Lc labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedSigmaLabels{"producedSigmaLabels", -1, "Produce sigma labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedSigmaPlusLabels{"producedSigmaPlusLabels", -1, "Produce sigma plus labels (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedSigmaPlusPcmLabels{"producedSigmaPlusPcmLabels", -1, "Produce sigma plus (PCM) labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedXiLabels{"producedXiLabels", -1, "Produce xi labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedOmegaLabels{"producedOmegaLabels", -1, "Produce omega labels (-1: auto; 0 off; 1 on)"}; }; @@ -159,6 +161,7 @@ class McBuilder mProduceLcLabels = utils::enableTable("FLcLabels_001", table.producedLcLabels.value, initContext); mProduceSigmaLabels = utils::enableTable("FSigmaLabels_001", table.producedSigmaLabels.value, initContext); mProduceSigmaPlusLabels = utils::enableTable("FSigmaPlusLabels_001", table.producedSigmaPlusLabels.value, initContext); + mProduceSigmaPlusPcmLabels = utils::enableTable("FSigmaPlusPcmLabels_001", table.producedSigmaPlusPcmLabels.value, initContext); mProduceXiLabels = utils::enableTable("FXiLabels_001", table.producedXiLabels.value, initContext); mProduceOmegaLabels = utils::enableTable("FOmegaLabels_001", table.producedOmegaLabels.value, initContext); @@ -167,7 +170,7 @@ class McBuilder mProduceMcMothers || mProduceMcPartonicMothers || mProduceTrackLabels || mProduceLambdaLabels || mProduceK0shortLabels || - mProduceSigmaLabels || mProduceSigmaPlusLabels || + mProduceSigmaLabels || mProduceSigmaPlusLabels || mProduceSigmaPlusPcmLabels || mProduceXiLabels || mProduceOmegaLabels || mProduceD0Labels || mProduceLcLabels) { mFillAnyTable = true; @@ -426,6 +429,21 @@ class McBuilder fillMcLabelGeneric(sigmaPlusDaughter, mcParticles, mcCols, mcProducts, [](auto& prod, int64_t p) { prod.producedSigmaPlusLabels(p); }, true); } + template + void fillMcSigmaPlusPcmWithLabel(T1 const& sigmaPlusPcm, T2 const& chaDaughter, T3 const& mcParticles, T4 const& mcCols, T5& mcProducts) + { + if (!mProduceSigmaPlusPcmLabels) { + mcProducts.producedSigmaPlusPcmLabels(-1); + return; + } + // true sigma plus (proton and photon from it): label of the sigma plus, otherwise label of the proton, its mother gives the origin of the background + if (sigmaPlusPcm.has_mcParticle()) { + fillMcLabelGeneric(sigmaPlusPcm, mcParticles, mcCols, mcProducts, [](auto& prod, int64_t p) { prod.producedSigmaPlusPcmLabels(p); }); + } else { + fillMcLabelGeneric(chaDaughter, mcParticles, mcCols, mcProducts, [](auto& prod, int64_t p) { prod.producedSigmaPlusPcmLabels(p); }); + } + } + template void fillMcXiWithLabel(T1 const& xi, T2 const& mcParticles, T3 const& mcCols, T4& mcProducts) { @@ -741,6 +759,7 @@ class McBuilder bool mProduceLcLabels = false; bool mProduceSigmaLabels = false; bool mProduceSigmaPlusLabels = false; + bool mProduceSigmaPlusPcmLabels = false; bool mProduceXiLabels = false; bool mProduceOmegaLabels = false; bool mProduceMcMotherLabels = false; @@ -767,6 +786,7 @@ struct McBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup { o2::framework::Produces producedTrackLabels; o2::framework::Produces producedSigmaLabels; o2::framework::Produces producedSigmaPlusLabels; + o2::framework::Produces producedSigmaPlusPcmLabels; }; struct ConfMcTablesDerivedToDerived : o2::framework::ConfigurableGroup { @@ -850,6 +870,18 @@ class McBuilderDerivedToDerived this->getOrCreateMcParticleRow(mcParticle, mcCols, mcMothers, mcPartonicMothers, mcProducts)); } + template + void fillSigmaPlusPcmWithLabel(T1 const& sigmaPlusPcm, T2 const& mcCols, T3 const& /*mcParticles*/, T4 const& mcMothers, T5 const& mcPartonicMothers, T6& mcProducts) + { + if (!sigmaPlusPcm.has_fMcParticle()) { + mcProducts.producedSigmaPlusPcmLabels(-1); + return; + } + auto mcParticle = sigmaPlusPcm.template fMcParticle_as(); + mcProducts.producedSigmaPlusPcmLabels( + this->getOrCreateMcParticleRow(mcParticle, mcCols, mcMothers, mcPartonicMothers, mcProducts)); + } + template void reset(T1 const& mcCols, T2 const& mcParticles) { diff --git a/PWGCF/Femto/Core/modes.h b/PWGCF/Femto/Core/modes.h index 0b0bf75121e..8276bac97f2 100644 --- a/PWGCF/Femto/Core/modes.h +++ b/PWGCF/Femto/Core/modes.h @@ -224,7 +224,8 @@ enum class V0 : o2::analysis::femto::datatypes::V0Type { enum class Kink : o2::analysis::femto::datatypes::KinkType { kSigma, - kSigmaPlus + kSigmaPlus, + kSigmaPlusPcm }; enum class Cascade : o2::analysis::femto::datatypes::CascadeType { diff --git a/PWGCF/Femto/Core/particleCleaner.h b/PWGCF/Femto/Core/particleCleaner.h index b7387cc3ec8..f284385cce9 100644 --- a/PWGCF/Femto/Core/particleCleaner.h +++ b/PWGCF/Femto/Core/particleCleaner.h @@ -73,6 +73,11 @@ constexpr const char PrefixSigmaPlusCleaner2[] = "SigmaPlusCleaner2"; using ConfSigmaPlusCleaner1 = ConfParticleCleaner; using ConfSigmaPlusCleaner2 = ConfParticleCleaner; +constexpr const char PrefixSigmaPlusPcmCleaner1[] = "SigmaPlusPcmCleaner1"; +constexpr const char PrefixSigmaPlusPcmCleaner2[] = "SigmaPlusPcmCleaner2"; +using ConfSigmaPlusPcmCleaner1 = ConfParticleCleaner; +using ConfSigmaPlusPcmCleaner2 = ConfParticleCleaner; + constexpr const char PrefixXiCleaner1[] = "XiCleaner1"; constexpr const char PrefixXiCleaner2[] = "XiCleaner2"; using ConfXiCleaner1 = ConfParticleCleaner; diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index cb3cfe24b53..6a3a473ecf9 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -244,6 +244,21 @@ (o2::aod::femtobase::stored::mass < (selection).massMax) && \ ncheckbit(o2::aod::femtokinks::mask, (selection).mask) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_SIGMAPLUSPCM_PARTITION(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + (o2::aod::femtokinks::mlScore >= (selection).mlScoreMin) && \ + ncheckbit(o2::aod::femtokinks::mask, (selection).mask) + // partition for D0 // sign of signedPt encodes the hypothesis: D0 (+) / D0bar (-) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 9de9dbe28b3..4816b1527b7 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -1096,6 +1096,18 @@ DECLARE_SOA_COLUMN(DauTpcNSigmaPi, dauTpcNSigmaPi, float); DECLARE_SOA_COLUMN(DauTofNSigmaPr, dauTofNSigmaPr, float); DECLARE_SOA_COLUMN(PtOriginal, ptOriginal, float); +// columns for sigma plus reconstructed with a PCM photon +DECLARE_SOA_COLUMN(MlScore, mlScore, float); //! BDT score of the candidate +DECLARE_SOA_COLUMN(FlightDirTilt, flightDirTilt, float); //! Tilt of the flight direction needed for a real solution of the missing photon +DECLARE_SOA_COLUMN(DauDcaXY, dauDcaXY, float); //! DCAxy of the charged daughter to the primary vertex +DECLARE_SOA_COLUMN(DauDcaZ, dauDcaZ, float); //! DCAz of the charged daughter to the primary vertex +DECLARE_SOA_COLUMN(PhotonDcaXYToPV, photonDcaXYToPV, float); //! Transverse DCA of the photon flight line to the primary vertex +DECLARE_SOA_COLUMN(PhotonDcaZToPV, photonDcaZToPV, float); //! Longitudinal DCA of the photon flight line to the primary vertex +DECLARE_SOA_COLUMN(PhotonCosPAToPV, photonCosPAToPV, float); //! Cosine of the photon pointing angle to the primary vertex +DECLARE_SOA_COLUMN(PhotonConvRadius, photonConvRadius, float); //! Conversion radius of the photon +DECLARE_SOA_COLUMN(AntiSigmaPointingAngle, antiSigmaPointingAngle, float); //! Angle between the unbent proton momentum and the flight direction +DECLARE_SOA_COLUMN(DcaDauPhoton, dcaDauPhoton, float); //! DCA between charged daughter and photon at the decay vertex + // id column for charged daughter track DECLARE_SOA_INDEX_COLUMN_FULL(ChaDau, chaDau, int32_t, FTracks, "_ChaDau"); //! @@ -1266,6 +1278,72 @@ DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusExtras_002, "FSIGMAPLUSEXTRAS", 2, using FSigmaPlusExtras = FSigmaPlusExtras_002; using StoredFSigmaPlusExtras = StoredFSigmaPlusExtras_002; +// table for basic sigma plus information, sigma plus reconstructed with a PCM photon +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcm_001, "FSIGMAPLUSPCM", 1, + o2::soa::Index<>, + femtobase::stored::FColId, + femtobase::stored::SignedPt, // use sign to differentiate between sigma plus (+1) and anti sigma plus (-1) + femtobase::stored::Eta, + femtobase::stored::Phi, + femtobase::stored::Mass, + femtokinks::ChaDauId, + femtobase::dynamic::Sign, + femtobase::dynamic::Pt, + femtobase::dynamic::P, + femtobase::dynamic::Px, + femtobase::dynamic::Py, + femtobase::dynamic::Pz, + femtobase::dynamic::Theta); +using FSigmaPlusPcm = FSigmaPlusPcm_001; +using FSigmaPlusPcmRow = FSigmaPlusPcm::iterator; +using StoredFSigmaPlusPcm = StoredFSigmaPlusPcm_001; + +// table for basic sigma plus information, sigma plus reconstructed with a PCM photon, compressed/binned kinematics +DECLARE_SOA_TABLE_STAGED_VERSIONED(FLiteSigmaPlusPcm_001, "FLITESIGMAPCM", 1, + o2::soa::Index<>, + femtobase::stored::FLiteColId, + femtobase::lite::SignedBinnedPt, + femtobase::lite::BinnedEta, + femtobase::lite::BinnedPhi, + femtokinks::lite::BinnedSigmaMass, + femtokinks::lite::ChaDauId, + femtobase::lite::Sign, + femtobase::lite::SignedPt, + femtobase::lite::signedpt::Pt, + femtobase::lite::Eta, + femtobase::lite::Phi, + femtokinks::lite::SigmaMass); +using FLiteSigmaPlusPcm = FLiteSigmaPlusPcm_001; +using FLiteSigmaPlusPcmRow = FLiteSigmaPlusPcm::iterator; +using StoredFLiteSigmaPlusPcm = StoredFLiteSigmaPlusPcm_001; + +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcmMasks_001, "FSIGMAPCMMASKS", 1, + femtokinks::Mask); +using FSigmaPlusPcmMasks = FSigmaPlusPcmMasks_001; +using StoredFSigmaPlusPcmMasks = StoredFSigmaPlusPcmMasks_001; + +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcmMlScores_001, "FSIGMAPCMML", 1, + femtokinks::MlScore); +using FSigmaPlusPcmMlScores = FSigmaPlusPcmMlScores_001; +using StoredFSigmaPlusPcmMlScores = StoredFSigmaPlusPcmMlScores_001; + +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcmExtras_001, "FSIGMAPCMEXTRA", 1, + femtokinks::FlightDirTilt, + femtokinks::DcaMothToPV, + femtokinks::DauDcaXY, + femtokinks::DauDcaZ, + femtokinks::DauTpcNSigmaPr, + femtokinks::DauTofNSigmaPr, + femtokinks::PhotonDcaXYToPV, + femtokinks::PhotonDcaZToPV, + femtokinks::PhotonCosPAToPV, + femtokinks::PhotonConvRadius, + femtokinks::AntiSigmaPointingAngle, + femtokinks::DcaDauPhoton, + femtokinks::TransRadius); +using FSigmaPlusPcmExtras = FSigmaPlusPcmExtras_001; +using StoredFSigmaPlusPcmExtras = StoredFSigmaPlusPcmExtras_001; + namespace femtocascades { // columns for cascade bit masks @@ -1754,6 +1832,13 @@ using FSigmaPlusLabel = FSigmaPlusLabels::iterator; using StoredFSigmaPlusLabels = StoredFSigmaPlusLabels_001; using StoredFSigmaPlusLabel = StoredFSigmaPlusLabels::iterator; +DECLARE_SOA_TABLE_STAGED_VERSIONED(FSigmaPlusPcmLabels_001, "FSIGMAPCMLABEL", 1, //! label from femto sigma plus (PCM) to femto mc particle + femtolabels::FMcParticleId); +using FSigmaPlusPcmLabels = FSigmaPlusPcmLabels_001; +using FSigmaPlusPcmLabel = FSigmaPlusPcmLabels::iterator; +using StoredFSigmaPlusPcmLabels = StoredFSigmaPlusPcmLabels_001; +using StoredFSigmaPlusPcmLabel = StoredFSigmaPlusPcmLabels::iterator; + DECLARE_SOA_TABLE_STAGED_VERSIONED(FXiLabels_001, "FXILABEL", 1, //! label from femto xi to femto mc particle femtolabels::FMcParticleId); using FXiLabels = FXiLabels_001; diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 41922a24837..4b1082941ca 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -94,6 +94,9 @@ using Run3RecoCascades = o2::soa::Join; using Run3Kinks = o2::aod::KinkCands; +using Run3SigmaPlusPcms = o2::aod::SigmaPlusCands; +using Run3RecoSigmaPlusPcms = o2::aod::SigmaPlusCandsMC; + using Run3McGenParticles = o2::aod::McParticles; } // namespace o2::analysis::femto::rawinputs @@ -109,6 +112,7 @@ struct FemtoProducer { o2::framework::Preslice perColRecoPCMPhotons = o2::aod::v0photonkf::collisionId; o2::framework::Preslice perColRecoCascades = o2::aod::cascdata::collisionId; o2::framework::Preslice perColRecoKinks = o2::aod::kinkcand::collisionId; + o2::framework::Preslice perColRecoSigmaPlusPcms = o2::aod::sigmapluscand::collisionId; o2::framework::Preslice perColRecoD0s = o2::aod::hf_cand::collisionId; o2::framework::Preslice perColRecoLcs = o2::aod::hf_cand::collisionId; } preslices; @@ -130,6 +134,7 @@ struct FemtoProducer { cascadebuilder::CascadeBuilder omegaBuilder; kinkbuilder::KinkBuilder sigmaBuilder; kinkbuilder::KinkBuilder sigmaPlusBuilder; + kinkbuilder::SigmaPlusPcmBuilder sigmaPlusPcmBuilder; mcbuilder::McBuilder mcBuilder; } builders; @@ -182,6 +187,7 @@ struct FemtoProducer { kinkbuilder::ConfKinkFilters confKinkFilters; kinkbuilder::ConfSigmaBits confSigmaBits; kinkbuilder::ConfSigmaPlusBits confSigmaPlusBits; + kinkbuilder::ConfSigmaPlusPcmBits confSigmaPlusPcmBits; // mc builder mcbuilder::ConfMc confMc; @@ -227,6 +233,7 @@ struct FemtoProducer { builders.sigmaBuilder.init(&hRegistry, confSigmaBits, confKinkFilters, confKinkTables, context, builders.trackBuilder); builders.sigmaPlusBuilder.init(&hRegistry, confSigmaPlusBits, confKinkFilters, confKinkTables, context, builders.trackBuilder); + builders.sigmaPlusPcmBuilder.init(&hRegistry, confSigmaPlusPcmBits, confKinkFilters, confKinkTables, context, builders.trackBuilder); builders.xiBuilder.init(&hRegistry, confXiBits, confCascadeFilters, confCascadeTables, context, builders.trackBuilder); builders.omegaBuilder.init(&hRegistry, confOmegaBits, confCascadeFilters, confCascadeTables, context, builders.trackBuilder); @@ -262,6 +269,10 @@ struct FemtoProducer { !doprocessTracksKinksRun3ppMc && !doprocessTracksV0sKinksRun3ppMc)) { LOG(fatal) << "At least one kink table is enabled, but wrong process function is enabled. Breaking..."; } + if (builders.sigmaPlusPcmBuilder.fillAnyTable() && + (!doprocessTracksSigmaPlusPcmsRun3pp && !doprocessTracksSigmaPlusPcmsRun3ppMc)) { + LOG(fatal) << "At least one sigma plus (PCM) table is enabled, but wrong process function is enabled. Breaking..."; + } if ((builders.d0Builder.fillAnyTable() || builders.d0barBuilder.fillAnyTable()) && (!doprocessTracksD0sRun3pp && !doprocessTracksD0sRun3PbPb && !doprocessTracksD0sRun3ppMc && !doprocessTracksD0sRun3PbPbMc)) { @@ -277,6 +288,7 @@ struct FemtoProducer { !doprocessTracksV0sRun3ppMc && !doprocessTracksV0sRun3PbPbMc && !doprocessTracksV0sCascadesRun3ppMc && !doprocessTracksV0sCascadesRun3PbPbMc && !doprocessTracksKinksRun3ppMc && !doprocessTracksV0sKinksRun3ppMc && + !doprocessTracksSigmaPlusPcmsRun3ppMc && !doprocessTracksD0sRun3ppMc && !doprocessTracksD0sRun3PbPbMc && !doprocessTracksLcsRun3ppMc && !doprocessTracksLcsRun3PbPbMc && !doprocessMcOnly)) { @@ -304,6 +316,7 @@ struct FemtoProducer { add("lcbar", builders.lcBarBuilder.fillAnyTable(), builders.lcBarBuilder.isPassThrough()); add("sigma", builders.sigmaBuilder.fillAnyTable(), builders.sigmaBuilder.isPassThrough()); add("sigmaplus", builders.sigmaPlusBuilder.fillAnyTable(), builders.sigmaPlusBuilder.isPassThrough()); + add("sigmapluspcm", builders.sigmaPlusPcmBuilder.fillAnyTable(), builders.sigmaPlusPcmBuilder.isPassThrough()); add("xi", builders.xiBuilder.fillAnyTable(), builders.xiBuilder.isPassThrough()); add("omega", builders.omegaBuilder.fillAnyTable(), builders.omegaBuilder.isPassThrough()); add("mc", builders.mcBuilder.fillAnyTable(), builders.mcBuilder.isPassThrough()); @@ -337,7 +350,7 @@ struct FemtoProducer { // without FTrackExtras (fillType) these rows cannot be told apart from selected tracks downstream const bool anyDaughterBuilder = builders.k0shortBuilder.fillAnyTable() || builders.lambdaBuilder.fillAnyTable() || builders.antilambdaBuilder.fillAnyTable() || builders.xiBuilder.fillAnyTable() || builders.omegaBuilder.fillAnyTable() || - builders.sigmaBuilder.fillAnyTable() || builders.sigmaPlusBuilder.fillAnyTable() || + builders.sigmaBuilder.fillAnyTable() || builders.sigmaPlusBuilder.fillAnyTable() || builders.sigmaPlusPcmBuilder.fillAnyTable() || builders.d0Builder.fillAnyTable() || builders.d0barBuilder.fillAnyTable() || builders.lcBuilder.fillAnyTable() || builders.lcBarBuilder.fillAnyTable(); if (builders.trackBuilder.isPassThrough() && anyDaughterBuilder && !builders.trackBuilder.producingTrackExtras()) { LOG(warn) << "Track pass-through is enabled together with candidates that register daughter tracks, but FTrackExtras is not produced. " @@ -361,6 +374,7 @@ struct FemtoProducer { static_cast(doprocessTracksKinksRun3pp) + static_cast(doprocessTracksV0sCascadesKinksRun3pp) + static_cast(doprocessTracksV0sCascadesKinksPhotonsRun3pp) + + static_cast(doprocessTracksSigmaPlusPcmsRun3pp) + static_cast(doprocessTracksD0sRun3pp) + static_cast(doprocessTracksD0sRun3PbPb) + static_cast(doprocessTracksRun3ppMc) + @@ -371,6 +385,7 @@ struct FemtoProducer { static_cast(doprocessTracksV0sCascadesRun3PbPbMc) + static_cast(doprocessTracksKinksRun3ppMc) + static_cast(doprocessTracksV0sKinksRun3ppMc) + + static_cast(doprocessTracksSigmaPlusPcmsRun3ppMc) + static_cast(doprocessTracksD0sRun3ppMc) + static_cast(doprocessTracksD0sRun3PbPbMc) + static_cast(doprocessTracksLcsRun3pp) + @@ -478,6 +493,18 @@ struct FemtoProducer { builders.sigmaPlusBuilder.fillMcKinks(col, builders.collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, kinkBuilderProducts, kinks, tracks, builders.trackBuilder, mcParticles, builders.mcBuilder, mcProducts); } + // processing sigma plus reconstructed with a PCM photon + template + void processSigmaPlusPcms(T1 const& col, T2 const& tracks, T3 const& sigmaPlusPcms) + { + builders.sigmaPlusPcmBuilder.fillSigmaPlusPcms(col, builders.collisionBuilder, collisionBuilderProducts, trackBuilderProducts, kinkBuilderProducts, sigmaPlusPcms, tracks, builders.trackBuilder); + } + template + void processMcSigmaPlusPcms(T1 const& col, T2 const& mcCols, T3 const& tracks, T4 const& sigmaPlusPcms, T5 const& mcParticles) + { + builders.sigmaPlusPcmBuilder.fillMcSigmaPlusPcms(col, builders.collisionBuilder, collisionBuilderProducts, mcCols, trackBuilderProducts, kinkBuilderProducts, sigmaPlusPcms, tracks, builders.trackBuilder, mcParticles, builders.mcBuilder, mcProducts); + } + // processing cascades template void processCascades(T1 const& col, T2 const& tracks, T3 const& cascades) @@ -720,6 +747,21 @@ struct FemtoProducer { } PROCESS_SWITCH(FemtoProducer, processTracksKinksRun3pp, "Provide tracks and kinks", false); + void processTracksSigmaPlusPcmsRun3pp(rawinputs::Run3PpCollisions::iterator const& col, + o2::aod::BCsWithTimestamps const& bcs, + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3SigmaPlusPcms const& sigmaPlusPcms) + { + if (!processCollisions(col, bcs, tracks)) { + return; + } + auto tracksWithItsPid = o2::soa::Attach(tracks); + processTracks(col, tracksWithItsPid); + processSigmaPlusPcms(col, tracks, sigmaPlusPcms); + } + PROCESS_SWITCH(FemtoProducer, processTracksSigmaPlusPcmsRun3pp, "Provide tracks and sigma plus reconstructed with a PCM photon", false); + void processTracksV0sCascadesKinksRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, rawinputs::Run3FullPidTracks const& tracks, @@ -996,6 +1038,33 @@ struct FemtoProducer { } PROCESS_SWITCH(FemtoProducer, processTracksKinksRun3ppMc, "Provide reconstructed and generated tracks and kinks", false); + void processTracksSigmaPlusPcmsRun3ppMc(rawinputs::Run3PpMcGenCollisions const& mcCols, + rawinputs::Run3PpMcRecoCollisions const& cols, + o2::aod::BCsWithTimestamps const& bcs, + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3RecoSigmaPlusPcms const& sigmaPlusPcms, + rawinputs::Run3McGenParticles const& mcParticles) + { + builders.mcBuilder.reset(mcCols, mcParticles); + if (builders.mcBuilder.isPassThrough()) { + builders.mcBuilder.fillMcPassThrough(mcCols, mcParticles, preslices.perMcCollision, mcProducts); + } + + for (const auto& col : cols) { + auto tracksThisCol = tracks.sliceBy(preslices.perColRecoTracks, col.globalIndex()); + if (!processMcCollisions(col, mcCols, bcs, tracksThisCol)) { + continue; + } + auto tracksWithItsPid = o2::soa::Attach(tracksThisCol); + processMcTracks(col, mcCols, tracksThisCol, tracksWithItsPid, mcParticles); + + auto sigmaPlusPcmsThisCol = sigmaPlusPcms.sliceBy(preslices.perColRecoSigmaPlusPcms, col.globalIndex()); + processMcSigmaPlusPcms(col, mcCols, tracks, sigmaPlusPcmsThisCol, mcParticles); + } + } + PROCESS_SWITCH(FemtoProducer, processTracksSigmaPlusPcmsRun3ppMc, "Provide reconstructed and generated tracks and sigma plus reconstructed with a PCM photon", false); + void processTracksV0sKinksRun3ppMc(rawinputs::Run3PpMcGenCollisions const& mcCols, rawinputs::Run3PpMcRecoCollisions const& cols, o2::aod::BCsWithTimestamps const& bcs, diff --git a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx index a2bc14986b2..2d6b5f1c580 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx @@ -61,11 +61,15 @@ using FemtoOmegas = o2::soa::Join; using FemtoSigma = o2::soa::Join; using FemtoSigmaPlus = o2::soa::Join; using FemtoSigmaPlusExtended = o2::soa::Join; +using FemtoSigmaPlusPcm = o2::soa::Join; +using FemtoSigmaPlusPcmExtended = o2::soa::Join; using FemtoMcTracks = o2::soa::Join; using FemtoMcSigma = o2::soa::Join; using FemtoMcSigmaPlus = o2::soa::Join; using FemtoMcSigmaPlusExtended = o2::soa::Join; +using FemtoMcSigmaPlusPcm = o2::soa::Join; +using FemtoMcSigmaPlusPcmExtended = o2::soa::Join; using FemtoMcParticles = o2::soa::Join; } // namespace femtotables @@ -85,12 +89,16 @@ struct FemtoProducerDerivedToDerived { o2::framework::Preslice perColSigma = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColSigmaPlus = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColSigmaPlusExtended = o2::aod::femtobase::stored::fColId; + o2::framework::Preslice perColSigmaPlusPcm = o2::aod::femtobase::stored::fColId; + o2::framework::Preslice perColSigmaPlusPcmExtended = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColXis = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColOmegas = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColMcTracks = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColMcSigma = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColMcSigmaPlus = o2::aod::femtobase::stored::fColId; o2::framework::Preslice perColMcSigmaPlusExtended = o2::aod::femtobase::stored::fColId; + o2::framework::Preslice perColMcSigmaPlusPcm = o2::aod::femtobase::stored::fColId; + o2::framework::Preslice perColMcSigmaPlusPcmExtended = o2::aod::femtobase::stored::fColId; } preslices; // plain builder helper objects, grouped into a single data member (not Configurable/Partition/ @@ -156,6 +164,10 @@ struct FemtoProducerDerivedToDerived { o2::framework::Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(sigmaPlusSelection1); o2::framework::Partition sigmaPlusExtendedPartition = MAKE_SIGMAPLUS_PARTITION(sigmaPlusSelection1); + kinkbuilder::ConfSigmaPlusPcmSelection1 sigmaPlusPcmSelection1; + o2::framework::Partition sigmaPlusPcmPartition = MAKE_SIGMAPLUSPCM_PARTITION(sigmaPlusPcmSelection1); + o2::framework::Partition sigmaPlusPcmExtendedPartition = MAKE_SIGMAPLUSPCM_PARTITION(sigmaPlusPcmSelection1); + // cascade builder cascadebuilder::CascadeBuilderDerivedToDerivedProducts cascadeBuilderProducts; cascadebuilder::ConfCascadeTablesDerivedToDerived confCascadeBuilder; @@ -178,6 +190,9 @@ struct FemtoProducerDerivedToDerived { o2::framework::Partition mcSigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(sigmaPlusSelection1); o2::framework::Partition mcSigmaPlusExtendedPartition = MAKE_SIGMAPLUS_PARTITION(sigmaPlusSelection1); + o2::framework::Partition mcSigmaPlusPcmPartition = MAKE_SIGMAPLUSPCM_PARTITION(sigmaPlusPcmSelection1); + o2::framework::Partition mcSigmaPlusPcmExtendedPartition = MAKE_SIGMAPLUSPCM_PARTITION(sigmaPlusPcmSelection1); + void init(o2::framework::InitContext& /*context*/) { const int activeProcesses = @@ -187,9 +202,11 @@ struct FemtoProducerDerivedToDerived { static_cast(doprocessTracksXis) + static_cast(doprocessTracksOmegas) + static_cast(doprocessTracksK0shorts) + static_cast(doprocessTracksSigma) + static_cast(doprocessTracksSigmaPlus) + static_cast(doprocessTracksSigmaPlusExtended) + + static_cast(doprocessTracksSigmaPlusPcm) + static_cast(doprocessTracksSigmaPlusPcmExtended) + static_cast(doprocessTracksRho0) + static_cast(doprocessTracksPhi) + static_cast(doprocessTracksMc) + static_cast(doprocessTracksSigmaMc) + - static_cast(doprocessTracksSigmaPlusMc) + static_cast(doprocessTracksSigmaPlusExtendedMc); + static_cast(doprocessTracksSigmaPlusMc) + static_cast(doprocessTracksSigmaPlusExtendedMc) + + static_cast(doprocessTracksSigmaPlusPcmMc) + static_cast(doprocessTracksSigmaPlusPcmExtendedMc); if (activeProcesses != 1) { LOG(fatal) << "Exactly one process function must be activated (got " << activeProcesses << ")."; } @@ -343,6 +360,30 @@ struct FemtoProducerDerivedToDerived { } PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlusExtended, "Process sigmaPlus (with SigmaPlusExtras) and tracks", false); + void processTracksSigmaPlusPcm(femtotables::FilteredFemtoCollision const& col, femtotables::FemtoTracks const& tracks, femtotables::FemtoSigmaPlusPcm const& sigmapluspcm) + { + if (builders.trackBuilder.collisionHasTooFewTracks(col, tracks, trackPartition1, trackPartition2, cache) || builders.kinkBuilder.collisionHasTooFewSigmaPlusPcm(col, sigmapluspcm, sigmaPlusPcmPartition, cache)) { + return; + } + builders.trackBuilder.reset(tracks); + builders.collisionBuilder.processCollision(col, collisionBuilderProducts); + builders.trackBuilder.processTracks(col, tracks, trackPartition1, trackPartition2, cache, trackBuilderProducts, collisionBuilderProducts); + builders.kinkBuilder.processSigmaPlusPcm(col, sigmapluspcm, tracks, sigmaPlusPcmPartition, builders.trackBuilder, cache, kinkBuilderProducts, trackBuilderProducts, collisionBuilderProducts); + } + PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlusPcm, "Process sigmaPlusPcm (with SigmaPlusPcmMlScores, selected on the BDT score) and tracks", false); + + void processTracksSigmaPlusPcmExtended(femtotables::FilteredFemtoCollision const& col, femtotables::FemtoTracks const& tracks, femtotables::FemtoSigmaPlusPcmExtended const& sigmapluspcm) + { + if (builders.trackBuilder.collisionHasTooFewTracks(col, tracks, trackPartition1, trackPartition2, cache) || builders.kinkBuilder.collisionHasTooFewSigmaPlusPcm(col, sigmapluspcm, sigmaPlusPcmExtendedPartition, cache)) { + return; + } + builders.trackBuilder.reset(tracks); + builders.collisionBuilder.processCollision(col, collisionBuilderProducts); + builders.trackBuilder.processTracks(col, tracks, trackPartition1, trackPartition2, cache, trackBuilderProducts, collisionBuilderProducts); + builders.kinkBuilder.processSigmaPlusPcm(col, sigmapluspcm, tracks, sigmaPlusPcmExtendedPartition, builders.trackBuilder, cache, kinkBuilderProducts, trackBuilderProducts, collisionBuilderProducts); + } + PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlusPcmExtended, "Process sigmaPlusPcm (with SigmaPlusPcmMlScores and SigmaPlusPcmExtras, selected on the BDT score) and tracks", false); + void processTracksRho0(femtotables::FilteredFemtoCollision const& col, femtotables::FemtoTracks const& tracks, femtotables::FemtoRho0s const& rho0s) { if (builders.trackBuilder.collisionHasTooFewTracks(col, tracks, trackPartition1, trackPartition2, cache) || builders.resonanceBuilder.collisionHasTooFewRho0s(col, rho0s, rho0Partition, cache)) { @@ -473,6 +514,58 @@ struct FemtoProducerDerivedToDerived { } } PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlusExtendedMc, "Process sigmaPlus (with SigmaPlusExtras) and tracks with MC information", false); + + void processTracksSigmaPlusPcmMc(femtotables::FilteredFemtoMcCollisions const& cols, + femtotables::FemtoMcTracks const& tracks, + femtotables::FemtoMcSigmaPlusPcm const& sigmapluspcm, + o2::aod::FMcCols const& mcCols, + femtotables::FemtoMcParticles const& mcParticles, + o2::aod::FMcMothers const& mcMothers, + o2::aod::FMcPartMoths const& mcPartonicMothers) + { + builders.mcBuilder.reset(mcCols, mcParticles); + + for (auto const& col : cols) { + if (builders.trackBuilder.collisionHasTooFewTracks(col, tracks, mcTrackPartition1, mcTrackPartition2, cache) || builders.kinkBuilder.collisionHasTooFewSigmaPlusPcm(col, sigmapluspcm, mcSigmaPlusPcmPartition, cache)) { + continue; + } + builders.trackBuilder.reset(tracks); + builders.collisionBuilder.processCollision(col, collisionBuilderProducts); + builders.mcBuilder.fillCollisionWithLabel(col, mcCols, mcBuilderProducts); + builders.trackBuilder.processTracksWithMc(col, tracks, mcTrackPartition1, mcTrackPartition2, cache, + trackBuilderProducts, collisionBuilderProducts, + builders.mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcBuilderProducts); + builders.kinkBuilder.processSigmaPlusPcmWithMc(col, sigmapluspcm, tracks, mcSigmaPlusPcmPartition, builders.trackBuilder, cache, kinkBuilderProducts, trackBuilderProducts, collisionBuilderProducts, + builders.mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcBuilderProducts); + } + } + PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlusPcmMc, "Process sigmaPlusPcm (with SigmaPlusPcmMlScores, selected on the BDT score) and tracks with MC information", false); + + void processTracksSigmaPlusPcmExtendedMc(femtotables::FilteredFemtoMcCollisions const& cols, + femtotables::FemtoMcTracks const& tracks, + femtotables::FemtoMcSigmaPlusPcmExtended const& sigmapluspcm, + o2::aod::FMcCols const& mcCols, + femtotables::FemtoMcParticles const& mcParticles, + o2::aod::FMcMothers const& mcMothers, + o2::aod::FMcPartMoths const& mcPartonicMothers) + { + builders.mcBuilder.reset(mcCols, mcParticles); + + for (auto const& col : cols) { + if (builders.trackBuilder.collisionHasTooFewTracks(col, tracks, mcTrackPartition1, mcTrackPartition2, cache) || builders.kinkBuilder.collisionHasTooFewSigmaPlusPcm(col, sigmapluspcm, mcSigmaPlusPcmExtendedPartition, cache)) { + continue; + } + builders.trackBuilder.reset(tracks); + builders.collisionBuilder.processCollision(col, collisionBuilderProducts); + builders.mcBuilder.fillCollisionWithLabel(col, mcCols, mcBuilderProducts); + builders.trackBuilder.processTracksWithMc(col, tracks, mcTrackPartition1, mcTrackPartition2, cache, + trackBuilderProducts, collisionBuilderProducts, + builders.mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcBuilderProducts); + builders.kinkBuilder.processSigmaPlusPcmWithMc(col, sigmapluspcm, tracks, mcSigmaPlusPcmExtendedPartition, builders.trackBuilder, cache, kinkBuilderProducts, trackBuilderProducts, collisionBuilderProducts, + builders.mcBuilder, mcCols, mcParticles, mcMothers, mcPartonicMothers, mcBuilderProducts); + } + } + PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlusPcmExtendedMc, "Process sigmaPlusPcm (with SigmaPlusPcmMlScores and SigmaPlusPcmExtras, selected on the BDT score) and tracks with MC information", false); }; o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) diff --git a/PWGCF/Femto/TableProducer/femtoProducerLiteConverter.cxx b/PWGCF/Femto/TableProducer/femtoProducerLiteConverter.cxx index 3d2c5fe0eef..fe68e9c13ad 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerLiteConverter.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerLiteConverter.cxx @@ -34,6 +34,7 @@ struct FemtoProducerLiteConverter { o2::framework::Produces producedOmegas; o2::framework::Produces producedSigmas; o2::framework::Produces producedSigmaPlus; + o2::framework::Produces producedSigmaPlusPcm; void init(o2::framework::InitContext&) { @@ -138,6 +139,17 @@ struct FemtoProducerLiteConverter { liteSigmaPlus.chaDauId()); } PROCESS_SWITCH(FemtoProducerLiteConverter, processLiteSigmaPlus, "Convert FLiteSigmaPlus to FSigmaPlus", false); + + void processLiteSigmaPlusPcm(o2::aod::FLiteSigmaPlusPcm::iterator const& liteSigmaPlusPcm) + { + producedSigmaPlusPcm(liteSigmaPlusPcm.fLiteColId(), + liteSigmaPlusPcm.signedPt(), + liteSigmaPlusPcm.eta(), + liteSigmaPlusPcm.phi(), + liteSigmaPlusPcm.sigmaMass(), + liteSigmaPlusPcm.chaDauId()); + } + PROCESS_SWITCH(FemtoProducerLiteConverter, processLiteSigmaPlusPcm, "Convert FLiteSigmaPlusPcm to FSigmaPlusPcm", false); }; o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) diff --git a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx index 13d722338de..affa4a1fcff 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx @@ -60,10 +60,12 @@ struct FemtoPairTrackKink { using FemtoTracks = o2::soa::Join; using FemtoSigmas = o2::soa::Join; using FemtoSigmaPlus = o2::soa::Join; + using FemtoSigmaPlusPcm = o2::soa::Join; using FemtoTracksWithLabel = o2::soa::Join; using FemtoSigmasWithLabel = o2::soa::Join; using FemtoSigmaPlusWithLabel = o2::soa::Join; + using FemtoSigmaPlusPcmWithLabel = o2::soa::Join; using FemtoMcParticlesWithLabel = o2::soa::Join; @@ -110,6 +112,17 @@ struct FemtoPairTrackKink { o2::framework::Partition sigmaPlusWithLabelPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); o2::framework::Preslice perColSigmaPlusWithLabel = o2::aod::femtobase::stored::fColId; + // setup for sigma plus reconstructed with a PCM photon + kinkbuilder::ConfSigmaPlusPcmSelection1 confSigmaPlusPcmSelection; + kinkhistmanager::ConfSigmaPlusPcmBinning1 confSigmaPlusPcmBinning; + particlecleaner::ConfSigmaPlusPcmCleaner1 confSigmaPlusPcmCleaner; + + o2::framework::Partition sigmaPlusPcmPartition = MAKE_SIGMAPLUSPCM_PARTITION(confSigmaPlusPcmSelection); + o2::framework::Preslice perColSigmaPlusPcm = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition sigmaPlusPcmWithLabelPartition = MAKE_SIGMAPLUSPCM_PARTITION(confSigmaPlusPcmSelection); + o2::framework::Preslice perColSigmaPlusPcmWithLabel = o2::aod::femtobase::stored::fColId; + // setup pairs pairhistmanager::ConfPairBinning confPairBinning; pairhistmanager::ConfPairCuts confPairCuts; @@ -143,6 +156,20 @@ struct FemtoPairTrackKink { modes::Kink::kSigmaPlus> pairTrackSigmaPlusBuilder; + pairbuilder::PairTrackKinkBuilder< + trackhistmanager::PrefixTrack1Se, + kinkhistmanager::PrefixSigmaPlusPcm1Se, + trackhistmanager::PrefixKinkChaDaughterSe, + trackhistmanager::PrefixTrack1Me, + kinkhistmanager::PrefixSigmaPlusPcm1Me, + trackhistmanager::PrefixKinkChaDaughterMe, + pairhistmanager::PrefixTrackKinkSe, + pairhistmanager::PrefixTrackKinkMe, + closepairrejection::PrefixTrackKinkSe, + closepairrejection::PrefixTrackKinkMe, + modes::Kink::kSigmaPlusPcm> + pairTrackSigmaPlusPcmBuilder; + // setup mixing std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; @@ -159,8 +186,8 @@ struct FemtoPairTrackKink { void init(o2::framework::InitContext&) { - bool processData = doprocessSigmaSameEvent || doprocessSigmaMixedEvent || doprocessSigmaPlusSameEvent || doprocessSigmaPlusMixedEvent; - bool processMc = doprocessSigmaSameEventMc || doprocessSigmaMixedEventMc || doprocessSigmaPlusSameEventMc || doprocessSigmaPlusMixedEventMc; + bool processData = doprocessSigmaSameEvent || doprocessSigmaMixedEvent || doprocessSigmaPlusSameEvent || doprocessSigmaPlusMixedEvent || doprocessSigmaPlusPcmSameEvent || doprocessSigmaPlusPcmMixedEvent; + bool processMc = doprocessSigmaSameEventMc || doprocessSigmaMixedEventMc || doprocessSigmaPlusSameEventMc || doprocessSigmaPlusMixedEventMc || doprocessSigmaPlusPcmSameEventMc || doprocessSigmaPlusPcmMixedEventMc; if (processData && processMc) { LOG(fatal) << "Both data and mc processing is enabled. Breaking..."; @@ -169,9 +196,14 @@ struct FemtoPairTrackKink { bool processSigma = doprocessSigmaSameEvent || doprocessSigmaSameEventMc || doprocessSigmaMixedEvent || doprocessSigmaMixedEventMc; bool processSigmaPlus = doprocessSigmaPlusSameEvent || doprocessSigmaPlusSameEventMc || doprocessSigmaPlusMixedEvent || doprocessSigmaPlusMixedEventMc; + bool processSigmaPlusPcm = doprocessSigmaPlusPcmSameEvent || doprocessSigmaPlusPcmSameEventMc || doprocessSigmaPlusPcmMixedEvent || doprocessSigmaPlusPcmMixedEventMc; + if (processSigma && processSigmaPlus) { LOG(fatal) << "Both Sigma-track and SigmaPlus-track processing is enabled. Breaking..."; } + if ((processSigma || processSigmaPlus) && processSigmaPlusPcm) { + LOG(fatal) << "Both Sigma/SigmaPlus-track and SigmaPlusPcm-track processing is enabled. Breaking..."; + } // setup columnpolicy for binning // default values are used during instantiation, so we need to explicity update them here @@ -184,6 +216,7 @@ struct FemtoPairTrackKink { std::map> chaDauSpec; std::map> sigmaHistSpec; std::map> sigmaPlusHistSpec; + std::map> sigmaPlusPcmHistSpec; std::map> pairTrackKinkHistSpec; std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); std::map> pairCleanerHistSpec = paircleaner::makePairCleanerHistSpecMap(confPairCleaner); @@ -196,9 +229,12 @@ struct FemtoPairTrackKink { if (processSigma) { sigmaHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaBinning); pairTrackSigmaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec, pairCleanerHistSpec); - } else { + } else if (processSigmaPlus) { sigmaPlusHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaPlusBinning); pairTrackSigmaPlusBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec, pairCleanerHistSpec); + } else { + sigmaPlusPcmHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaPlusPcmBinning); + pairTrackSigmaPlusPcmBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusPcmSelection, confSigmaPlusPcmCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusPcmHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec, pairCleanerHistSpec); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -208,9 +244,12 @@ struct FemtoPairTrackKink { if (processSigma) { sigmaHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaBinning); pairTrackSigmaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec, pairCleanerHistSpec); - } else { + } else if (processSigmaPlus) { sigmaPlusHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaPlusBinning); pairTrackSigmaPlusBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec, pairCleanerHistSpec); + } else { + sigmaPlusPcmHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaPlusPcmBinning); + pairTrackSigmaPlusPcmBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusPcmSelection, confSigmaPlusPcmCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusPcmHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec, pairCleanerHistSpec); } } hRegistry.print(); @@ -263,6 +302,30 @@ struct FemtoPairTrackKink { pairTrackSigmaPlusBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusMixedEventMc, "Enable processing mixed event processing for tracks and sigma plus with MC information", false); + + void processSigmaPlusPcmSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoSigmaPlusPcm const& sigmapluspcm) + { + pairTrackSigmaPlusPcmBuilder.processSameEvent(col, tracks, trackPartition, sigmapluspcm, sigmaPlusPcmPartition, cache); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusPcmSameEvent, "Enable processing same event processing for tracks and sigma plus (PCM), selected on the mask and the BDT score", false); + + void processSigmaPlusPcmSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusPcmWithLabel const& sigmapluspcm, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairTrackSigmaPlusPcmBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmapluspcm, sigmaPlusPcmWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusPcmSameEventMc, "Enable processing same event processing for tracks and sigma plus (PCM) with MC information", false); + + void processSigmaPlusPcmMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoSigmaPlusPcm const& /*sigmapluspcm*/) + { + pairTrackSigmaPlusPcmBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPlusPcmPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusPcmMixedEvent, "Enable processing mixed event processing for tracks and sigma plus (PCM), selected on the mask and the BDT score", false); + + void processSigmaPlusPcmMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusPcmWithLabel const& /*sigmapluspcm*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairTrackSigmaPlusPcmBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaPlusPcmWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusPcmMixedEventMc, "Enable processing mixed event processing for tracks and sigma plus (PCM) with MC information", false); }; o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) diff --git a/PWGLF/DataModel/LFKinkDecayTables.h b/PWGLF/DataModel/LFKinkDecayTables.h index db5e3825d43..c636358e20b 100644 --- a/PWGLF/DataModel/LFKinkDecayTables.h +++ b/PWGLF/DataModel/LFKinkDecayTables.h @@ -163,6 +163,12 @@ DECLARE_SOA_TABLE(SlimKinkCandsMC, "AOD", "SLIMKINKCANDSMC", namespace sigmapluscand { +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! Collision of the candidate (the proton's collision), -1 for generated-only MC rows +DECLARE_SOA_INDEX_COLUMN_FULL(ProtonTrack, protonTrack, int, TracksIU, "_Proton"); //! Proton track +DECLARE_SOA_INDEX_COLUMN_FULL(PhotonPosTrack, photonPosTrack, int, TracksIU, "_PosDau"); //! Positive daughter track of the measured photon +DECLARE_SOA_INDEX_COLUMN_FULL(PhotonNegTrack, photonNegTrack, int, TracksIU, "_NegDau"); //! Negative daughter track of the measured photon +DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle of the true Sigma+ if proton and photon come from it, -1 otherwise + DECLARE_SOA_COLUMN(XDecVtx, xDecVtx, float); //! Decay vertex of the candidate (x direction) DECLARE_SOA_COLUMN(YDecVtx, yDecVtx, float); //! Decay vertex of the candidate (y direction) DECLARE_SOA_COLUMN(ZDecVtx, zDecVtx, float); //! Decay vertex of the candidate (z direction) @@ -221,6 +227,7 @@ DECLARE_SOA_COLUMN(PhotonPosTpcNClsFindable, photonPosTpcNClsFindable, int16_t); DECLARE_SOA_COLUMN(PhotonNegTpcNClsFindable, photonNegTpcNClsFindable, int16_t); //! Number of findable TPC clusters of the photon's negative daughter DECLARE_SOA_COLUMN(PhotonPosTpcChi2NCl, photonPosTpcChi2NCl, float); //! TPC chi2 per cluster of the photon's positive daughter DECLARE_SOA_COLUMN(PhotonNegTpcChi2NCl, photonNegTpcChi2NCl, float); //! TPC chi2 per cluster of the photon's negative daughter +DECLARE_SOA_COLUMN(MlScore, mlScore, float); //! BDT score of the candidate (signal probability), -1 if not computed // MC columns DECLARE_SOA_COLUMN(CollisionIdCheck, collisionIdCheck, bool); //! True if the proton's collision ID matches the reconstructed collision ID @@ -281,6 +288,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(YSigmaPlusMC, ySigmaPlusMC, //! True rapidity of the } // namespace sigmapluscand DECLARE_SOA_TABLE(SigmaPlusCands, "AOD", "SIGMAPLUSCANDS", + sigmapluscand::CollisionId, sigmapluscand::ProtonTrackId, sigmapluscand::PhotonPosTrackId, sigmapluscand::PhotonNegTrackId, sigmapluscand::XDecVtx, sigmapluscand::YDecVtx, sigmapluscand::ZDecVtx, sigmapluscand::FlightDistance, sigmapluscand::DcaProtonGamma, sigmapluscand::PxProton, sigmapluscand::PyProton, sigmapluscand::PzProton, @@ -297,6 +305,7 @@ DECLARE_SOA_TABLE(SigmaPlusCands, "AOD", "SIGMAPLUSCANDS", sigmapluscand::PhotonDcaDau, sigmapluscand::PhotonCosPAToPV, sigmapluscand::PhotonDcaXYToPV, sigmapluscand::PhotonDcaZToPV, sigmapluscand::PhotonPsiPair, sigmapluscand::PhotonPosDcaXY, sigmapluscand::PhotonPosDcaZ, sigmapluscand::PhotonNegDcaXY, sigmapluscand::PhotonNegDcaZ, sigmapluscand::PhotonPosTpcNClsFindable, sigmapluscand::PhotonNegTpcNClsFindable, sigmapluscand::PhotonPosTpcChi2NCl, sigmapluscand::PhotonNegTpcChi2NCl, + sigmapluscand::MlScore, // dynamic columns sigmapluscand::Radius, @@ -308,6 +317,8 @@ DECLARE_SOA_TABLE(SigmaPlusCands, "AOD", "SIGMAPLUSCANDS", sigmapluscand::MassSigmaPlus); DECLARE_SOA_TABLE(SigmaPlusCandsMC, "AOD", "SIGMAPLUSMC", + sigmapluscand::CollisionId, sigmapluscand::ProtonTrackId, sigmapluscand::PhotonPosTrackId, sigmapluscand::PhotonNegTrackId, + sigmapluscand::McParticleId, sigmapluscand::XDecVtx, sigmapluscand::YDecVtx, sigmapluscand::ZDecVtx, sigmapluscand::FlightDistance, sigmapluscand::DcaProtonGamma, sigmapluscand::PxProton, sigmapluscand::PyProton, sigmapluscand::PzProton, @@ -324,6 +335,7 @@ DECLARE_SOA_TABLE(SigmaPlusCandsMC, "AOD", "SIGMAPLUSMC", sigmapluscand::PhotonDcaDau, sigmapluscand::PhotonCosPAToPV, sigmapluscand::PhotonDcaXYToPV, sigmapluscand::PhotonDcaZToPV, sigmapluscand::PhotonPsiPair, sigmapluscand::PhotonPosDcaXY, sigmapluscand::PhotonPosDcaZ, sigmapluscand::PhotonNegDcaXY, sigmapluscand::PhotonNegDcaZ, sigmapluscand::PhotonPosTpcNClsFindable, sigmapluscand::PhotonNegTpcNClsFindable, sigmapluscand::PhotonPosTpcChi2NCl, sigmapluscand::PhotonNegTpcChi2NCl, + sigmapluscand::MlScore, sigmapluscand::CollisionIdCheck, sigmapluscand::IsSignal, sigmapluscand::IsProtonFromSigma, sigmapluscand::IsPhotonFromSigma, sigmapluscand::XDecVtxMC, sigmapluscand::YDecVtxMC, sigmapluscand::ZDecVtxMC, @@ -344,6 +356,7 @@ DECLARE_SOA_TABLE(SigmaPlusCandsMC, "AOD", "SIGMAPLUSMC", sigmapluscand::YSigmaPlusMC); DECLARE_SOA_TABLE(SlimSigmaPlusCands, "AOD", "SLIMSIGMAPLUS", + sigmapluscand::CollisionId, sigmapluscand::ProtonTrackId, sigmapluscand::PhotonPosTrackId, sigmapluscand::PhotonNegTrackId, sigmapluscand::TransDecayRadius, sigmapluscand::CandDcaToPV, sigmapluscand::FlightDirTilt, sigmapluscand::DcaProtonGamma, @@ -358,6 +371,7 @@ DECLARE_SOA_TABLE(SlimSigmaPlusCands, "AOD", "SLIMSIGMAPLUS", sigmapluscand::PhotonDcaDau, sigmapluscand::PhotonCosPAToPV, sigmapluscand::PhotonDcaXYToPV, sigmapluscand::PhotonDcaZToPV, sigmapluscand::PhotonPsiPair, sigmapluscand::PhotonPosDcaXY, sigmapluscand::PhotonPosDcaZ, sigmapluscand::PhotonNegDcaXY, sigmapluscand::PhotonNegDcaZ, sigmapluscand::PhotonPosTpcNClsFindable, sigmapluscand::PhotonNegTpcNClsFindable, sigmapluscand::PhotonPosTpcChi2NCl, sigmapluscand::PhotonNegTpcChi2NCl, + sigmapluscand::MlScore, // dynamic columns sigmapluscand::PxSigmaPlus, @@ -367,6 +381,8 @@ DECLARE_SOA_TABLE(SlimSigmaPlusCands, "AOD", "SLIMSIGMAPLUS", sigmapluscand::MassSigmaPlus); DECLARE_SOA_TABLE(SlimSigmaPlusCandsMC, "AOD", "SLIMSIGMAPLUSMC", + sigmapluscand::CollisionId, sigmapluscand::ProtonTrackId, sigmapluscand::PhotonPosTrackId, sigmapluscand::PhotonNegTrackId, + sigmapluscand::McParticleId, sigmapluscand::TransDecayRadius, sigmapluscand::CandDcaToPV, sigmapluscand::FlightDirTilt, sigmapluscand::DcaProtonGamma, @@ -381,6 +397,7 @@ DECLARE_SOA_TABLE(SlimSigmaPlusCandsMC, "AOD", "SLIMSIGMAPLUSMC", sigmapluscand::PhotonDcaDau, sigmapluscand::PhotonCosPAToPV, sigmapluscand::PhotonDcaXYToPV, sigmapluscand::PhotonDcaZToPV, sigmapluscand::PhotonPsiPair, sigmapluscand::PhotonPosDcaXY, sigmapluscand::PhotonPosDcaZ, sigmapluscand::PhotonNegDcaXY, sigmapluscand::PhotonNegDcaZ, sigmapluscand::PhotonPosTpcNClsFindable, sigmapluscand::PhotonNegTpcNClsFindable, sigmapluscand::PhotonPosTpcChi2NCl, sigmapluscand::PhotonNegTpcChi2NCl, + sigmapluscand::MlScore, sigmapluscand::CollisionIdCheck, sigmapluscand::IsSignal, sigmapluscand::IsProtonFromSigma, sigmapluscand::IsPhotonFromSigma, sigmapluscand::DecayRadiusMC, sigmapluscand::MassMC, diff --git a/PWGLF/TableProducer/Strangeness/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/CMakeLists.txt index e892688ebb4..a0a64e95190 100644 --- a/PWGLF/TableProducer/Strangeness/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/CMakeLists.txt @@ -106,7 +106,7 @@ o2physics_add_dpl_workflow(sigmaminus-task # o2-linter: disable=name/o2-workflow o2physics_add_dpl_workflow(sigmaplusbuilder SOURCES sigmaplusbuilder.cxx REUSE_FROM LfStrangenessPCH - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(strange-tree-creator diff --git a/PWGLF/TableProducer/Strangeness/sigmaplusbuilder.cxx b/PWGLF/TableProducer/Strangeness/sigmaplusbuilder.cxx index e9df7b7e324..9d342f942f8 100644 --- a/PWGLF/TableProducer/Strangeness/sigmaplusbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/sigmaplusbuilder.cxx @@ -26,8 +26,10 @@ #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "Tools/ML/MlResponse.h" #include +#include #include #include #include @@ -60,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +119,7 @@ struct Sigmaplusbuilder { Configurable protonRequireTofHit{"protonRequireTofHit", false, "Above protonPtMinRequireTOF, reject a proton with no TOF hit at all"}; Configurable protonMinDcaToPV{"protonMinDcaToPV", 0.005, "Min DCAxy of the proton track to the PV (cm)"}; Configurable protonMaxDcaToPV{"protonMaxDcaToPV", 5.0, "Max DCAxy of the proton track to the PV (cm)"}; + Configurable protonMaxDcaZToPV{"protonMaxDcaZToPV", 0.3, "Max |DCAz| of the proton track to the PV (cm)"}; // proton-photon candidate selection Configurable candVertexProtonWeight{"candVertexProtonWeight", 1.0, "Sigma+ vertex between the proton's (1) and the photon's (0) point of closest approach"}; @@ -134,11 +138,12 @@ struct Sigmaplusbuilder { Configurable candMaxPhotonOpeningAngle{"candMaxPhotonOpeningAngle", 3.15, "Max photon opening angle (rad), recomputed from the daughters' track momenta"}; Configurable candMaxPhotonPointingAngle{"candMaxPhotonPointingAngle", 0.5, "Max angle between the photon momentum and the decay-vertex-to-conversion-point line (rad)"}; Configurable candMaxPhotonDcaToPV{"candMaxPhotonDcaToPV", 250.0, "Max DCA of the photon's flight line to the PV (cm)"}; + Configurable candMaxPhotonDcaZToPV{"candMaxPhotonDcaZToPV", 2.0, "Max |DCAz| of the photon's flight line to the PV at its transverse DCA (cm), applied to the photon before the pairing with the proton"}; Configurable candDeduplicatePhotons{"candDeduplicatePhotons", true, "Per timeframe, write only the candidate with the smallest DCA to PV among candidates sharing the same photon"}; // tilt search: if the measured flight direction gives no real solution for the missing photon, // tilted flight directions are tried starting with the smallest tilt - Configurable candMaxTilt{"candMaxTilt", 0.3, "Max tilt of the flight direction searched for a real root (rad)"}; + Configurable candMaxTilt{"candMaxTilt", 0.05, "Max tilt of the flight direction searched for a real root (rad)"}; Configurable candTiltStep{"candTiltStep", 0.005, "Tilt step between the rings of tried flight directions (rad)"}; Configurable candTiltNAzimuth{"candTiltNAzimuth", 36, "Flight directions tried per ring"}; @@ -148,6 +153,13 @@ struct Sigmaplusbuilder { Configurable fillSlimTables{"fillSlimTables", false, "write the slim candidate tables instead of the full ones"}; + // BDT score (MlScore column) of every written candidate, inputs in the order of the training (see computeMlScore) + Configurable applyMl{"applyMl", false, "Compute the BDT score of every written candidate (otherwise MlScore = -1)"}; + Configurable mlLoadModelFromCcdb{"mlLoadModelFromCcdb", true, "Load the ONNX model from the CCDB instead of a local file"}; + Configurable mlModelPathCcdb{"mlModelPathCcdb", "Users/h/hfribert/SigmaPlusPcm/BDT_nominalB", "CCDB path of the ONNX model (nominal field: .../BDT_nominalB, low field: .../BDT_lowB)"}; + Configurable mlOnnxFileName{"mlOnnxFileName", "model.onnx", "ONNX file name (local file, or name of the file retrieved from the CCDB)"}; + Configurable mlTimestampCcdb{"mlTimestampCcdb", -1, "CCDB timestamp of the ONNX model (-1: now)"}; + Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "CCDB path of the material budget LUT"}; @@ -163,6 +175,7 @@ struct Sigmaplusbuilder { float mBz = 0; o2::base::MatLayerCylSet* mLut = nullptr; o2::aod::common::TPCVDriftManager mVDriftMgr; + o2::analysis::MlResponse mlResponse; // daughter pairing (electrons and positrons with the range of collisions each is compatible with) svPoolCreator svPhotonPoolCreator{PDG_t::kElectron, PDG_t::kPositron}; @@ -173,6 +186,10 @@ struct Sigmaplusbuilder { // values of a candidate, kept until the end of the timeframe and then written to the tables struct SigmaPlusCandidate { uint64_t photonId = 0; + int collisionId = -1; + int protonTrackId = -1; + int photonPosTrackId = -1; + int photonNegTrackId = -1; bool isSignal = false; int photonLegsWithoutIts = 0; int matchedSigmaId = -1; @@ -257,6 +274,19 @@ struct Sigmaplusbuilder { fitter.setUseAbsDCA(true); mVDriftMgr.init(&ccdb->instance()); + if (applyMl) { + // one model with two classes (background, signal) and no cut on the scores + const std::array noCuts{0., 0.}; + mlResponse.configure({0., 1.e6}, LabeledArray(noCuts.data(), 1, 2), {o2::cuts_ml::CutNot, o2::cuts_ml::CutNot}, 2); + if (mlLoadModelFromCcdb) { + o2::ccdb::CcdbApi ccdbApi; + ccdbApi.init(ccdbPath.value); + mlResponse.setModelPathsCCDB({mlOnnxFileName.value}, ccdbApi, {mlModelPathCcdb.value}, mlTimestampCcdb.value); + } else { + mlResponse.setModelPathsLocal({mlOnnxFileName.value}); + } + mlResponse.init(); + } svPhotonPoolCreator.setTimeMargin(photonPoolTimeMarginNS); if (photonSkipAmbiTracks) { svPhotonPoolCreator.setSkipAmbiTracks(); @@ -302,7 +332,7 @@ struct Sigmaplusbuilder { const AxisSpec axisSigmaSel{6, -0.5, 5.5, "step"}; const std::vector photonSteps{"All", "Neg eta", "Pos eta", "TPC clusters", "TPC nSigma_{el}, p_{T}", "DCA daughters", "Radius", - "Opening angle", "Delta theta", "CosPA", "Rapidity", "Qt", "Alpha", "Mass"}; + "Opening angle", "Delta theta", "CosPA, DCA_{z}", "Rapidity", "Qt", "Alpha", "Mass"}; const std::vector protonSteps{"All", "Pt", "Eta", "TPC clusters", "TPC nSigma", "TOF nSigma", "DCA to PV"}; const std::vector candSteps{"All pairs", "Autocorrelation", "Vertex fit", "DCA(p,#gamma)", "Radius", "Flight distance", "Real root", "Valid root", "DCA to PV", "Mass", "Rapidity", "Photon opening angle", "Photon pointing angle", "Photon DCA to PV", "Written"}; @@ -417,6 +447,14 @@ struct Sigmaplusbuilder { TTrack posTrack; }; + // longitudinal distance of the photon's flight line to the PV at its transverse DCA (cm) + static float photonDcaZ(const std::array& conv, const std::array& pGamma, const std::array& pv) + { + float pt2 = pGamma[0] * pGamma[0] + pGamma[1] * pGamma[1]; + float tAtDcaXY = pt2 > 0.f ? ((pv[0] - conv[0]) * pGamma[0] + (pv[1] - conv[1]) * pGamma[1]) / pt2 : 0.f; + return conv[2] + tAtDcaXY * pGamma[2] - pv[2]; + } + // MC counter of generated Sigma+ -> p pi0 in acceptance void fillSigmaCounter(int sigmaId, int step) { @@ -536,7 +574,7 @@ struct Sigmaplusbuilder { std::array pGamma{pNeg[0] + pPos[0], pNeg[1] + pPos[1], pNeg[2] + pPos[2]}; float cosPA = RecoDecay::cpa(pv, secVtx, pGamma); - if (cosPA < photonMinV0cospa) { + if (cosPA < photonMinV0cospa || std::abs(photonDcaZ(secVtx, pGamma, pv)) > candMaxPhotonDcaZToPV) { continue; } fillPhotonStep(9); @@ -923,8 +961,9 @@ struct Sigmaplusbuilder { passStep(8); // opening angle, and delta theta that is cut before the fit std::array pGamma{fit.pNeg[0] + fit.pPos[0], fit.pNeg[1] + fit.pPos[1], fit.pNeg[2] + fit.pPos[2]}; - float cosPA = RecoDecay::cpa(std::array{collision.posX(), collision.posY(), collision.posZ()}, fit.secVtx, pGamma); - if (cosPA < photonMinV0cospa) { + std::array pv{collision.posX(), collision.posY(), collision.posZ()}; + float cosPA = RecoDecay::cpa(pv, fit.secVtx, pGamma); + if (cosPA < photonMinV0cospa || std::abs(photonDcaZ(fit.secVtx, pGamma, pv)) > candMaxPhotonDcaZToPV) { continue; } passStep(9); @@ -1034,7 +1073,7 @@ struct Sigmaplusbuilder { fillProtonStep(5); fillProtonHist(HIST("h2DcaToPVVsPt"), isSignal, track.pt(), std::abs(track.dcaXY())); - if (std::abs(track.dcaXY()) < protonMinDcaToPV || std::abs(track.dcaXY()) > protonMaxDcaToPV) { + if (std::abs(track.dcaXY()) < protonMinDcaToPV || std::abs(track.dcaXY()) > protonMaxDcaToPV || std::abs(track.dcaZ()) > protonMaxDcaZToPV) { return false; } fillProtonStep(6); @@ -1181,7 +1220,7 @@ struct Sigmaplusbuilder { // Build a Sigma+ -> p pi0 candidate from a proton track and a PCM photon template - void buildSigmaPlusCandidate(const TTrack& protonTrack, const PhotonCand& photon, const std::array& pv) + void buildSigmaPlusCandidate(const TTrack& protonTrack, const PhotonCand& photon, int collisionIndex, const std::array& pv) { auto posTrack = photon.posTrack; auto negTrack = photon.negTrack; @@ -1508,19 +1547,22 @@ struct Sigmaplusbuilder { std::array pvToConvCrossDir = cross3(pvToConv, photonDir); float photonDcaToPV = std::sqrt(dot3(pvToConvCrossDir, pvToConvCrossDir)); fillCandHist(HIST("hPhotonDcaToPV"), isSignal, photonDcaToPV); - if (photonDcaToPV > candMaxPhotonDcaToPV) { - return; - } - fillCandStep(13); // photon DCA to PV - float photonPt2 = photon.px * photon.px + photon.py * photon.py; float tAtDcaXY = photonPt2 > 0.f ? ((pv[0] - photon.x) * photon.px + (pv[1] - photon.y) * photon.py) / photonPt2 : 0.f; float photonDcaXYToPV = std::hypot(photon.x + tAtDcaXY * photon.px - pv[0], photon.y + tAtDcaXY * photon.py - pv[1]); float photonDcaZToPV = photon.z + tAtDcaXY * photon.pz - pv[2]; + if (photonDcaToPV > candMaxPhotonDcaToPV || std::abs(photonDcaZToPV) > candMaxPhotonDcaZToPV) { + return; + } + fillCandStep(13); // photon DCA to PV float psiPair = photonPsiPair(posTrack, negTrack, photon.radius); SigmaPlusCandidate cand; cand.photonId = photonId(posTrack.globalIndex(), negTrack.globalIndex()); + cand.collisionId = collisionIndex; + cand.protonTrackId = protonTrack.globalIndex(); + cand.photonPosTrackId = posTrack.globalIndex(); + cand.photonNegTrackId = negTrack.globalIndex(); cand.isSignal = isSignal; cand.photonLegsWithoutIts = photonLegsWithoutIts; cand.matchedSigmaId = matchedSigmaId; @@ -1579,12 +1621,25 @@ struct Sigmaplusbuilder { mCandidatesOfTimeframe.push_back(cand); } + // BDT score + float computeMlScore(const SigmaPlusCandidate& cand) + { + constexpr float NoTofNSigmaThreshold = -900.f; // tofNSigma is -999 without TOF, NaN for the BDT + std::vector inputs{std::abs(cand.photonDcaZToPV), std::abs(cand.protonDcaXY), std::abs(cand.protonDcaZ), cand.dcaToPV, + cand.protonTpcNSigma, cand.protonTofNSigma < NoTofNSigmaThreshold ? std::numeric_limits::quiet_NaN() : cand.protonTofNSigma, + cand.antiSigmaPointingAngle, cand.dcaProtonGamma, cand.photonDcaXYToPV, cand.photonCosPAToPV, cand.tiltAngle}; + return mlResponse.getModelOutput(inputs, 0)[1]; + } + template void fillCandidateTables(const SigmaPlusCandidate& cand) { + const float mlScore = applyMl ? computeMlScore(cand) : -1.f; if constexpr (IsMC) { if (fillSlimTables) { - slimSigmaPlusCandsMC(cand.radius, + slimSigmaPlusCandsMC(cand.collisionId, cand.protonTrackId, cand.photonPosTrackId, cand.photonNegTrackId, + cand.matchedSigmaId, + cand.radius, cand.dcaToPV, cand.tiltAngle, cand.dcaProtonGamma, cand.protonSign, cand.protonDcaXY, cand.protonDcaZ, @@ -1597,13 +1652,16 @@ struct Sigmaplusbuilder { cand.photonDcaDau, cand.photonCosPAToPV, cand.photonDcaXYToPV, cand.photonDcaZToPV, cand.photonPsiPair, cand.posDcaXY, cand.posDcaZ, cand.negDcaXY, cand.negDcaZ, cand.posTpcNClsFindable, cand.negTpcNClsFindable, cand.posTpcChi2NCl, cand.negTpcChi2NCl, + mlScore, cand.collisionIdCheck, cand.isSignal, cand.protonIsSignal, cand.photonIsSignal, cand.decayRadiusMC, cand.massMC, cand.pSigmaPlusMC[0], cand.pSigmaPlusMC[1], cand.pSigmaPlusMC[2]); return; } - sigmaPlusCandsMC(cand.decVtx[0], cand.decVtx[1], cand.decVtx[2], + sigmaPlusCandsMC(cand.collisionId, cand.protonTrackId, cand.photonPosTrackId, cand.photonNegTrackId, + cand.matchedSigmaId, + cand.decVtx[0], cand.decVtx[1], cand.decVtx[2], cand.flightDistance, cand.dcaProtonGamma, cand.pProton[0], cand.pProton[1], cand.pProton[2], cand.pGamma1[0], cand.pGamma1[1], cand.pGamma1[2], @@ -1619,6 +1677,7 @@ struct Sigmaplusbuilder { cand.photonDcaDau, cand.photonCosPAToPV, cand.photonDcaXYToPV, cand.photonDcaZToPV, cand.photonPsiPair, cand.posDcaXY, cand.posDcaZ, cand.negDcaXY, cand.negDcaZ, cand.posTpcNClsFindable, cand.negTpcNClsFindable, cand.posTpcChi2NCl, cand.negTpcChi2NCl, + mlScore, cand.collisionIdCheck, cand.isSignal, cand.protonIsSignal, cand.photonIsSignal, cand.decVtxMC[0], cand.decVtxMC[1], cand.decVtxMC[2], @@ -1628,7 +1687,8 @@ struct Sigmaplusbuilder { cand.decayRadiusMC, cand.massMC); } else { if (fillSlimTables) { - slimSigmaPlusCands(cand.radius, + slimSigmaPlusCands(cand.collisionId, cand.protonTrackId, cand.photonPosTrackId, cand.photonNegTrackId, + cand.radius, cand.dcaToPV, cand.tiltAngle, cand.dcaProtonGamma, cand.protonSign, cand.protonDcaXY, cand.protonDcaZ, @@ -1640,10 +1700,12 @@ struct Sigmaplusbuilder { cand.photonMass, cand.photonDcaDau, cand.photonCosPAToPV, cand.photonDcaXYToPV, cand.photonDcaZToPV, cand.photonPsiPair, cand.posDcaXY, cand.posDcaZ, cand.negDcaXY, cand.negDcaZ, - cand.posTpcNClsFindable, cand.negTpcNClsFindable, cand.posTpcChi2NCl, cand.negTpcChi2NCl); + cand.posTpcNClsFindable, cand.negTpcNClsFindable, cand.posTpcChi2NCl, cand.negTpcChi2NCl, + mlScore); return; } - sigmaPlusCands(cand.decVtx[0], cand.decVtx[1], cand.decVtx[2], + sigmaPlusCands(cand.collisionId, cand.protonTrackId, cand.photonPosTrackId, cand.photonNegTrackId, + cand.decVtx[0], cand.decVtx[1], cand.decVtx[2], cand.flightDistance, cand.dcaProtonGamma, cand.pProton[0], cand.pProton[1], cand.pProton[2], cand.pGamma1[0], cand.pGamma1[1], cand.pGamma1[2], @@ -1658,11 +1720,12 @@ struct Sigmaplusbuilder { cand.posItsNCls, cand.posTpcNCls, cand.negItsNCls, cand.negTpcNCls, cand.photonDcaDau, cand.photonCosPAToPV, cand.photonDcaXYToPV, cand.photonDcaZToPV, cand.photonPsiPair, cand.posDcaXY, cand.posDcaZ, cand.negDcaXY, cand.negDcaZ, - cand.posTpcNClsFindable, cand.negTpcNClsFindable, cand.posTpcChi2NCl, cand.negTpcChi2NCl); + cand.posTpcNClsFindable, cand.negTpcNClsFindable, cand.posTpcChi2NCl, cand.negTpcChi2NCl, + mlScore); } } - // The same photon can be in candidates of several collisions (with candDeduplicatePhotons only the one with the smallest DCA to PV is written) + // The same photon can be in candidates of several collisions template void deduplicateAndWriteCandidates() { @@ -1760,7 +1823,7 @@ struct Sigmaplusbuilder { for (const auto& photon : acceptedPhotons) { for (const auto& proton : acceptedProtons) { - buildSigmaPlusCandidate(proton, photon, pv); + buildSigmaPlusCandidate(proton, photon, collision.globalIndex(), pv); } } } @@ -1847,7 +1910,7 @@ struct Sigmaplusbuilder { for (const auto& photon : acceptedPhotons) { for (const auto& proton : acceptedProtons) { - buildSigmaPlusCandidate(proton, photon, pv); + buildSigmaPlusCandidate(proton, photon, collision.globalIndex(), pv); } } } @@ -1874,7 +1937,9 @@ struct Sigmaplusbuilder { float genMassMC = std::sqrt(mcPart.e() * mcPart.e() - mcPart.p() * mcPart.p()); if (fillSlimTables) { - slimSigmaPlusCandsMC(-999.f, + slimSigmaPlusCandsMC(-1, -1, -1, -1, + mcPart.globalIndex(), + -999.f, -999.f, -999.f, -999.f, 0, -999.f, -999.f, @@ -1887,6 +1952,7 @@ struct Sigmaplusbuilder { -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, 0, 0, -999.f, -999.f, + -1.f, false, false, false, false, genDecayRadiusMC, genMassMC, @@ -1894,7 +1960,9 @@ struct Sigmaplusbuilder { continue; } - sigmaPlusCandsMC(-999.f, -999.f, -999.f, + sigmaPlusCandsMC(-1, -1, -1, -1, + mcPart.globalIndex(), + -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, @@ -1910,6 +1978,7 @@ struct Sigmaplusbuilder { -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, -999.f, 0, 0, -999.f, -999.f, + -1.f, false, false, false, false, genDecVtx[0], genDecVtx[1], genDecVtx[2],