diff --git a/PWGLF/DataModel/LFStrangenessPIDTables.h b/PWGLF/DataModel/LFStrangenessPIDTables.h index 36a345b87ad..e689dc28141 100644 --- a/PWGLF/DataModel/LFStrangenessPIDTables.h +++ b/PWGLF/DataModel/LFStrangenessPIDTables.h @@ -137,15 +137,15 @@ DECLARE_SOA_COLUMN(BachTOFEventTime, bachTOFEventTime, float); //! bachelor tr // delta-times DECLARE_SOA_COLUMN(PosTOFDeltaTXiPi, posTOFDeltaTXiPi, float); //! positive track TOFDeltaT from pion <- lambda <- xi expectation -DECLARE_SOA_COLUMN(PosTOFDeltaTXiPr, posTOFDeltaTXiPr, float); //! positive track TOFDeltaT from pion <- lambda <- xi expectation +DECLARE_SOA_COLUMN(PosTOFDeltaTXiPr, posTOFDeltaTXiPr, float); //! positive track TOFDeltaT from proton <- lambda <- xi expectation DECLARE_SOA_COLUMN(NegTOFDeltaTXiPi, negTOFDeltaTXiPi, float); //! negative track TOFDeltaT from pion <- lambda <- xi expectation -DECLARE_SOA_COLUMN(NegTOFDeltaTXiPr, negTOFDeltaTXiPr, float); //! negative track TOFDeltaT from pion <- lambda <- xi expectation +DECLARE_SOA_COLUMN(NegTOFDeltaTXiPr, negTOFDeltaTXiPr, float); //! negative track TOFDeltaT from proton <- lambda <- xi expectation DECLARE_SOA_COLUMN(BachTOFDeltaTXiPi, bachTOFDeltaTXiPi, float); //! bachelor track TOFDeltaT from pion <- xi expectation DECLARE_SOA_COLUMN(PosTOFDeltaTOmPi, posTOFDeltaTOmPi, float); //! positive track TOFDeltaT from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(PosTOFDeltaTOmPr, posTOFDeltaTOmPr, float); //! positive track TOFDeltaT from pion <- lambda <- omega expectation +DECLARE_SOA_COLUMN(PosTOFDeltaTOmPr, posTOFDeltaTOmPr, float); //! positive track TOFDeltaT from proton <- lambda <- omega expectation DECLARE_SOA_COLUMN(NegTOFDeltaTOmPi, negTOFDeltaTOmPi, float); //! negative track TOFDeltaT from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float); //! negative track TOFDeltaT from pion <- lambda <- omega expectation -DECLARE_SOA_COLUMN(BachTOFDeltaTOmPi, bachTOFDeltaTOmPi, float); //! bachelor track TOFDeltaT from pion <- omega expectation +DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float); //! negative track TOFDeltaT from proton <- lambda <- omega expectation +DECLARE_SOA_COLUMN(BachTOFDeltaTOmKa, bachTOFDeltaTOmKa, float); //! bachelor track TOFDeltaT from kaon <- omega expectation // n-sigmas DECLARE_SOA_COLUMN(TOFNSigmaXiLaPi, tofNSigmaXiLaPi, float); //! meson track NSigma from pion <- lambda <- xi expectation @@ -170,7 +170,7 @@ DECLARE_SOA_TABLE(CascTOFPIDs, "AOD", "CASCTOFPID", // processed information for cascdata::BachTOFDeltaTXiPi, cascdata::PosTOFDeltaTOmPi, cascdata::PosTOFDeltaTOmPr, cascdata::NegTOFDeltaTOmPi, cascdata::NegTOFDeltaTOmPr, - cascdata::BachTOFDeltaTOmPi); + cascdata::BachTOFDeltaTOmKa); DECLARE_SOA_TABLE(CascTOFNSigmas, "AOD", "CascTOFNSigmas", // Nsigmas for cascades cascdata::TOFNSigmaXiLaPi, cascdata::TOFNSigmaXiLaPr, cascdata::TOFNSigmaXiPi, cascdata::TOFNSigmaOmLaPi, cascdata::TOFNSigmaOmLaPr, cascdata::TOFNSigmaOmKa); diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 1e6f3b990b9..0b0a30f7301 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -22,10 +22,37 @@ #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/McCollisionExtra.h" #include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGUD/DataModel/UDTables.h" namespace o2::aod { +namespace straupc +{ +DECLARE_SOA_COLUMN(IsUPC, isUPC, bool); //! is event upc-like + +DECLARE_SOA_DYNAMIC_COLUMN(EnergyCommonZNA, energyCommonZNA, //! + [](float value) -> float { return value; }); + +DECLARE_SOA_DYNAMIC_COLUMN(EnergyCommonZNC, energyCommonZNC, //! + [](float value) -> float { return value; }); + +DECLARE_SOA_DYNAMIC_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, //! + [](float value) -> float { return value; }); + +DECLARE_SOA_DYNAMIC_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, //! + [](float value) -> float { return value; }); + +DECLARE_SOA_DYNAMIC_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, //! + [](float value) -> float { return value; }); + +DECLARE_SOA_DYNAMIC_COLUMN(TotalFDDAmplitudeA, totalFDDAmplitudeA, //! + [](float value) -> float { return value; }); + +DECLARE_SOA_DYNAMIC_COLUMN(TotalFDDAmplitudeC, totalFDDAmplitudeC, //! + [](float value) -> float { return value; }); +} // namespace straupc + //______________________________________________________ // Collision declarations for derived data analysis // this is optional but will ensure full flexibility @@ -59,19 +86,26 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_003, "AOD", "STRARAWCENTS", 3, //! mult::MultAllTracksITSTPC, // ITSTPC track multiplicities, all, no eta cut mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals mult::MultZEM2, mult::MultZPA, mult::MultZPC); -DECLARE_SOA_TABLE_VERSIONED(StraRawCents_004, "AOD", "STRARAWCENTS", 4, //! debug information - mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors - mult::MultNTracksPVeta1, // track multiplicities with eta cut for INEL>0 - mult::MultPVTotalContributors, // number of PV contribs total - mult::MultNTracksGlobal, // global track multiplicities - mult::MultNTracksITSTPC, // track multiplicities, PV contribs, no eta cut - mult::MultAllTracksTPCOnly, // TPConly track multiplicities, all, no eta cut - mult::MultAllTracksITSTPC, // ITSTPC track multiplicities, all, no eta cut - mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals +DECLARE_SOA_TABLE_VERSIONED(StraRawCents_004, "AOD", "STRARAWCENTS", 4, //! debug information + mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, mult::MultFDDA, mult::MultFDDC, // FIT detectors + mult::MultNTracksPVeta1, // track multiplicities with eta cut for INEL>0 + mult::MultPVTotalContributors, // number of PV contribs total + mult::MultNTracksGlobal, // global track multiplicities + mult::MultNTracksITSTPC, // track multiplicities, PV contribs, no eta cut + mult::MultAllTracksTPCOnly, // TPConly track multiplicities, all, no eta cut + mult::MultAllTracksITSTPC, // ITSTPC track multiplicities, all, no eta cut + mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals mult::MultZEM2, mult::MultZPA, mult::MultZPC, - evsel::NumTracksInTimeRange); // add occupancy as extra -DECLARE_SOA_TABLE(StraEvSels, "AOD", "STRAEVSELS", //! event selection: sel8 - evsel::Sel8, evsel::Selection); + evsel::NumTracksInTimeRange, + straupc::EnergyCommonZNA, + straupc::EnergyCommonZNC, + straupc::TotalFT0AmplitudeA, + straupc::TotalFT0AmplitudeC, + straupc::TotalFV0AmplitudeA, + straupc::TotalFDDAmplitudeA, + straupc::TotalFDDAmplitudeC); // add occupancy as extra +DECLARE_SOA_TABLE(StraEvSels, "AOD", "STRAEVSELS", //! event selections + evsel::Sel8, evsel::Selection, straupc::IsUPC, udcollision::GapSide); DECLARE_SOA_TABLE(StraFT0AQVs, "AOD", "STRAFT0AQVS", //! t0a Qvec qvec::QvecFT0ARe, qvec::QvecFT0AIm, qvec::SumAmplFT0A); DECLARE_SOA_TABLE(StraFT0CQVs, "AOD", "STRAFT0CQVS", //! t0c Qvec diff --git a/PWGLF/TableProducer/Strangeness/Converters/strarawcentsconverter2v4.cxx b/PWGLF/TableProducer/Strangeness/Converters/strarawcentsconverter2v4.cxx index c94227e31cd..61dcd18985d 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/strarawcentsconverter2v4.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/strarawcentsconverter2v4.cxx @@ -26,6 +26,8 @@ struct strarawcentsconverter2v4 { straRawCents_004(values.multFT0A(), values.multFT0C(), values.multFT0A(), + 0, /*dummy FDDA value*/ + 0, /*dummy FDDC value*/ values.multNTracksPVeta1(), values.multPVTotalContributors(), values.multNTracksGlobal(), diff --git a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx index 08526c22d5d..ea73758cf30 100644 --- a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx @@ -48,6 +48,7 @@ #include "Framework/StaticFor.h" #include "Common/DataModel/McCollisionExtra.h" #include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGUD/DataModel/UDTables.h" using namespace o2; using namespace o2::framework; @@ -58,6 +59,7 @@ using TracksWithExtra = soa::Join; using FullTracksExtIUTOF = soa::Join; using FullCollisions = soa::Join; +using UDCollisionsFull = soa::Join; // simple bit checkers #define bitset(var, nbit) ((var) |= (1 << (nbit))) @@ -167,6 +169,8 @@ struct strangederivedbuilder { Configurable fillRawFT0A{"fillRawFT0A", false, "Fill raw FT0A information for debug"}; Configurable fillRawFT0C{"fillRawFT0C", true, "Fill raw FT0C information for debug"}; Configurable fillRawFV0A{"fillRawFV0A", false, "Fill raw FV0A information for debug"}; + Configurable fillRawFDDA{"fillRawFDDA", false, "Fill raw FDDA information for debug"}; + Configurable fillRawFDDC{"fillRawFDDC", false, "Fill raw FDDC information for debug"}; Configurable fillRawZDC{"fillRawZDC", false, "Fill raw ZDC information for debug"}; Configurable fillRawNTracksEta1{"fillRawNTracksEta1", true, "Fill raw NTracks |eta|<1 information for debug"}; Configurable fillRawNTracksForCorrelation{"fillRawNTracksForCorrelation", true, "Fill raw NTracks for correlation cuts"}; @@ -180,6 +184,7 @@ struct strangederivedbuilder { Preslice KFCascperCollision = o2::aod::cascdata::collisionId; Preslice TraCascperCollision = o2::aod::cascdata::collisionId; Preslice mcParticlePerMcCollision = o2::aod::mcparticle::mcCollisionId; + Preslice udCollisionsPerCollision = o2::aod::udcollision::collisionId; std::vector genK0Short; std::vector genLambda; @@ -200,6 +205,18 @@ struct strangederivedbuilder { void init(InitContext&) { + + Configurable nBinsZDCen{"nBinsZDCen", 200, "N bins in ZN energy"}; + Configurable lowEnZN{"lowEnZN", -50., "lower limit in ZN energy histo"}; + Configurable highEnZN{"highEnZN", 250., "upper limit in ZN energy histo"}; + const AxisSpec axisEnergyZNA{nBinsZDCen, lowEnZN, highEnZN, "ZNA energy (TeV)"}; + const AxisSpec axisEnergyZNC{nBinsZDCen, lowEnZN, highEnZN, "ZNC energy (TeV)"}; + AxisSpec signalFT0AAxis = {200, -50, 2000, "FT0A amplitude"}; + AxisSpec signalFT0CAxis = {200, -50, 2000, "FT0C amplitude"}; + AxisSpec signalFDDAAxis = {200, -50, 2000, "FDDA amplitude"}; + AxisSpec signalFDDCAxis = {200, -50, 2000, "FDDC amplitude"}; + AxisSpec signalFV0AAxis = {200, -50, 2000, "FV0A amplitude"}; + // setup map for fast checking if enabled static_for<0, nSpecies - 1>([&](auto i) { constexpr int index = i.value; @@ -229,6 +246,13 @@ struct strangederivedbuilder { // for QA and test purposes auto hRawCentrality = histos.add("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality}); + histos.add("h2dZNA", "h2dZNA", kTH2F, {axisEnergyZNA, axisEnergyZNA}); + histos.add("h2dZNC", "h2dZNC", kTH2F, {axisEnergyZNC, axisEnergyZNC}); + histos.add("h2dFT0A", "h2dFT0A", {HistType::kTH2F, {signalFT0AAxis, signalFT0AAxis}}); + histos.add("h2dFT0C", "h2dFT0C", {HistType::kTH2F, {signalFT0CAxis, signalFT0CAxis}}); + histos.add("h2dFV0A", "h2dFV0A", {HistType::kTH2F, {signalFV0AAxis, signalFV0AAxis}}); + histos.add("h2dFDDA", "h2dFDDA", {HistType::kTH2F, {signalFDDAAxis, signalFDDAAxis}}); + histos.add("h2dFDDC", "h2dFDDC", {HistType::kTH2F, {signalFDDCAxis, signalFDDCAxis}}); for (int ii = 1; ii < 101; ii++) { float value = 100.5f - static_cast(ii); @@ -250,25 +274,43 @@ struct strangederivedbuilder { } } - void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + void processCollisionsV0sOnly(soa::Join const& collisions, + UDCollisionsFull const& udCollisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisColl = V0s.sliceBy(V0perCollision, collIdx); bool strange = V0Table_thisColl.size() > 0; + + bool isUPC = kFALSE; + int gapSide = -1; + + if (udCollisions.size() != 0) { + auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collision.globalIndex()); + if (udCollision.size() == 1) { + for (auto& udColl : udCollision) { + isUPC = kTRUE; + gapSide = udColl.gapSide(); + } + } + } + // casc table sliced if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centFV0A()); - strangeEvSels(collision.sel8(), collision.selection_raw()); + strangeEvSels(collision.sel8(), collision.selection_raw(), isUPC, gapSide); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); - if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) { + if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC || fillRawFDDA || fillRawFDDC) { + strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), collision.multFT0C() * static_cast(fillRawFT0C), collision.multFV0A() * static_cast(fillRawFV0A), + collision.multFDDA() * static_cast(fillRawFDDA), + collision.multFDDC() * static_cast(fillRawFDDC), collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), @@ -289,7 +331,8 @@ struct strangederivedbuilder { } } - void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&) + void processCollisions(soa::Join const& collisions, + UDCollisionsFull const& udCollisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&) { // create collision indices beforehand std::vector V0CollIndices(V0s.size(), -1); // index -1: no collision @@ -314,19 +357,59 @@ struct strangederivedbuilder { CascTable_thisColl.size() > 0 || KFCascTable_thisColl.size() > 0 || TraCascTable_thisColl.size() > 0; + + bool isUPC = kFALSE; + int gapSide = -1; + float sig_zna = -1; + float sig_znc = -1; + float sig_ft0a = -1; + float sig_ft0c = -1; + float sig_fv0a = -1; + float sig_fdda = -1; + float sig_fddc = -1; + + if (udCollisions.size() != 0) { + auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collision.globalIndex()); + if (udCollision.size() == 1) { + for (auto& udColl : udCollision) { + isUPC = kTRUE; + gapSide = udColl.gapSide(); + sig_zna = udColl.energyCommonZNA(); + sig_znc = udColl.energyCommonZNC(); + sig_ft0a = udColl.totalFT0AmplitudeA(); + sig_ft0c = udColl.totalFT0AmplitudeC(); + sig_fv0a = udColl.totalFV0AmplitudeA(); + sig_fdda = udColl.totalFDDAmplitudeA(); + sig_fddc = udColl.totalFDDAmplitudeC(); + } + } + } + // casc table sliced if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), centrality, collision.centFV0A()); - strangeEvSels(collision.sel8(), collision.selection_raw()); + strangeEvSels(collision.sel8(), collision.selection_raw(), isUPC, gapSide); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); - if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) { + if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC || fillRawFDDA || fillRawFDDC) { + if (isUPC) { + histos.fill(HIST("h2dZNA"), collision.multZNA(), sig_zna); + histos.fill(HIST("h2dZNC"), collision.multZNC(), sig_znc); + histos.fill(HIST("h2dFT0A"), collision.multFT0A(), sig_ft0a); + histos.fill(HIST("h2dFT0C"), collision.multFT0C(), sig_ft0c); + histos.fill(HIST("h2dFV0A"), collision.multFV0A(), sig_fv0a); + histos.fill(HIST("h2dFDDA"), collision.multFDDA(), sig_fdda); + histos.fill(HIST("h2dFDDC"), collision.multFDDC(), sig_fddc); + } + strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), collision.multFT0C() * static_cast(fillRawFT0C), collision.multFV0A() * static_cast(fillRawFV0A), + collision.multFDDA() * static_cast(fillRawFDDA), + collision.multFDDC() * static_cast(fillRawFDDC), collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), @@ -364,7 +447,8 @@ struct strangederivedbuilder { tracasccollref(TraCascadeCollIndices[casc.globalIndex()]); } - void processCollisionsMC(soa::Join const& collisions, soa::Join const& V0s, soa::Join const& /*V0MCCores*/, soa::Join const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&, soa::Join const& mcCollisions, aod::McParticles const&) + void processCollisionsMC(soa::Join const& collisions, + soa::Join const& V0s, soa::Join const& /*V0MCCores*/, soa::Join const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&, soa::Join const& mcCollisions, aod::McParticles const&) { // create collision indices beforehand std::vector V0CollIndices(V0s.size(), -1); // index -1: no collision @@ -402,20 +486,23 @@ struct strangederivedbuilder { CascTable_thisColl.size() > 0 || KFCascTable_thisColl.size() > 0 || TraCascTable_thisColl.size() > 0; + // casc table sliced if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCollLabels(collision.mcCollisionId()); strangeCents(collision.centFT0M(), collision.centFT0A(), centrality, collision.centFV0A()); - strangeEvSels(collision.sel8(), collision.selection_raw()); + strangeEvSels(collision.sel8(), collision.selection_raw(), 0, -1); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); - if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) { + if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC || fillRawFDDA || fillRawFDDC) { strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), collision.multFT0C() * static_cast(fillRawFT0C), collision.multFV0A() * static_cast(fillRawFV0A), + collision.multFDDA() * static_cast(fillRawFDDA), + collision.multFDDC() * static_cast(fillRawFDDC), collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1), collision.multPVTotalContributors() * static_cast(fillRawNTracksForCorrelation), collision.multNTracksGlobal() * static_cast(fillRawNTracksForCorrelation), @@ -470,7 +557,7 @@ struct strangederivedbuilder { // Figure out the numbering of the new tracks table // assume filling per order int nTracks = 0; - for (int i = 0; i < int(trackMap.size()); i++) { + for (int i = 0; i < static_cast(trackMap.size()); i++) { if (trackMap[i] >= 0) { trackMap[i] = nTracks++; } @@ -545,7 +632,7 @@ struct strangederivedbuilder { // Figure out the numbering of the new tracks table // assume filling per order int nTracks = 0; - for (int i = 0; i < int(trackMap.size()); i++) { + for (int i = 0; i < static_cast(trackMap.size()); i++) { if (trackMap[i] >= 0) { trackMap[i] = nTracks++; } @@ -637,7 +724,7 @@ struct strangederivedbuilder { // Figure out the numbering of the new mcMother table // assume filling per order int nParticles = 0; - for (int i = 0; i < int(motherReference.size()); i++) { + for (int i = 0; i < static_cast(motherReference.size()); i++) { if (motherReference[i] >= 0) { motherReference[i] = nParticles++; // count particles of interest } @@ -829,7 +916,7 @@ struct strangederivedbuilder { uint64_t combineProngIndices(uint32_t low, uint32_t high) { - return (((uint64_t)high) << 32) | ((uint64_t)low); + return ((static_cast(high)) << 32) | (static_cast(low)); } void processV0FoundTags(aod::V0s const& foundV0s, aod::V0Datas const& findableV0s, aod::FindableV0s const& /* added to avoid troubles */) @@ -851,7 +938,7 @@ struct strangederivedbuilder { using uint128_t = __uint128_t; uint128_t combineProngIndices128(uint32_t pos, uint32_t neg, uint32_t bach) { - return (((uint128_t)pos) << 64) | (((uint128_t)neg) << 32) | ((uint128_t)bach); + return ((static_cast(pos)) << 64) | ((static_cast(neg)) << 32) | (static_cast(bach)); } void processCascFoundTags(aod::Cascades const& foundCascades, aod::CascDatas const& findableCascades, aod::V0s const&, aod::FindableCascades const& /* added to avoid troubles */) diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt index 4873d3e6b1b..8505b70be01 100644 --- a/PWGLF/Tasks/Strangeness/CMakeLists.txt +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -102,4 +102,9 @@ o2physics_add_dpl_workflow(strangeness-in-jets o2physics_add_dpl_workflow(v0topologicalcuts SOURCES v0topologicalcuts.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(strange-yield-pbpb + SOURCES strange-yield-pbpb.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx index 3bbff7b117a..592480cddcf 100644 --- a/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx +++ b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx @@ -216,8 +216,8 @@ struct cascpostprocessing { registry.add("hPtCascPlusTrueRec", "hPtCascPlusTrueRec", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); registry.add("hPtCascMinusTrueRec", "hPtCascMinusTrueRec", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); - registry.add("hCascMinusMassvsPtTrueRec", "hCascMinusMassvsPtTrueRec", {HistType::kTH2F, {ptAxis, massAxis}}); - registry.add("hCascPlusMassvsPtTrueRec", "hCascPlusMassvsPtTrueRec", {HistType::kTH2F, {ptAxis, massAxis}}); + registry.add("hCascMinusMassvsPtTrueRec", "hCascMinusMassvsPtTrueRec", {HistType::kTH3F, {ptAxis, massAxis, centFT0MAxis}}); + registry.add("hCascPlusMassvsPtTrueRec", "hCascPlusMassvsPtTrueRec", {HistType::kTH3F, {ptAxis, massAxis, centFT0MAxis}}); registry.add("hCascMinusMassvsPtBG", "hCascMinusMassvsPtBG", {HistType::kTH2F, {ptAxis, massAxis}}); registry.add("hCascPlusMassvsPtBG", "hCascPlusMassvsPtBG", {HistType::kTH2F, {ptAxis, massAxis}}); if (isMC) { @@ -238,7 +238,7 @@ struct cascpostprocessing { float ctau = 0; float rapidity = 0; bool isCandidate = 0; - int counter = -1; + int64_t counter = -1; bool isCorrectlyRec = 0; for (auto& candidate : mycascades) { @@ -489,7 +489,7 @@ struct cascpostprocessing { if (candidate.sign() < 0) { if (isCorrectlyRec) { registry.fill(HIST("hPtCascMinusTrueRec"), candidate.pt(), rapidity, candidate.centFT0M()); // 3rd axis is from MC calibration - registry.fill(HIST("hCascMinusMassvsPtTrueRec"), candidate.pt(), invmass); + registry.fill(HIST("hCascMinusMassvsPtTrueRec"), candidate.pt(), invmass, candidate.centFT0M()); } else { registry.fill(HIST("hCascMinusMassvsPtBG"), candidate.pt(), invmass); } @@ -500,7 +500,7 @@ struct cascpostprocessing { if (candidate.sign() > 0) { if (isCorrectlyRec) { registry.fill(HIST("hPtCascPlusTrueRec"), candidate.pt(), rapidity, candidate.centFT0M()); // 3rd axis is from MC calibration - registry.fill(HIST("hCascPlusMassvsPtTrueRec"), candidate.pt(), invmass); + registry.fill(HIST("hCascPlusMassvsPtTrueRec"), candidate.pt(), invmass, candidate.centFT0M()); } else { registry.fill(HIST("hCascPlusMassvsPtBG"), candidate.pt(), invmass); } diff --git a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx index 012da260c95..7fa45f2a24e 100644 --- a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx @@ -842,7 +842,7 @@ struct derivedCascadeAnalysis { histos.fill(HIST("InvMassAfterSel/hNegativeCascade"), casc.pt(), invmass, coll.centFT0C()); if (doOccupancyCheck) { static_for<0, 9>([&](auto i) { - constexpr int index = i.value; + static constexpr int index = i.value; if (coll.centFT0C() < centralityIntervals[index + 1] && coll.centFT0C() > centralityIntervals[index]) { histos.fill(HIST("InvMassAfterSelCent") + HIST(Index[index]) + HIST("/hNegativeCascade"), casc.pt(), invmass, coll.trackOccupancyInTimeRange()); } @@ -875,7 +875,7 @@ struct derivedCascadeAnalysis { histos.fill(HIST("InvMassAfterSel/hPositiveCascade"), casc.pt(), invmass, coll.centFT0C()); if (doOccupancyCheck) { static_for<0, 9>([&](auto i) { - constexpr int index = i.value; + static constexpr int index = i.value; if (coll.centFT0C() < centralityIntervals[index + 1] && coll.centFT0C() > centralityIntervals[index]) { histos.fill(HIST("InvMassAfterSelCent") + HIST(Index[index]) + HIST("/hPositiveCascade"), casc.pt(), invmass, coll.trackOccupancyInTimeRange()); } @@ -1111,7 +1111,7 @@ struct derivedCascadeAnalysis { histos.fill(HIST("InvMassAfterSel/hNegativeCascade"), casc.pt(), invmass, coll.centFT0C()); if (doOccupancyCheck) { static_for<0, 9>([&](auto i) { - constexpr int index = i.value; + static constexpr int index = i.value; if (coll.centFT0C() < centralityIntervals[index + 1] && coll.centFT0C() > centralityIntervals[index]) { histos.fill(HIST("InvMassAfterSelCent") + HIST(Index[index]) + HIST("/hNegativeCascade"), casc.pt(), invmass, coll.trackOccupancyInTimeRange()); } @@ -1174,7 +1174,7 @@ struct derivedCascadeAnalysis { histos.fill(HIST("InvMassAfterSel/hPositiveCascade"), casc.pt(), invmass, coll.centFT0C()); if (doOccupancyCheck) { static_for<0, 9>([&](auto i) { - constexpr int index = i.value; + static constexpr int index = i.value; if (coll.centFT0C() < centralityIntervals[index + 1] && coll.centFT0C() > centralityIntervals[index]) { histos.fill(HIST("InvMassAfterSelCent") + HIST(Index[index]) + HIST("/hPositiveCascade"), casc.pt(), invmass, coll.trackOccupancyInTimeRange()); } diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx index 0c163e41a9f..2493764e939 100644 --- a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx @@ -289,9 +289,9 @@ struct derivedlambdakzeroanalysis { // TOF PID if (TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaNegativePionK0Short) | (uint64_t(1) << selTOFDeltaTNegativePionK0Short); - if (TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut - maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda); if (TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda); + if (TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativeProtonLambda) | (uint64_t(1) << selTOFDeltaTNegativeProtonLambda); } @@ -1138,11 +1138,12 @@ struct derivedlambdakzeroanalysis { if (minOccupancy > 0 && collision.trackOccupancyInTimeRange() < minOccupancy) { return; } - histos.fill(HIST("hEventSelection"), 12 /* Below min occupancy */); + + histos.fill(HIST("hEventSelection"), 12 /* Above min occupancy */); if (maxOccupancy > 0 && collision.trackOccupancyInTimeRange() > maxOccupancy) { return; } - histos.fill(HIST("hEventSelection"), 13 /* Above max occupancy */); + histos.fill(HIST("hEventSelection"), 13 /* Below max occupancy */); float centrality = collision.centFT0C(); if (qaCentrality) { @@ -1242,11 +1243,11 @@ struct derivedlambdakzeroanalysis { if (minOccupancy > 0 && collision.trackOccupancyInTimeRange() < minOccupancy) { return; } - histos.fill(HIST("hEventSelection"), 12 /* Below min occupancy */); + histos.fill(HIST("hEventSelection"), 12 /* Above min occupancy */); if (maxOccupancy > 0 && collision.trackOccupancyInTimeRange() > maxOccupancy) { return; } - histos.fill(HIST("hEventSelection"), 13 /* Above max occupancy */); + histos.fill(HIST("hEventSelection"), 13 /* Below max occupancy */); float centrality = collision.centFT0C(); if (qaCentrality) { @@ -1497,49 +1498,49 @@ struct derivedlambdakzeroanalysis { auto hOmegaMinus = histos.get(HIST("h2dGeneratedOmegaMinus")); auto hOmegaPlus = histos.get(HIST("h2dGeneratedOmegaPlus")); for (auto& gVec : geK0Short) { - if (int(gVec.generatedK0Short().size()) != hK0Short->GetNcells()) + if (static_cast(gVec.generatedK0Short().size()) != hK0Short->GetNcells()) LOGF(fatal, "K0Short: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedK0Short().size(), hK0Short->GetNcells()); for (int iv = 0; iv < hK0Short->GetNcells(); iv++) { hK0Short->SetBinContent(iv, hK0Short->GetBinContent(iv) + gVec.generatedK0Short()[iv]); } } for (auto& gVec : geLambda) { - if (int(gVec.generatedLambda().size()) != hLambda->GetNcells()) + if (static_cast(gVec.generatedLambda().size()) != hLambda->GetNcells()) LOGF(fatal, "Lambda: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedLambda().size(), hLambda->GetNcells()); for (int iv = 0; iv < hLambda->GetNcells(); iv++) { hLambda->SetBinContent(iv, hLambda->GetBinContent(iv) + gVec.generatedLambda()[iv]); } } for (auto& gVec : geAntiLambda) { - if (int(gVec.generatedAntiLambda().size()) != hAntiLambda->GetNcells()) + if (static_cast(gVec.generatedAntiLambda().size()) != hAntiLambda->GetNcells()) LOGF(fatal, "AntiLambda: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedAntiLambda().size(), hAntiLambda->GetNcells()); for (int iv = 0; iv < hAntiLambda->GetNcells(); iv++) { hAntiLambda->SetBinContent(iv, hAntiLambda->GetBinContent(iv) + gVec.generatedAntiLambda()[iv]); } } for (auto& gVec : geXiMinus) { - if (int(gVec.generatedXiMinus().size()) != hXiMinus->GetNcells()) + if (static_cast(gVec.generatedXiMinus().size()) != hXiMinus->GetNcells()) LOGF(fatal, "XiMinus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedXiMinus().size(), hXiMinus->GetNcells()); for (int iv = 0; iv < hXiMinus->GetNcells(); iv++) { hXiMinus->SetBinContent(iv, hXiMinus->GetBinContent(iv) + gVec.generatedXiMinus()[iv]); } } for (auto& gVec : geXiPlus) { - if (int(gVec.generatedXiPlus().size()) != hXiPlus->GetNcells()) + if (static_cast(gVec.generatedXiPlus().size()) != hXiPlus->GetNcells()) LOGF(fatal, "XiPlus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedXiPlus().size(), hXiPlus->GetNcells()); for (int iv = 0; iv < hXiPlus->GetNcells(); iv++) { hXiPlus->SetBinContent(iv, hXiPlus->GetBinContent(iv) + gVec.generatedXiPlus()[iv]); } } for (auto& gVec : geOmegaMinus) { - if (int(gVec.generatedOmegaMinus().size()) != hOmegaMinus->GetNcells()) + if (static_cast(gVec.generatedOmegaMinus().size()) != hOmegaMinus->GetNcells()) LOGF(fatal, "OmegaMinus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedOmegaMinus().size(), hOmegaMinus->GetNcells()); for (int iv = 0; iv < hOmegaMinus->GetNcells(); iv++) { hOmegaMinus->SetBinContent(iv, hOmegaMinus->GetBinContent(iv) + gVec.generatedOmegaMinus()[iv]); } } for (auto& gVec : geOmegaPlus) { - if (int(gVec.generatedOmegaPlus().size()) != hOmegaPlus->GetNcells()) + if (static_cast(gVec.generatedOmegaPlus().size()) != hOmegaPlus->GetNcells()) LOGF(fatal, "OmegaPlus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedOmegaPlus().size(), hOmegaPlus->GetNcells()); for (int iv = 0; iv < hOmegaPlus->GetNcells(); iv++) { hOmegaPlus->SetBinContent(iv, hOmegaPlus->GetBinContent(iv) + gVec.generatedOmegaPlus()[iv]); diff --git a/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx b/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx new file mode 100644 index 00000000000..c48229a9d4c --- /dev/null +++ b/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx @@ -0,0 +1,1346 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Strangeness in UPC analysis task +// ================ +// This code is meant to be run over derived data. +// +// Comments, questions, complaints, suggestions? +// Please write to: +// roman.nepeivoda@cern.ch +// + +#include +#include +#include +#include +#include +#include +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "ReconstructionDataFormats/Track.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/PIDResponse.h" +#include "Framework/StaticFor.h" +#include "PWGUD/Core/SGSelector.h" +#include "PWGLF/Utils/strangenessMasks.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +using dauTracks = soa::Join; +using dauMCTracks = soa::Join; + +using v0Candidates = soa::Join; +using v0MCCandidates = soa::Join; + +using cascadeCandidates = soa::Join; + +using straCollisonFull = soa::Join::iterator; + +struct strangeYieldPbPb { + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // master analysis switches + Configurable analyseK0Short{"analyseK0Short", true, "process K0Short-like candidates"}; + Configurable analyseLambda{"analyseLambda", true, "process Lambda-like candidates"}; + Configurable analyseAntiLambda{"analyseAntiLambda", true, "process AntiLambda-like candidates"}; + Configurable analyseXi{"analyseXi", false, "process Xi-like candidates"}; + Configurable analyseAntiXi{"analyseAntiXi", true, "process AntiXi-like candidates"}; + Configurable analyseOmega{"analyseOmega", true, "process Omega-like candidates"}; + Configurable analyseAntiOmega{"analyseAntiOmega", true, "process AntiOmega-like candidates"}; + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + + Configurable requireIsTriggerTVX{"requireIsTriggerTVX", true, "require coincidence in FT0A and FT0C"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable studyUPConly{"studyUPConly", false, "is UPC-only analysis"}; + + Configurable verbose{"verbose", false, "additional printouts"}; + + // Selection criteria: acceptance + Configurable rapidityCut{"rapidityCut", 0.5, "rapidity"}; + Configurable daughterEtaCut{"daughterEtaCut", 0.8, "max eta for daughters"}; + + // Standard V0 topological criteria + struct : ConfigurableGroup { + Configurable v0cospa{"v0cospa", 0.97, "min V0 CosPA"}; + Configurable dcav0dau{"dcav0dau", 1.5, "max DCA V0 Daughters (cm)"}; + Configurable dcanegtopv{"dcanegtopv", .05, "min DCA Neg To PV (cm)"}; + Configurable dcapostopv{"dcapostopv", .05, "min DCA Pos To PV (cm)"}; + Configurable v0radius{"v0radius", 1.2, "minimum V0 radius (cm)"}; + Configurable v0radiusMax{"v0radiusMax", 1E5, "maximum V0 radius (cm)"}; + // Additional selection on the AP plot (exclusive for K0Short) + // original equation: lArmPt*5>fabs(lArmAlpha) + Configurable armPodCut{"armPodCut", 5.0f, "pT * (cut) > |alpha|, AP cut. Negative: no cut"}; + Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; + } v0cuts; + static constexpr float lifetimeCutsV0[1][2] = {{30., 20.}}; + Configurable> lifetimecutV0{"lifetimecutV0", {lifetimeCutsV0[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecutV0"}; + + // Standard cascade topological criteria + Configurable casccospa{"casccospa", 0.97, "Casc CosPA"}; + Configurable dcacascdau{"dcacascdau", 1.2, "DCA Casc Daughters"}; + Configurable cascradius{"cascradius", 0.6, "minimum cascade radius (cm)"}; + Configurable cascradiusMax{"cascradiusMax", 1E5, "maximum cascade radius (cm)"}; + Configurable doBachelorBaryonCut{"doBachelorBaryonCut", false, "Enable Bachelor-Baryon cut "}; + Configurable bachbaryoncospa{"bachbaryoncospa", 2, "Bachelor baryon CosPA"}; + Configurable bachbaryondcaxytopv{"bachbaryondcaxytopv", -1, "DCA bachelor baryon to PV"}; + Configurable dcamesontopv{"dcamesontopv", 0.1, "DCA of meson doughter track To PV"}; + Configurable dcabaryontopv{"dcabaryontopv", 0.05, "DCA of baryon doughter track To PV"}; + Configurable dcabachtopv{"dcabachtopv", 0.04, "DCA Bach To PV"}; + Configurable dcav0topv{"dcav0topv", 0.06, "DCA V0 To PV"}; + // Cascade specific selections + Configurable masswin{"masswin", 0.05, "mass window limit"}; + Configurable lambdamasswin{"lambdamasswin", 0.005, "V0 Mass window limit"}; + Configurable rejcomp{"rejcomp", 0.008, "competing Cascade rejection"}; + static constexpr float nCtauCutsCasc[1][2] = {{6., 6.}}; + Configurable> nCtauCutCasc{"nCtauCutCasc", {nCtauCutsCasc[0], 2, {"lifetimecutXi", "lifetimecutOmega"}}, "nCtauCutCasc"}; + + // UPC selections + SGSelector sgSelector; + struct : ConfigurableGroup { + Configurable FV0cut{"FV0cut", 100., "FV0A threshold"}; + Configurable FT0Acut{"FT0Acut", 200., "FT0A threshold"}; + Configurable FT0Ccut{"FT0Ccut", 100., "FT0C threshold"}; + Configurable ZDCcut{"ZDCcut", 10., "ZDC threshold"}; + // Configurable gapSel{"gapSel", 2, "Gap selection"}; + } upcCuts; + + // Track quality + struct : ConfigurableGroup { + Configurable minTPCrows{"minTPCrows", 70, "minimum TPC crossed rows"}; + Configurable minITSclusters{"minITSclusters", -1, "minimum ITS clusters"}; + Configurable skipTPConly{"skipTPConly", false, "skip V0s comprised of at least one TPC only prong"}; + Configurable requireBachITSonly{"requireBachITSonly", false, "require that bachelor track is ITSonly (overrides TPC quality)"}; + Configurable requirePosITSonly{"requirePosITSonly", false, "require that positive track is ITSonly (overrides TPC quality)"}; + Configurable requireNegITSonly{"requireNegITSonly", false, "require that negative track is ITSonly (overrides TPC quality)"}; + } TrackConfigurations; + + // PID (TPC/TOF) + struct : ConfigurableGroup { + Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 1e+6, "TpcPidNsigmaCut"}; + Configurable TofPidNsigmaCutLaPr{"TofPidNsigmaCutLaPr", 1e+6, "TofPidNsigmaCutLaPr"}; + Configurable TofPidNsigmaCutLaPi{"TofPidNsigmaCutLaPi", 1e+6, "TofPidNsigmaCutLaPi"}; + Configurable TofPidNsigmaCutK0Pi{"TofPidNsigmaCutK0Pi", 1e+6, "TofPidNsigmaCutK0Pi"}; + + Configurable TofPidNsigmaCutXiPi{"TofPidNsigmaCutXiPi", 1e+6, "TofPidNsigmaCutXiPi"}; + Configurable TofPidNsigmaCutOmegaKaon{"TofPidNsigmaCutOmegaKaon", 1e+6, "TofPidNsigmaCutOmegaKaon"}; + + Configurable doTPCQA{"doTPCQA", false, "do TPC QA histograms"}; + Configurable doTOFQA{"doTOFQA", false, "do TOF QA histograms"}; + Configurable doDetectPropQA{"doDetectPropQA", 0, "do Detector/ITS map QA: 0: no, 1: 4D, 2: 5D with mass"}; + + Configurable doPlainTopoQA{"doPlainTopoQA", true, "do simple 1D QA of candidates"}; + Configurable qaMinPt{"qaMinPt", 0.0f, "minimum pT for QA plots"}; + Configurable qaMaxPt{"qaMaxPt", 1000.0f, "maximum pT for QA plots"}; + + // PID (TOF) + Configurable maxDeltaTimeProton{"maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimePion{"maxDeltaTimePion", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimeKaon{"maxDeltaTimeKaon", 1e+9, "check maximum allowed time"}; + } PIDConfigurations; + + // for MC + Configurable doMCAssociation{"doMCAssociation", true, "if MC, do MC association"}; + Configurable doCollisionAssociationQA{"doCollisionAssociationQA", true, "check collision association"}; + + // fast check on occupancy + Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for v0 analysis"}; + ConfigurableAxis axisPtXi{"axisPtCasc", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for cascade analysis"}; + ConfigurableAxis axisPtCoarse{"axisPtCoarse", {VARIABLE_WIDTH, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 7.0f, 10.0f, 15.0f}, "pt axis for QA"}; + + ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; + ConfigurableAxis axisXiMass{"axisXiMass", {200, 1.28f, 1.36f}, ""}; + ConfigurableAxis axisOmegaMass{"axisOmegaMass", {200, 1.59f, 1.75f}, ""}; + + ConfigurableAxis axisNch{"axisNch", {1000, -0.5f, 999.5f}, "Number of charged particles"}; + ConfigurableAxis axisFT0C{"FT0C", + {VARIABLE_WIDTH, 0., 0.01, 0.05, 0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 105.5}, + "FT0C (%)"}; + + ConfigurableAxis axisOccupancy{"axisOccupancy", {VARIABLE_WIDTH, 0.0f, 250.0f, 500.0f, 750.0f, 1000.0f, 1500.0f, 2000.0f, 3000.0f, 4500.0f, 6000.0f, 8000.0f, 10000.0f, 50000.0f}, "Occupancy"}; + + // UPC axes + ConfigurableAxis axisSelGap{"axisSelGap", {4, -1.5, 2.5}, "Gap side"}; + + // AP plot axes + ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; + ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; + + // Track quality axes + ConfigurableAxis axisTPCrows{"axisTPCrows", {160, -0.5f, 159.5f}, "N TPC rows"}; + ConfigurableAxis axisITSclus{"axisITSclus", {7, -0.5f, 6.5f}, "N ITS Clusters"}; + ConfigurableAxis axisITScluMap{"axisITSMap", {128, -0.5f, 127.5f}, "ITS Cluster map"}; + ConfigurableAxis axisDetMap{"axisDetMap", {16, -0.5f, 15.5f}, "Detector use map"}; + ConfigurableAxis axisITScluMapCoarse{"axisITScluMapCoarse", {16, -3.5f, 12.5f}, "ITS Coarse cluster map"}; + ConfigurableAxis axisDetMapCoarse{"axisDetMapCoarse", {5, -0.5f, 4.5f}, "Detector Coarse user map"}; + + // MC coll assoc QA axis + ConfigurableAxis axisMonteCarloNch{"axisMonteCarloNch", {300, 0.0f, 3000.0f}, "N_{ch} MC"}; + // Topological variable QA axes + ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {80, -4.0f, 4.0f}, "DCA (cm)"}; + ConfigurableAxis axisDCAdau{"axisDCAdau", {24, 0.0f, 1.2f}, "DCA (cm)"}; + ConfigurableAxis axisPointingAngle{"axisPointingAngle", {100, 0.0f, 0.5f}, "pointing angle (rad)"}; + ConfigurableAxis axisV0Radius{"axisV0Radius", {60, 0.0f, 60.0f}, "V0 2D radius (cm)"}; + ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {200, -10.0f, 10.0f}, "N sigma TPC"}; + ConfigurableAxis axisTPCsignal{"axisTPCsignal", {200, 0.0f, 200.0f}, "TPC signal"}; + ConfigurableAxis axisTOFdeltaT{"axisTOFdeltaT", {200, -5000.0f, 5000.0f}, "TOF Delta T (ps)"}; + + // PDG database + Service pdgDB; + + void setBits(std::bitset& mask, std::initializer_list selections) + { + for (int sel : selections) { + mask.set(sel); + } + } + + void init(InitContext const&) + { + // initialise bit masks + setBits(maskTopologicalV0, {selV0CosPA, selDCANegToPV, selDCAPosToPV, selDCAV0Dau, selV0Radius, selV0RadiusMax}); + setBits(maskTopologicalCasc, {selCascCosPA, selDCACascDau, selCascRadius, selCascRadiusMax, selBachToPV, selMesonToPV, selBaryonToPV, + selDCAV0ToPV, selV0CosPA, selDCAV0Dau, selV0Radius, selV0RadiusMax, selLambdaMassWin}); + + if (doBachelorBaryonCut) + maskTopologicalCasc.set(selBachBaryon); + + setBits(maskKinematicV0, {selPosEta, selNegEta}); + setBits(maskKinematicCasc, {selPosEta, selNegEta, selBachEta}); + + // Specific masks + setBits(maskK0ShortSpecific, {selK0ShortRapidity, selK0ShortCTau, selK0ShortArmenteros, selConsiderK0Short}); + setBits(maskLambdaSpecific, {selLambdaRapidity, selLambdaCTau, selConsiderLambda}); + setBits(maskAntiLambdaSpecific, {selLambdaRapidity, selLambdaCTau, selConsiderAntiLambda}); + setBits(maskXiSpecific, {selXiRapidity, selXiCTau, selRejCompXi, selMassWinXi, selConsiderXi}); + setBits(maskAntiXiSpecific, {selXiRapidity, selXiCTau, selRejCompXi, selMassWinXi, selConsiderAntiXi}); + setBits(maskOmegaSpecific, {selOmegaRapidity, selOmegaCTau, selRejCompOmega, selMassWinOmega, selConsiderOmega}); + setBits(maskAntiOmegaSpecific, {selOmegaRapidity, selOmegaCTau, selRejCompOmega, selMassWinOmega, selConsiderAntiOmega}); + + // ask for specific TPC/TOF PID selections + // positive track + if (TrackConfigurations.requirePosITSonly) { + setBits(maskTrackPropertiesV0, {selPosItsOnly, selPosGoodITSTrack}); + } else { + setBits(maskTrackPropertiesV0, {selPosGoodTPCTrack, selPosGoodITSTrack}); + // TPC signal is available: ask for positive track PID + if (PIDConfigurations.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskK0ShortSpecific.set(selTPCPIDPositivePion); + maskLambdaSpecific.set(selTPCPIDPositiveProton); + maskAntiLambdaSpecific.set(selTPCPIDPositivePion); + + maskXiSpecific.set(selTPCPIDPositiveProton); + maskAntiXiSpecific.set(selTPCPIDPositivePion); + maskOmegaSpecific.set(selTPCPIDPositiveProton); + maskAntiOmegaSpecific.set(selTPCPIDPositivePion); + } + // TOF PID + if (PIDConfigurations.TofPidNsigmaCutK0Pi < 1e+5) { // safeguard for no cut + setBits(maskK0ShortSpecific, {selTOFNSigmaPositivePionK0Short, selTOFDeltaTPositivePionK0Short}); + } + if (PIDConfigurations.TofPidNsigmaCutLaPr < 1e+5) { // safeguard for no cut + setBits(maskLambdaSpecific, {selTOFNSigmaPositiveProtonLambda, selTOFDeltaTPositiveProtonLambda}); + setBits(maskXiSpecific, {selTOFNSigmaPositiveProtonLambdaXi, selTOFDeltaTPositiveProtonLambdaXi}); + setBits(maskOmegaSpecific, {selTOFNSigmaPositiveProtonLambdaOmega, selTOFDeltaTPositiveProtonLambdaOmega}); + } + if (PIDConfigurations.TofPidNsigmaCutLaPi < 1e+5) { // safeguard for no cut + setBits(maskAntiLambdaSpecific, {selTOFNSigmaPositivePionLambda, selTOFDeltaTPositivePionLambda}); + setBits(maskAntiXiSpecific, {selTOFNSigmaPositivePionLambdaXi, selTOFDeltaTPositivePionLambdaXi}); + setBits(maskAntiOmegaSpecific, {selTOFNSigmaPositivePionLambdaOmega, selTOFDeltaTPositivePionLambdaOmega}); + } + } + // negative track + if (TrackConfigurations.requireNegITSonly) { + setBits(maskTrackPropertiesV0, {selNegItsOnly, selNegGoodITSTrack}); + } else { + setBits(maskTrackPropertiesV0, {selNegGoodTPCTrack, selNegGoodITSTrack}); + // TPC signal is available: ask for negative track PID + if (PIDConfigurations.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskK0ShortSpecific.set(selTPCPIDNegativePion); + maskLambdaSpecific.set(selTPCPIDNegativePion); + maskAntiLambdaSpecific.set(selTPCPIDNegativeProton); + + maskXiSpecific.set(selTPCPIDNegativePion); + maskAntiXiSpecific.set(selTPCPIDPositiveProton); + maskOmegaSpecific.set(selTPCPIDNegativePion); + maskAntiOmegaSpecific.set(selTPCPIDPositiveProton); + } + // TOF PID + if (PIDConfigurations.TofPidNsigmaCutK0Pi < 1e+5) { // safeguard for no cut + setBits(maskK0ShortSpecific, {selTOFNSigmaNegativePionK0Short, selTOFDeltaTNegativePionK0Short}); + } + if (PIDConfigurations.TofPidNsigmaCutLaPr < 1e+5) { // safeguard for no cut + setBits(maskAntiLambdaSpecific, {selTOFNSigmaNegativeProtonLambda, selTOFDeltaTNegativeProtonLambda}); + setBits(maskAntiXiSpecific, {selTOFNSigmaNegativeProtonLambdaXi, selTOFDeltaTNegativeProtonLambdaXi}); + setBits(maskAntiOmegaSpecific, {selTOFNSigmaNegativeProtonLambdaOmega, selTOFDeltaTNegativeProtonLambdaOmega}); + } + if (PIDConfigurations.TofPidNsigmaCutLaPi < 1e+5) { // safeguard for no cut + setBits(maskLambdaSpecific, {selTOFNSigmaNegativePionLambda, selTOFDeltaTNegativePionLambda}); + setBits(maskXiSpecific, {selTOFNSigmaNegativePionLambdaXi, selTOFDeltaTNegativePionLambdaXi}); + setBits(maskOmegaSpecific, {selTOFNSigmaNegativePionLambdaOmega, selTOFDeltaTNegativePionLambdaOmega}); + } + } + // bachelor track + maskTrackPropertiesCasc = maskTrackPropertiesV0; + if (TrackConfigurations.requireBachITSonly) { + setBits(maskTrackPropertiesCasc, {selBachItsOnly, selBachGoodITSTrack}); + } else { + setBits(maskTrackPropertiesCasc, {selBachGoodTPCTrack, selBachGoodITSTrack}); + // TPC signal is available: ask for positive track PID + if (PIDConfigurations.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskXiSpecific.set(selTPCPIDBachPion); + maskAntiXiSpecific.set(selTPCPIDBachPion); + maskOmegaSpecific.set(selTPCPIDBachKaon); + maskAntiOmegaSpecific.set(selTPCPIDBachKaon); + } + // TOF PID + if (PIDConfigurations.TofPidNsigmaCutXiPi < 1e+5) { // safeguard for no cut + setBits(maskXiSpecific, {selTOFNSigmaBachPionXi, selTOFDeltaTBachPionXi}); + setBits(maskAntiXiSpecific, {selTOFNSigmaBachPionXi, selTOFDeltaTBachPionXi}); + } + if (PIDConfigurations.TofPidNsigmaCutOmegaKaon < 1e+5) { // safeguard for no cut + setBits(maskOmegaSpecific, {selTOFNSigmaBachKaonOmega, selTOFDeltaTBachKaonOmega}); + setBits(maskAntiOmegaSpecific, {selTOFNSigmaBachKaonOmega, selTOFDeltaTBachKaonOmega}); + } + } + + if (TrackConfigurations.skipTPConly) { + setBits(maskK0ShortSpecific, {selPosNotTPCOnly, selNegNotTPCOnly}); + setBits(maskLambdaSpecific, {selPosNotTPCOnly, selNegNotTPCOnly}); + setBits(maskAntiLambdaSpecific, {selPosNotTPCOnly, selNegNotTPCOnly}); + setBits(maskXiSpecific, {selPosNotTPCOnly, selNegNotTPCOnly, selBachNotTPCOnly}); + setBits(maskOmegaSpecific, {selPosNotTPCOnly, selNegNotTPCOnly, selBachNotTPCOnly}); + setBits(maskAntiXiSpecific, {selPosNotTPCOnly, selNegNotTPCOnly, selBachNotTPCOnly}); + setBits(maskAntiOmegaSpecific, {selPosNotTPCOnly, selNegNotTPCOnly, selBachNotTPCOnly}); + } + + // Primary particle selection, central to analysis + maskSelectionK0Short = maskTopologicalV0 | maskKinematicV0 | maskTrackPropertiesV0 | maskK0ShortSpecific | (std::bitset(1) << selPhysPrimK0Short); + maskSelectionLambda = maskTopologicalV0 | maskKinematicV0 | maskTrackPropertiesV0 | maskLambdaSpecific | (std::bitset(1) << selPhysPrimLambda); + maskSelectionAntiLambda = maskTopologicalV0 | maskKinematicV0 | maskTrackPropertiesV0 | maskAntiLambdaSpecific | (std::bitset(1) << selPhysPrimAntiLambda); + maskSelectionXi = maskTopologicalCasc | maskKinematicCasc | maskTrackPropertiesCasc | maskXiSpecific | (std::bitset(1) << selPhysPrimXi); + maskSelectionAntiXi = maskTopologicalCasc | maskKinematicCasc | maskTrackPropertiesCasc | maskAntiXiSpecific | (std::bitset(1) << selPhysPrimAntiXi); + maskSelectionOmega = maskTopologicalCasc | maskKinematicCasc | maskTrackPropertiesCasc | maskOmegaSpecific | (std::bitset(1) << selPhysPrimOmega); + maskSelectionAntiOmega = maskTopologicalCasc | maskKinematicCasc | maskTrackPropertiesCasc | maskAntiOmegaSpecific | (std::bitset(1) << selPhysPrimAntiOmega); + + // Check if doing the right thing in AP space please + histos.add("GeneralQA/h2dArmenterosAll", "h2dArmenterosAll", kTH2F, {axisAPAlpha, axisAPQt}); + histos.add("GeneralQA/h2dArmenterosSelected", "h2dArmenterosSelected", kTH2F, {axisAPAlpha, axisAPQt}); + + // Event Counters + histos.add("hEventSelection", "hEventSelection", kTH1F, {{15, -0.5f, +14.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "kIsTriggerTVX"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "Above max occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "isUPC"); + + // Event QA + histos.add("eventQA/hEventCentrality", "hEventCentrality", kTH1F, {axisFT0C}); + histos.add("eventQA/hCentralityVsNch", "hCentralityVsNch", kTH2F, {axisFT0C, axisNch}); + histos.add("eventQA/hEventOccupancy", "hEventOccupancy", kTH1F, {axisOccupancy}); + histos.add("eventQA/hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH2F, {axisFT0C, axisOccupancy}); + histos.add("eventQA/hGapSide", "Gap side; Entries", kTH1F, {{5, -0.5, 4.5}}); + histos.add("eventQA/hSelGapSide", "Selected gap side; Entries", kTH1F, {axisSelGap}); + histos.add("eventQA/hPosX", "Vertex position in x", kTH1F, {{100, -0.1, 0.1}}); + histos.add("eventQA/hPosY", "Vertex position in y", kTH1F, {{100, -0.1, 0.1}}); + histos.add("eventQA/hPosZ", "Vertex position in z", kTH1F, {{100, -20., 20.}}); + + if (PIDConfigurations.doPlainTopoQA) { + // For all candidates + histos.add("GeneralQA/hPt", "hPt", kTH1F, {axisPtCoarse}); + histos.add("GeneralQA/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("GeneralQA/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("GeneralQA/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("GeneralQA/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("GeneralQA/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("GeneralQA/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("GeneralQA/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } + + if (doprocessV0s) { + // K0s + if (analyseK0Short) { + histos.add("K0Short/h4dMassK0Short", "h4dMassK0Short", kTHnF, {axisFT0C, axisPt, axisK0Mass, axisSelGap}); + histos.add("K0Short/h2dMassK0Short", "h2dMassK0Short", kTH2F, {axisK0Mass, axisSelGap}); + if (PIDConfigurations.doTPCQA) { + histos.add("K0Short/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("K0Short/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("K0Short/h3dPosTPCsignal", "h3dPosTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("K0Short/h3dNegTPCsignal", "h3dNegTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("K0Short/h3dPosNsigmaTPCvsTrackPtot", "h3dPosNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("K0Short/h3dNegNsigmaTPCvsTrackPtot", "h3dNegNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("K0Short/h3dPosTPCsignalVsTrackPtot", "h3dPosTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("K0Short/h3dNegTPCsignalVsTrackPtot", "h3dNegTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("K0Short/h3dPosNsigmaTPCvsTrackPt", "h3dPosNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("K0Short/h3dNegNsigmaTPCvsTrackPt", "h3dNegNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("K0Short/h3dPosTPCsignalVsTrackPt", "h3dPosTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("K0Short/h3dNegTPCsignalVsTrackPt", "h3dNegTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + } + if (PIDConfigurations.doTOFQA) { + histos.add("K0Short/h3dPosTOFdeltaT", "h3dPosTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("K0Short/h3dNegTOFdeltaT", "h3dNegTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("K0Short/h3dPosTOFdeltaTvsTrackPtot", "h3dPosTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("K0Short/h3dNegTOFdeltaTvsTrackPtot", "h3dNegTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("K0Short/h3dPosTOFdeltaTvsTrackPt", "h3dPosTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("K0Short/h3dNegTOFdeltaTvsTrackPt", "h3dNegTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + } + if (PIDConfigurations.doDetectPropQA == 1) { + histos.add("K0Short/h6dDetectPropVsCentrality", "h6dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add("K0Short/h4dPosDetectPropVsCentrality", "h4dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add("K0Short/h4dNegDetectPropVsCentrality", "h4dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + } + if (PIDConfigurations.doDetectPropQA == 2) { + histos.add("K0Short/h7dDetectPropVsCentrality", "h7dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisK0Mass}); + histos.add("K0Short/h5dPosDetectPropVsCentrality", "h5dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisK0Mass}); + histos.add("K0Short/h5dNegDetectPropVsCentrality", "h5dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisK0Mass}); + } + if (PIDConfigurations.doPlainTopoQA) { + histos.add("K0Short/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("K0Short/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("K0Short/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("K0Short/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("K0Short/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("K0Short/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("K0Short/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } + } + + // Lambda + if (analyseLambda) { + histos.add("Lambda/h4dMassLambda", "h4dMassLambda", kTHnF, {axisFT0C, axisPt, axisLambdaMass, axisSelGap}); + histos.add("Lambda/h2dMassLambda", "h2dMassLambda", kTH2F, {axisLambdaMass, axisSelGap}); + if (PIDConfigurations.doTPCQA) { + histos.add("Lambda/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("Lambda/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("Lambda/h3dPosTPCsignal", "h3dPosTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("Lambda/h3dNegTPCsignal", "h3dNegTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("Lambda/h3dPosNsigmaTPCvsTrackPtot", "h3dPosNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("Lambda/h3dNegNsigmaTPCvsTrackPtot", "h3dNegNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("Lambda/h3dPosTPCsignalVsTrackPtot", "h3dPosTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("Lambda/h3dNegTPCsignalVsTrackPtot", "h3dNegTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("Lambda/h3dPosNsigmaTPCvsTrackPt", "h3dPosNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("Lambda/h3dNegNsigmaTPCvsTrackPt", "h3dNegNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("Lambda/h3dPosTPCsignalVsTrackPt", "h3dPosTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("Lambda/h3dNegTPCsignalVsTrackPt", "h3dNegTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + } + if (PIDConfigurations.doTOFQA) { + histos.add("Lambda/h3dPosTOFdeltaT", "h3dPosTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("Lambda/h3dNegTOFdeltaT", "h3dNegTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("Lambda/h3dPosTOFdeltaTvsTrackPtot", "h3dPosTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("Lambda/h3dNegTOFdeltaTvsTrackPtot", "h3dNegTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("Lambda/h3dPosTOFdeltaTvsTrackPt", "h3dPosTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("Lambda/h3dNegTOFdeltaTvsTrackPt", "h3dNegTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + } + if (PIDConfigurations.doDetectPropQA == 1) { + histos.add("Lambda/h6dDetectPropVsCentrality", "h6dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add("Lambda/h4dPosDetectPropVsCentrality", "h4dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add("Lambda/h4dNegDetectPropVsCentrality", "h4dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + } + if (PIDConfigurations.doDetectPropQA == 2) { + histos.add("Lambda/h7dDetectPropVsCentrality", "h7dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisLambdaMass}); + histos.add("Lambda/h5dPosDetectPropVsCentrality", "h5dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisLambdaMass}); + histos.add("Lambda/h5dNegDetectPropVsCentrality", "h5dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisLambdaMass}); + } + if (PIDConfigurations.doPlainTopoQA) { + histos.add("Lambda/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("Lambda/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("Lambda/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("Lambda/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("Lambda/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("Lambda/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("Lambda/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } + if (doCollisionAssociationQA) { + histos.add("Lambda/h2dPtVsNch", "h2dPtVsNch", kTH2F, {axisMonteCarloNch, axisPt}); + histos.add("Lambda/h2dPtVsNch_BadCollAssig", "h2dPtVsNch_BadCollAssig", kTH2F, {axisMonteCarloNch, axisPt}); + } + } + + // Anti-Lambda + if (analyseAntiLambda) { + histos.add("AntiLambda/h4dMassAntiLambda", "h4dMassAntiLambda", kTHnF, {axisFT0C, axisPt, axisLambdaMass, axisSelGap}); + histos.add("AntiLambda/h2dMassAntiLambda", "h2dMassAntiLambda", kTH2F, {axisLambdaMass, axisSelGap}); + if (PIDConfigurations.doTPCQA) { + histos.add("AntiLambda/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("AntiLambda/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("AntiLambda/h3dPosTPCsignal", "h3dPosTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("AntiLambda/h3dNegTPCsignal", "h3dNegTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("AntiLambda/h3dPosNsigmaTPCvsTrackPtot", "h3dPosNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("AntiLambda/h3dNegNsigmaTPCvsTrackPtot", "h3dNegNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("AntiLambda/h3dPosTPCsignalVsTrackPtot", "h3dPosTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("AntiLambda/h3dNegTPCsignalVsTrackPtot", "h3dNegTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("AntiLambda/h3dPosNsigmaTPCvsTrackPt", "h3dPosNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("AntiLambda/h3dNegNsigmaTPCvsTrackPt", "h3dNegNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add("AntiLambda/h3dPosTPCsignalVsTrackPt", "h3dPosTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add("AntiLambda/h3dNegTPCsignalVsTrackPt", "h3dNegTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + } + if (PIDConfigurations.doTOFQA) { + histos.add("AntiLambda/h3dPosTOFdeltaT", "h3dPosTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("AntiLambda/h3dNegTOFdeltaT", "h3dNegTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("AntiLambda/h3dPosTOFdeltaTvsTrackPtot", "h3dPosTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("AntiLambda/h3dNegTOFdeltaTvsTrackPtot", "h3dNegTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("AntiLambda/h3dPosTOFdeltaTvsTrackPt", "h3dPosTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add("AntiLambda/h3dNegTOFdeltaTvsTrackPt", "h3dNegTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + } + if (PIDConfigurations.doPlainTopoQA) { + histos.add("AntiLambda/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("AntiLambda/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("AntiLambda/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("AntiLambda/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("AntiLambda/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("AntiLambda/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("AntiLambda/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } + if (PIDConfigurations.doDetectPropQA == 1) { + histos.add("AntiLambda/h6dDetectPropVsCentrality", "h6dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add("AntiLambda/h4dPosDetectPropVsCentrality", "h4dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add("AntiLambda/h4dNegDetectPropVsCentrality", "h4dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + } + if (PIDConfigurations.doDetectPropQA == 2) { + histos.add("AntiLambda/h7dDetectPropVsCentrality", "h7dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisLambdaMass}); + histos.add("AntiLambda/h5dPosDetectPropVsCentrality", "h5dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisLambdaMass}); + histos.add("AntiLambda/h5dNegDetectPropVsCentrality", "h5dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisLambdaMass}); + } + if (doCollisionAssociationQA) { + histos.add("AntiLambda/h2dPtVsNch", "h2dPtVsNch", kTH2F, {axisMonteCarloNch, axisPt}); + histos.add("AntiLambda/h2dPtVsNch_BadCollAssig", "h2dPtVsNch_BadCollAssig", kTH2F, {axisMonteCarloNch, axisPt}); + } + } + } + + if (doprocessCascades) { + // Xi + if (analyseXi) { + histos.add("Xi/h2dMassXi", "h2dMassXi", kTH2F, {axisXiMass, axisSelGap}); + if (PIDConfigurations.doPlainTopoQA) { + histos.add("Xi/hCascCosPA", "hCascCosPA", kTH2F, {axisPtCoarse, {100, 0.9f, 1.0f}}); + histos.add("Xi/hDCACascDaughters", "hDCACascDaughters", kTH2F, {axisPtCoarse, {44, 0.0f, 2.2f}}); + histos.add("Xi/hCascRadius", "hCascRadius", kTH2D, {axisPtCoarse, {500, 0.0f, 50.0f}}); + histos.add("Xi/hMesonDCAToPV", "hMesonDCAToPV", kTH2F, {axisPtCoarse, axisDCAtoPV}); + histos.add("Xi/hBaryonDCAToPV", "hBaryonDCAToPV", kTH2F, {axisPtCoarse, axisDCAtoPV}); + histos.add("Xi/hBachDCAToPV", "hBachDCAToPV", kTH2F, {axisPtCoarse, {200, -1.0f, 1.0f}}); + histos.add("Xi/hV0DCAToPV", "hV0DCAToPV", kTH2F, {axisPtCoarse, axisDCAtoPV}); + histos.add("Xi/hV0CosPA", "hV0CosPA", kTH2F, {axisPtCoarse, {100, 0.9f, 1.0f}}); + histos.add("Xi/hV0Radius", "hV0Radius", kTH2D, {axisPtCoarse, axisV0Radius}); + histos.add("Xi/hDCAV0Daughters", "hDCAV0Daughters", kTH2F, {axisPtCoarse, axisDCAdau}); + histos.add("Xi/hDCAV0ToPV", "hDCAV0ToPV", kTH2F, {axisPtCoarse, {55, 0.0f, 2.20f}}); + histos.add("Xi/hMassLambdaDau", "hMassLambdaDau", kTH2F, {axisPtCoarse, axisLambdaMass}); + if (doBachelorBaryonCut) { + histos.add("Xi/hBachBaryonCosPA", "hBachBaryonCosPA", kTH2F, {axisPtCoarse, {100, 0.0f, 1.0f}}); + histos.add("Xi/hBachBaryonDCAxyToPV", "hBachBaryonDCAxyToPV", kTH2F, {axisPtCoarse, {300, -3.0f, 3.0f}}); + } + } + } + + // Anti-Xi + if (analyseAntiXi) { + histos.add("AntiXi/h2dMassAntiXi", "h2dMassAntiXi", kTH2F, {axisXiMass, axisSelGap}); + } + + // Omega + if (analyseOmega) { + histos.add("Omega/h2dMassOmega", "h2dMassOmega", kTH2F, {axisOmegaMass, axisSelGap}); + } + + // Anti-Omega + if (analyseAntiOmega) { + histos.add("AntiOmega/h2dMassAntiOmega", "h2dMassAntiOmega", kTH2F, {axisOmegaMass, axisSelGap}); + } + } + + if (verbose) { + histos.print(); + } + } + + template + bool acceptEvent(TCollision const& collision) + { + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + + if (requireIsTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + return false; + } + histos.fill(HIST("hEventSelection"), 1 /* triggered by FT0M */); + + if (fabs(collision.posZ()) > 10.f) { + return false; + } + histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); + + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return false; + } + histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); + + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return false; + } + histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + + if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + histos.fill(HIST("hEventSelection"), 5 /* Contains at least one ITS-TPC track */); + + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + histos.fill(HIST("hEventSelection"), 6 /* PV position consistency check */); + + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return false; + } + histos.fill(HIST("hEventSelection"), 7 /* PV with at least one contributor matched with TOF */); + + if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + return false; + } + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TRD */); + + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + histos.fill(HIST("hEventSelection"), 9 /* Not at same bunch pile-up */); + + if (requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + histos.fill(HIST("hEventSelection"), 10 /* No other collision within +/- 10 microseconds */); + + if (requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 4 microseconds */); + + if (minOccupancy > 0 && collision.trackOccupancyInTimeRange() < minOccupancy) { + return false; + } + histos.fill(HIST("hEventSelection"), 12 /* Above min occupancy */); + + if (maxOccupancy > 0 && collision.trackOccupancyInTimeRange() > maxOccupancy) { + return false; + } + histos.fill(HIST("hEventSelection"), 13 /* Below max occupancy */); + + if (studyUPConly && !collision.isUPC()) { + return false; + } else if (collision.isUPC()) { + histos.fill(HIST("hEventSelection"), 14 /* is UPC compatible */); + } + + // QA histograms + float centrality = collision.centFT0C(); + histos.fill(HIST("eventQA/hEventCentrality"), centrality); + histos.fill(HIST("eventQA/hCentralityVsNch"), centrality, collision.multNTracksPVeta1()); + histos.fill(HIST("eventQA/hEventOccupancy"), collision.trackOccupancyInTimeRange()); + histos.fill(HIST("eventQA/hCentralityVsOccupancy"), centrality, collision.trackOccupancyInTimeRange()); + histos.fill(HIST("eventQA/hPosX"), collision.posX()); + histos.fill(HIST("eventQA/hPosY"), collision.posY()); + histos.fill(HIST("eventQA/hPosZ"), collision.posZ()); + + return true; + } + + bool verifyMask(std::bitset bitmap, std::bitset mask) + { + return (bitmap & mask) == mask; + } + + int computeITSclusBitmap(uint8_t itsClusMap, bool fromAfterburner) + { + int bitMap = 0; + + struct MaskBitmapPair { + uint8_t mask; + int bitmap; + int afterburnerBitmap; + }; + + constexpr MaskBitmapPair configs[] = { + // L6 <-- L0 + {0x7F, 12, 12}, // 01111 111 (L0 to L6) + {0x7E, 11, 11}, // 01111 110 (L1 to L6) + {0x7C, 10, 10}, // 01111 100 (L2 to L6) + {0x78, 9, -3}, // 01111 000 (L3 to L6) + {0x70, 8, -2}, // 01110 000 (L4 to L6) + {0x60, 7, -1}, // 01100 000 (L5 to L6) + {0x3F, 6, 6}, // 00111 111 (L0 to L5) + {0x3E, 5, 5}, // 00111 110 (L1 to L5) + {0x3C, 4, 4}, // 00111 100 (L2 to L5) + {0x1F, 3, 3}, // 00011 111 (L0 to L4) + {0x1E, 2, 2}, // 00011 110 (L1 to L4) + {0x0F, 1, 1}, // 00001 111 (L0 to L3) + }; + + for (const auto& config : configs) { + if (verifyMask(itsClusMap, config.mask)) { + bitMap = fromAfterburner ? config.afterburnerBitmap : config.bitmap; + break; + } + } + + return bitMap; + } + + uint computeDetBitmap(uint8_t detMap) + { + uint bitMap = 0; + + struct MaskBitmapPair { + uint8_t mask; + int bitmap; + }; + + constexpr MaskBitmapPair configs[] = { + {o2::aod::track::ITS | o2::aod::track::TPC | o2::aod::track::TRD | o2::aod::track::TOF, 4}, // ITS-TPC-TRD-TOF + {o2::aod::track::ITS | o2::aod::track::TPC | o2::aod::track::TOF, 3}, // ITS-TPC-TOF + {o2::aod::track::ITS | o2::aod::track::TPC | o2::aod::track::TRD, 2}, // ITS-TPC-TRD + {o2::aod::track::ITS | o2::aod::track::TPC, 1} // ITS-TPC + }; + + for (const auto& config : configs) { + if (verifyMask(detMap, config.mask)) { + bitMap = config.bitmap; + break; + } + } + + return bitMap; + } + + template + std::bitset computeBitmapCascade(TCasc casc, TCollision coll) + { + float rapidityXi = casc.yXi(); + float rapidityOmega = casc.yOmega(); + + // Access daughter tracks + auto posTrackExtra = casc.template posTrackExtra_as(); + auto negTrackExtra = casc.template negTrackExtra_as(); + auto bachTrackExtra = casc.template bachTrackExtra_as(); + + // c x tau + float decayPos = std::hypot(casc.x() - coll.posX(), casc.y() - coll.posY(), casc.z() - coll.posZ()); + float totalMom = std::hypot(casc.px(), casc.py(), casc.pz()); + float ctauXi = 1e6; + float ctauOmega = 1e6; + if (totalMom != 0) { + ctauXi = pdgDB->Mass(3312) * decayPos / (totalMom); + ctauOmega = pdgDB->Mass(3334) * decayPos / (totalMom); + } + + std::bitset bitMap = 0; + + if (casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()) > casccospa) + bitMap.set(selCascCosPA); + if (casc.dcacascdaughters() < dcacascdau) + bitMap.set(selDCACascDau); + if (casc.cascradius() > cascradius) + bitMap.set(selCascRadius); + if (casc.cascradius() < cascradiusMax) + bitMap.set(selCascRadiusMax); + if (doBachelorBaryonCut && casc.bachBaryonCosPA() < bachbaryoncospa && fabs(casc.bachBaryonDCAxyToPV()) > bachbaryondcaxytopv) + bitMap.set(selBachBaryon); + if (fabs(casc.dcabachtopv()) > dcabachtopv) + bitMap.set(selBachToPV); + + if (casc.sign() > 0) { + if (fabs(casc.dcanegtopv()) > dcabaryontopv) + bitMap.set(selBaryonToPV); + if (fabs(casc.dcapostopv()) > dcamesontopv) + bitMap.set(selMesonToPV); + } else { // no sign == 0, in principle + if (fabs(casc.dcapostopv()) > dcabaryontopv) + bitMap.set(selBaryonToPV); + if (fabs(casc.dcanegtopv()) > dcamesontopv) + bitMap.set(selMesonToPV); + } + + if (fabs(casc.mXi() - pdgDB->Mass(3312)) < masswin) + bitMap.set(selMassWinXi); + if (fabs(casc.mOmega() - pdgDB->Mass(3334)) < masswin) + bitMap.set(selMassWinOmega); + if (fabs(casc.mLambda() - pdgDB->Mass(3122)) < lambdamasswin) + bitMap.set(selLambdaMassWin); + + if (fabs(casc.dcav0topv(coll.posX(), coll.posY(), coll.posZ())) > dcav0topv) + bitMap.set(selDCAV0ToPV); + if (casc.v0radius() > v0cuts.v0radius) + bitMap.set(selV0Radius); + if (casc.v0radius() < v0cuts.v0radiusMax) + bitMap.set(selV0RadiusMax); + if (casc.v0cosPA(coll.posX(), coll.posY(), coll.posZ()) > v0cuts.v0cospa) + bitMap.set(selV0CosPA); + if (casc.dcaV0daughters() < v0cuts.dcav0dau) + bitMap.set(selDCAV0Dau); + + // proper lifetime + if (ctauXi < nCtauCutCasc->get("lifetimecutXi") * ctauxiPDG) + bitMap.set(selXiCTau); + if (ctauOmega < nCtauCutCasc->get("lifetimecutOmega") * ctauomegaPDG) + bitMap.set(selOmegaCTau); + + auto poseta = RecoDecay::eta(std::array{casc.pxpos(), casc.pypos(), casc.pzpos()}); + auto negeta = RecoDecay::eta(std::array{casc.pxneg(), casc.pyneg(), casc.pzneg()}); + auto bacheta = RecoDecay::eta(std::array{casc.pxbach(), casc.pybach(), casc.pzbach()}); + + // kinematic + if (fabs(rapidityXi) < rapidityCut) + bitMap.set(selXiRapidity); + if (fabs(rapidityOmega) < rapidityCut) + bitMap.set(selOmegaRapidity); + if (fabs(poseta) < daughterEtaCut) + bitMap.set(selNegEta); + if (fabs(negeta) < daughterEtaCut) + bitMap.set(selPosEta); + if (fabs(bacheta) < daughterEtaCut) + bitMap.set(selBachEta); + + // ITS quality flags + if (posTrackExtra.itsNCls() >= TrackConfigurations.minITSclusters) + bitMap.set(selPosGoodITSTrack); + if (negTrackExtra.itsNCls() >= TrackConfigurations.minITSclusters) + bitMap.set(selNegGoodITSTrack); + if (bachTrackExtra.itsNCls() >= TrackConfigurations.minITSclusters) + bitMap.set(selBachGoodITSTrack); + + // TPC quality flags + if (posTrackExtra.tpcCrossedRows() >= TrackConfigurations.minTPCrows) + bitMap.set(selPosGoodTPCTrack); + if (negTrackExtra.tpcCrossedRows() >= TrackConfigurations.minTPCrows) + bitMap.set(selNegGoodTPCTrack); + if (bachTrackExtra.tpcCrossedRows() >= TrackConfigurations.minTPCrows) + bitMap.set(selBachGoodTPCTrack); + + // TPC PID + // positive track + if (fabs(posTrackExtra.tpcNSigmaPi()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDPositivePion); + if (fabs(posTrackExtra.tpcNSigmaPr()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDPositiveProton); + // negative track + if (fabs(negTrackExtra.tpcNSigmaPi()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDNegativePion); + if (fabs(negTrackExtra.tpcNSigmaPr()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDNegativeProton); + // bachelor track + if (fabs(bachTrackExtra.tpcNSigmaPi()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDBachPion); + if (fabs(bachTrackExtra.tpcNSigmaKa()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDBachKaon); + + // TOF PID in DeltaT + // positive track + if (fabs(casc.posTOFDeltaTXiPr()) < PIDConfigurations.maxDeltaTimeProton) + bitMap.set(selTOFDeltaTPositiveProtonLambdaXi); + if (fabs(casc.posTOFDeltaTXiPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTPositivePionLambdaXi); + if (fabs(casc.posTOFDeltaTOmPr()) < PIDConfigurations.maxDeltaTimeProton) + bitMap.set(selTOFDeltaTPositiveProtonLambdaOmega); + if (fabs(casc.posTOFDeltaTOmPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTPositivePionLambdaOmega); + // negative track + if (fabs(casc.negTOFDeltaTXiPr()) < PIDConfigurations.maxDeltaTimeProton) + bitMap.set(selTOFDeltaTNegativeProtonLambdaXi); + if (fabs(casc.negTOFDeltaTXiPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTNegativePionLambdaXi); + if (fabs(casc.negTOFDeltaTOmPr()) < PIDConfigurations.maxDeltaTimeProton) + bitMap.set(selTOFDeltaTNegativeProtonLambdaOmega); + if (fabs(casc.negTOFDeltaTOmPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTNegativePionLambdaOmega); + // bachelor track + if (fabs(casc.bachTOFDeltaTOmKa()) < PIDConfigurations.maxDeltaTimeKaon) + bitMap.set(selTOFDeltaTBachKaonOmega); + if (fabs(casc.bachTOFDeltaTXiPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTBachPionXi); + + // TOF PID in NSigma + // meson track + if (fabs(casc.tofNSigmaXiLaPi()) < PIDConfigurations.TofPidNsigmaCutLaPi) { + bitMap.set(selTOFNSigmaPositivePionLambdaXi); + bitMap.set(selTOFNSigmaNegativePionLambdaXi); + } + if (fabs(casc.tofNSigmaOmLaPi()) < PIDConfigurations.TofPidNsigmaCutLaPi) { + bitMap.set(selTOFNSigmaPositivePionLambdaOmega); + bitMap.set(selTOFNSigmaNegativePionLambdaOmega); + } + // baryon track + if (fabs(casc.tofNSigmaXiLaPr()) < PIDConfigurations.TofPidNsigmaCutLaPr) { + bitMap.set(selTOFNSigmaNegativeProtonLambdaXi); + bitMap.set(selTOFNSigmaPositiveProtonLambdaXi); + } + if (fabs(casc.tofNSigmaOmLaPr()) < PIDConfigurations.TofPidNsigmaCutLaPr) { + bitMap.set(selTOFNSigmaNegativePionLambdaOmega); + bitMap.set(selTOFNSigmaPositivePionLambdaOmega); + } + // bachelor track + if (fabs(casc.tofNSigmaXiPi()) < PIDConfigurations.TofPidNsigmaCutXiPi) { + bitMap.set(selTOFNSigmaBachPionXi); + } + if (fabs(casc.tofNSigmaOmKa()) < PIDConfigurations.TofPidNsigmaCutOmegaKaon) { + bitMap.set(selTOFNSigmaBachKaonOmega); + } + + // ITS only tag + if (posTrackExtra.tpcCrossedRows() < 1) + bitMap.set(selPosItsOnly); + if (negTrackExtra.tpcCrossedRows() < 1) + bitMap.set(selNegItsOnly); + if (bachTrackExtra.tpcCrossedRows() < 1) + bitMap.set(selBachItsOnly); + + // rej. comp. + if (fabs(casc.mOmega() - pdgDB->Mass(3334)) > rejcomp) + bitMap.set(selRejCompXi); + if (fabs(casc.mXi() - pdgDB->Mass(3312)) > rejcomp) + bitMap.set(selRejCompOmega); + + // TPC only tag + if (posTrackExtra.detectorMap() != o2::aod::track::TPC) + bitMap.set(selPosNotTPCOnly); + if (negTrackExtra.detectorMap() != o2::aod::track::TPC) + bitMap.set(selNegNotTPCOnly); + if (bachTrackExtra.detectorMap() != o2::aod::track::TPC) + bitMap.set(selBachNotTPCOnly); + + return bitMap; + } + + template + std::bitset computeBitmapV0(TV0 v0, TCollision collision) + { + float rapidityLambda = v0.yLambda(); + float rapidityK0Short = v0.yK0Short(); + + std::bitset bitMap = 0; + + // base topological variables + if (v0.v0radius() > v0cuts.v0radius) + bitMap.set(selV0Radius); + if (v0.v0radius() < v0cuts.v0radiusMax) + bitMap.set(selV0RadiusMax); + if (fabs(v0.dcapostopv()) > v0cuts.dcapostopv) + bitMap.set(selDCAPosToPV); + if (fabs(v0.dcanegtopv()) > v0cuts.dcanegtopv) + bitMap.set(selDCANegToPV); + if (v0.v0cosPA() > v0cuts.v0cospa) + bitMap.set(selV0CosPA); + if (v0.dcaV0daughters() < v0cuts.dcav0dau) + bitMap.set(selDCAV0Dau); + + // kinematic + if (fabs(rapidityLambda) < rapidityCut) + bitMap.set(selLambdaRapidity); + if (fabs(rapidityK0Short) < rapidityCut) + bitMap.set(selK0ShortRapidity); + if (fabs(v0.negativeeta()) < daughterEtaCut) + bitMap.set(selNegEta); + if (fabs(v0.positiveeta()) < daughterEtaCut) + bitMap.set(selPosEta); + + auto posTrackExtra = v0.template posTrackExtra_as(); + auto negTrackExtra = v0.template negTrackExtra_as(); + + // ITS quality flags + if (posTrackExtra.itsNCls() >= TrackConfigurations.minITSclusters) + bitMap.set(selPosGoodITSTrack); + if (negTrackExtra.itsNCls() >= TrackConfigurations.minITSclusters) + bitMap.set(selNegGoodITSTrack); + + // TPC quality flags + if (posTrackExtra.tpcCrossedRows() >= TrackConfigurations.minTPCrows) + bitMap.set(selPosGoodTPCTrack); + if (negTrackExtra.tpcCrossedRows() >= TrackConfigurations.minTPCrows) + bitMap.set(selNegGoodTPCTrack); + + // TPC PID + if (fabs(posTrackExtra.tpcNSigmaPi()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDPositivePion); + if (fabs(posTrackExtra.tpcNSigmaPr()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDPositiveProton); + if (fabs(negTrackExtra.tpcNSigmaPi()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDNegativePion); + if (fabs(negTrackExtra.tpcNSigmaPr()) < PIDConfigurations.TpcPidNsigmaCut) + bitMap.set(selTPCPIDNegativeProton); + + // TOF PID in DeltaT + // positive track + if (fabs(v0.posTOFDeltaTLaPr()) < PIDConfigurations.maxDeltaTimeProton) + bitMap.set(selTOFDeltaTPositiveProtonLambda); + if (fabs(v0.posTOFDeltaTLaPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTPositivePionLambda); + if (fabs(v0.posTOFDeltaTK0Pi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTPositivePionK0Short); + // negative track + if (fabs(v0.negTOFDeltaTLaPr()) < PIDConfigurations.maxDeltaTimeProton) + bitMap.set(selTOFDeltaTNegativeProtonLambda); + if (fabs(v0.negTOFDeltaTLaPi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTNegativePionLambda); + if (fabs(v0.negTOFDeltaTK0Pi()) < PIDConfigurations.maxDeltaTimePion) + bitMap.set(selTOFDeltaTNegativePionK0Short); + + // TOF PID in NSigma + // positive track + if (fabs(v0.tofNSigmaLaPr()) < PIDConfigurations.TofPidNsigmaCutLaPr) + bitMap.set(selTOFNSigmaPositiveProtonLambda); + if (fabs(v0.tofNSigmaALaPi()) < PIDConfigurations.TofPidNsigmaCutLaPi) + bitMap.set(selTOFNSigmaPositivePionLambda); + if (fabs(v0.tofNSigmaK0PiPlus()) < PIDConfigurations.TofPidNsigmaCutK0Pi) + bitMap.set(selTOFNSigmaPositivePionK0Short); + // negative track + if (fabs(v0.tofNSigmaALaPr()) < PIDConfigurations.TofPidNsigmaCutLaPr) + bitMap.set(selTOFNSigmaNegativeProtonLambda); + if (fabs(v0.tofNSigmaLaPi()) < PIDConfigurations.TofPidNsigmaCutLaPi) + bitMap.set(selTOFNSigmaNegativePionLambda); + if (fabs(v0.tofNSigmaK0PiMinus()) < PIDConfigurations.TofPidNsigmaCutK0Pi) + bitMap.set(selTOFNSigmaNegativePionK0Short); + + // ITS only tag + if (posTrackExtra.tpcCrossedRows() < 1) + bitMap.set(selPosItsOnly); + if (negTrackExtra.tpcCrossedRows() < 1) + bitMap.set(selNegItsOnly); + + // TPC only tag + if (posTrackExtra.detectorMap() != o2::aod::track::TPC) + bitMap.set(selPosNotTPCOnly); + if (negTrackExtra.detectorMap() != o2::aod::track::TPC) + bitMap.set(selNegNotTPCOnly); + + // proper lifetime + if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecutV0->get("lifetimecutLambda")) + bitMap.set(selLambdaCTau); + if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecutV0->get("lifetimecutK0S")) + bitMap.set(selK0ShortCTau); + + // armenteros + if (v0.qtarm() * v0cuts.armPodCut > fabs(v0.alpha()) || v0cuts.armPodCut < 1e-4) + bitMap.set(selK0ShortArmenteros); + + return bitMap; + } + + template + void analyseCascCandidate(TCasc casc, TCollision coll, int gap, std::bitset selMap) + { + if (PIDConfigurations.doPlainTopoQA) { + histos.fill(HIST("GeneralQA/hPt"), casc.pt()); + } + // Xi + if (verifyMask(selMap, maskSelectionXi) && analyseXi) { + histos.fill(HIST("Xi/h2dMassXi"), casc.mXi(), gap); + if (PIDConfigurations.doPlainTopoQA) { + histos.fill(HIST("Xi/hCascCosPA"), casc.pt(), casc.casccosPA(coll.posX(), coll.posY(), coll.posZ())); + histos.fill(HIST("Xi/hDCACascDaughters"), casc.pt(), casc.dcacascdaughters()); + histos.fill(HIST("Xi/hCascRadius"), casc.pt(), casc.cascradius()); + histos.fill(HIST("Xi/hMesonDCAToPV"), casc.pt(), casc.dcanegtopv()); + histos.fill(HIST("Xi/hBaryonDCAToPV"), casc.pt(), casc.dcapostopv()); + histos.fill(HIST("Xi/hBachDCAToPV"), casc.pt(), casc.dcabachtopv()); + histos.fill(HIST("Xi/hV0DCAToPV"), casc.pt(), fabs(casc.dcav0topv(coll.posX(), coll.posY(), coll.posZ()))); + histos.fill(HIST("Xi/hV0CosPA"), casc.pt(), casc.v0cosPA(coll.posX(), coll.posY(), coll.posZ())); + histos.fill(HIST("Xi/hV0Radius"), casc.pt(), casc.v0radius()); + histos.fill(HIST("Xi/hDCAV0Daughters"), casc.pt(), casc.dcaV0daughters()); + histos.fill(HIST("Xi/hMassLambdaDau"), casc.pt(), casc.mLambda()); + } + } + + // Anti-Xi + if (verifyMask(selMap, maskSelectionAntiXi) && analyseAntiXi) { + histos.fill(HIST("AntiXi/h2dMassAntiXi"), casc.mXi(), gap); + } + + // Omega + if (verifyMask(selMap, maskSelectionOmega) && analyseOmega) { + histos.fill(HIST("Omega/h2dMassOmega"), casc.mOmega(), gap); + } + + // Anti-Omega + if (verifyMask(selMap, maskSelectionAntiOmega) && analyseAntiOmega) { + histos.fill(HIST("AntiOmega/h2dMassAntiOmega"), casc.mOmega(), gap); + } + } + + template + void analyseV0Candidate(TV0 v0, float centrality, int gap, std::bitset selMap) + { + auto posTrackExtra = v0.template posTrackExtra_as(); + auto negTrackExtra = v0.template negTrackExtra_as(); + + bool posIsFromAfterburner = posTrackExtra.itsChi2PerNcl() < 0; + bool negIsFromAfterburner = negTrackExtra.itsChi2PerNcl() < 0; + + uint posDetMap = computeDetBitmap(posTrackExtra.detectorMap()); + int posITSclusMap = computeITSclusBitmap(posTrackExtra.itsClusterMap(), posIsFromAfterburner); + uint negDetMap = computeDetBitmap(negTrackExtra.detectorMap()); + int negITSclusMap = computeITSclusBitmap(negTrackExtra.itsClusterMap(), negIsFromAfterburner); + + // QA plots + if (PIDConfigurations.doPlainTopoQA) { + histos.fill(HIST("GeneralQA/hPt"), v0.pt()); + histos.fill(HIST("GeneralQA/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("GeneralQA/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("GeneralQA/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("GeneralQA/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("GeneralQA/hV0Radius"), v0.v0radius()); + histos.fill(HIST("GeneralQA/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("GeneralQA/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } + + histos.fill(HIST("GeneralQA/h2dArmenterosAll"), v0.alpha(), v0.qtarm()); + + // K0s + if (verifyMask(selMap, maskSelectionK0Short) && analyseK0Short) { + histos.fill(HIST("K0Short/h2dMassK0Short"), v0.mK0Short(), gap); + histos.fill(HIST("K0Short/h4dMassK0Short"), centrality, v0.pt(), v0.mK0Short(), gap); + histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), v0.alpha(), v0.qtarm()); + if (PIDConfigurations.doPlainTopoQA) { + histos.fill(HIST("K0Short/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("K0Short/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("K0Short/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("K0Short/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("K0Short/hV0Radius"), v0.v0radius()); + histos.fill(HIST("K0Short/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("K0Short/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } + if (PIDConfigurations.doDetectPropQA == 1) { + histos.fill(HIST("K0Short/h6dDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, v0.pt()); + histos.fill(HIST("K0Short/h4dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), v0.pt()); + histos.fill(HIST("K0Short/h4dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), v0.pt()); + } + if (PIDConfigurations.doDetectPropQA == 2) { + histos.fill(HIST("K0Short/h7dPosDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, v0.pt(), v0.mK0Short()); + histos.fill(HIST("K0Short/h5dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), v0.pt(), v0.mK0Short()); + histos.fill(HIST("K0Short/h5dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), v0.pt(), v0.mK0Short()); + } + if (PIDConfigurations.doTPCQA) { + histos.fill(HIST("K0Short/h3dPosNsigmaTPC"), centrality, v0.pt(), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("K0Short/h3dNegNsigmaTPC"), centrality, v0.pt(), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("K0Short/h3dPosTPCsignal"), centrality, v0.pt(), posTrackExtra.tpcSignal()); + histos.fill(HIST("K0Short/h3dNegTPCsignal"), centrality, v0.pt(), negTrackExtra.tpcSignal()); + histos.fill(HIST("K0Short/h3dPosNsigmaTPCvsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("K0Short/h3dNegNsigmaTPCvsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("K0Short/h3dPosTPCsignalVsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), posTrackExtra.tpcSignal()); + histos.fill(HIST("K0Short/h3dNegTPCsignalVsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), negTrackExtra.tpcSignal()); + histos.fill(HIST("K0Short/h3dPosNsigmaTPCvsTrackPt"), centrality, v0.positivept(), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("K0Short/h3dNegNsigmaTPCvsTrackPt"), centrality, v0.negativept(), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("K0Short/h3dPosTPCsignalVsTrackPt"), centrality, v0.positivept(), posTrackExtra.tpcSignal()); + histos.fill(HIST("K0Short/h3dNegTPCsignalVsTrackPt"), centrality, v0.negativept(), negTrackExtra.tpcSignal()); + } + if (PIDConfigurations.doTOFQA) { + histos.fill(HIST("K0Short/h3dPosTOFdeltaT"), centrality, v0.pt(), v0.posTOFDeltaTK0Pi()); + histos.fill(HIST("K0Short/h3dNegTOFdeltaT"), centrality, v0.pt(), v0.negTOFDeltaTK0Pi()); + histos.fill(HIST("K0Short/h3dPosTOFdeltaTvsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), v0.posTOFDeltaTK0Pi()); + histos.fill(HIST("K0Short/h3dNegTOFdeltaTvsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), v0.negTOFDeltaTK0Pi()); + histos.fill(HIST("K0Short/h3dPosTOFdeltaTvsTrackPt"), centrality, v0.positivept(), v0.posTOFDeltaTK0Pi()); + histos.fill(HIST("K0Short/h3dNegTOFdeltaTvsTrackPt"), centrality, v0.negativept(), v0.negTOFDeltaTK0Pi()); + } + } + + // Lambda + if (verifyMask(selMap, maskSelectionLambda) && analyseLambda) { + histos.fill(HIST("Lambda/h2dMassLambda"), v0.mLambda(), gap); + histos.fill(HIST("Lambda/h4dMassLambda"), centrality, v0.pt(), v0.mLambda(), gap); + if (PIDConfigurations.doPlainTopoQA) { + histos.fill(HIST("Lambda/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("Lambda/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("Lambda/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("Lambda/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("Lambda/hV0Radius"), v0.v0radius()); + histos.fill(HIST("Lambda/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("Lambda/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } + if (PIDConfigurations.doDetectPropQA == 1) { + histos.fill(HIST("Lambda/h6dDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, v0.pt()); + histos.fill(HIST("Lambda/h4dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), v0.pt()); + histos.fill(HIST("Lambda/h4dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), v0.pt()); + } + if (PIDConfigurations.doDetectPropQA == 2) { + histos.fill(HIST("Lambda/h7dDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, v0.pt(), v0.mLambda()); + histos.fill(HIST("Lambda/h5dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), v0.pt(), v0.mLambda()); + histos.fill(HIST("Lambda/h5dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), v0.pt(), v0.mLambda()); + } + if (PIDConfigurations.doTPCQA) { + histos.fill(HIST("Lambda/h3dPosNsigmaTPC"), centrality, v0.pt(), posTrackExtra.tpcNSigmaPr()); + histos.fill(HIST("Lambda/h3dNegNsigmaTPC"), centrality, v0.pt(), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("Lambda/h3dPosTPCsignal"), centrality, v0.pt(), posTrackExtra.tpcSignal()); + histos.fill(HIST("Lambda/h3dNegTPCsignal"), centrality, v0.pt(), negTrackExtra.tpcSignal()); + histos.fill(HIST("Lambda/h3dPosNsigmaTPCvsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), posTrackExtra.tpcNSigmaPr()); + histos.fill(HIST("Lambda/h3dNegNsigmaTPCvsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("Lambda/h3dPosTPCsignalVsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), posTrackExtra.tpcSignal()); + histos.fill(HIST("Lambda/h3dNegTPCsignalVsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), negTrackExtra.tpcSignal()); + histos.fill(HIST("Lambda/h3dPosNsigmaTPCvsTrackPt"), centrality, v0.positivept(), posTrackExtra.tpcNSigmaPr()); + histos.fill(HIST("Lambda/h3dNegNsigmaTPCvsTrackPt"), centrality, v0.negativept(), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("Lambda/h3dPosTPCsignalVsTrackPt"), centrality, v0.positivept(), posTrackExtra.tpcSignal()); + histos.fill(HIST("Lambda/h3dNegTPCsignalVsTrackPt"), centrality, v0.negativept(), negTrackExtra.tpcSignal()); + } + if (PIDConfigurations.doTOFQA) { + histos.fill(HIST("Lambda/h3dPosTOFdeltaT"), centrality, v0.pt(), v0.posTOFDeltaTLaPr()); + histos.fill(HIST("Lambda/h3dNegTOFdeltaT"), centrality, v0.pt(), v0.negTOFDeltaTLaPi()); + histos.fill(HIST("Lambda/h3dPosTOFdeltaTvsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), v0.posTOFDeltaTLaPr()); + histos.fill(HIST("Lambda/h3dNegTOFdeltaTvsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), v0.negTOFDeltaTLaPi()); + histos.fill(HIST("Lambda/h3dPosTOFdeltaTvsTrackPt"), centrality, v0.positivept(), v0.posTOFDeltaTLaPr()); + histos.fill(HIST("Lambda/h3dNegTOFdeltaTvsTrackPt"), centrality, v0.negativept(), v0.negTOFDeltaTLaPi()); + } + } + + // Anti-Lambda + if (verifyMask(selMap, maskSelectionAntiLambda) && analyseAntiLambda) { + histos.fill(HIST("AntiLambda/h2dMassAntiLambda"), v0.mAntiLambda(), gap); + histos.fill(HIST("AntiLambda/h4dMassAntiLambda"), centrality, v0.pt(), v0.mAntiLambda(), gap); + if (PIDConfigurations.doPlainTopoQA) { + histos.fill(HIST("AntiLambda/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("AntiLambda/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("AntiLambda/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("AntiLambda/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("AntiLambda/hV0Radius"), v0.v0radius()); + histos.fill(HIST("AntiLambda/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("AntiLambda/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } + if (PIDConfigurations.doDetectPropQA == 1) { + histos.fill(HIST("AntiLambda/h6dDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, v0.pt()); + histos.fill(HIST("AntiLambda/h4dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), v0.pt()); + histos.fill(HIST("AntiLambda/h4dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), v0.pt()); + } + if (PIDConfigurations.doDetectPropQA == 2) { + histos.fill(HIST("AntiLambda/h7dDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, v0.pt(), v0.mAntiLambda()); + histos.fill(HIST("AntiLambda/h5dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), v0.pt(), v0.mAntiLambda()); + histos.fill(HIST("AntiLambda/h5dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), v0.pt(), v0.mAntiLambda()); + } + if (PIDConfigurations.doTPCQA) { + histos.fill(HIST("AntiLambda/h3dPosNsigmaTPC"), centrality, v0.pt(), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("AntiLambda/h3dNegNsigmaTPC"), centrality, v0.pt(), negTrackExtra.tpcNSigmaPr()); + histos.fill(HIST("AntiLambda/h3dPosTPCsignal"), centrality, v0.pt(), posTrackExtra.tpcSignal()); + histos.fill(HIST("AntiLambda/h3dNegTPCsignal"), centrality, v0.pt(), negTrackExtra.tpcSignal()); + histos.fill(HIST("AntiLambda/h3dPosNsigmaTPCvsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("AntiLambda/h3dNegNsigmaTPCvsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), negTrackExtra.tpcNSigmaPr()); + histos.fill(HIST("AntiLambda/h3dPosTPCsignalVsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), posTrackExtra.tpcSignal()); + histos.fill(HIST("AntiLambda/h3dNegTPCsignalVsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), negTrackExtra.tpcSignal()); + histos.fill(HIST("AntiLambda/h3dPosNsigmaTPCvsTrackPt"), centrality, v0.positivept(), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST("AntiLambda/h3dNegNsigmaTPCvsTrackPt"), centrality, v0.negativept(), negTrackExtra.tpcNSigmaPr()); + histos.fill(HIST("AntiLambda/h3dPosTPCsignalVsTrackPt"), centrality, v0.positivept(), posTrackExtra.tpcSignal()); + histos.fill(HIST("AntiLambda/h3dNegTPCsignalVsTrackPt"), centrality, v0.negativept(), negTrackExtra.tpcSignal()); + } + if (PIDConfigurations.doTOFQA) { + histos.fill(HIST("AntiLambda/h3dPosTOFdeltaT"), centrality, v0.pt(), v0.posTOFDeltaTLaPi()); + histos.fill(HIST("AntiLambda/h3dNegTOFdeltaT"), centrality, v0.pt(), v0.negTOFDeltaTLaPr()); + histos.fill(HIST("AntiLambda/h3dPosTOFdeltaTvsTrackPtot"), centrality, v0.positivept() * TMath::CosH(v0.positiveeta()), v0.posTOFDeltaTLaPi()); + histos.fill(HIST("AntiLambda/h3dNegTOFdeltaTvsTrackPtot"), centrality, v0.negativept() * TMath::CosH(v0.negativeeta()), v0.negTOFDeltaTLaPr()); + histos.fill(HIST("AntiLambda/h3dPosTOFdeltaTvsTrackPt"), centrality, v0.positivept(), v0.posTOFDeltaTLaPi()); + histos.fill(HIST("AntiLambda/h3dNegTOFdeltaTvsTrackPt"), centrality, v0.negativept(), v0.negTOFDeltaTLaPr()); + } + } + } + + void processV0s(straCollisonFull const& collision, v0Candidates const& fullV0s, dauTracks const&) + { + if (!acceptEvent(collision)) { + return; + } // event is accepted + + // gap side + int gapSide = collision.gapSide(); + int selGapSide = -1; + if (collision.isUPC()) { + selGapSide = sgSelector.trueGap(collision, upcCuts.FV0cut, upcCuts.FT0Acut, upcCuts.FT0Ccut, upcCuts.ZDCcut); + histos.fill(HIST("eventQA/hGapSide"), gapSide); + histos.fill(HIST("eventQA/hSelGapSide"), selGapSide); + if (studyUPConly && selGapSide < -0.5) // 0 - A, 1 - C, 2 - DG; -1 - no gap + return; + } + + for (auto& v0 : fullV0s) { + if (v0.v0Type() != v0cuts.v0TypeSelection && v0cuts.v0TypeSelection > 0) + continue; // skip V0s that are not standard + + std::bitset selMap = computeBitmapV0(v0, collision); + + // consider for histograms for all species + setBits(selMap, {selConsiderK0Short, selConsiderLambda, selConsiderAntiLambda, + selPhysPrimK0Short, selPhysPrimLambda, selPhysPrimAntiLambda}); + + analyseV0Candidate(v0, collision.centFT0C(), selGapSide, selMap); + } // end v0 loop + } + + void processCascades(straCollisonFull const& collision, cascadeCandidates const& fullCascades, dauTracks const&) + { + if (!acceptEvent(collision)) { + return; + } // event is accepted + + // gap side + int gapSide = collision.gapSide(); + int selGapSide = -1; + if (collision.isUPC()) { + selGapSide = sgSelector.trueGap(collision, upcCuts.FV0cut, upcCuts.FT0Acut, upcCuts.FT0Ccut, upcCuts.ZDCcut); + histos.fill(HIST("eventQA/hGapSide"), gapSide); + histos.fill(HIST("eventQA/hSelGapSide"), selGapSide); + if (studyUPConly && selGapSide < -0.5) // 0 - A, 1 - C, 2 - DG; -1 - no gap + return; + } + + for (auto& casc : fullCascades) { + std::bitset selMap = computeBitmapCascade(casc, collision); + // consider for histograms for all species + setBits(selMap, {selConsiderXi, selConsiderAntiXi, selConsiderOmega, selConsiderAntiOmega, + selPhysPrimXi, selPhysPrimAntiXi, selPhysPrimOmega, selPhysPrimAntiOmega}); + + analyseCascCandidate(casc, collision, selGapSide, selMap); + } // end casc loop + } + + PROCESS_SWITCH(strangeYieldPbPb, processV0s, "Process V0s in UPC", true); + PROCESS_SWITCH(strangeYieldPbPb, processCascades, "Process Cascades in UPC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Utils/strangenessMasks.h b/PWGLF/Utils/strangenessMasks.h new file mode 100644 index 00000000000..7b567218de6 --- /dev/null +++ b/PWGLF/Utils/strangenessMasks.h @@ -0,0 +1,150 @@ +// Copyright 2019-2024 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \author Roman Nepeivoda (roman.nepeivoda@cern.ch) +/// \since August 27, 2024 + +#ifndef PWGLF_UTILS_STRANGENESSMASKS_H_ +#define PWGLF_UTILS_STRANGENESSMASKS_H_ + +enum selectionsCombined : int { selV0CosPA = 0, + selV0Radius, + selV0RadiusMax, + selDCANegToPV, + selDCAPosToPV, + selDCAV0Dau, + selK0ShortRapidity, + selLambdaRapidity, + selTPCPIDPositivePion, + selTPCPIDNegativePion, + selTPCPIDPositiveProton, + selTPCPIDNegativeProton, + selTOFDeltaTPositiveProtonLambda, + selTOFDeltaTPositivePionLambda, + selTOFDeltaTPositivePionK0Short, + selTOFDeltaTNegativeProtonLambda, + selTOFDeltaTNegativePionLambda, + selTOFDeltaTNegativePionK0Short, + selTOFNSigmaPositiveProtonLambda, // Nsigma + selTOFNSigmaPositivePionLambda, // Nsigma + selTOFNSigmaPositivePionK0Short, // Nsigma + selTOFNSigmaNegativeProtonLambda, // Nsigma + selTOFNSigmaNegativePionLambda, // Nsigma + selTOFNSigmaNegativePionK0Short, // Nsigma + selK0ShortCTau, + selLambdaCTau, + selK0ShortArmenteros, + selPosGoodTPCTrack, // at least min # TPC rows + selNegGoodTPCTrack, // at least min # TPC rows + selPosGoodITSTrack, // at least min # ITS clusters + selNegGoodITSTrack, // at least min # ITS clusters + selPosItsOnly, + selNegItsOnly, + selPosNotTPCOnly, + selNegNotTPCOnly, + selConsiderK0Short, // for mc tagging + selConsiderLambda, // for mc tagging + selConsiderAntiLambda, // for mc tagging + selPhysPrimK0Short, // for mc tagging + selPhysPrimLambda, // for mc tagging + selPhysPrimAntiLambda, // for mc tagging + selPosEta, + selNegEta, + // cascade selections + selCascCosPA, + selMassWinXi, + selMassWinOmega, + selDCACascDau, + selDCAV0ToPV, + selCascRadius, + selCascRadiusMax, + selBachBaryon, + selRejCompXi, + selRejCompOmega, + selBachToPV, + selMesonToPV, + selBaryonToPV, + selXiRapidity, + selXiCTau, + selConsiderXi, + selConsiderAntiXi, + selPhysPrimXi, + selPhysPrimAntiXi, + selOmegaRapidity, + selOmegaCTau, + selConsiderOmega, + selConsiderAntiOmega, + selPhysPrimOmega, + selPhysPrimAntiOmega, + selBachItsOnly, + selBachNotTPCOnly, + selBachGoodTPCTrack, + selBachGoodITSTrack, + selTPCPIDBachPion, + selTPCPIDBachKaon, + selTOFNSigmaBachPionXi, + selTOFNSigmaBachKaonOmega, + selTOFNSigmaPositiveProtonLambdaXi, + selTOFNSigmaPositiveProtonLambdaOmega, + selTOFNSigmaPositivePionLambdaXi, + selTOFNSigmaPositivePionLambdaOmega, + selTOFNSigmaNegativePionLambdaXi, + selTOFNSigmaNegativePionLambdaOmega, + selTOFNSigmaNegativeProtonLambdaXi, + selTOFNSigmaNegativeProtonLambdaOmega, + selTOFDeltaTPositiveProtonLambdaXi, + selTOFDeltaTPositiveProtonLambdaOmega, + selTOFDeltaTPositivePionLambdaXi, + selTOFDeltaTPositivePionLambdaOmega, + selTOFDeltaTNegativeProtonLambdaXi, + selTOFDeltaTNegativeProtonLambdaOmega, + selTOFDeltaTNegativePionLambdaXi, + selTOFDeltaTNegativePionLambdaOmega, + selTOFDeltaTBachPionXi, + selTOFDeltaTBachKaonOmega, + selBachEta, + selLambdaMassWin, + selCount, +}; + +static constexpr int selNum = static_cast(selectionsCombined::selCount); + +// constants +const float ctauxiPDG = 4.91; // from PDG +const float ctauomegaPDG = 2.461; // from PDG + +// bit masks +std::bitset maskTopologicalV0; +std::bitset maskTopologicalCasc; + +std::bitset maskKinematicV0; +std::bitset maskKinematicCasc; + +std::bitset maskTrackPropertiesV0; +std::bitset maskTrackPropertiesCasc; + +std::bitset maskK0ShortSpecific; +std::bitset maskLambdaSpecific; +std::bitset maskAntiLambdaSpecific; +std::bitset maskXiSpecific; +std::bitset maskAntiXiSpecific; +std::bitset maskOmegaSpecific; +std::bitset maskAntiOmegaSpecific; + +std::bitset maskSelectionK0Short; +std::bitset maskSelectionLambda; +std::bitset maskSelectionAntiLambda; +std::bitset maskSelectionXi; +std::bitset maskSelectionAntiXi; +std::bitset maskSelectionOmega; +std::bitset maskSelectionAntiOmega; + +#endif // PWGLF_UTILS_STRANGENESSMASKS_H_