diff --git a/PWGLF/Tasks/Strangeness/strangeCascTrack.cxx b/PWGLF/Tasks/Strangeness/strangeCascTrack.cxx index de8e38ecbfb..4f2c3dea4d0 100644 --- a/PWGLF/Tasks/Strangeness/strangeCascTrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangeCascTrack.cxx @@ -65,6 +65,7 @@ struct StrangeCascTrack { PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; PresliceUnsorted cascsPerMcCollision = aod::cascdata::straMCCollisionId; + Preslice cascsPerCollision = aod::cascdata::straCollisionId; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -122,10 +123,9 @@ struct StrangeCascTrack { Configurable cutMaxV0CosPA{"cutMaxV0CosPA", 1.1f, "max V0 cosPA"}; Configurable cutMinBachCosPA{"cutMinBachCosPA", -1.1f, "min Bachelor cosPA"}; Configurable cutMaxBachCosPA{"cutMaxBachCosPA", 1.1f, "max Bachelor cosPA"}; - Configurable> cutMinCascCosPaVsPt{ - "cutMinCascCosPaVsPt", - {0.993, 0.993, 0.994, 0.995, 0.996, 0.997, 0.997, 0.998, 0.998, 0.999, 0.999}, - "Min Casc CosPA per pT bin (same binning as axisPt)"}; + Configurable> cutMinCascCosPaVsPt{"cutMinCascCosPaVsPt", + {0.993, 0.993, 0.994, 0.995, 0.996, 0.997, 0.997, 0.998, 0.998, 0.999, 0.999}, + "Min Casc CosPA per pT bin (same binning as axisPt)"}; Configurable cutRapidity{"cutRapidity", 0.5f, "max rapidity"}; Configurable cutDauEta{"cutDauEta", 1.0f, "max eta of dau tracks"}; Configurable cutCompMassRej{"cutCompMassRej", 0.008f, "Competing mass rejection"}; @@ -407,333 +407,367 @@ struct StrangeCascTrack { } // applies selections for and fills histograms - template - void analyseCascs(TEvent collision, TCascs cascades) + template + void analyseCascade(TEvent collision, TCasc cascade) { - int64_t casccollid = 0; - for (auto const& cascade : cascades) { + if constexpr (requires { cascade.topologyChi2(); }) { + if (!cascade.has_standardCascade()) + return; // safety check: dismisses tracked cascades without proper reference + } + // for tracked cascades, make a reference to standard table + auto stdCasc = [&]() { if constexpr (requires { cascade.topologyChi2(); }) { - if (!cascade.has_standardCascade()) - continue; // safety check: dismisses tracked cascades without proper reference - } - - // for tracked cascades, make a reference to standard table - auto stdCasc = [&]() { - if constexpr (requires { cascade.topologyChi2(); }) { - if constexpr (requires { collision.straMCCollisionId(); }) { - return cascade.template standardCascade_as(); - } else { - return cascade.template standardCascade_as(); - } - } else { - return cascade; - } - }(); - - // Type 1 for tracked cascades, Type 0 for standard - static constexpr int Type = [&]() { - if constexpr (requires { cascade.topologyChi2(); }) { - return 1; + if constexpr (requires { collision.straMCCollisionId(); }) { + return cascade.template standardCascade_as(); } else { - return 0; + return cascade.template standardCascade_as(); } - }(); - - double mult = (doProcessIons) ? collision.centFT0C() : collision.centFT0M(); // ion collisions use FT0C for multiplicity, pp uses both + } else { + return cascade; + } + }(); - // fill multiplicity for events with >=1 cascade - if (collision.index() != casccollid) { - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/EvMult"), mult); - if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "Xi") || isMCTruth(stdCasc, "Omega")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/EvMult"), mult); - } - } - casccollid = collision.index(); + // Type 1 for tracked cascades, Type 0 for standard + static constexpr int Type = [&]() { + if constexpr (requires { cascade.topologyChi2(); }) { + return 1; + } else { + return 0; } + }(); - double massXi = cascade.mXi(); - double massOmega = cascade.mOmega(); - double pt = cascade.pt(); - double v0cosPA = cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); - double casccosPA = cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()); - double bachEta = cascade.bacheloreta(); - double negEta = cascade.negativeeta(); - double posEta = cascade.positiveeta(); + double mult = (doProcessIons) ? collision.centFT0C() : collision.centFT0M(); // ion collisions use FT0C for multiplicity, pp uses both - // fill filters for no cascade selections - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PropDCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/V0CosPA"), v0cosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/CascCosPA"), casccosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/RapidityXi"), cascade.yXi()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PtVsRapidityXi"), pt, cascade.yXi()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/RapidityOmega"), cascade.yOmega()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PtVsRapidityOmega"), pt, cascade.yOmega()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/EtaDau"), bachEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/EtaDau"), negEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/EtaDau"), posEta); - // fill inv mass for no cascade selections - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/MassXi"), massXi); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/MassOmega"), massOmega); - // fill filters and inv mass for no cascade selections (MC truth) - if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "Xi") || isMCTruth(stdCasc, "Omega")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/PropDCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/V0CosPA"), v0cosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/CascCosPA"), casccosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/EtaDau"), bachEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/EtaDau"), negEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/EtaDau"), posEta); - if (isMCTruth(stdCasc, "Xi")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/RapidityXi"), cascade.yXi()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/MassXi"), massXi); - } - if (isMCTruth(stdCasc, "Omega")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/RapidityOmega"), cascade.yOmega()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); - } - } - } - // start checking selections - bool passedAllSelsXi = true; - bool passedAllSelsOmega = true; - bool fillTruthXi = false; - bool fillTruthOmega = false; - if constexpr (requires { collision.straMCCollisionId(); }) { + double massXi = cascade.mXi(); + double massOmega = cascade.mOmega(); + double pt = cascade.pt(); + double v0cosPA = cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + double casccosPA = cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()); + double bachEta = cascade.bacheloreta(); + double negEta = cascade.negativeeta(); + double posEta = cascade.positiveeta(); + + // fill filters for no cascade selections + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PropDCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/V0CosPA"), v0cosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/CascCosPA"), casccosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/RapidityXi"), cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PtVsRapidityXi"), pt, cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/RapidityOmega"), cascade.yOmega()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/PtVsRapidityOmega"), pt, cascade.yOmega()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/EtaDau"), bachEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/EtaDau"), negEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/Filters/EtaDau"), posEta); + // fill inv mass for no cascade selections + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/MassXi"), massXi); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/MassOmega"), massOmega); + // fill filters and inv mass for no cascade selections (MC truth) + if constexpr (requires { collision.straMCCollisionId(); }) { + if (isMCTruth(stdCasc, "Xi") || isMCTruth(stdCasc, "Omega")) { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/PropDCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/V0CosPA"), v0cosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/CascCosPA"), casccosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/EtaDau"), bachEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/EtaDau"), negEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/EtaDau"), posEta); if (isMCTruth(stdCasc, "Xi")) { - fillTruthXi = true; + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/RapidityXi"), cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/MassXi"), massXi); } - } - if constexpr (requires { collision.straMCCollisionId(); }) { if (isMCTruth(stdCasc, "Omega")) { - fillTruthOmega = true; + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/Filters/RapidityOmega"), cascade.yOmega()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); } } - // apply pt cuts - if (doApplyPtCutsXi) { - if (isValidPt(cascade, "Xi", Type)) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 0.5); - if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 0.5); - } else { - passedAllSelsXi = false; - } + } + // start checking selections + bool passedAllSelsXi = true; + bool passedAllSelsOmega = true; + bool fillTruthXi = false; + bool fillTruthOmega = false; + if constexpr (requires { collision.straMCCollisionId(); }) { + if (isMCTruth(stdCasc, "Xi")) { + fillTruthXi = true; } - if (doApplyPtCutsOmega) { - if (isValidPt(cascade, "Omega", Type)) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 0.5); - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 0.5); - } else { - passedAllSelsOmega = false; - } + } + if constexpr (requires { collision.straMCCollisionId(); }) { + if (isMCTruth(stdCasc, "Omega")) { + fillTruthOmega = true; } - // apply general cascade cuts - if (doApplyGenCutsXi) { - auto genSels = isValidCasc(collision, cascade, stdCasc, "Xi"); - for (size_t i = 0; i < std::size(genSels); ++i) { - if (genSels[i]) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenFiltersXi"), (i + 0.5)); - if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenFiltersXi"), (i + 0.5)); - } - } - if (genSels[std::size(genSels) - 1]) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 1.5); - if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 1.5); - } else { - passedAllSelsXi = false; - } + } + // apply pt cuts + if (doApplyPtCutsXi) { + if (isValidPt(cascade, "Xi", Type)) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 0.5); + if (fillTruthXi) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 0.5); + } else { + passedAllSelsXi = false; } - if (doApplyGenCutsOmega) { - auto genSels = isValidCasc(collision, cascade, stdCasc, "Omega"); - for (size_t i = 0; i < std::size(genSels); ++i) { - if (genSels[i]) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenFiltersOmega"), (i + 0.5)); - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenFiltersOmega"), (i + 0.5)); - } - } - if (genSels[std::size(genSels) - 1]) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 1.5); - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 1.5); - } else { - passedAllSelsOmega = false; - } + } + if (doApplyPtCutsOmega) { + if (isValidPt(cascade, "Omega", Type)) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 0.5); + if (fillTruthOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 0.5); + } else { + passedAllSelsOmega = false; } - // apply tpc pid - if (doApplyTPCPIDXi) { - if (passesTPC(stdCasc, "Xi")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 2.5); + } + // apply general cascade cuts + if (doApplyGenCutsXi) { + auto genSels = isValidCasc(collision, cascade, stdCasc, "Xi"); + for (size_t i = 0; i < std::size(genSels); ++i) { + if (genSels[i]) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenFiltersXi"), (i + 0.5)); if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 2.5); - } else { - passedAllSelsXi = false; + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenFiltersXi"), (i + 0.5)); } } - if (doApplyTPCPIDOmega) { - if (passesTPC(stdCasc, "Omega")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 2.5); + if (genSels[std::size(genSels) - 1]) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 1.5); + if (fillTruthXi) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 1.5); + } else { + passedAllSelsXi = false; + } + } + if (doApplyGenCutsOmega) { + auto genSels = isValidCasc(collision, cascade, stdCasc, "Omega"); + for (size_t i = 0; i < std::size(genSels); ++i) { + if (genSels[i]) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenFiltersOmega"), (i + 0.5)); if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 2.5); - } else { - passedAllSelsOmega = false; + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenFiltersOmega"), (i + 0.5)); } } - // apply tof pid - if (doApplyTOFPIDXi) { - if (passesTOF(stdCasc, "Xi")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 3.5); - if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 3.5); - } else { - passedAllSelsXi = false; - } + if (genSels[std::size(genSels) - 1]) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 1.5); + if (fillTruthOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 1.5); + } else { + passedAllSelsOmega = false; } - if (doApplyTOFPIDOmega) { - if (passesTOF(stdCasc, "Omega")) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 3.5); - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 3.5); - } else { - passedAllSelsOmega = false; - } + } + // apply tpc pid + if (doApplyTPCPIDXi) { + if (passesTPC(stdCasc, "Xi")) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 2.5); + if (fillTruthXi) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 2.5); + } else { + passedAllSelsXi = false; } - // apply competing mass rej - if (doCompetingMassRej) { - if ((std::abs(massXi - o2::constants::physics::MassXiMinus) > cascCuts.cutCompMassRej)) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 4.5); - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 4.5); - } else { - passedAllSelsOmega = false; - } + } + if (doApplyTPCPIDOmega) { + if (passesTPC(stdCasc, "Omega")) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 2.5); + if (fillTruthOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 2.5); + } else { + passedAllSelsOmega = false; } - - // fil rec histograms - if (passedAllSelsXi || passedAllSelsOmega) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/EvMult"), mult); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PropDCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/V0CosPA"), v0cosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/CascCosPA"), casccosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/EtaDau"), bachEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/EtaDau"), negEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/EtaDau"), posEta); - if (passedAllSelsXi) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/RapidityXi"), cascade.yXi()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PtVsRapidityXi"), pt, cascade.yXi()); - } - if (passedAllSelsOmega) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/RapidityOmega"), cascade.yOmega()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PtVsRapidityOmega"), pt, cascade.yOmega()); - } - if (fillTruthXi || fillTruthOmega) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/EvMult"), mult); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/PropDCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/V0CosPA"), v0cosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/CascCosPA"), casccosPA); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/EtaDau"), bachEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/EtaDau"), negEta); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/EtaDau"), posEta); - if (passedAllSelsXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/RapidityXi"), cascade.yXi()); - if (passedAllSelsOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/RapidityOmega"), cascade.yOmega()); - } + } + // apply tof pid + if (doApplyTOFPIDXi) { + if (passesTOF(stdCasc, "Xi")) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 3.5); + if (fillTruthXi) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 3.5); + } else { + passedAllSelsXi = false; + } + } + if (doApplyTOFPIDOmega) { + if (passesTOF(stdCasc, "Omega")) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 3.5); + if (fillTruthOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 3.5); + } else { + passedAllSelsOmega = false; + } + } + // apply competing mass rej + if (doCompetingMassRej) { + if ((std::abs(massXi - o2::constants::physics::MassXiMinus) > cascCuts.cutCompMassRej)) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 4.5); + if (fillTruthOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 4.5); + } else { + passedAllSelsOmega = false; } + } + + // fil rec histograms + if (passedAllSelsXi || passedAllSelsOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PropDCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/V0CosPA"), v0cosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/CascCosPA"), casccosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/EtaDau"), bachEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/EtaDau"), negEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/EtaDau"), posEta); if (passedAllSelsXi) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 4.5); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassXi"), massXi); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Xi"), massXi, pt, mult); - // fill for particle-antiparticle type - if (cascade.sign() < 0) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassXiMinus"), massXi); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/XiMinus"), massXi, pt, mult); - } - if (cascade.sign() > 0) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassXiPlus"), massXi); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/XiPlus"), massXi, pt, mult); - } - // fill truth - if (fillTruthXi) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 4.5); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/MassXi"), massXi); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Xi"), massXi, pt, mult); - // - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/RapCheck_TH3_Truth_Xi"), pt, mult, cascade.yXi()); - } + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/RapidityXi"), cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PtVsRapidityXi"), pt, cascade.yXi()); } if (passedAllSelsOmega) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 5.5); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassOmega"), massOmega); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Xi"), massXi, pt, mult); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Omega"), massOmega, pt, mult); - // fill for particle-antiparticle type - if (cascade.sign() < 0) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassOmegaMinus"), massOmega); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/OmegaMinus"), massOmega, pt, mult); - } - if (cascade.sign() > 0) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassOmegaPlus"), massOmega); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/OmegaPlus"), massOmega, pt, mult); - } - // fill truth - if (fillTruthOmega) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 5.5); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/MassOmega"), massOmega); - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Omega"), massOmega, pt, mult); - // - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/RapCheck_TH3_Truth_Omega"), pt, mult, cascade.yOmega()); - } + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/RapidityOmega"), cascade.yOmega()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Filters/PtVsRapidityOmega"), pt, cascade.yOmega()); + } + if (fillTruthXi || fillTruthOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/PropDCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/PropDCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/V0CosPA"), v0cosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/CascCosPA"), casccosPA); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/EtaDau"), bachEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/EtaDau"), negEta); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/EtaDau"), posEta); + if (passedAllSelsXi) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/RapidityXi"), cascade.yXi()); + if (passedAllSelsOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Filters/RapidityOmega"), cascade.yOmega()); + } + } + if (passedAllSelsXi) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersXi"), 4.5); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassXi"), massXi); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Xi"), massXi, pt, mult); + // fill for particle-antiparticle type + if (cascade.sign() < 0) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassXiMinus"), massXi); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/XiMinus"), massXi, pt, mult); + } + if (cascade.sign() > 0) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassXiPlus"), massXi); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/XiPlus"), massXi, pt, mult); + } + // fill truth + if (fillTruthXi) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersXi"), 4.5); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/MassXi"), massXi); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Xi"), massXi, pt, mult); + // + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/RapCheck_TH3_Truth_Xi"), pt, mult, cascade.yXi()); + } + } + if (passedAllSelsOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/FiltersOmega"), 5.5); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassOmega"), massOmega); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Xi"), massXi, pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/Omega"), massOmega, pt, mult); + // fill for particle-antiparticle type + if (cascade.sign() < 0) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassOmegaMinus"), massOmega); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/OmegaMinus"), massOmega, pt, mult); } + if (cascade.sign() > 0) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/MassOmegaPlus"), massOmega); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/OmegaPlus"), massOmega, pt, mult); + } + // fill truth + if (fillTruthOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/FiltersOmega"), 5.5); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/MassOmega"), massOmega); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Omega"), massOmega, pt, mult); + // + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/RapCheck_TH3_Truth_Omega"), pt, mult, cascade.yOmega()); + } + } - // statistics - compare gen and reco pt and rapidity - if constexpr (requires { collision.straMCCollisionId(); }) { - if constexpr (requires { stdCasc.has_cascMCCore(); }) { - auto cascmccore = stdCasc.template cascMCCore_as(); - double genPt = cascmccore.ptMC(); - double genYXi = cascmccore.rapidityMC(0); - double genYOmega = cascmccore.rapidityMC(2); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/GenRecPt"), genPt, pt); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/GenRecRapidityXi"), genYXi, cascade.yXi()); - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); + // statistics - compare gen and reco pt and rapidity + int charmBeautyCodes = 4000; + if constexpr (requires { collision.straMCCollisionId(); }) { + if constexpr (requires { stdCasc.has_cascMCCore(); }) { + auto cascmccore = stdCasc.template cascMCCore_as(); + double genPt = cascmccore.ptMC(); + double genYXi = cascmccore.rapidityMC(0); + double genYOmega = cascmccore.rapidityMC(2); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/GenRecPt"), genPt, pt); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/GenRecRapidityXi"), genYXi, cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); + if (fillTruthXi || fillTruthOmega) + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/GenRecPt"), genPt, pt); + if (passedAllSelsOmega || passedAllSelsXi) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenRecPt"), genPt, pt); if (fillTruthXi || fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/GenRecPt"), genPt, pt); - if (passedAllSelsOmega || passedAllSelsXi) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenRecPt"), genPt, pt); - if (fillTruthXi || fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenRecPt"), genPt, pt); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenRecPt"), genPt, pt); + } + if (fillTruthXi) { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/GenRecRapidityXi"), genYXi, cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAxyPrimaryXi"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAzPrimaryXi"), cascade.dcaZCascToPV(), pt, mult); + if (std::abs(cascmccore.pdgCodeMother()) > charmBeautyCodes) { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAxyDecayXi"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAzDecayXi"), cascade.dcaZCascToPV(), pt, mult); + } else { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAxyDirectXi"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAzDirectXi"), cascade.dcaZCascToPV(), pt, mult); } - if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/GenRecRapidityXi"), genYXi, cascade.yXi()); - if (passedAllSelsXi) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenRecRapidityXi"), genYXi, cascade.yXi()); - if (fillTruthXi) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenRecRapidityXi"), genYXi, cascade.yXi()); + } + if (passedAllSelsXi) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenRecRapidityXi"), genYXi, cascade.yXi()); + if (fillTruthXi) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenRecRapidityXi"), genYXi, cascade.yXi()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAxyPrimaryXi"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAzPrimaryXi"), cascade.dcaZCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Radius/PrimaryXi"), cascade.cascradius(), pt); + if (std::abs(cascmccore.pdgCodeMother()) > charmBeautyCodes) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAxyDecayXi"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAzDecayXi"), cascade.dcaZCascToPV(), pt, mult); + } else { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAxyDirectXi"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAzDirectXi"), cascade.dcaZCascToPV(), pt, mult); + } } - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); - if (passedAllSelsOmega) { - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); - if (fillTruthOmega) - histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); + } + if (fillTruthOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAxyPrimaryOmega"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAzPrimaryOmega"), cascade.dcaZCascToPV(), pt, mult); + if (std::abs(cascmccore.pdgCodeMother()) > charmBeautyCodes) { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAxyDecayOmega"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAzDecayOmega"), cascade.dcaZCascToPV(), pt, mult); + } else { + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAxyDirectOmega"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/NoSel-Truth/DCA/DCAzDirectOmega"), cascade.dcaZCascToPV(), pt, mult); + } + } + if (passedAllSelsOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); + if (fillTruthOmega) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/GenRecRapidityOmega"), genYOmega, cascade.yOmega()); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAxyPrimaryOmega"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAzPrimaryOmega"), cascade.dcaZCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/Radius/PrimaryOmega"), cascade.cascradius(), pt); + if (std::abs(cascmccore.pdgCodeMother()) > charmBeautyCodes) { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAxyDecayOmega"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAzDecayOmega"), cascade.dcaZCascToPV(), pt, mult); + } else { + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAxyDirectOmega"), cascade.dcaXYCascToPV(), pt, mult); + histos.fill(HIST(TypeNames[Type]) + HIST("/Rec-Truth/DCA/DCAzDirectOmega"), cascade.dcaZCascToPV(), pt, mult); + } } } } } } + template + void analyseCascs(TEvent const& collision, TCascs const& cascades) + { + for (auto const& cascade : cascades) { + analyseCascade(collision, cascade); + } + } + void init(InitContext const&) { // check if cut configuration is valid @@ -773,7 +807,6 @@ struct StrangeCascTrack { histos.add(Form("%s/NoSel/Filters/RapidityOmega", TypeNames[Type].data()), "y under Omega hypothesis", kTH1D, {{200, -1.0, 1.0}}); histos.add(Form("%s/NoSel/Filters/PtVsRapidityOmega", TypeNames[Type].data()), "pt vs y under Xi hypothesis", kTH2D, {axesConfig.axisPt, {200, -1.0, 1.0}}); histos.add(Form("%s/NoSel/Filters/EtaDau", TypeNames[Type].data()), "|#eta| of dau tracks", kTH1D, {axesConfig.axisEta}); - histos.add(Form("%s/NoSel/EvMult", TypeNames[Type].data()), "Multiplicity of events with >=1 cascade", kTH1D, {axesConfig.axisMult}); histos.add(Form("%s/NoSel/GenRecPt", TypeNames[Type].data()), "Generated vs reconstructed pt", kTH2D, {axesConfig.axisPt, axesConfig.axisPt}); histos.add(Form("%s/NoSel/GenRecRapidityXi", TypeNames[Type].data()), "Generated vs reconstructed y (Xi)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); histos.add(Form("%s/NoSel/GenRecRapidityOmega", TypeNames[Type].data()), "Generated vs reconstructed y (Omega)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); @@ -788,12 +821,24 @@ struct StrangeCascTrack { histos.add(Form("%s/NoSel-Truth/Filters/RapidityXi", TypeNames[Type].data()), "y under Xi hypothesis", kTH1D, {{200, -1.0, 1.0}}); histos.add(Form("%s/NoSel-Truth/Filters/RapidityOmega", TypeNames[Type].data()), "y under Omega hypothesis", kTH1D, {{200, -1.0, 1.0}}); histos.add(Form("%s/NoSel-Truth/Filters/EtaDau", TypeNames[Type].data()), "|#eta| of dau tracks", kTH1D, {axesConfig.axisEta}); - histos.add(Form("%s/NoSel-Truth/EvMult", TypeNames[Type].data()), "Multiplicity of events with >=1 cascade", kTH1D, {axesConfig.axisMult}); histos.add(Form("%s/NoSel-Truth/GenRecPt", TypeNames[Type].data()), "Generated vs reconstructed pt", kTH2D, {axesConfig.axisPt, axesConfig.axisPt}); histos.add(Form("%s/NoSel-Truth/GenRecRapidityXi", TypeNames[Type].data()), "Generated vs reconstructed y (Xi)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); histos.add(Form("%s/NoSel-Truth/GenRecRapidityOmega", TypeNames[Type].data()), "Generated vs reconstructed y (Omega)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); histos.add(Form("%s/NoSel-Truth/MassXi", TypeNames[Type].data()), "Invariant mass hypothesis", kTH1D, {axesConfig.axisXiMass}); histos.add(Form("%s/NoSel-Truth/MassOmega", TypeNames[Type].data()), "Invariant mass hypothesis", kTH1D, {axesConfig.axisOmegaMass}); + /// + histos.add(Form("%s/NoSel-Truth/DCA/DCAxyPrimaryXi", TypeNames[Type].data()), "DCA xy for primary Xi", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAzPrimaryXi", TypeNames[Type].data()), "DCA z for primary Xi", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAxyDirectXi", TypeNames[Type].data()), "DCA xy for direct Xi (has no mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAzDirectXi", TypeNames[Type].data()), "DCA z for direct Xi (has no mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAxyDecayXi", TypeNames[Type].data()), "DCA xy for decay Xi (has mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAzDecayXi", TypeNames[Type].data()), "DCA z for decay Xi (has mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAxyPrimaryOmega", TypeNames[Type].data()), "DCA xy for primary Omega", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAzPrimaryOmega", TypeNames[Type].data()), "DCA z for primary Omega", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAxyDirectOmega", TypeNames[Type].data()), "DCA xy for direct Omega (has no mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAzDirectOmega", TypeNames[Type].data()), "DCA z for direct Omega (has no mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAxyDecayOmega", TypeNames[Type].data()), "DCA xy for decay Omega (has mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/DCA/DCAzDecayOmega", TypeNames[Type].data()), "DCA z for decay Omega (has mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); // xi and omega selection statistics histos.add(Form("%s/Rec/Filters/PropDCAxy", TypeNames[Type].data()), "DCA to xy (propagated)", kTH1D, {axesConfig.axisDCAxy}); histos.add(Form("%s/Rec/Filters/PropDCAz", TypeNames[Type].data()), "DCA to z (propagated)", kTH1D, {axesConfig.axisDCAz}); @@ -805,7 +850,6 @@ struct StrangeCascTrack { histos.add(Form("%s/Rec/Filters/RapidityOmega", TypeNames[Type].data()), "y under Omega hypothesis", kTH1D, {{200, -1.0, 1.0}}); histos.add(Form("%s/Rec/Filters/PtVsRapidityOmega", TypeNames[Type].data()), "pt vs y under Omega hypothesis", kTH2D, {axesConfig.axisPt, {200, -1.0, 1.0}}); histos.add(Form("%s/Rec/Filters/EtaDau", TypeNames[Type].data()), "|#eta| of dau tracks", kTH1D, {axesConfig.axisEta}); - histos.add(Form("%s/Rec/EvMult", TypeNames[Type].data()), "Multiplicity of events with >=1 selected cascade", kTH1D, {axesConfig.axisMult}); histos.add(Form("%s/Rec/GenRecPt", TypeNames[Type].data()), "Generated vs reconstructed pt", kTH2D, {axesConfig.axisPt, axesConfig.axisPt}); histos.add(Form("%s/Rec/GenRecRapidityXi", TypeNames[Type].data()), "Generated vs reconstructed y (Xi)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); histos.add(Form("%s/Rec/GenRecRapidityOmega", TypeNames[Type].data()), "Generated vs reconstructed y (Omega)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); @@ -837,7 +881,6 @@ struct StrangeCascTrack { histos.add(Form("%s/Rec-Truth/Filters/RapidityXi", TypeNames[Type].data()), "y under Xi hypothesis", kTH1D, {{200, -1.0, 1.0}}); histos.add(Form("%s/Rec-Truth/Filters/RapidityOmega", TypeNames[Type].data()), "y under Omega hypothesis", kTH1D, {{200, -1.0, 1.0}}); histos.add(Form("%s/Rec-Truth/Filters/EtaDau", TypeNames[Type].data()), "|#eta| of dau tracks", kTH1D, {axesConfig.axisEta}); - histos.add(Form("%s/Rec-Truth/EvMult", TypeNames[Type].data()), "Multiplicity of events with >=1 cascade", kTH1D, {axesConfig.axisMult}); histos.add(Form("%s/Rec-Truth/GenRecPt", TypeNames[Type].data()), "Generated vs reconstructed pt", kTH2D, {axesConfig.axisPt, axesConfig.axisPt}); histos.add(Form("%s/Rec-Truth/GenRecRapidityXi", TypeNames[Type].data()), "Generated vs reconstructed y (Xi)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); histos.add(Form("%s/Rec-Truth/GenRecRapidityOmega", TypeNames[Type].data()), "Generated vs reconstructed y (Omega)", kTH2D, {{200, -1.0, 1.0}, {200, -1.0, 1.0}}); @@ -852,6 +895,22 @@ struct StrangeCascTrack { /// histos.add(Form("%s/Rec-Truth/RapCheck_TH3_Truth_Xi", TypeNames[Type].data()), "Rapidity check (pt, mult, y)", kTHnD, {axesConfig.axisPt, axesConfig.axisMult, {200, -1.0, 1.0}}); histos.add(Form("%s/Rec-Truth/RapCheck_TH3_Truth_Omega", TypeNames[Type].data()), "Rapidity check (pt, mult, y)", kTHnD, {axesConfig.axisPt, axesConfig.axisMult, {200, -1.0, 1.0}}); + /// + histos.add(Form("%s/Rec-Truth/DCA/DCAxyPrimaryXi", TypeNames[Type].data()), "DCA xy for primary Xi", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAzPrimaryXi", TypeNames[Type].data()), "DCA z for primary Xi", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAxyDirectXi", TypeNames[Type].data()), "DCA xy for direct Xi (has no mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAzDirectXi", TypeNames[Type].data()), "DCA z for direct Xi (has no mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAxyDecayXi", TypeNames[Type].data()), "DCA xy for decay Xi (has mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAzDecayXi", TypeNames[Type].data()), "DCA z for decay Xi (has mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAxyPrimaryOmega", TypeNames[Type].data()), "DCA xy for primary Omega", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAzPrimaryOmega", TypeNames[Type].data()), "DCA z for primary Omega", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAxyDirectOmega", TypeNames[Type].data()), "DCA xy for direct Omega (has no mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAzDirectOmega", TypeNames[Type].data()), "DCA z for direct Omega (has no mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAxyDecayOmega", TypeNames[Type].data()), "DCA xy for decay Omega (has mothers)", kTHnD, {axesConfig.axisDCAxy, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/DCA/DCAzDecayOmega", TypeNames[Type].data()), "DCA z for decay Omega (has mothers)", kTHnD, {axesConfig.axisDCAz, axesConfig.axisPt, axesConfig.axisMult}); + /// + histos.add(Form("%s/Rec-Truth/Radius/PrimaryXi", TypeNames[Type].data()), "Cascade radius (primary Xi)", kTH2D, {{500, 0.0, 50.0}, axesConfig.axisPt}); + histos.add(Form("%s/Rec-Truth/Radius/PrimaryOmega", TypeNames[Type].data()), "Cascade radius (primary Omega)", kTH2D, {{500, 0.0, 50.0}, axesConfig.axisPt}); }); // for MC-specific processing // all generated events: @@ -1131,17 +1190,30 @@ struct StrangeCascTrack { } } - void processDerivedMCRec(DerMCRecCollisions::iterator const& collision, DerMCRecCascDatas const& allCascs, DerMCRecTraCascDatas const& traCascs, DauTracks const&, DerMCGenCascades const&) + std::vector> traCascsGrouped; + void processDerivedMCRec(DerMCRecCollisions const& collisions, DerMCRecCascDatas const& allCascs, DerMCRecTraCascDatas const& traCascs, DauTracks const&, DerMCGenCascades const&) { - fillEvents(collision); // save info about all processed events - if (isValidEvent(collision, true)) { - histos.fill(HIST("Rec-Events/EvCounter"), 0.5); - histos.fill(HIST("Rec-Events/PVxy"), collision.posX(), collision.posY()); - histos.fill(HIST("Rec-Events/PVz"), collision.posZ()); - double mult = (doProcessIons) ? collision.centFT0C() : collision.centFT0M(); - histos.fill(HIST("Rec-Events/Mult"), mult); - analyseCascs(collision, allCascs); // process all cascades - analyseCascs(collision, traCascs); // process tracked cascades + // custom group tracked cascades - a temporary fix for wrong ordering in OO MC + traCascsGrouped.clear(); + traCascsGrouped.resize(collisions.size()); + for (const auto& casc : traCascs) { + traCascsGrouped[casc.straCollisionId()].push_back(casc.globalIndex()); + } + for (const auto& collision : collisions) { + fillEvents(collision); // save info about all processed events + auto slicedAllCascs = allCascs.sliceBy(cascsPerCollision, collision.globalIndex()); + if (isValidEvent(collision, true)) { + histos.fill(HIST("Rec-Events/EvCounter"), 0.5); + histos.fill(HIST("Rec-Events/PVxy"), collision.posX(), collision.posY()); + histos.fill(HIST("Rec-Events/PVz"), collision.posZ()); + double mult = (doProcessIons) ? collision.centFT0C() : collision.centFT0M(); + histos.fill(HIST("Rec-Events/Mult"), mult); + analyseCascs(collision, slicedAllCascs); // process all cascades + for (int const& idx : traCascsGrouped[collision.globalIndex()]) { + auto casc = traCascs.rawIteratorAt(idx); + analyseCascade(collision, casc); + } + } } }